diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index d57bbc9e85ed0f60e6c41ea4593ed1e1c12c6b38..a22babc33f4c1cd573f854d7abb52dac929257fc 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -314,7 +314,8 @@ file(GLOB rrc_h ${RRC_FULL_DIR}/*.h) set(rrc_h ${rrc_h} ${RRC_FULL_DIR}/asn1_constants.h) set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code add_library(RRC_LIB ${rrc_h} ${rrc_source} - ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg.c) + ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg.c + ${OPENAIR2_DIR}/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c) include_directories ("${RRC_FULL_DIR}") # add the command to generate the source code @@ -1042,6 +1043,19 @@ include_directories(${NFAPI_USER_DIR}) # Layer 1 ############################# +set(PHY_TURBOSRC + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder.c +) +set(PHY_TURBOIF + ${OPENAIR1_DIR}/PHY/CODING/coding_load.c +) + +add_library(coding MODULE ${PHY_TURBOSRC} ) set(PHY_SRC # depend on code generation from asn1c ${RRC_FULL_DIR}/asn1_constants.h @@ -1109,11 +1123,8 @@ set(PHY_SRC ${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c ${OPENAIR1_DIR}/PHY/CODING/crc_byte.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${PHY_TURBOIF} ${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c ${OPENAIR1_DIR}/PHY/CODING/viterbi.c ${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c @@ -1206,9 +1217,7 @@ set(PHY_SRC_UE ${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c ${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c ${OPENAIR1_DIR}/PHY/CODING/crc_byte.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c - ${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c + ${PHY_TURBOIF} ${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c ${OPENAIR1_DIR}/PHY/CODING/viterbi.c ${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c @@ -1300,7 +1309,6 @@ set(L2_SRC ) set(L2_SRC_UE - ${OPENAIR2_DIR}/LAYER2/openair2_proc.c ${PDCP_DIR}/pdcp.c ${PDCP_DIR}/pdcp_fifo.c ${PDCP_DIR}/pdcp_sequence_manager.c @@ -1374,6 +1382,7 @@ set (MAC_SRC_UE set (ENB_APP_SRC ${OPENAIR2_DIR}/ENB_APP/enb_app.c ${OPENAIR2_DIR}/ENB_APP/enb_config.c + ${OPENAIR2_DIR}/ENB_APP/RRC_config_tools.c ) add_library(L2 @@ -1709,6 +1718,17 @@ if(NAS_UE) endif() +# nbiot +add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16") +set (NBIOT_SOURCES + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c +) +add_library(NB_IoT MODULE ${NBIOT_SOURCES} ) + +# shared library loader +set (SHLIB_LOADER_SOURCES + ${OPENAIR_DIR}/common/utils/load_module_shlib.c +) # Make lfds as a own source code (even if it is a outside library) # For better intergration with compilation flags & structure of cmake @@ -1781,6 +1801,7 @@ include_directories("${NFAPI_DIR}/nfapi/inc") include_directories("${NFAPI_DIR}/sim_common/inc") include_directories("${NFAPI_DIR}/pnf_sim/inc") + # System packages that are required # We use either the cmake buildin, in ubuntu are in: /usr/share/cmake*/Modules/ # or cmake provide a generic interface to pkg-config that widely used @@ -1936,14 +1957,13 @@ add_executable(lte-softmodem ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c - ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c @@ -1959,9 +1979,9 @@ add_executable(lte-softmodem target_link_libraries (lte-softmodem -Wl,--start-group - RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB - NFAPI_USER_LIB + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS L2 + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES}) @@ -1976,14 +1996,13 @@ add_executable(lte-softmodem-nos1 ${s1ap_h} ${OPENAIR_BIN_DIR}/messages_xml.h ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c - ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c - ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c @@ -1997,9 +2016,9 @@ add_executable(lte-softmodem-nos1 ) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group - RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 - NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB - NFAPI_USER_LIB + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB PHY LFDS L2 ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 + NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl ) target_link_libraries (lte-softmodem-nos1 ${LIBXML2_LIBRARIES}) @@ -2007,6 +2026,76 @@ target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES}) target_link_libraries (lte-softmodem-nos1 ${T_LIB}) +# lte-uesoftmodem is UE implementation +####################################### + +add_executable(lte-uesoftmodem + ${rrc_h} + ${s1ap_h} + ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c + ${OPENAIR_DIR}/common/utils/utils.c + ${OPENAIR_DIR}/common/utils/system.c + ${XFORMS_SOURCE} + ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ) + +target_link_libraries (lte-uesoftmodem + -Wl,--start-group + RRC_LIB S1AP_LIB S1AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_UE_LIB PHY_UE LFDS L2_UE + ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + -Wl,--end-group z dl) + +target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES}) +target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem ${T_LIB}) + +# lte-softmodem-nos1 is both eNB and UE implementation +################################################### +add_executable(lte-uesoftmodem-nos1 + ${rrc_h} + ${s1ap_h} + ${OPENAIR_BIN_DIR}/messages_xml.h + ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c + ${OPENAIR_TARGETS}/RT/USER/lte-ue.c + ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c + ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c + ${OPENAIR_TARGETS}/COMMON/create_tasks_ue.c + ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c + ${OPENAIR2_DIR}/RRC/NAS/nas_config.c + ${OPENAIR2_DIR}/RRC/NAS/rb_config.c + ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c + ${OPENAIR_DIR}/common/utils/system.c + ${XFORMS_SOURCE} + ${XFORMS_SOURCE_SOFTMODEM} + ${T_SOURCE} + ${CONFIG_SOURCES} + ${SHLIB_LOADER_SOURCES} + ) +target_link_libraries (lte-uesoftmodem-nos1 + -Wl,--start-group + RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_UE_LIB PHY_UE LFDS L2_UE ${MSC_LIB} ${RAL_LIB} ${ITTI_LIB} + ${MIH_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 + -Wl,--end-group z dl ) + +target_link_libraries (lte-uesoftmodem-nos1 ${LIBXML2_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 ${LIB_LMS_LIBRARIES}) +target_link_libraries (lte-uesoftmodem-nos1 ${T_LIB}) + # USIM process ################# #add_executable(usim @@ -2148,11 +2237,12 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c ${XFORMS_SOURCE} ${T_SOURCE} + ${CONFIG_SOURCES} ) target_link_libraries (${myExe} -Wl,--start-group SIMU UTIL SCHED_LIB PHY LFDS ${ITTI_LIB} LFDS7 -Wl,--end-group - pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} + pthread m rt ${CONFIG_LIBRARIES} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) endforeach(myExe) @@ -2398,3 +2488,8 @@ ADD_CUSTOM_TARGET(oarf DEPENDS ${OCT_FILES} ) +include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt) + + + + diff --git a/cmake_targets/autotests/v2/connection.py b/cmake_targets/autotests/v2/connection.py index 1952b8b72f713ff2eb7cff44802b6b18fc138f63..3a254f89b8b0fe02dbbd43fecddbad5ea17ee087 100644 --- a/cmake_targets/autotests/v2/connection.py +++ b/cmake_targets/autotests/v2/connection.py @@ -13,7 +13,7 @@ class connection: try: (pid, fd) = os.forkpty() except BaseException, e: - log("ERROR: forkpty for '" + description + "': " + e) + log("ERROR: forkpty for '" + description + "': " + str(e)) (pid, fd) = (-1, -1) if pid == -1: @@ -26,7 +26,7 @@ class connection: os.execvp('sshpass', ['sshpass', '-p', password, 'ssh', user + '@' + host]) except BaseException, e: - log("ERROR: execvp for '" + description + "': " + e) + log("ERROR: execvp for '" + description + "': " + str(e)) log("ERROR: execvp failed for '" + description + "'") os._exit(1) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 7e0c0ca169c5708b69527fd6db9c0e559032653b..f5be69d3fa2caea77f0bf0ac28960600e761f5bf 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -359,7 +359,11 @@ function main() { CMAKE_CMD="$CMAKE_CMD .." echo_info "CMAKE_CMD=$CMAKE_CMD" - + if [ "$eNB" = "1" ] && [ "$UE" = "1" ]; then + echo_error "Cannot build UE and eNB on one build_oai execution" + echo_error "use 2 build_oai invocations" + exit + fi ######################################################### # check validity of HW and TP parameters for eNB ######################################################### @@ -488,10 +492,20 @@ function main() { DIR=$OPENAIR_DIR/cmake_targets if [ "$NOS1" = "1" ] ; then lte_build_dir=lte_noS1_build_oai - lte_exec=lte-softmodem-nos1 + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem-nos1 + fi + if [ "$UE" = "1" ] ; then + lte_exec=lte-uesoftmodem-nos1 + fi else lte_build_dir=lte_build_oai - lte_exec=lte-softmodem + if [ "$eNB" = "1" ] ; then + lte_exec=lte-softmodem + fi + if [ "$UE" = "1" ] ; then + lte_exec=lte-uesoftmodem + fi fi # configuration module libraries, one currently available, using libconfig @@ -544,6 +558,9 @@ function main() { compilations \ $lte_build_dir $config_libconfig_shlib \ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so + compilations \ + $lte_build_dir coding \ + libcoding.so $dbin/libcoding.so if [ "$NOS1" = "1" ] ; then compilations \ @@ -766,17 +783,10 @@ function main() { # Telnet server compilation ##################### if [ "$BUILD_TELNETSRV" = "1" ] ; then - - telnetsrv_build_dir=telnetsrv - mkdir -p $DIR/$telnetsrv_build_dir/build - cd $DIR/$telnetsrv_build_dir/build - echo_info "Compiling telnet server library ..." - - [ "$CLEAN" = "1" ] && rm -rf $DIR/$telnetsrv_build_dir - cmake_file=$OPENAIR_DIR/common/utils/$telnetsrv_build_dir/CMakeLists.txt - cd $DIR/$telnetsrv_build_dir/build - eval "$CMAKE_CMD $OPENAIR_DIR/common/utils/$telnetsrv_build_dir/" - make + build_dir=$lte_build_dir + compilations \ + $build_dir telnetsrv \ + libtelnetsrv.so $dbin/libtelnetsrv.so fi # build RF device and transport protocol libraries diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 1ea97c030f2b07169c0009920e55be800c7da3c1..706cd05fe9ff084d62bf818aebf5e126c6e183dc 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -249,14 +249,14 @@ install_usrp_uhd_driver_from_source(){ cd /tmp echo "Downloading UHD driver" rm -rf /tmp/uhd - git clone git://github.com/EttusResearch/uhd.git + git clone https://github.com/EttusResearch/uhd.git cd uhd git checkout tags/release_003_010_001_001 mkdir -p host/build cd host/build $CMAKE ../ echo "Compiling UHD" - make + make -j`nproc` make test $SUDO make install $SUDO ldconfig @@ -277,10 +277,11 @@ check_install_usrp_uhd_driver(){ $SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake + $SUDO pip install requests if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source $SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware - install_ursp_uhd_driver_from_source + install_usrp_uhd_driver_from_source else $SUDO $INSTALLER -y install uhd uhd-devel uhd-firmware fi @@ -644,7 +645,8 @@ check_install_oai_software() { lapack \ lapack-devel \ blas \ - blas-devel + blas-devel \ + libyaml-devel fi install_asn1c_from_source diff --git a/cmake_targets/tools/fix_asn1 b/cmake_targets/tools/fix_asn1 index 5cdab5ffd8cae3b43bb41b6908924de5ec04985b..fe819c27162df2174c27cc2cc93aa250b00c3bd1 100755 --- a/cmake_targets/tools/fix_asn1 +++ b/cmake_targets/tools/fix_asn1 @@ -5,6 +5,7 @@ RRC_Rel14=( "SystemInformation-r8-IEs.h" 4df485c5ddf2540eca271876cdc512caa19b0890 "fix_asn1.data/RRC.rel14/SystemInformation-r8-IEs.h.diff" + "SystemInformation-NB-r13-IEs.h" 6d91332d5c39205819b06e5e36efe62ff8e5b33b "fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff" ) RRC_Rel10=( diff --git a/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff new file mode 100644 index 0000000000000000000000000000000000000000..37ac4cd85855c7436de8d1ab89a25e7041b3c9c6 --- /dev/null +++ b/cmake_targets/tools/fix_asn1.data/RRC.rel14/SystemInformation-NB-r13-IEs.h.diff @@ -0,0 +1,47 @@ +48a49,70 +> struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member { +> SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present; +> union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u { +> SystemInformationBlockType2_NB_r13_t sib2_r13; +> SystemInformationBlockType3_NB_r13_t sib3_r13; +> SystemInformationBlockType4_NB_r13_t sib4_r13; +> SystemInformationBlockType5_NB_r13_t sib5_r13; +> SystemInformationBlockType14_NB_r13_t sib14_r13; +> SystemInformationBlockType16_NB_r13_t sib16_r13; +> /* +> * This type is extensible, +> * possible extensions are below. +> */ +> SystemInformationBlockType15_NB_r14_t sib15_v1430; +> SystemInformationBlockType20_NB_r14_t sib20_v1430; +> SystemInformationBlockType22_NB_r14_t sib22_v1430; +> } choice; +> +> /* Context for parsing across buffer boundaries */ +> asn_struct_ctx_t _asn_ctx; +> }; +> +52,72c74 +< A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member { +< SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR present; +< union SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_u { +< SystemInformationBlockType2_NB_r13_t sib2_r13; +< SystemInformationBlockType3_NB_r13_t sib3_r13; +< SystemInformationBlockType4_NB_r13_t sib4_r13; +< SystemInformationBlockType5_NB_r13_t sib5_r13; +< SystemInformationBlockType14_NB_r13_t sib14_r13; +< SystemInformationBlockType16_NB_r13_t sib16_r13; +< /* +< * This type is extensible, +< * possible extensions are below. +< */ +< SystemInformationBlockType15_NB_r14_t sib15_v1430; +< SystemInformationBlockType20_NB_r14_t sib20_v1430; +< SystemInformationBlockType22_NB_r14_t sib22_v1430; +< } choice; +< +< /* Context for parsing across buffer boundaries */ +< asn_struct_ctx_t _asn_ctx; +< } ) list; +--- +> A_SEQUENCE_OF(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member) list; diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index cb24cc52222f3a4fed6af979b61882a4db234c39..040cd92fafaad3f799a9e2ac5baa212daf67e355 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index ff66d22a1c847bd783ccd43211709b1e5bf741c1..7860742804ea72b9a0e1b5d387f3a15af485ed4f 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -197,25 +197,40 @@ int i; return cfgptr; } -void end_configmodule() + +/* free memory allocated when reading parameters */ +/* config module could be initialized again after this call */ +void end_configmodule(void) { if (cfgptr != NULL) { if (cfgptr->end != NULL) { printf ("[CONFIG] calling config module end function...\n"); cfgptr->end(); } - if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); - printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); - for (int i=0; i<cfgptr->num_cfgP; i++) { - if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); - } + printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); for(int i=0; i<cfgptr->numptrs ; i++) { if (cfgptr->ptrs[i] != NULL) { free(cfgptr->ptrs[i]); + cfgptr->ptrs[i]=NULL; } - cfgptr->ptrs[i]=NULL; } + cfgptr->numptrs=0; + } +} + +/* free all memory used by config module */ +/* should be called only at program exit */ +void free_configmodule(void) +{ + if (cfgptr != NULL) { + end_configmodule(); + if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); + printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); + for (int i=0; i<cfgptr->num_cfgP; i++) { + if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); + } + free(cfgptr); cfgptr=NULL; diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index 76f074cd6c38cf805938f28567237368b2d8e253..724cd1dbf528f5e38e865d05d94d1b050a006e84 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -40,15 +40,18 @@ #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2... #define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module -/* rtflags bit position definitions */ -#define CONFIG_PRINTPARAMS 1 // print parameters values while processing -#define CONFIG_DEBUGPTR 2 // print memory allocation/free debug messages -#define CONFIG_DEBUGCMDLINE 4 // print command line processing messages -#define CONFIG_HELP 8 // print help message -#define CONFIG_ABORT 16 // config failed,abort execution -#define CONFIG_NOOOPT 32 // no -O option found when parsing command line - +/* default values for configuration module parameters */ +#define DEFAULT_CFGMODE "libconfig" // use libconfig file +#define DEFAULT_CFGFILENAME "oai.conf" // default config file +/* rtflags bit position definitions */ +#define CONFIG_PRINTPARAMS 1 // print parameters values while processing +#define CONFIG_DEBUGPTR 1<<1 // print memory allocation/free debug messages +#define CONFIG_DEBUGCMDLINE 1<<2 // print command line processing messages +#define CONFIG_NOABORTONCHKF 1<<3 // disable abort execution when parameter checking function fails +#define CONFIG_HELP 1<<20 // print help message +#define CONFIG_ABORT 1<<21 // config failed,abort execution +#define CONFIG_NOOOPT 1<<22 // no -O option found when parsing command line typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP); typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix); typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix); diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index a7de5e3098ffabc47226eb8c04ab0381b3593af8..6f153535fb56c2cf0ef5c8cb7599899195604abc 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -55,16 +55,61 @@ #define PARAMFLAG_PARAMSET (1 << 16) // parameter has been explicitely set in get functions #define PARAMFLAG_PARAMSETDEF (1 << 17) // parameter has been set to default value in get functions + +/* checkedparam_t is possibly used in paramdef_t for specific parameter value validation */ +#define CONFIG_MAX_NUMCHECKVAL 20 +typedef struct paramdef paramdef_t; +typedef union checkedparam { + struct { + int (*f1)(paramdef_t *param); /* check an integer against a list of authorized values */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1; + struct { + int (*f1a)(paramdef_t *param); /* check an integer against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values in config file */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1a; + struct { + int (*f2)(paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */ + int okintrange[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store min and max values */ + + } s2; + struct { + int (*f3)(paramdef_t *param); /* check a string against a list of authorized values */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3; + struct { + int (*f3a)(paramdef_t *param); /* check a string against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3a; + struct { + int (*f4)(paramdef_t *param); /* generic check function, no arguments but the param description */ + + } s4; + struct { + void (*checkfunc)(void) ; + } s5; +} checkedparam_t; + +/* paramdef is used to describe a parameter, array of paramdef_t strustures is used as the main parameter in */ +/* config apis used to retrieve parameters values */ typedef struct paramdef { - char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ - char *helpstr; /* help string */ - unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ - union { /* pointer to the parameter value, completed by the config module */ + char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ + char *helpstr; /* help string */ + unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ + union { /* pointer to the parameter value, completed by the config module */ char **strptr; char **strlistptr; uint8_t *u8ptr; - char *i8ptr; + int8_t *i8ptr; uint16_t *u16ptr; int16_t *i16ptr; uint32_t *uptr; @@ -72,18 +117,21 @@ typedef struct paramdef uint64_t *u64ptr; int64_t *i64ptr; double *dblptr; + void *voidptr; } ; union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */ - char *defstrval; - char **defstrlistval; - uint32_t defuintval; - int defintval; - uint64_t defint64val; - int *defintarrayval; - double defdblval; + char *defstrval; + char **defstrlistval; + uint32_t defuintval; + int defintval; + uint64_t defint64val; + int *defintarrayval; + double defdblval; } ; char type; /* parameter value type, as listed below as TYPE_XXXX macro */ int numelt; /* number of elements in a list or array parameters or max size of string value */ + checkedparam_t *chkPptr; /* possible pointer to the structure containing the info used to check parameter values */ + int *processedvalue; /* used to store integer values computed from string original value */ } paramdef_t; #define TYPE_INT TYPE_INT32 diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index acee5646cd7aae319f6fccef056a309e306d8fde..c1acc84384a0d91045c8b2e95f66ac98bd16ca68 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -36,6 +36,7 @@ #include <errno.h> #include <dlfcn.h> #include "config_userapi.h" +extern void exit_fun(const char* s); // lte-softmodem clean exit function configmodule_interface_t *config_get_if(void) @@ -59,7 +60,7 @@ char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) *ptr = malloc(length); if ( *ptr != NULL) { memset(*ptr,0,length); - if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) != 0) { + if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { config_get_if()->ptrs[config_get_if()->numptrs] = *ptr; config_get_if()->numptrs++; } @@ -111,7 +112,29 @@ int tmpval=val; break; } } +void config_assign_processedint(paramdef_t *cfgoption, int val) { + cfgoption->processedvalue = malloc(sizeof(int)); + if ( cfgoption->processedvalue != NULL) { + *(cfgoption->processedvalue) = val; + } else { + fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__); + exit(-1); + } +} +int config_get_processedint(paramdef_t *cfgoption) { + int ret; + if ( cfgoption->processedvalue != NULL) { + ret=*(cfgoption->processedvalue); + free( cfgoption->processedvalue); + cfgoption->processedvalue=NULL; + printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret); + } else { + fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname); + ret=0; + } +return ret; +} void config_printhelp(paramdef_t *params,int numparams) { for (int i=0 ; i<numparams ; i++) { @@ -124,11 +147,31 @@ void config_printhelp(paramdef_t *params,int numparams) } } +int config_execcheck(paramdef_t *params,int numparams, char *prefix) +{ +int st=0; + + for (int i=0 ; i<numparams ; i++) { + if ( params[i].chkPptr == NULL) { + continue; + } + if (params[i].chkPptr->s4.f4 != NULL) { + st += params[i].chkPptr->s4.f4(&(params[i])); + } + } + if (st != 0) { + fprintf(stderr,"[CONFIG] config_execcheck: %i parameters with wrong value\n", -st); + if ( CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) == 0) { + exit_fun("exit because configuration failed\n"); + } + } +return st; +} + int config_get(paramdef_t *params,int numparams, char *prefix) { int ret= -1; -printf("numparams:%d prefix:%s\n", numparams, prefix); if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); return ret; @@ -138,6 +181,7 @@ configmodule_interface_t *cfgif = config_get_if(); ret = config_get_if()->get(params, numparams,prefix); if (ret >= 0) { config_process_cmdline(params,numparams,prefix); + config_execcheck(params,numparams,prefix); } return ret; } @@ -153,6 +197,89 @@ int config_isparamset(paramdef_t *params,int paramidx) } } -int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx) { +void print_intvalueerror(paramdef_t *param, char *fname, int *okval, int numokval) { + fprintf(stderr,"[CONFIG] %s: %s: %i invalid value, authorized values:\n ", + fname,param->optname, (int)*(param->uptr)); + for ( int i=0; i<numokval ; i++) { + fprintf(stderr, " %i",okval[i]); + } + fprintf(stderr, " \n"); +} + +int config_check_intval(paramdef_t *param) +{ + if ( param == NULL ){ + fprintf(stderr,"[CONFIG] config_check_intval: NULL param argument\n"); + return -1; + } + for ( int i=0; i<param->chkPptr->s1.num_okintval ; i++) { + if( *(param->uptr) == param->chkPptr->s1.okintval[i] ) { + return 0; + } + } + print_intvalueerror(param,"config_check_intval", param->chkPptr->s1.okintval,param->chkPptr->s1.num_okintval); + return -1; +} + +int config_check_modify_integer(paramdef_t *param) +{ + + for (int i=0; i < param->chkPptr->s1a.num_okintval ; i++) { + if (*(param->uptr) == param->chkPptr->s1a.okintval[i] ) { + printf_params("[CONFIG] %s: read value %i, set to %i\n",param->optname,*(param->uptr),param->chkPptr->s1a.setintval [i]); + *(param->uptr) = param->chkPptr->s1a.setintval [i]; + return 0; + } + } + print_intvalueerror(param,"config_check_modify_integer", param->chkPptr->s1a.okintval,param->chkPptr->s1a.num_okintval); + return -1; +} + +int config_check_intrange(paramdef_t *param) +{ + if( *(param->iptr) >= param->chkPptr->s2.okintrange[0] && *(param->iptr) <= param->chkPptr->s2.okintrange[1] ) { + return 0; + } + fprintf(stderr,"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n", + param->optname, (int)*(param->uptr), param->chkPptr->s2.okintrange[0], param->chkPptr->s2.okintrange[1]); + return -1; +} + +void print_strvalueerror(paramdef_t *param, char *fname, char **okval, int numokval) { + fprintf(stderr,"[CONFIG] %s: %s: %s invalid value, authorized values:\n ", + fname,param->optname, *(param->strptr)); + for ( int i=0; i<numokval ; i++) { + fprintf(stderr, " %s",okval[i]); + } + fprintf(stderr, " \n"); +} + +int config_check_strval(paramdef_t *param) +{ + if ( param == NULL ){ + fprintf(stderr,"[CONFIG] config_check_strval: NULL param argument\n"); + return -1; + } + for ( int i=0; i<param->chkPptr->s3.num_okstrval ; i++) { + if( strcasecmp(*(param->strptr),param->chkPptr->s3.okstrval[i] ) == 0) { + return 0; + } + } + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3.okstrval, param->chkPptr->s3.num_okstrval); + return -1; +} + +int config_checkstr_assign_integer(paramdef_t *param) +{ + + + for (int i=0; i < param->chkPptr->s3a.num_okstrval ; i++) { + if (strcasecmp(*(param->strptr),param->chkPptr->s3a.okstrval[i] ) == 0) { + config_assign_processedint(param, param->chkPptr->s3a.setintval[i]); + return 0; + } + } + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3a.okstrval, param->chkPptr->s3a.num_okstrval); + return -1; } diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 5bbc20a950bfb2150a6bfb0945821a08008dab41..923a690f51986fdd0772e10480440e6cb68892fe 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -38,24 +38,34 @@ extern "C" { #endif -#define DEFAULT_CFGFILENAME "oaisoftmodem.conf" -#define DEFAULT_CFGMODE "libconfig" - #define CONFIG_GETSOURCE ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode ) #define CONFIG_GETNUMP ( (config_get_if()==NULL) ? 0 : config_get_if()->num_cfgP ) #define CONFIG_GETP(P) ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P] ) #define CONFIG_ISFLAGSET(P) ( (config_get_if()==NULL) ? 0 : !!(config_get_if()->rtflags & P)) - +#define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) +/* utility functions, to be used by configuration module and/or configuration libraries */ extern configmodule_interface_t *config_get_if(void); extern char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; extern void config_printhelp(paramdef_t *,int numparams); extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix); -extern int config_get(paramdef_t *params,int numparams, char *prefix); -extern int config_isparamset(paramdef_t *params,int paramidx); +extern void config_assign_processedint(paramdef_t *cfgoption, int val); extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val); -extern int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix); -extern int config_getparamval_fromparamdefidx(paramdef_t *cfgoptions,int paramidx); + +/* apis to get parameters, to be used by oai modules, at configuration time */ +extern int config_get(paramdef_t *params,int numparams, char *prefix); #define config_getlist config_get_if()->getlist + +/* apis to retrieve parameters info after calling get or getlist functions */ +extern int config_isparamset(paramdef_t *params,int paramidx); +extern int config_get_processedint(paramdef_t *cfgoption); + +/* functions to be used in parameters definition, to check parameters values */ +extern int config_check_intval(paramdef_t *param); +extern int config_check_modify_integer(paramdef_t *param); +extern int config_check_intrange(paramdef_t *param); +extern int config_check_strval(paramdef_t *param); +extern int config_checkstr_assign_integer(paramdef_t *param); + #define CONFIG_GETCONFFILE (config_get_if()->cfgP[0]) #ifdef __cplusplus diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index 00f5f38b8fba60a042b42ebde78f78e6e87c886e..a73a0737f25849fba1f59d820cc229f5547a063a 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -1,3 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +/*! \file common/config/libconfig/config_libconfig.c + * \brief: implementation libconfig configuration library + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ #define _GNU_SOURCE #include <libconfig.h> @@ -21,21 +51,23 @@ int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath { const char *str; int st; +int numelt; - cfgoptions->numelt=config_setting_length(setting); - cfgoptions->strlistptr=malloc(sizeof(char *) * (cfgoptions->numelt)); + numelt=config_setting_length(setting); + config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt); st=0; - for (int i=0; i< cfgoptions->numelt && cfgoptions->strlistptr != NULL; i++) { + for (int i=0; i< numelt ; i++) { str=config_setting_get_string_elem(setting,i); if (str==NULL) { printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i); } else { - cfgoptions->strlistptr[i]=malloc(strlen(str)+1); + config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1); sprintf(cfgoptions->strlistptr[i],"%s",str); st++; printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]); } } + cfgoptions->numelt=numelt; return st; } @@ -108,10 +140,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1); sprintf( *(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) ); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) ); } else { sprintf( (char *)(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: %s\n", cfgpath,(char *)cfgoptions[i].strptr ); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr ); } } else { if( cfgoptions[i].defstrval != NULL) { @@ -121,10 +153,10 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1); sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); - printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr)); + printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, *(cfgoptions[i].strptr)); } else { - sprintf((char *)(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); - printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, (char *)cfgoptions[i].strptr); + sprintf((char *)*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval); + printf_params("[LIBCONFIG] %s set to default value \"%s\"\n", cfgpath, (char *)*(cfgoptions[i].strptr)); } } else { notfound=1; @@ -374,6 +406,7 @@ void config_libconfig_end(void ) config_destroy(&(libconfig_privdata.cfg)); if ( libconfig_privdata.configfile != NULL ) { free(libconfig_privdata.configfile); + libconfig_privdata.configfile=NULL; } } diff --git a/common/config/libconfig/config_libconfig.h b/common/config/libconfig/config_libconfig.h index 8013d602cf6d1da96ee79ac6e66aede9958c2495..f541584185ec691e00b8f0ad734651152a69e6bc 100644 --- a/common/config/libconfig/config_libconfig.h +++ b/common/config/libconfig/config_libconfig.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/config/libconfig/config_libconfig_private.h b/common/config/libconfig/config_libconfig_private.h index 022e0e6330457aefce694cdc778107a87c8b1873..fb126ff7cb8c6c57c58ce4c42e45ded26a2d89b6 100644 --- a/common/config/libconfig/config_libconfig_private.h +++ b/common/config/libconfig/config_libconfig_private.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/common/ran_context.h b/common/ran_context.h index f59fd8a79c466ae96522c93e671dc8811b5e23f9..4380dc65f12f167a5b2dc99a6a0b98590e74a1de 100644 --- a/common/ran_context.h +++ b/common/ran_context.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -48,6 +48,8 @@ #include "NwGtpv1uPrivate.h" #include "gtpv1u_eNB_defs.h" +#include "PHY/defs_L1_NB_IoT.h" +#include "RRC/LITE/defs_NB_IoT.h" typedef struct { /// RAN context config file name char *config_file_name; @@ -55,12 +57,18 @@ typedef struct { int nb_inst; /// Number of Component Carriers per instance in this node int *nb_CC; + /// Number of NB_IoT instances in this node + int nb_nb_iot_rrc_inst; /// Number of MACRLC instances in this node int nb_macrlc_inst; + /// Number of NB_IoT MACRLC instances in this node + int nb_nb_iot_macrlc_inst; /// Number of component carriers per instance in this node int *nb_mac_CC; /// Number of L1 instances in this node int nb_L1_inst; + /// Number of NB_IoT L1 instances in this node + int nb_nb_iot_L1_inst; /// Number of Component Carriers per instance in this node int *nb_L1_CC; /// Number of RU instances in this node @@ -69,10 +77,16 @@ typedef struct { flexran_agent_info_t **flexran; /// eNB context variables struct PHY_VARS_eNB_s ***eNB; + /// NB_IoT L1 context variables + struct PHY_VARS_eNB_NB_IoT_s **L1_NB_IoT; /// RRC context variables struct eNB_RRC_INST_s **rrc; - /// RRC context variables + /// NB_IoT RRC context variables + //struct eNB_RRC_INST_NB_IoT_s **nb_iot_rrc; + /// MAC context variables struct eNB_MAC_INST_s **mac; + /// NB_IoT MAC context variables + struct eNB_MAC_INST_NB_IoT_s **nb_iot_mac; /// GTPu descriptor gtpv1u_data_t *gtpv1u_data_g; /// RU descriptors. These describe what each radio unit is supposed to do and contain the necessary functions for fronthaul interfaces diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c index 554f50a2a103bf35044030974e8347d5bf22491e..85b5fef5096a4ddabf4f0463ebb07d6675c2d3d0 100644 --- a/common/utils/itti/intertask_interface.c +++ b/common/utils/itti/intertask_interface.c @@ -391,6 +391,103 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me return 0; } +/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */ +/* TODO: this is a hack - the whole logic needs a proper rework. */ +/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ +int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message) +{ + thread_id_t destination_thread_id; + task_id_t origin_task_id; + message_list_t *new; + uint32_t priority; + message_number_t message_number; + uint32_t message_id; + + AssertFatal (message != NULL, "Message is NULL!\n"); + AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max); + + destination_thread_id = TASK_GET_THREAD_ID(destination_task_id); + message->ittiMsgHeader.destinationTaskId = destination_task_id; + message->ittiMsgHeader.instance = instance; + message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame; + message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot; + message_id = message->ittiMsgHeader.messageId; + AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max); + + origin_task_id = ITTI_MSG_ORIGIN_ID(message); + + priority = itti_get_message_priority (message_id); + + /* Increment the global message number */ + message_number = itti_increment_message_number (); + + itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name, + sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize); + + if (destination_task_id != TASK_UNKNOWN) { + + if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED) { + ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), ended destination task!\n", + itti_desc.messages_info[message_id].name, + message_number, + priority, + itti_get_task_name(origin_task_id), + destination_task_id, + itti_get_task_name(destination_task_id)); + } else { + /* We cannot send a message if the task is not running */ + AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY, + "Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n", + itti_get_task_name(origin_task_id), + itti_desc.messages_info[message_id].name, + message_id, + destination_thread_id, + itti_desc.threads[destination_thread_id].task_state); + + /* Allocate new list element */ + new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s)); + + /* Fill in members */ + new->msg = message; + new->message_number = message_number; + new->message_priority = priority; + + /* Enqueue message in destination task queue */ + if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) { + itti_free(origin_task_id, new); + return -1; + } + + { + /* Only use event fd for tasks, subtasks will pool the queue */ + if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) { + ssize_t write_ret; + eventfd_t sem_counter = 1; + + /* Call to write for an event fd must be of 8 bytes */ + write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter)); + AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n", + destination_thread_id, (int) write_ret, (int) sizeof(sem_counter)); + } + } + + ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n", + itti_desc.messages_info[message_id].name, + message_number, + priority, + itti_get_task_name(origin_task_id), + destination_task_id, + itti_get_task_name(destination_task_id)); + } + } else { + /* This is a debug message to TASK_UNKNOWN, we can release safely release it */ + int result = itti_free(origin_task_id, message); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } + + return 0; +} + void itti_subscribe_event_fd(task_id_t task_id, int fd) { thread_id_t thread_id; diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h index 606c851d1de02dd6647f68321499a83da3e6fcc3..ada34ce1b722a09722373cc5a650870364891b4e 100644 --- a/common/utils/itti/intertask_interface.h +++ b/common/utils/itti/intertask_interface.h @@ -108,6 +108,18 @@ int itti_send_broadcast_message(MessageDef *message_p); **/ int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); +/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks + * the return value so it has been changed to crash the program in case + * of failure instead of returning -1 as the documentation above says. + * The RLC UM code may receive too much data when doing UDP at a higher + * throughput than the link allows and so for this specific case we need + * a version that actually returns -1 on failure. + * + * This needs to be cleaned at some point. + */ +/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ +int itti_try_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message); + /** \brief Add a new fd to monitor. * NOTE: it is up to the user to read data associated with the fd * \param task_id Task ID of the receiving task diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index b21f39e69dff7b05ba44b23f1d097852681dcd2f..fecdc2a58c624139f24bb44189b220dbf1f0d1d5 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -34,6 +34,7 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <errno.h> #include <sys/ioctl.h> #include <dlfcn.h> #include "openair1/PHY/defs.h" @@ -44,68 +45,162 @@ void loader_init(void) { paramdef_t LoaderParams[] = LOADER_PARAMS_DESC; - + loader_data.mainexec_buildversion = PACKAGE_VERSION; int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),LOADER_CONFIG_PREFIX); if (ret <0) { - fprintf(stderr,"[LOADER] configuration couldn't be performed"); + printf("[LOADER] configuration couldn't be performed via config module, parameters set to default values\n"); if (loader_data.shlibpath == NULL) { loader_data.shlibpath=DEFAULT_PATH; } - return; - } + loader_data.maxshlibs = DEFAULT_MAXSHLIBS; + } + loader_data.shlibs = malloc(loader_data.maxshlibs * sizeof(loader_shlibdesc_t)); + if(loader_data.shlibs == NULL) { + fprintf(stderr,"[LOADER] %s %d memory allocation error %s\n",__FILE__, __LINE__,strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } + memset(loader_data.shlibs,0,loader_data.maxshlibs * sizeof(loader_shlibdesc_t)); +} + +/* build the full shared lib name from the module name */ +char *loader_format_shlibpath(char *modname) +{ + +char *tmpstr; +char *shlibpath =NULL; +char *shlibversion=NULL; +char *cfgprefix; +paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0}, + {"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0}}; + +int ret; + + + + +/* looks for specific path for this module in the config file */ +/* specific value for a module path and version is located in a modname subsection of the loader section */ +/* shared lib name is formatted as lib<module name><module version>.so */ + cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16); + if (cfgprefix == NULL) { + fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } else { + sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname); + int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix); + if (ret <0) { + fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix); + } + } +/* no specific path, use loader default shared lib path */ + if (shlibpath == NULL) { + shlibpath = loader_data.shlibpath ; + } +/* no specific shared lib version */ + if (shlibversion == NULL) { + shlibversion = "" ; + } +/* alloc memory for full module shared lib file name */ + tmpstr = malloc(strlen(shlibpath)+strlen(modname)+strlen(shlibversion)+16); + if (tmpstr == NULL) { + fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); + exit_fun("[LOADER] unrecoverable error"); + } + if(shlibpath[0] != 0) { + ret=sprintf(tmpstr,"%s/",shlibpath); + } else { + ret = 0; + } + + sprintf(tmpstr+ret,"lib%s%s.so",modname,shlibversion); + + + return tmpstr; } int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) { void *lib_handle; initfunc_t fpi; - char *tmpstr; + checkverfunc_t fpc; + getfarrayfunc_t fpg; + char *shlib_path; + char *afname=NULL; int ret=0; if (loader_data.shlibpath == NULL) { loader_init(); } - tmpstr = malloc(strlen(loader_data.shlibpath)+strlen(modname)+16); - if (tmpstr == NULL) { - fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); - return -1; - } - if(loader_data.shlibpath[0] != 0) { - ret=sprintf(tmpstr,"%s/",loader_data.shlibpath); - } - if(strstr(modname,".so") == NULL) { - sprintf(tmpstr+ret,"lib%s.so",modname); - } else { - sprintf(tmpstr+ret,"%s",modname); - } + shlib_path = loader_format_shlibpath(modname); + ret = 0; - lib_handle = dlopen(tmpstr, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); + lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); if (!lib_handle) { - fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", tmpstr,dlerror()); + fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); ret = -1; } else { - printf("[LOADER] library %s uccessfully loaded loaded\n", tmpstr); - sprintf(tmpstr,"%s_autoinit",modname); - fpi = dlsym(lib_handle,tmpstr); + printf("[LOADER] library %s successfully loaded\n", shlib_path); + afname=malloc(strlen(modname)+15); + sprintf(afname,"%s_checkbuildver",modname); + fpc = dlsym(lib_handle,afname); + if (fpc != NULL ){ + int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); + if (chkver_ret < 0) { + fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); + exit_fun("[LOADER] unrecoverable error"); + } + } + sprintf(afname,"%s_autoinit",modname); + fpi = dlsym(lib_handle,afname); - if (fpi != NULL ) - { + if (fpi != NULL ) { fpi(); - } + } if (farray != NULL) { + loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t)); + loader_data.shlibs[loader_data.numshlibs].numfunc=0; for (int i=0; i<numf; i++) { farray[i].fptr = dlsym(lib_handle,farray[i].fname); if (farray[i].fptr == NULL ) { fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname); - ret= -1; - } + ret= -1; + } else { /* farray[i].fptr == NULL */ + loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname); + loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr; + loader_data.shlibs[loader_data.numshlibs].numfunc++; + }/* farray[i].fptr != NULL */ } /* for int i... */ - } /* farray ! NULL */ - } + } else { /* farray ! NULL */ + sprintf(afname,"%s_getfarray",modname); + fpg = dlsym(lib_handle,afname); + if (fpg != NULL ) { + loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray)); + } + } /* farray ! NULL */ + loader_data.shlibs[loader_data.numshlibs].name=strdup(modname); + loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path); + + (loader_data.numshlibs)++; + } /* lib_handle != NULL */ - if (tmpstr != NULL) free(tmpstr); + if ( shlib_path!= NULL) free(shlib_path); + if ( afname!= NULL) free(afname); if (lib_handle != NULL) dlclose(lib_handle); return ret; } + +void * get_shlibmodule_fptr(char *modname, char *fname) +{ + for (int i=0; i<loader_data.numshlibs && loader_data.shlibs[i].name != NULL; i++) { + if ( strcmp(loader_data.shlibs[i].name, modname) == 0) { + for (int j =0; j<loader_data.shlibs[i].numfunc ; j++) { + if (strcmp(loader_data.shlibs[i].funcarray[j].fname, fname) == 0) { + return loader_data.shlibs[i].funcarray[j].fptr; + } + } /* for j loop on module functions*/ + } + } /* for i loop on modules */ + return NULL; +} diff --git a/common/utils/load_module_shlib.h b/common/utils/load_module_shlib.h index 1f991dddd2ca96c7215b4227cedf0bbb9fc8d0e4..ffbad665708ef0ffe1f890d14e6f04039b5afb80 100644 --- a/common/utils/load_module_shlib.h +++ b/common/utils/load_module_shlib.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -33,33 +33,60 @@ #define LOAD_SHLIB_H -typedef int(*initfunc_t)(void); -typedef struct { - char *shlibpath; -}loader_data_t; typedef struct { char *fname; int (*fptr)(void); }loader_shlibfunc_t; + +typedef struct { + char *name; + char *shlib_version; // + char *shlib_buildversion; + char *thisshlib_path; + uint32_t numfunc; + loader_shlibfunc_t *funcarray; +}loader_shlibdesc_t; + +typedef struct { + char *mainexec_buildversion; + char *shlibpath; + uint32_t maxshlibs; + uint32_t numshlibs; + loader_shlibdesc_t *shlibs; +}loader_data_t; + +/* function type of functions which may be implemented by a module */ +/* 1: init function, called when loading, if found in the shared lib */ +typedef int(*initfunc_t)(void); +/* 2: version checking function, called when loading, if it returns -1, trigger main exec abort */ +typedef int(*checkverfunc_t)(char * mainexec_version, char ** shlib_version); +/* 3: get function array function, called when loading when a module doesn't provide */ +/* the function array when calling load_module_shlib (farray param NULL) */ +typedef int(*getfarrayfunc_t)(loader_shlibfunc_t **funcarray); + #ifdef LOAD_MODULE_SHLIB_MAIN #define LOADER_CONFIG_PREFIX "loader" -#define DEFAULT_PATH "" +#define DEFAULT_PATH "" +#define DEFAULT_MAXSHLIBS 10 loader_data_t loader_data; -/*--------------------------------------------------------------------------------------------------------------------------------------*/ -/* LOADER parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*--------------------------------------------------------------------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* LOADER parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOADER_PARAMS_DESC { \ -{"shlibpath", NULL, 0, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0} \ +{"shlibpath", NULL, PARAMFLAG_NOFREE, strptr:(char **)&(loader_data.shlibpath), defstrval:DEFAULT_PATH, TYPE_STRING, 0}, \ +{"maxshlibs", NULL, 0, uptr:&(loader_data.maxshlibs), defintval:DEFAULT_MAXSHLIBS, TYPE_UINT32, 0}, \ } /*-------------------------------------------------------------------------------------------------------------*/ -#else +#else /* LOAD_MODULE_SHLIB_MAIN */ extern int load_module_shlib(char *modname, loader_shlibfunc_t *farray, int numf); -#endif +extern void * get_shlibmodule_fptr(char *modname, char *fname); +extern loader_data_t loader_data; +#endif /* LOAD_MODULE_SHLIB_MAIN */ #endif diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt deleted file mode 100644 index bc4a550742291e2c9a67cbf4e923ca79d00eb8e0..0000000000000000000000000000000000000000 --- a/common/utils/telnetsrv/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -cmake_minimum_required(VERSION 2.8 FATAL_ERROR) -IF(DEFINED ENV{OPENAIR_DIR}) - message("...using oai source files in $ENV{OPENAIR_DIR}") -ELSE() - message("OPENAIR_DIR is not defined. You must run \"source oaienv\" from the oai root dir") - # exit early - return() -ENDIF() - - - -set(OPENAIR_DIR $ENV{OPENAIR_DIR}) -set(APPROOT ${OPENAIR_DIR}/common/utils/telnetsrv ) -set(OPENAIR_BUILD_DIR $ENV{OPENAIR_DIR}/cmake_targets) -set(OPENAIR1_DIR $ENV{OPENAIR1_DIR}) -set(OPENAIR2_DIR $ENV{OPENAIR2_DIR}) -set(OPENAIR3_DIR $ENV{OPENAIR3_DIR}) -set(OPENAIR_PHY_DIR $ENV{OPENAIR1_DIR}/PHY) -set(OPENAIR_TARGET_DIR $ENV{OPENAIR_DIR}/targets) -set(OPENAIR_COMMONUTILS_DIR $ENV{OPENAIR_DIR}/common/utils) -set(OPENAIR2_COMMON_DIR $ENV{OPENAIR_DIR}/openair2/COMMON) -set(OPENAIR_ASN1INC ${OPENAIR_BUILD_DIR}/lte_build_oai/build/CMakeFiles/Rel14) -set(OPENAIR_NFAPIINC $ENV{NFAPI_DIR} ) - -set(CMAKE_INSTALL_PREFIX $ENV{OPENAIR_TARGETS}) - -add_definitions (-DRel14 -DCMAKER -DENABLE_ITTI -DENABLE_NAS_UE_LOGGING -DENABLE_SECURITY -DENABLE_USE_CPU_EXECUTION_TIME -DENABLE_USE_MME -DENABLE_VCD -DENB_AGENT -DENB_MODE -DETHERNET=1 -DEXMIMO_IOT -DJUMBO_FRAME -DLINK_ENB_PDCP_TO_GTPV1U -DLOG_NO_THREAD -DMAC_CONTEXT -DMAX_NUM_CCs=1 -DNAS_BUILT_IN_UE -DNAS_UE -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK -DOPENAIR2 -DOPENAIR_LTE -DPHYSIM -DPHY_CONTEXT -DRel10=1 -DS1AP_VERSION=R10 -DTRACE_RLC_MUTEX -DX2AP_VERSION=R11 -DXFORMS -mavx2 -msse4.1 -mssse3) -add_compile_options( -fPIC -march=native -Ofast) - -include_directories( ./ ${OPENAIR_COMMON_DIR} ${OPENAIR_DIR} ${OPENAIR1_DIR} ${OPENAIR2_DIR} ${OPENAIR2_COMMON_DIR} ${OPENAIR2_DIR}/UTIL/LOG - ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC} - ${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0 ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC} - ${OPENAIR2_DIR}/LAYER2/RLC ${OPENAIR2_DIR}/UTIL/LISTS ${OPENAIR2_DIR}/UTIL/MEM ${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0 - ${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0 ${OPENAIR2_DIR}/RRC/LITE ${OPENAIR_TARGET_DIR}/COMMON ${OPENAIR_TARGET_DIR}/ARCH/COMMON - ${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK ${OPENAIR3_DIR}/NAS/COMMON/EMM/MSG/ ${OPENAIR3_DIR}/NAS/COMMON/IES/ ${OPENAIR3_DIR}/NAS/COMMON/UTIL - ${OPENAIR3_DIR}/NAS/COMMON/ESM/MSG/ ${OPENAIR3_DIR}/GTPV1-U ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/shared ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/include - ${OPENAIR3_DIR}/UTILS ${OPENAIR_NFAPIINC}) - -set(TELNETSRV_SOURCE - ${APPROOT}/telnetsrv.c - ${APPROOT}/telnetsrv_phycmd.c - ${APPROOT}/telnetsrv_proccmd.c - ) - -#set(TELNETSRV_ETHDEVCMD_SOURCE -# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c -# ) - - - -add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} ) -#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} ) - - -install(TARGETS telnetsrv DESTINATION bin) - -if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") - install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build) -endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index f99a83f3218c78226a052a2dd65bf5d910e6860a..a49311d0994a16420abf3edf10bf92dac36f35ba 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -43,7 +43,7 @@ #include <string.h> #include <signal.h> #include <pthread.h> -#include <telnetsrv.h> +#include "telnetsrv.h" #include <string.h> #include <stdarg.h> #include <unistd.h> @@ -51,20 +51,27 @@ #include <dlfcn.h> #include <sys/time.h> #include <sys/resource.h> - +#include "common/utils/load_module_shlib.h" #include "common/config/config_userapi.h" +#include <readline/history.h> #include "telnetsrv_phycmd.h" #include "telnetsrv_proccmd.h" -static char* telnet_defstatmod[] = {"softmodem","phy"}; +static char* telnet_defstatmod[] = {"softmodem","phy","loader"}; static telnetsrv_params_t telnetparams; #define TELNETSRV_LISTENADDR 0 #define TELNETSRV_LISTENPORT 1 #define TELNETSRV_PRIORITY 2 #define TELNETSRV_DEBUG 3 -#define TELNETSRV_STATICMOD 7 -#define TELNETSRV_SHRMOD 8 +#define TELNETSRV_LOOPC 4 +#define TELNETSRV_LOOPD 5 +#define TELNETSRV_HISFILE 6 +#define TELNETSRV_HISSIZE 7 +#define TELNETSRV_PHYBSIZE 8 +#define TELNETSRV_STATICMOD 9 +#define TELNETSRV_SHRMOD 10 + paramdef_t telnetoptions[] = { /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* configuration parameters for telnet utility */ @@ -72,19 +79,22 @@ paramdef_t telnetoptions[] = { /*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ {"listenaddr", "<listen ip address>", 0, uptr:&telnetparams.listenaddr, defstrval:"0.0.0.0", TYPE_IPV4ADDR, 0 }, {"listenport", "<local port>", 0, uptr:&(telnetparams.listenport), defuintval:9090, TYPE_UINT, 0 }, - {"priority", "<scheduling policy (0-99)", 0, uptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 }, + {"priority", "<scheduling policy (0-99)", 0, iptr:&telnetparams.priority, defuintval:0, TYPE_INT, 0 }, {"debug", "<debug level>", 0, uptr:NULL, defuintval:0, TYPE_UINT, 0 }, {"loopcount", "<loop command iterations>", 0, uptr:&(telnetparams.loopcount), defuintval:10, TYPE_UINT, 0 }, {"loopdelay", "<loop command delay (ms)>", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 }, + {"histfile", "<history file name>", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 }, + {"histsize", "<history sizes>", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 }, {"phypbsize", "<phy dump buff size (bytes)>",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 }, - {"staticmod", "<static modules selection>", 0, NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,1}, - {"shrmod", "<static modules selection>", 0, NULL, NULL,TYPE_STRINGLIST,0 }, + {"staticmod", "<static modules selection>", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))}, + {"shrmod", "<dynamic modules selection>", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 } }; -int get_phybsize() {return telnetparams.phyprntbuff_size; }; +int get_phybsize(void) {return telnetparams.phyprntbuff_size; }; int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd ); int setoutput(char *buff, int debug, telnet_printfunc_t prnt); int setparam(char *buff, int debug, telnet_printfunc_t prnt); +int history_cmd(char *buff, int debug, telnet_printfunc_t prnt); telnetshell_vardef_t telnet_vardef[] = { {"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg}, @@ -92,12 +102,15 @@ telnetshell_vardef_t telnet_vardef[] = { {"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount}, {"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay}, {"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size}, +{"hsize",TELNET_VARTYPE_INT32,&telnetparams.histsize}, +{"hfile",TELNET_VARTYPE_STRING,&telnetparams.histfile}, {"",0,NULL} }; telnetshell_cmddef_t telnet_cmdarray[] = { {"redirlog","[here,file,off]",setoutput}, {"param","[prio]",setparam}, + {"history","[list,reset]",history_cmd}, {"","",NULL}, }; @@ -131,41 +144,54 @@ char strpolicy[10]; //sched_get_priority_max(SCHED_FIFO) -if (priority < NICE_MIN) - { +if (priority < NICE_MIN) { policy=SCHED_FIFO; sprintf(strpolicy,"%s","fifo"); - schedp.sched_priority= NICE_MIN - priority ; + schedp.sched_priority= NICE_MIN - priority ; + if ( (schedp.sched_priority < sched_get_priority_min(SCHED_FIFO)) || + (schedp.sched_priority > sched_get_priority_max(SCHED_FIFO)) ) { + client_printf("Error: %i invalid prio, should be %i to %i, \n", + priority, NICE_MIN -sched_get_priority_min(SCHED_FIFO), + NICE_MIN - sched_get_priority_max(SCHED_FIFO) ); } -else if (priority > NICE_MAX) - { +} else if (priority > NICE_MAX) { policy=SCHED_IDLE; sprintf(strpolicy,"%s","idle"); schedp.sched_priority=0; - } -else - { +} else { policy=SCHED_OTHER; sprintf(strpolicy,"%s","other"); schedp.sched_priority=0; - } -if( tid != 0) - { +} + +if( tid != 0) { rt = pthread_setschedparam(tid, policy, &schedp); - } -else if(pid > 0) - { +} else if(pid > 0) { rt = sched_setscheduler( pid, policy,&schedp); - } -if (rt != 0) - { +} else { + rt= -1; + client_printf("Error: no pid or tid specified\n"); +} + +if (rt != 0) { client_printf("Error %i: %s modifying sched param to %s:%i, \n", errno,strerror(errno),strpolicy,schedp.sched_priority); - } -else - { +} else { client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority); + if ( policy==SCHED_OTHER) { + rt = getpriority(PRIO_PROCESS,tid); + if (rt != -1) { + rt = setpriority(PRIO_PROCESS,tid,priority); + if (rt < 0) { + client_printf("Error %i: %s trying to set nice value of thread %u to %i\n", + errno,strerror(errno),tid,priority); + } + } else { + client_printf("Error %i: %s trying to get nice value of thread %u \n", + errno,strerror(errno),tid); + } } +} @@ -198,14 +224,13 @@ int rt; CPU_ZERO(&cpuset); CPU_SET(coreid, &cpuset); - if (tid > 0) - { + if (tid > 0) { rt = pthread_setaffinity_np((pthread_t)tid, sizeof(cpu_set_t), &cpuset); - } - else if (pid > 0) - { + } else if (pid > 0){ rt = sched_setaffinity((pid_t)pid, sizeof(cpu_set_t), &cpuset); - } + } else { + rt= -1; + } if (rt != 0) { client_printf("Error %i: %s calling , xxx_setaffinity...\n",errno,strerror(errno)); @@ -284,7 +309,6 @@ memset(cmds,0,sizeof(cmds)); sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] ); if (strncasecmp(cmds[0],"prio",4) == 0) { - pthread_attr_t attr; int prio; prio=(int)strtol(cmds[1],NULL,0); if (errno == ERANGE) @@ -305,6 +329,35 @@ if (strncasecmp(cmds[0],"aff",3) == 0) return CMDSTATUS_NOTFOUND; } /* setparam */ + +int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ +char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE]; + + +memset(cmds,0,sizeof(cmds)); +sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] ); +if (cmds[0] == NULL) + return CMDSTATUS_VARNOTFOUND; +if (strncasecmp(cmds[0],"list",4) == 0) + { + HIST_ENTRY **hist = history_list(); + if (hist) { + for (int i = 0; hist[i]; i++) { + prnt ("%d: %s\n", i + history_base, hist[i]->line); + } + } + return CMDSTATUS_FOUND; + } +if (strncasecmp(cmds[0],"reset",5) == 0) + { + clear_history(); + write_history(telnetparams.histfile); + return CMDSTATUS_FOUND; + } + +return CMDSTATUS_NOTFOUND; +} /* history_cmd */ /*-------------------------------------------------------------------------------------------------------*/ /* generic commands available for all modules loaded by the server @@ -314,11 +367,11 @@ int setgetvar(int moduleindex,char getorset,char *params) { int n,i; char varname[TELNET_CMD_MAXSIZE]; -char varval[TELNET_CMD_MAXSIZE]; +char *varval=NULL; memset(varname,0,sizeof(varname)); - memset(varval,0,sizeof(varval)); - n = sscanf(params,"%s %s",varname,varval); + + n = sscanf(params,"%s %ms",varname,&varval); for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++) { if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0) @@ -330,7 +383,10 @@ char varval[TELNET_CMD_MAXSIZE]; switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) { case TELNET_VARTYPE_INT32: - client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + client_printf("%i\n",*(int32_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_INT64: + client_printf("%lli\n",*(int64_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; case TELNET_VARTYPE_INT16: client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); @@ -338,8 +394,8 @@ char varval[TELNET_CMD_MAXSIZE]; case TELNET_VARTYPE_DOUBLE: client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; - case TELNET_VARTYPE_PTR: - client_printf("0x%08x\n",*((unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr))); + case TELNET_VARTYPE_STRING: + client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; default: client_printf("unknown type\n"); @@ -364,6 +420,10 @@ char varval[TELNET_CMD_MAXSIZE]; case TELNET_VARTYPE_DOUBLE: *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL); client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); + break; + case TELNET_VARTYPE_STRING: + sprintf(*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr),"%s", varval); + client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)); break; default: client_printf("unknown type\n"); @@ -372,6 +432,9 @@ char varval[TELNET_CMD_MAXSIZE]; } } } +if (n>1 && varval != NULL) { + free(varval); +} return CMDSTATUS_VARNOTFOUND; } /*----------------------------------------------------------------------------------------------------*/ @@ -515,13 +578,14 @@ if(listen(sock, 1) == -1) fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno)); +using_history(); printf("\nInitializing telnet server...\n"); while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) { printf("[TELNETSRV] Telnet client connected....\n"); - - + read_history(telnetparams.histfile); + stifle_history(telnetparams.histsize); if(telnetparams.new_socket < 0) fprintf(stderr,"[TELNETSRV] Error %s on accept call\n",strerror(errno)); @@ -548,31 +612,43 @@ while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) break; } if (telnetparams.telnetdbg > 0) - printf("[TELNETSRV] Command received: readc %i filled %i %s\n", readc, filled ,buf); - if (strlen(buf) >= 2 ) + printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled ,buf); + if (buf[0] == '!') { + if (buf[1] == '!') { + sprintf(buf,"%s","telnet history list"); + } else { + HIST_ENTRY *hisentry = history_get(strtol(buf+1,NULL,0)); + if (hisentry) { + char msg[TELNET_MAX_MSGLENGTH + sizeof(TELNET_PROMPT) +10]; + sprintf(buf,"%s",hisentry->line); + sprintf(msg,"%s %s\n",TELNET_PROMPT, hisentry->line); + send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL); + } + } + } + if (strlen(buf) > 2 ) { status=process_command(buf); } else status=CMDSTATUS_NOCMD; - if (status != CMDSTATUS_EXIT) - { - if (status == CMDSTATUS_NOTFOUND) - { + if (status != CMDSTATUS_EXIT) { + if (status == CMDSTATUS_NOTFOUND) { char msg[TELNET_MAX_MSGLENGTH + 50]; sprintf(msg,"Error: \n %s\n is not a softmodem command\n",buf); send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL); - } + } else if (status == CMDSTATUS_FOUND) { + add_history(buf); + } send(telnetparams.new_socket, TELNET_PROMPT, sizeof(TELNET_PROMPT), MSG_NOSIGNAL); - } - else - { + } else { printf ("[TELNETSRV] Closing telnet connection...\n"); break; - } + } } - + write_history(telnetparams.histfile); + clear_history(); close(telnetparams.new_socket); printf ("[TELNETSRV] Telnet server waitting for connection...\n"); } @@ -588,7 +664,7 @@ return; */ void exec_moduleinit(char *modname) { -void (*fptr)(); +void (*fptr)(void); char initfunc[TELNET_CMD_MAXSIZE+9]; if (strlen(modname) > TELNET_CMD_MAXSIZE) @@ -609,23 +685,26 @@ char initfunc[TELNET_CMD_MAXSIZE+9]; } } -int add_embeddedmodules() +int add_embeddedmodules(void) { - +int ret=0; for(int i=0; i<telnetoptions[TELNETSRV_STATICMOD].numelt;i++) { + ret++; exec_moduleinit(telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]); } +return ret; + } -int add_sharedmodules() +int add_sharedmodules(void) { char initfunc[TELNET_CMD_MAXSIZE+9]; -void (*fptr)(); - +void (*fptr)(void); +int ret=0; for(int i=0; i<telnetoptions[TELNETSRV_SHRMOD].numelt;i++) { @@ -634,22 +713,23 @@ void (*fptr)(); if ( fptr != NULL) { fptr(); + ret++; } else { fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]); } } + return ret; } -int init_telnetsrv(char *cfgfile) +int telnetsrv_autoinit(void) { - void *lib_handle; - char** moduleslist; + memset(&telnetparams,0,sizeof(telnetparams)); - config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),NULL); + config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),"telnetsrv"); if(pthread_create(&telnetparams.telnet_pthread,NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0) @@ -691,6 +771,26 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde } +/* function which will be called by the shared lib loader, to check shared lib version + against main exec version. version mismatch no considered as fatal (interfaces not supposed to change) +*/ +int telnetsrv_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion) +{ +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__ +#endif + *shlib_buildversion = PACKAGE_VERSION; + if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) { + fprintf(stderr,"[TELNETSRV] shared lib version %s, doesn't match main version %s, compatibility should be checked\n", + mainexec_buildversion,*shlib_buildversion); + } + return 0; +} - - +int telnetsrv_getfarray(loader_shlibfunc_t **farray) + { + *farray=malloc(sizeof(loader_shlibfunc_t)); + (*farray)[0].fname=TELNET_ADDCMD_FNAME; + (*farray)[0].fptr=(int (*)(void) )add_telnetcmd; + return 1; + } diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index c8cad58784df9381f1040b0200d3597b838df3df..2d3ef531aee8494ad080f00f42c9b42c1934eb50 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -18,7 +18,6 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - /*! \file common/utils/telnetsrv/telnetsrv.h * \brief: include file for telnet server implementation * \author Francois TABURET @@ -38,7 +37,7 @@ #define TELNET_MAX_MSGLENGTH 2048 #define TELNET_PROMPT "softmodem> " #define TELNET_MAXCMD 20 -#define TELNET_CMD_MAXSIZE 10 +#define TELNET_CMD_MAXSIZE 20 #define TELNET_HELPSTR_SIZE 80 /* status return by the command parser after it analysed user input */ @@ -70,7 +69,7 @@ typedef struct cmddef { #define TELNET_VARTYPE_INT64 3 #define TELNET_VARTYPE_STRING 4 #define TELNET_VARTYPE_DOUBLE 5 -#define TELNET_VARTYPE_PTR 6 +//#define TELNET_VARTYPE_PTR 6 typedef struct variabledef { char varname[TELNET_CMD_MAXSIZE]; char vartype; @@ -96,6 +95,8 @@ typedef struct { pthread_t telnet_pthread; // thread id of the telnet server int telnetdbg; // debug level of the server int priority; // server running priority + char *histfile; // command history + int histsize; // command history length int new_socket; // socket of the client connection int logfilefd; // file id of the log file when log output is redirected to a file int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout @@ -130,10 +131,12 @@ VT escape sequence definition, for smarter display.... #define STDFMT "\x1b[0m" /*---------------------------------------------------------------------------------------------*/ +#define TELNET_ADDCMD_FNAME "add_telnetcmd" +typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); #ifdef TELNETSERVERCODE int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); void set_sched(pthread_t tid, int pid,int priority); void set_affinity(pthread_t tid, int pid, int coreid); -extern int get_phybsize(); +extern int get_phybsize(void); #endif #endif diff --git a/common/utils/telnetsrv/telnetsrv_CMakeLists.txt b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5dee7db4c41fef1d5c3f96b18eb770d64e044054 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_CMakeLists.txt @@ -0,0 +1,28 @@ + + +set(TELNETROOT ${OPENAIR_DIR}/common/utils/telnetsrv ) + + + +set(TELNETSRV_SOURCE + ${TELNETROOT}/telnetsrv.c + ${TELNETROOT}/telnetsrv_phycmd.c + ${TELNETROOT}/telnetsrv_proccmd.c + ${TELNETROOT}/telnetsrv_loader.c + ) + +#set(TELNETSRV_ETHDEVCMD_SOURCE +# ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c +# ) + + + +add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} ) +#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} ) +target_link_libraries(telnetsrv PRIVATE history) + +install(TARGETS telnetsrv DESTINATION bin) + +if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") + install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build) +endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build") diff --git a/common/utils/telnetsrv/telnetsrv_loader.c b/common/utils/telnetsrv/telnetsrv_loader.c new file mode 100644 index 0000000000000000000000000000000000000000..a23e25eb835fbd3a728424a7afb4a8991a179caa --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_loader.c @@ -0,0 +1,84 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file common/utils/telnetsrv/telnetsrv_loader.c + * \brief: implementation of telnet commands related to softmodem linux process + * \author Francois TABURET + * \date 2018 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include <string.h> +#include <pthread.h> + + +#define TELNETSERVERCODE +#include "telnetsrv.h" +#define TELNETSRV_LOADER_MAIN +#include "telnetsrv_loader.h" + + +int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); +telnetshell_cmddef_t loader_cmdarray[] = { + {"show","[params,modules]",loader_show_cmd}, + {"","",NULL}, +}; + + +/*-------------------------------------------------------------------------------------*/ +int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ + if (debug > 0) + prnt( "loader_show_cmd received %s\n",buff); + + if (strcasestr(buff,"params") != NULL) { + prnt( "loader parameters:\n"); + prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion); + prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath); + prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs); + } + else if (strcasestr(buff,"modules") != NULL) { + prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs); + for (int i=0 ; i<loader_data.numshlibs ; i++) { + prnt( " Module %i: %s\n", i,loader_data.shlibs[i].name); + prnt( " Shared library build version: \"%s\"\n",((loader_data.shlibs[i].shlib_buildversion == NULL )?"":loader_data.shlibs[i].shlib_buildversion)); + prnt( " Shared library path: \"%s\"\n", loader_data.shlibs[i].thisshlib_path); + prnt( " %i function pointers registered:\n", loader_data.shlibs[i].numfunc); + for(int j=0 ; j<loader_data.shlibs[i].numfunc;j++) { + prnt( " function %i %s at %p\n",j, + loader_data.shlibs[i].funcarray[j].fname, loader_data.shlibs[i].funcarray[j].fptr); + } + } + } else { + prnt("%s: wrong loader command...\n",buff); + } + return 0; +} + +void add_loader_cmds(void) +{ + + add_telnetcmd("loader", loader_globalvardef, loader_cmdarray); +} diff --git a/common/utils/telnetsrv/telnetsrv_loader.h b/common/utils/telnetsrv/telnetsrv_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..404aabfc7019b2ccf82f718e145696bb63584ca3 --- /dev/null +++ b/common/utils/telnetsrv/telnetsrv_loader.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file common/utils/telnetsrv_proccmd.h + * \brief: Include file defining telnet commands related to softmodem linux process + * \author Francois TABURET + * \date 2018 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + +#ifdef TELNETSRV_LOADER_MAIN + +#include "UTIL/LOG/log.h" + + +#include "common/utils/load_module_shlib.h" + + +telnetshell_vardef_t loader_globalvardef[] = { +{"mainversion",TELNET_VARTYPE_STRING,&(loader_data.mainexec_buildversion)}, +{"defpath",TELNET_VARTYPE_STRING,&(loader_data.shlibpath)}, +{"maxshlibs",TELNET_VARTYPE_INT32,&(loader_data.maxshlibs)}, +{"numshlibs",TELNET_VARTYPE_INT32,&(loader_data.numshlibs)}, +{"",0,NULL} +}; +telnetshell_vardef_t *loader_modulesvardef; + +extern void add_loader_cmds(void); + +#endif + +/*-------------------------------------------------------------------------------------*/ + diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c index 6867d5deeef8fde9baa5880ca5f3bc28f043525c..c60126f1c741e4d9d93323e761862d0f7458e561 100644 --- a/common/utils/telnetsrv/telnetsrv_phycmd.c +++ b/common/utils/telnetsrv/telnetsrv_phycmd.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -41,7 +41,7 @@ char *prnbuff; extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length); -void init_phytelnet() +void init_phytelnet(void) { prnbuff=malloc(get_phybsize() ); if (prnbuff == NULL) @@ -134,7 +134,7 @@ telnetshell_cmddef_t phy_cmdarray[] = { /*-------------------------------------------------------------------------------------*/ -void add_phy_cmds() +void add_phy_cmds(void) { init_phytelnet(); diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.h b/common/utils/telnetsrv/telnetsrv_phycmd.h index 3922bda727c0e140d3e4529c81dd167cbb21df29..6e2b0ecacff74813b6635436dfea3fc6078995e9 100644 --- a/common/utils/telnetsrv/telnetsrv_phycmd.h +++ b/common/utils/telnetsrv/telnetsrv_phycmd.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -42,8 +42,6 @@ #define TELNETVAR_PHYCC1 1 telnetshell_vardef_t phy_vardef[] = { -{"phycc1",TELNET_VARTYPE_PTR,NULL}, -{"phycc2",TELNET_VARTYPE_PTR,NULL}, //{"iqmax",TELNET_VARTYPE_INT16,NULL}, //{"iqmin",TELNET_VARTYPE_INT16,NULL}, //{"loglvl",TELNET_VARTYPE_INT32,NULL}, @@ -57,7 +55,7 @@ telnetshell_vardef_t phy_vardef[] = { #else -extern void add_phy_cmds(); +extern void add_phy_cmds(void); #endif diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c index 82c4549faeab7b7eaf79ec00f5a145fdfb7717d7..91f0e9c93a591f04bb85ddd991c8cf9d2e1142cd 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.c +++ b/common/utils/telnetsrv/telnetsrv_proccmd.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -54,6 +54,8 @@ #define TELNETSRV_PROCCMD_MAIN #include "log.h" #include "log_extern.h" +#include "common/config/config_userapi.h" +#include "openair1/PHY/extern.h" #include "telnetsrv_proccmd.h" void decode_procstat(char *record, int debug, telnet_printfunc_t prnt) @@ -70,14 +72,13 @@ char toksep[2]; lptr= prntline; /*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */ - while( procfile_fiels != NULL && fieldcnt < 42) - { + while( procfile_fiels != NULL && fieldcnt < 42) { + long int policy; if (strlen(procfile_fiels) == 0) continue; fieldcnt++; sprintf(toksep," "); - switch(fieldcnt) - { + switch(fieldcnt) { case 1: /* id */ lptr+=sprintf(lptr,"%9.9s ",procfile_fiels); sprintf(toksep,")"); @@ -104,12 +105,36 @@ char toksep[2]; break; case 41: //policy lptr+=sprintf(lptr,"%3.3s ",procfile_fiels); + policy=strtol(procfile_fiels,NULL,0); + switch(policy) { + case SCHED_FIFO: + lptr+=sprintf(lptr,"%s ","rt: fifo"); + break; + case SCHED_OTHER: + lptr+=sprintf(lptr,"%s ","other"); + break; + case SCHED_IDLE: + lptr+=sprintf(lptr,"%s ","idle"); + break; + case SCHED_BATCH: + lptr+=sprintf(lptr,"%s ","batch"); + break; + case SCHED_RR: + lptr+=sprintf(lptr,"%s ","rt: rr"); + break; + case SCHED_DEADLINE: + lptr+=sprintf(lptr,"%s ","rt: deadline"); + break; + default: + lptr+=sprintf(lptr,"%s ","????"); + break; + } break; default: break; - }/* switch on fieldcnr */ + }/* switch on fieldcnr */ procfile_fiels =strtok_r(NULL,toksep,&strtokptr); - } /* while on proc_fields != NULL */ + } /* while on proc_fields != NULL */ prnt("%s\n",prntline); } /*decode_procstat */ @@ -141,7 +166,7 @@ char aname[256]; DIR *proc_dir; struct dirent *entry; -int rt; + prnt(" id name state USRmod KRNmod prio nice vsize proc pol \n\n"); snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid()); @@ -172,14 +197,51 @@ extern log_t *g_log; if (debug > 0) prnt(" proccmd_show received %s\n",buf); - if (strcasestr(buf,"thread") != NULL) - { + if (strcasestr(buf,"thread") != NULL) { print_threads(buf,debug,prnt); - } + } if (strcasestr(buf,"loglvl") != NULL) { - for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++){ - prnt("\t%s:\t%s\t%s\n",g_log->log_component[i].name, map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), - map_int_to_str(log_level_names,g_log->log_component[i].level)); + prnt("component verbosity level enabled\n"); + for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + prnt("%02i %17.17s:%10.10s%10.10s %s\n",i ,g_log->log_component[i].name, + map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), + map_int_to_str(log_level_names,g_log->log_component[i].level), + ((g_log->log_component[i].interval>0)?"Y":"N") ); + } + } + if (strcasestr(buf,"config") != NULL) { + prnt("Command line arguments:\n"); + for (int i=0; i < config_get_if()->argc; i++) { + prnt(" %02i %s\n",i ,config_get_if()->argv[i]); + } + prnt("Config module flags ( -O <cfg source>:<xxx>:dbgl<flags>): 0x%08x\n", config_get_if()->rtflags); + + prnt(" Print config debug msg, params values (flag %u): %s\n",CONFIG_PRINTPARAMS, + ((config_get_if()->rtflags & CONFIG_PRINTPARAMS) ? "Y" : "N") ); + prnt(" Print config debug msg, memory management(flag %u): %s\n",CONFIG_DEBUGPTR, + ((config_get_if()->rtflags & CONFIG_DEBUGPTR) ? "Y" : "N") ); + prnt(" Print config debug msg, command line processing (flag %u): %s\n",CONFIG_DEBUGCMDLINE, + ((config_get_if()->rtflags & CONFIG_DEBUGCMDLINE) ? "Y" : "N") ); + prnt(" Don't exit if param check fails (flag %u): %s\n",CONFIG_NOABORTONCHKF, + ((config_get_if()->rtflags & CONFIG_NOABORTONCHKF) ? "Y" : "N") ); + prnt("Config source: %s, parameters:\n",CONFIG_GETSOURCE ); + for (int i=0; i < config_get_if()->num_cfgP; i++) { + prnt(" %02i %s\n",i ,config_get_if()->cfgP[i]); + } + prnt("Softmodem components:\n"); + prnt(" %02i Ru(s)\n", RC.nb_RU); + prnt(" %02i lte RRc(s), %02i NbIoT RRC(s)\n", RC.nb_inst, RC.nb_nb_iot_rrc_inst); + prnt(" %02i lte MACRLC(s), %02i NbIoT MACRLC(s)\n", RC.nb_macrlc_inst, RC.nb_nb_iot_macrlc_inst); + prnt(" %02i lte L1, %02i NbIoT L1\n", RC.nb_L1_inst, RC.nb_nb_iot_L1_inst); + + for(int i=0; i<RC.nb_inst; i++) { + prnt(" lte RRC %i: %02i CC(s) \n",i,((RC.nb_CC == NULL)?0:RC.nb_CC[i])); + } + for(int i=0; i<RC.nb_L1_inst; i++) { + prnt(" lte L1 %i: %02i CC(s)\n",i,((RC.nb_L1_CC == NULL)?0:RC.nb_L1_CC[i])); + } + for(int i=0; i<RC.nb_macrlc_inst; i++) { + prnt(" lte macrlc %i: %02i CC(s)\n",i,((RC.nb_mac_CC == NULL)?0:RC.nb_mac_CC[i])); } } return 0; @@ -190,12 +252,16 @@ int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt) int bv1,bv2; int res; char sv1[64]; -char tname[32]; + bv1=0; bv2=0; sv1[0]=0; if (debug > 0) prnt("proccmd_thread received %s\n",buf); + if (strcasestr(buf,"help") != NULL) { + prnt(PROCCMD_THREAD_HELP_STRING); + return 0; + } res=sscanf(buf,"%i %9s %i",&bv1,sv1,&bv2); if (debug > 0) prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2); @@ -231,32 +297,95 @@ extern void exit_fun(const char* s); return 0; } + int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt) { int idx1=0; int idx2=NUM_LOG_LEVEL-1; -int s = sscanf(buf,"%*s %i-%i",&idx1,&idx2); +char *logsubcmd=NULL; + +int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2); if (debug > 0) - prnt("process module received %s\n",buf); + prnt( "proccmd_log received %s\n s=%i sub command %s\n",buf,s,((logsubcmd==NULL)?"":logsubcmd)); + + if (s == 1 && logsubcmd != NULL) { + if (strcasestr(logsubcmd,"online") != NULL) { + if (strcasestr(buf,"noonline") != NULL) { + set_glog_onlinelog(0); + prnt("online logging disabled\n",buf); + } else { + set_glog_onlinelog(1); + prnt("online logging enabled\n",buf); + } + } + else if (strcasestr(logsubcmd,"show") != NULL) { + prnt("Available log levels: \n "); + for (int i=0; log_level_names[i].name != NULL; i++) + prnt("%s ",log_level_names[i].name); + prnt("\nAvailable verbosity: \n "); + for (int i=0; log_verbosity_names[i].name != NULL; i++) + prnt("%s ",log_verbosity_names[i].name); + prnt("\n"); + proccmd_show("loglvl",debug,prnt); + } + else if (strcasestr(logsubcmd,"help") != NULL) { + prnt(PROCCMD_LOG_HELP_STRING); + } else { + prnt("%s: wrong log command...\n",logsubcmd); + } + } else if ( s == 3 && logsubcmd != NULL) { + int level, verbosity, interval; + char *tmpstr=NULL; + char *logparam=NULL; + int l; + + level = verbosity = interval = -1; + l=sscanf(logsubcmd,"%m[^'_']_%m[^'_']",&logparam,&tmpstr); + if (debug > 0) + prnt("l=%i, %s %s\n",l,((logparam==NULL)?"\"\"":logparam), ((tmpstr==NULL)?"\"\"":tmpstr)); + if (l ==2 ) { + if (strcmp(logparam,"level") == 0) { + level=map_str_to_int(log_level_names,tmpstr); + if (level < 0) prnt("level %s unknown\n",tmpstr); + } else if (strcmp(logparam,"verbos") == 0) { + verbosity=map_str_to_int(log_verbosity_names,tmpstr); + if (verbosity < 0) prnt("verbosity %s unknown\n",tmpstr); + } else { + prnt("%s%s unknown log sub command \n",logparam, tmpstr); + } + } else if (l ==1 ) { + if (strcmp(logparam,"enable") == 0) { + interval = 1; + } else if (strcmp(logparam,"disable") == 0) { + interval = 0; + } else { + prnt("%s%s unknown log sub command \n",logparam, tmpstr); + } + } else { + prnt("%s unknown log sub command \n",logsubcmd); + } + if (logparam != NULL) free(logparam); + if (tmpstr != NULL) free(tmpstr); + for (int i=idx1; i<=idx2 ; i++) { + set_comp_log(i, level, verbosity, interval); + prnt("log level/verbosity comp %i %s set to %s / %s (%s)\n", + i,((g_log->log_component[i].name==NULL)?"":g_log->log_component[i].name), + map_int_to_str(log_level_names,g_log->log_component[i].level), + map_int_to_str(log_verbosity_names,g_log->log_component[i].flag), + ((g_log->log_component[i].interval>0)?"enabled":"disabled")); + + + } + } else { + prnt("%s: wrong log command...\n",buf); + } - if (strcasestr(buf,"enable") != NULL) - { - set_glog_onlinelog(1); - } - if (strcasestr(buf,"disable") != NULL) - { - set_glog_onlinelog(0); - } - if (strcasestr(buf,"show") != NULL) - { - proccmd_show("loglvl",debug,prnt); - } return 0; } /*-------------------------------------------------------------------------------------*/ -void add_softmodem_cmds() +void add_softmodem_cmds(void) { add_telnetcmd("softmodem",proc_vardef,proc_cmdarray); } diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.h b/common/utils/telnetsrv/telnetsrv_proccmd.h index d7fd0a6e2497df81bca617989ad142e5356997bd..b2c05315d8a46e2e1a989beefe775d5c53d8b21d 100644 --- a/common/utils/telnetsrv/telnetsrv_proccmd.h +++ b/common/utils/telnetsrv/telnetsrv_proccmd.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -19,6 +19,7 @@ * contact@openairinterface.org */ + /*! \file common/utils/telnetsrv/telnetsrv_proccmd.h * \brief: Include file defining telnet commands related to this linux process * \author Francois TABURET @@ -43,15 +44,33 @@ extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt); telnetshell_vardef_t proc_vardef[] = { {"",0,NULL} }; +#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\ + show: display current log configuration \n\ + online, noonline: enable or disable console logs \n\ + enable, disable id1-id2: enable or disable logs for components index id1 to id2 \n\ + level_<level> id1-id2: set log level to <level> for components index id1 to id2 \n\ + level_<verbosity> id1-id2: set log verbosity to <verbosity> for components index id1 to id2 \n\ +use the show command to get the values for <level>, <verbosity> and the list of component indexes \ +that can be used for id1 and id2 \n" + +#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\ + <thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\ + <thread id> prio <prio> : set scheduling parameters for thread <thread id> \n\ + if prio < -20: linux scheduling policy set to FIFO, \n\ + with priority = -20 - prio \n\ + if prio > 19: linux scheduling policy set to OTHER, \n\ + with priority (nice value) = prio \n\ + use \"softmodem show thread\" to get <thread id> \n" + telnetshell_cmddef_t proc_cmdarray[] = { - {"show","loglvl|thread", proccmd_show}, - {"log","[enable,disable]", proccmd_log}, - {"thread","<id> aff|prio <aff|prio>", proccmd_thread}, + {"show","loglvl|thread|config", proccmd_show}, + {"log","(enter help for details)", proccmd_log}, + {"thread","(enter help for details)", proccmd_thread}, {"exit","", proccmd_exit}, {"","",NULL}, }; #else -extern void add_proccmd_cmds(); +extern void add_proccmd_cmds(void); #endif /* TELNETSRV_PROCCMD_MAIN */ diff --git a/nfapi/oai_integration/nfapi_pnf.h b/nfapi/oai_integration/nfapi_pnf.h index 592d4877af1ac87a95c67f9d4d2365b0c586e36d..e213d785f14ef1c94a41cb61a058d25e7982b6e4 100644 --- a/nfapi/oai_integration/nfapi_pnf.h +++ b/nfapi/oai_integration/nfapi_pnf.h @@ -21,7 +21,7 @@ #if !defined(NFAPI_PNF_H__) #define NFAPI_PNF_H__ - +int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); #endif diff --git a/openair1/PHY/CODING/3gpplte.c b/openair1/PHY/CODING/3gpplte.c index ca63857d7205cc4b37c7da5d89ff4988127f0b5e..61acdb2ad9d3040dca9ed68d4264cc0fe0e332c4 100644 --- a/openair1/PHY/CODING/3gpplte.c +++ b/openair1/PHY/CODING/3gpplte.c @@ -27,7 +27,9 @@ #ifndef TC_MAIN //#include "defs.h" #endif - +#include <stdint.h> +#include <stdio.h> +#include "PHY/CODING/defs.h" #include "extern_3GPPinterleaver.h" //#define DEBUG_TURBO_ENCODER 1 @@ -35,7 +37,7 @@ uint32_t threegpplte_interleaver_output; uint32_t threegpplte_interleaver_tmp; -inline void threegpplte_interleaver_reset() +inline void threegpplte_interleaver_reset(void) { threegpplte_interleaver_output = 0; threegpplte_interleaver_tmp = 0; @@ -82,7 +84,7 @@ uint8_t output_lut[16],state_lut[16]; inline uint8_t threegpplte_rsc_lut(uint8_t input,uint8_t *state) { - uint8_t output; + uint8_t off; off = (*state<<1)|input; @@ -146,7 +148,7 @@ void threegpplte_turbo_encoder(uint8_t *input, for (i=0; f1f2mat[i].nb_bits!= input_length_bits && i <188; i++); if ( i == 188 ) { - msg("Illegal frame length!\n"); + printf("Illegal frame length!\n"); return; } else { base_interleaver=il_tb+f1f2mat[i].beg_index; diff --git a/openair1/PHY/CODING/3gpplte_sse.c b/openair1/PHY/CODING/3gpplte_sse.c index 5d87a60477db22600da14707604db1745ddc304c..8150f02da89abd7ed2e5351de2cf25057c238263 100644 --- a/openair1/PHY/CODING/3gpplte_sse.c +++ b/openair1/PHY/CODING/3gpplte_sse.c @@ -96,7 +96,7 @@ static inline void threegpplte_rsc_termination(unsigned char *x,unsigned char *z *state = (*state)>>1; } -void treillis_table_init(void) +static void treillis_table_init(void) { //struct treillis t[][]=all_treillis; //t=memalign(16,sizeof(struct treillis)*8*256); @@ -536,12 +536,12 @@ char interleave_compact_byte(short * base_interleaver,unsigned char * input, uns } */ -void threegpplte_turbo_encoder(unsigned char *input, - unsigned short input_length_bytes, - unsigned char *output, - unsigned char F, - unsigned short interleaver_f1, - unsigned short interleaver_f2) +void threegpplte_turbo_encoder_sse(unsigned char *input, + unsigned short input_length_bytes, + unsigned char *output, + unsigned char F, + unsigned short interleaver_f1, + unsigned short interleaver_f2) { int i; @@ -641,7 +641,24 @@ void threegpplte_turbo_encoder(unsigned char *input, #endif } - +void init_encoder_sse (void) { + treillis_table_init(); +} +/* function which will be called by the shared lib loader, to check shared lib version + against main exec version. version mismatch no considered as fatal (interfaces not supposed to change) +*/ +int coding_checkbuildver(char * mainexec_buildversion, char ** shlib_buildversion) +{ +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION "standalone built: " __DATE__ __TIME__ +#endif + *shlib_buildversion = PACKAGE_VERSION; + if (strcmp(mainexec_buildversion, *shlib_buildversion) != 0) { + fprintf(stderr,"[CODING] shared lib version %s, doesn't match main version %s, compatibility should be checked\n", + mainexec_buildversion,*shlib_buildversion); + } + return 0; +} #ifdef TC_MAIN #define INPUT_LENGTH 20 @@ -679,7 +696,7 @@ int main(int argc,char **argv) printf("Input %d : %d\n",i,input[i]); } - threegpplte_turbo_encoder(&input[0], + threegpplte_turbo_encoder_sse(&input[0], INPUT_LENGTH, &output[0], 0, diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder.c b/openair1/PHY/CODING/3gpplte_turbo_decoder.c index 4470ecca05ba426e30113e6a71eacf76e87a0465..c0e4ca12db42a30e768718336467da778dac3aa3 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder.c @@ -550,7 +550,7 @@ void compute_alpha_s(llr_t* alpha,llr_t* m_11,llr_t* m_10,unsigned short frame_l void compute_beta_s(llr_t* beta,llr_t *m_11,llr_t* m_10,llr_t* alpha,unsigned short frame_length,unsigned char F) { - int k,i; + int k; llr_t old0, old1, old2, old3, old4, old5, old6, old7; llr_t new0, new1, new2, new3, new4, new5, new6, new7; llr_t m_b0, m_b1, m_b2, m_b3, m_b4,m_b5, m_b6, m_b7; @@ -874,14 +874,22 @@ void compute_ext_s(llr_t* alpha,llr_t* beta,llr_t* m_11,llr_t* m_10,llr_t* ext, unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, + llr_t *y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, unsigned char max_iterations, unsigned char crc_type, unsigned char F, - unsigned char inst) + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) { /* y is a pointer to the input @@ -897,7 +905,7 @@ unsigned char phy_threegpplte_turbo_decoder_scalar(llr_t *y, unsigned char crc_len,temp; if (crc_type > 3) { - msg("Illegal crc length!\n"); + fprintf(stderr,"Illegal crc length!\n"); return 255; } diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c index 83a50f214b202be4823acbc667d5c7041b61b1e6..ef0ca48df465971ed2b89b66068f366a4937a519 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_avx2_16bit.c @@ -37,9 +37,9 @@ /// /// -#ifdef __AVX2__ -#include "PHY/sse_intrin.h" + + #ifndef TEST_DEBUG #include "PHY/defs.h" @@ -58,6 +58,8 @@ #include "mex.h" #endif +#ifdef __AVX2__ +#include "PHY/sse_intrin.h" //#define DEBUG_LOGMAP @@ -837,7 +839,7 @@ void free_td16avx2(void) } } -void init_td16avx2() +void init_td16avx2(void) { int ind,i,i2,i3,j,n,pi,pi2_i,pi2_pi; @@ -1408,6 +1410,36 @@ unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y, #endif return(iteration_cnt); } +#else //__AVX2__ +unsigned char phy_threegpplte_turbo_decoder16avx2(int16_t *y, + int16_t *y2, + uint8_t *decoded_bytes, + uint8_t *decoded_bytes2, + uint16_t n, + uint16_t f1, + uint16_t f2, + uint8_t max_iterations, + uint8_t crc_type, + uint8_t F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) +{ + return 0; +} +void free_td16avx2(void) +{ + +} + +void init_td16avx2(void) +{ + +} #endif //__AVX2__ diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c index a32edd711d338698b0acdaf5949d19b200a2b24e..ae3ce531d037cce540522aa6454a20ab96733132 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c @@ -1124,7 +1124,7 @@ void free_td16(void) } } -void init_td16() +void init_td16(void) { int ind,i,i2,i3,j,n,pi,pi3; @@ -1172,7 +1172,9 @@ void init_td16() } unsigned char phy_threegpplte_turbo_decoder16(short *y, + short *y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index 4754e26f38bc673595f16377682b37601869c713..5b7174e98964b9c9fec7e450fb892778755e57ff 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -849,7 +849,7 @@ void free_td8(void) extern RAN_CONTEXT_t RC; -void init_td8() +void init_td8(void) { int ind,i,j,n,n2,pi,pi3; @@ -898,7 +898,9 @@ void init_td8() } unsigned char phy_threegpplte_turbo_decoder8(short *y, + short y2, unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, unsigned short n, unsigned short f1, unsigned short f2, diff --git a/openair1/PHY/CODING/coding_load.c b/openair1/PHY/CODING/coding_load.c new file mode 100644 index 0000000000000000000000000000000000000000..31f71e6b31965e7777cba5fb9b4a2f260c56da51 --- /dev/null +++ b/openair1/PHY/CODING/coding_load.c @@ -0,0 +1,183 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair1/PHY/CODING + * \brief: load library implementing coding/decoding algorithms + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#define _GNU_SOURCE +#include <sys/types.h> + + +#include "PHY/defs.h" +#include "PHY/extern.h" +#include "common/utils/load_module_shlib.h" +#include "common/utils/telnetsrv/telnetsrv.h" + +static int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static telnetshell_cmddef_t coding_cmdarray[] = { + {"mode","[sse,avx2,stdc,none]",coding_setmod_cmd}, + {"","",NULL}, +}; +telnetshell_vardef_t coding_vardef[] = { +{"maxiter",TELNET_VARTYPE_INT32,&max_turbo_iterations}, +{"",0,NULL} +}; +/* PHY/defs.h contains MODE_DECODE_XXX macros, following table must match */ +static char *modedesc[] = {"none","sse","C","avx2"}; +static int curmode; +/* function description array, to be used when loading the encoding/decoding shared lib */ +loader_shlibfunc_t shlib_fdesc[DECODE_NUM_FPTR]; + +/* encoding decoding functions pointers, filled here and used when encoding/decoding */ +/*defined as extern in PHY?CODING/extern.h */ +decoder_if_t decoder16; +decoder_if_t decoder8; +encoder_if_t encoder; + +extern int _may_i_use_cpu_feature(unsigned __int64); +uint8_t nodecod(short *y, + short *y2, + unsigned char *decoded_bytes, + unsigned char *decoded_bytes2, + unsigned short n, + unsigned short f1, + unsigned short f2, + unsigned char max_iterations, + unsigned char crc_type, + unsigned char F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats) +{ + return max_iterations+1; +}; + +void decoding_setmode (int mode) { + switch (mode) { + case MODE_DECODE_NONE: + decoder8=nodecod; + decoder16=nodecod; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; + break; + case MODE_DECODE_C: + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD_C_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_C_FPTRIDX].fptr; + break; + case MODE_DECODE_AVX2: + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fptr; + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; + break; + default: + mode=MODE_DECODE_SSE; + case MODE_DECODE_SSE: + decoder8=(decoder_if_t)shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fptr; + decoder16=(decoder_if_t)shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fptr; + encoder=(encoder_if_t)shlib_fdesc[ENCODE_SSE_FPTRIDX].fptr; + break; + } + curmode=mode; +} + + +int load_codinglib(void) { + int ret; + + memset(shlib_fdesc,0,sizeof(shlib_fdesc)); + shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fname = "init_td8"; + shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fname= "init_td16"; + shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fname="init_td16avx2"; + + shlib_fdesc[DECODE_TD8_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder8"; + shlib_fdesc[DECODE_TD16_SSE_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16"; + shlib_fdesc[DECODE_TD_C_FPTRIDX].fname= "phy_threegpplte_turbo_decoder_scalar"; + shlib_fdesc[DECODE_TD16_AVX2_FPTRIDX].fname= "phy_threegpplte_turbo_decoder16avx2"; + + + shlib_fdesc[DECODE_FREETD8_FPTRIDX].fname = "free_td8"; + shlib_fdesc[DECODE_FREETD16_FPTRIDX].fname= "free_td16"; + shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fname= "free_td16avx2"; + + shlib_fdesc[ENCODE_SSE_FPTRIDX].fname= "threegpplte_turbo_encoder_sse"; + shlib_fdesc[ENCODE_C_FPTRIDX].fname= "threegpplte_turbo_encoder"; + shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fname= "init_encoder_sse"; + ret=load_module_shlib("coding",shlib_fdesc,DECODE_NUM_FPTR); + if (ret < 0) exit_fun("Error loading coding library"); + +/* execute encoder/decoder init functions */ + shlib_fdesc[DECODE_INITTD8_SSE_FPTRIDX].fptr(); + shlib_fdesc[DECODE_INITTD16_SSE_FPTRIDX].fptr(); + if(shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr != NULL) { + shlib_fdesc[DECODE_INITTD_AVX2_FPTRIDX].fptr(); + } + if(shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr != NULL) { + shlib_fdesc[ENCODE_INIT_SSE_FPTRIDX].fptr(); + } + decoding_setmode(MODE_DECODE_SSE); +/* look for telnet server, if it is loaded, add the coding commands to it */ + add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); + if (addcmd != NULL) { + addcmd("coding",coding_vardef,coding_cmdarray); + } +return 0; +} + +void free_codinglib(void) { + + shlib_fdesc[DECODE_FREETD8_FPTRIDX].fptr(); + shlib_fdesc[DECODE_FREETD16_FPTRIDX].fptr(); + shlib_fdesc[DECODE_FREETD_AVX2_FPTRIDX].fptr(); + + +} + +/* functions for telnet support, when telnet server is loaded */ +int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ + if (debug > 0) + prnt( "coding_setmod_cmd received %s\n",buff); + + if (strcasestr(buff,"sse") != NULL) { + decoding_setmode(MODE_DECODE_SSE); + } else if (strcasestr(buff,"avx2") != NULL) { + decoding_setmode(MODE_DECODE_AVX2); + } else if (strcasestr(buff,"stdc") != NULL) { + decoding_setmode(MODE_DECODE_C); + } else if (strcasestr(buff,"none") != NULL) { + decoding_setmode(MODE_DECODE_NONE); + } else { + prnt("%s: wrong setmod parameter...\n",buff); + } + prnt("Coding and decoding current mode: %s\n",modedesc[curmode]); + return 0; +} diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 5ec4fcaaa4bc73f8a26aec421159a4c0286c9ecf..21427de19b88c1568ac96b4a08b40b4d0813f1f2 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -109,7 +109,7 @@ crc24a (unsigned char * inptr, int bitlen) resbit = (bitlen % 8); while (octetlen-- > 0) { - // printf("in %x => crc %x\n",crc,*inptr); + // printf("crc24a: in %x => crc %x\n",crc,*inptr); crc = (crc << 8) ^ crc24aTable[(*inptr++) ^ (crc >> 24)]; } @@ -128,6 +128,7 @@ unsigned int crc24b (unsigned char * inptr, int bitlen) resbit = (bitlen % 8); while (octetlen-- > 0) { + // printf("crc24b: in %x => crc %x (%x)\n",crc,*inptr,crc24bTable[(*inptr) ^ (crc >> 24)]); crc = (crc << 8) ^ crc24bTable[(*inptr++) ^ (crc >> 24)]; } diff --git a/openair1/PHY/CODING/defs.h b/openair1/PHY/CODING/defs.h index 22339953c39afee26c0808b18bdb7e43ad846a9a..40e19964dfa1abc0d847f84bfc2560ee3f2ea96f 100644 --- a/openair1/PHY/CODING/defs.h +++ b/openair1/PHY/CODING/defs.h @@ -37,7 +37,7 @@ #define CRC8 3 #define MAX_TURBO_ITERATIONS_MBSFN 8 -#define MAX_TURBO_ITERATIONS 4 +#define MAX_TURBO_ITERATIONS max_turbo_iterations #define LTE_NULL 2 @@ -292,25 +292,9 @@ void ccodedot11_init(void); \brief This function initializes the trellis structure for decoding an 802.11 convolutional code.*/ void ccodedot11_init_inv(void); -/*!\fn void teillis_table_init(void) -\brief This function initializes the trellis structure for 3GPP LTE Turbo code.*/ -void treillis_table_init(void); - -/*\fn void threegpplte_turbo_encoder(uint8_t *input,uint16_t input_length_bytes,uint8_t *output,uint8_t F,uint16_t interleaver_f1,uint16_t interleaver_f2) -\brief This function implements a rate 1/3 8-state parralel concatenated turbo code (3GPP-LTE). -@param input Pointer to input buffer -@param input_length_bytes Number of bytes to encode -@param output Pointer to output buffer -@param F Number of filler bits at input -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -*/ -void threegpplte_turbo_encoder(uint8_t *input, - uint16_t input_length_bytes, - uint8_t *output, - uint8_t F, - uint16_t interleaver_f1, - uint16_t interleaver_f2); + + + /** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti) @@ -352,35 +336,7 @@ void ccodedab_init_inv(void); \brief This function initializes the different crc tables.*/ void crcTableInit (void); -/*!\fn void free_td8(void) -\brief This function frees the tables for 8-bit LLR Turbo decoder.*/ -void free_td8(void); - -/*!\fn void init_td8(void) -\brief This function initializes the tables for 8-bit LLR Turbo decoder.*/ -void init_td8 (void); - -/*!\fn void free_td16(void) -\brief This function frees the tables for 16-bit LLR Turbo decoder.*/ -void free_td16(void); - -/*!\fn void init_td16(void) -\brief This function initializes the tables for 16-bit LLR Turbo decoder.*/ -void init_td16 (void); - -#ifdef __AVX2__ -/*!\fn void init_td8(void) -\brief This function initializes the tables for 8-bit LLR Turbo decoder (AVX2).*/ -void init_td8avx2 (void); -/*!\fn void free_td16avx2(void) -\brief This function frees the tables for 16-bit LLR Turbo decoder (AVX2).*/ -void free_td16avx2(void); - -/*!\fn void init_td16(void) -\brief This function initializes the tables for 16-bit LLR Turbo decoder (AVX2).*/ -void init_td16avx2 (void); -#endif /*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen) \brief This computes a 24-bit crc ('a' variant for overall transport block) @@ -470,95 +426,7 @@ int32_t rate_matching_lte(uint32_t N_coded, uint32_t off); -/*! -\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 16-bit -LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU) -@param y LLR input (16-bit precision) -@param decoded_bytes Pointer to decoded output -@param n number of coded bits (including tail bits) -@param max_iterations The maximum number of iterations to perform -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8) -@param F Number of filler bits at start of packet -@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0) -*/ -uint8_t phy_threegpplte_turbo_decoder16(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -uint8_t phy_threegpplte_turbo_decoder16avx2(int16_t *y, - int16_t *y2, - uint8_t *decoded_bytes, - uint8_t *decoded_bytes2, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -/*! -\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 8-bit -LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU) -@param y LLR input (16-bit precision) -@param decoded_bytes Pointer to decoded output -@param n number of coded bits (including tail bits) -@param max_iterations The maximum number of iterations to perform -@param interleaver_f1 F1 generator -@param interleaver_f2 F2 generator -@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8) -@param F Number of filler bits at start of packet -@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0) -*/ -uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - time_stats_t *init_stats, - time_stats_t *alpha_stats, - time_stats_t *beta_stats, - time_stats_t *gamma_stats, - time_stats_t *ext_stats, - time_stats_t *intl1_stats, - time_stats_t *intl2_stats); - -uint8_t phy_threegpplte_turbo_decoder_scalar(int16_t *y, - uint8_t *decoded_bytes, - uint16_t n, - uint16_t interleaver_f1, - uint16_t interleaver_f2, - uint8_t max_iterations, - uint8_t crc_type, - uint8_t F, - uint8_t inst); - - - -/** @} */ + uint32_t crcbit (uint8_t * , int32_t, diff --git a/openair1/PHY/CODING/defs_NB_IoT.h b/openair1/PHY/CODING/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..2a6bee792412ae4f73d38f741b6ef5b615065418 --- /dev/null +++ b/openair1/PHY/CODING/defs_NB_IoT.h @@ -0,0 +1,275 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* file: PHY/CODING/defs_NB_IoT.h + purpose: Top-level definitions, data types and function prototypes for openairinterface coding blocks for NB-IoT + author: matthieu.kanj@b-com.com, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it + date: 29.06.2017 +*/ + +#ifndef OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ +#define OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ + +#include <stdint.h> // for uint8/16/32_t + +/* check if this ifndef is required for NB-IoT ?! +//#ifndef NO_OPENAIR1 +//#include "PHY/defs_NB_IoT.h" +//#else +//#include "PHY/TOOLS/time_meas.h" +//#endif +*/ + +#define CRC24_A_NB_IoT 0 +#define CRC24_B_NB_IoT 1 +#define CRC16_NB_IoT 2 +#define CRC8_NB_IoT 3 + +//#define MAX_TURBO_ITERATIONS_MBSFN 8 // no MBSFN +#define MAX_TURBO_ITERATIONS_NB_IoT 4 + +#define LTE_NULL_NB_IoT 2 // defined also in PHY/LTE_TRANSPORT/defs_NB_IoT.h + +/** \fn uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w) +\brief This is the subblock interleaving algorithm for convolutionally coded blocks from 36-212 (Release 13.4, 2017). +This function takes the d-sequence and generates the w-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of input bits +\param d Pointer to input (d-sequence, convolutional code output) +\param w Pointer to output (w-sequence, interleaver output) +\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212) +*/ +uint32_t sub_block_interleaving_cc_NB_IoT(uint32_t D, uint8_t *d,uint8_t *w); + +/** +\brief This is the NB-IoT rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) for up to 8 segments +\param E Number of coded channel bits +\param w This is a pointer to the w-sequence (second interleaver output) +\param e This is a pointer to the e-sequence (rate matching output, channel input/output bits) +\returns \f$E\f$, the number of coded bits per segment */ + +uint32_t lte_rate_matching_cc_NB_IoT(uint32_t RCC, // RRC = 2 + uint16_t E, // E = 1600 + uint8_t *w, // length + uint8_t *e); // length 1600 + +/** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti) +\brief This function implements the LTE convolutional code of rate 1/3 + with a constraint length of 7 bits. The inputs are bit packed in octets +(from MSB to LSB). Trellis tail-biting is included here. +@param numbits Number of bits to encode +@param add_crc crc to be appended (8 bits) if add_crc = 1 +@param inPtr Pointer to input buffer +@param outPtr Pointer to output buffer +@param rnti RNTI for CRC scrambling +*/ + +void ccode_encode_NB_IoT (int32_t numbits, + uint8_t add_crc, + uint8_t *inPtr, + uint8_t *outPtr, + uint16_t rnti); + +/*!\fn void ccodelte_init(void) +\brief This function initializes the generator polynomials for an LTE convolutional code.*/ +void ccodelte_init_NB_IoT(void); + +/*!\fn void crcTableInit(void) +\brief This function initializes the different crc tables.*/ +void crcTableInit_NB_IoT (void); + + +/*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 24-bit crc ('a' variant for overall transport block) +based on 3GPP UMTS/LTE specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits +*/ +uint32_t crc24a_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc24b(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 24-bit crc ('b' variant for transport-block segments) +based on 3GPP UMTS/LTE specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits +*/ +uint32_t crc24b_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 16-bit crc based on 3GPP UMTS specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits*/ +uint32_t crc16_NB_IoT (uint8_t *inPtr, int32_t bitlen); + +/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen) +\brief This computes a 8-bit crc based on 3GPP UMTS specifications. +@param inPtr Pointer to input byte stream +@param bitlen length of inputs in bits*/ +uint32_t crc8_NB_IoT (uint8_t *inPtr, int32_t bitlen); + + + + + + +uint32_t crcbit_NB_IoT (uint8_t * , + int32_t, + uint32_t); + + +/*!\fn void phy_viterbi_lte_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n) +\brief This routine performs a SIMD optmized Viterbi decoder for the LTE 64-state tail-biting convolutional code. +@param y Pointer to soft input (coded on 8-bits but should be limited to 4-bit precision to avoid overflow) +@param decoded_bytes Pointer to decoded output +@param n Length of input/trellis depth in bits*/ +//void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n); +void phy_viterbi_lte_sse2_NB_IoT(int8_t *y,uint8_t *decoded_bytes,uint16_t n); + +/** \fn void sub_block_deinterleaving_cc(uint32_t D, int8_t *d,int8_t *w) +\brief This is the subblock deinterleaving algorithm for convolutionally-coded data from 36-212 (Release 8, 8.6 2009-03), pages 15-16. +This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of input bits +\param d Pointer to output (d-sequence, turbo code output) +\param w Pointer to input (w-sequence, interleaver output) +*/ +void sub_block_deinterleaving_cc_NB_IoT(uint32_t D,int8_t *d,int8_t *w); + + +/* +\brief This is the LTE rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) +\param E This the number of coded bits allocated for channel +\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds +\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions +\param soft_input This is a pointer to the soft channel output +\returns \f$E\f$, the number of coded bits per segment +*/ +void lte_rate_matching_cc_rx_NB_IoT(uint32_t RCC, + uint16_t E, + int8_t *w, + uint8_t *dummy_w, + int8_t *soft_input); + +/** \fn generate_dummy_w_cc(uint32_t D, uint8_t *w) +\brief This function generates a dummy interleaved sequence (first row) for receiver (convolutionally-coded data), in order to identify the NULL positions used to make the matrix complete. +\param D Number of systematic bits plus 4 (plus 4 for termination) +\param w This is the dummy sequence (first row), it will contain zeros and at most 31 "LTE_NULL" values +\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212) +*/ +uint32_t generate_dummy_w_cc_NB_IoT(uint32_t D, uint8_t *w); + +/** \fn lte_segmentation(uint8_t *input_buffer, + uint8_t **output_buffers, + uint32_t B, + uint32_t *C, + uint32_t *Cplus, + uint32_t *Cminus, + uint32_t *Kplus, + uint32_t *Kminus, + uint32_t *F) +\brief This function implements the LTE transport block segmentation algorithm from 36-212, V8.6 2009-03. +@param input_buffer +@param output_buffers +@param B +@param C +@param Cplus +@param Cminus +@param Kplus +@param Kminus +@param F +*/ +int32_t lte_segmentation_NB_IoT(uint8_t *input_buffer, + uint8_t **output_buffers, + uint32_t B, + uint32_t *C, + uint32_t *Cplus, + uint32_t *Cminus, + uint32_t *Kplus, + uint32_t *Kminus, + uint32_t *F); + +/** \fn void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w) +\brief This is the subblock deinterleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16. +This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit. +\param D Number of systematic bits plus 4 (plus 4 for termination) +\param d Pointer to output (d-sequence, turbo code output) +\param w Pointer to input (w-sequence, interleaver output) +*/ +//*****************void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w); + +/** +\brief This is the LTE rate matching algorithm for Turbo-coded channels (e.g. DLSCH,ULSCH). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 ) +\param RTC R^TC_subblock from subblock interleaver (number of rows in interleaving matrix) +\param G This the number of coded transport bits allocated in sub-frame +\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds +\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions +\param soft_input This is a pointer to the soft channel output +\param C Number of segments (codewords) in the sub-frame +\param Nsoft Total number of soft bits (from UE capabilities in 36-306) +\param Mdlharq Number of HARQ rounds +\param Kmimo MIMO capability for this DLSCH (0 = no MIMO) +\param rvidx round index (0-3) +\param clear 1 means clear soft buffer (start of HARQ round) +\param Qm modulation order (2,4,6) +\param Nl number of layers (1,2) +\param r segment number +\param E_out the number of coded bits per segment +\returns 0 on success, -1 on failure +*/ + +// int lte_rate_matching_turbo_rx(uint32_t RTC, +// uint32_t G, +// int16_t *w, +// uint8_t *dummy_w, +// int16_t *soft_input, +// uint8_t C, +// uint32_t Nsoft, +// uint8_t Mdlharq, +// uint8_t Kmimo, +// uint8_t rvidx, +// uint8_t clear, +// uint8_t Qm, +// uint8_t Nl, +// uint8_t r, +// uint32_t *E_out); + +// uint32_t lte_rate_matching_turbo_rx_abs(uint32_t RTC, +// uint32_t G, +// double *w, +// uint8_t *dummy_w, +// double *soft_input, +// uint8_t C, +// uint32_t Nsoft, +// uint8_t Mdlharq, +// uint8_t Kmimo, +// uint8_t rvidx, +// uint8_t clear, +// uint8_t Qm, +// uint8_t Nl, +// uint8_t r, +// uint32_t *E_out); + +void ccode_encode_npdsch_NB_IoT (int32_t numbits, + uint8_t *inPtr, + uint8_t *outPtr, + uint32_t crc); + +#endif /* OPENAIR1_PHY_CODING_DEFS_NB_IOT_H_ */ diff --git a/openair1/PHY/CODING/extern.h b/openair1/PHY/CODING/extern.h index 9c58920a10d003db6e73768638cbdf594146dd24..0d3e2ccb02e3b050243443603bc0946f414f9745 100644 --- a/openair1/PHY/CODING/extern.h +++ b/openair1/PHY/CODING/extern.h @@ -20,5 +20,9 @@ */ extern unsigned short f1f2mat_old[2*188]; - - +extern double cpuf; +extern decoder_if_t decoder16; +extern decoder_if_t decoder8; +extern encoder_if_t encoder; +extern int load_codinglib(void); +extern int free_codinglib(void); diff --git a/openair1/PHY/CODING/lte_rate_matching.c b/openair1/PHY/CODING/lte_rate_matching.c index 13870e3303ccf17f117a97df225dc06a5f72c83b..41c3c5e5a91b314c62c2d9a701c1802def0b306c 100644 --- a/openair1/PHY/CODING/lte_rate_matching.c +++ b/openair1/PHY/CODING/lte_rate_matching.c @@ -463,7 +463,7 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, uint8_t Qm, uint8_t Nl, uint8_t r, - uint8_t nb_rb) + uint8_t nb_rb) // uint8_t m) { @@ -513,7 +513,7 @@ uint32_t lte_rate_matching_turbo(uint32_t RTC, // counter_buffer[rvidx][cnt]=0; if (Ncb>(3*(RTC<<5))) AssertFatal(1==0,"Exiting, RM condition (Ncb %d, RTC %d, Nir/C %d, Nsoft %d, Kw %d)\n",Ncb,RTC,Nir/C,Nsoft,3*(RTC<<5)); - + AssertFatal(Nl>0,"Nl is 0\n"); AssertFatal(Qm>0,"Qm is 0\n"); Gp = G/Nl/Qm; @@ -749,6 +749,10 @@ int lte_rate_matching_turbo_rx(uint32_t RTC, for (; (ind<Ncb)&&(k<E); ind++) { if (dummy_w[ind] != LTE_NULL) { + /* + if ((w[ind]>0 && soft_input2[k]<0) || + (w[ind]<0 && soft_input2[k]>0)) + printf("ind %d: w %d => soft_in %d\n",ind,w[ind],soft_input2[k]);*/ w[ind] += soft_input2[k++]; #ifdef RM_DEBUG printf("RM_RX k%d Ind: %d (%d)\n",k-1,ind,w[ind]); diff --git a/openair1/PHY/INIT/defs.h b/openair1/PHY/INIT/defs.h index 55d220824e23df0808e6750fd21f5d656f76399e..be3e5c160b61a7ad71562befd3f2da89cd3a8fb0 100644 --- a/openair1/PHY/INIT/defs.h +++ b/openair1/PHY/INIT/defs.h @@ -330,19 +330,25 @@ void init_lte_top(LTE_DL_FRAME_PARMS *lte_frame_parms); //void copy_lte_parms_to_phy_framing(LTE_DL_FRAME_PARMS *frame_parm, PHY_FRAMING *phy_framing); -void lte_param_init(unsigned char N_tx_port_eNB, - unsigned char N_tx, - unsigned char N_rx, +void lte_param_init(PHY_VARS_eNB **eNBp, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, + unsigned char N_tx_phy, + unsigned char N_rx_ru, + unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, - frame_t frame_type, + frame_t frame_type, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, + uint8_t pa, uint8_t threequarter_fs, uint8_t osf, uint32_t perfect_ce); + #if defined(Rel10) || defined(Rel14) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, @@ -367,18 +373,6 @@ void phy_config_request(PHY_Config_t *phy_config); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); -void lte_param_init(unsigned char N_tx_port_eNB, - unsigned char N_tx_phy, - unsigned char N_rx, - unsigned char transmission_mode, - uint8_t extended_prefix_flag, - frame_t frame_type, - uint16_t Nid_cell, - uint8_t tdd_config, - uint8_t N_RB_DL, - uint8_t threequarter_fs, - uint8_t osf, - uint32_t perfect_ce); /** @} */ #endif diff --git a/openair1/PHY/INIT/defs_NB_IoT.h b/openair1/PHY/INIT/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..8a83cbd03843e44686809823570832a8ef03c2e2 --- /dev/null +++ b/openair1/PHY/INIT/defs_NB_IoT.h @@ -0,0 +1,77 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#ifndef __INIT_DEFS_NB_IOT__H__ +#define __INIT_DEFS_NB_IOT__H__ + +//#include "PHY/defs_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "nfapi_interface.h" + +//#include "SystemInformationBlockType2.h" +//#include "RadioResourceConfigCommonSIB.h" +//#include "RadioResourceConfigDedicated.h" +//#include "TDD-Config.h" +//#include "MBSFN-SubframeConfigList.h" +//#include "MobilityControlInfo.h" +//#if defined(Rel10) || defined(Rel14) +//#include "SCellToAddMod-r10.h" +//#endif + +/*brief Configure LTE_DL_FRAME_PARMS with components derived after initial synchronization (MIB-NB decoding + primary/secondary synch).*/ +void phy_config_mib_eNB_NB_IoT(int Mod_id, + int eutra_band, + int Nid_cell, + int Ncp, + int Ncp_UL, + int p_eNB, + uint16_t EARFCN, + uint16_t prb_index, // NB_IoT_RB_ID, + uint16_t operating_mode, + uint16_t control_region_size, + uint16_t eutra_NumCRS_ports); + +/*NB_phy_config_sib1_eNB is not needed since NB-IoT use only FDD mode*/ + +/*brief Configure LTE_DL_FRAME_PARMS with components of SIB2-NB (at eNB).*/ + +//void NB_phy_config_sib2_eNB(module_id_t Mod_id, +// int CC_id, +// RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon +// ); + +void phy_config_sib2_eNB_NB_IoT(uint8_t Mod_id, + nfapi_nb_iot_config_t *config, + nfapi_rf_config_t *rf_config, + nfapi_uplink_reference_signal_config_t* ul_nrs_config, + extra_phyConfig_t* extra_phy_parms); + +void phy_config_dedicated_eNB_NB_IoT(module_id_t Mod_id, + rnti_t rnti, + extra_phyConfig_t* extra_phy_parms); + +// void phy_init_lte_top_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); +void phy_init_nb_iot_eNB(PHY_VARS_eNB_NB_IoT *phyvar); +int l1_north_init_NB_IoT(void); + +#endif + diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index a1edd9d1eab1de74f6920f0e4afc401d9a3d6996..6213520b8c8bf042aaf7c7212ea8a5a237156ba8 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -22,7 +22,7 @@ /*!\brief Initilization and reconfiguration routines for LTE PHY */ #include "defs.h" #include "PHY/extern.h" - +#include "PHY/CODING/extern.h" void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { @@ -34,15 +34,12 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) ccodelte_init(); ccodelte_init_inv(); - treillis_table_init(); + phy_generate_viterbi_tables(); phy_generate_viterbi_tables_lte(); - init_td8(); - init_td16(); -#ifdef __AVX2__ - init_td16avx2(); -#endif + + load_codinglib(); lte_sync_time_init(frame_parms); generate_ul_ref_sigs(); @@ -61,11 +58,7 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) void free_lte_top(void) { - free_td8(); - free_td16(); -#ifdef __AVX2__ - free_td16avx2(); -#endif + free_codinglib(); lte_sync_time_free(); /* free_ul_ref_sigs() is called in phy_free_lte_eNB() */ diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index 9df6e9fc66acf6d5c061a8a535dd78d3f3cf17c8..ff36b0a5e2f4597de8275ff59bad2a286d1d27ac 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -882,11 +882,11 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, AssertFatal(fp->N_RB_UL > 5, "fp->N_RB_UL %d < 6\n",fp->N_RB_UL); for (i=0; i<2; i++) { // RK 2 times because of output format of FFT! - // FIXME We should get rid of this, consider also phy_free_lte_eNB() - pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); + // FIXME We should get rid of this + pusch_vars[UE_id]->rxdataF_ext[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->rxdataF_ext2[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->drs_ch_estimates[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); - pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*2*sizeof(int32_t)*fp->ofdm_symbol_size ); + pusch_vars[UE_id]->drs_ch_estimates_time[i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->ofdm_symbol_size ); pusch_vars[UE_id]->rxdataF_comp[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti ); pusch_vars[UE_id]->ul_ch_mag[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); pusch_vars[UE_id]->ul_ch_magb[i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 ); diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index eb56cb04d3cbe159f9a2049803058247c12e8e42..91681930748052dd38dd69a74cd7a782e1d6cf6d 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -60,7 +60,7 @@ int phy_init_RU(RU_t *ru) { } } // IF5 or local RF else { - LOG_I(PHY,"No rxdata/txdata for RU\n"); + // LOG_I(PHY,"No rxdata/txdata for RU\n"); ru->common.txdata = (int32_t**)NULL; ru->common.rxdata = (int32_t**)NULL; @@ -91,8 +91,8 @@ int phy_init_RU(RU_t *ru) { } /* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */ - AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), - "nb_antennas_rx too large"); + // AssertFatal(ru->nb_rx <= sizeof(ru->prach_rxsigF) / sizeof(ru->prach_rxsigF[0]), + // "nb_antennas_rx too large"); ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); for (j=0;j<4;j++) ru->prach_rxsigF_br[j] = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c index d510fc7261e908f153e6f1d714982997125f9799..6cf05769e52e4ca2b4dfc4a0bba6ac5d4848239f 100644 --- a/openair1/PHY/INIT/lte_param_init.c +++ b/openair1/PHY/INIT/lte_param_init.c @@ -32,16 +32,23 @@ extern PHY_VARS_eNB *eNB; extern PHY_VARS_UE *UE; +extern RU_t *ru; +extern void phy_init_RU(RU_t*); -void lte_param_init(unsigned char N_tx_port_eNB, +void lte_param_init(PHY_VARS_eNB **eNBp, + PHY_VARS_UE **UEp, + RU_t **rup, + unsigned char N_tx_port_eNB, unsigned char N_tx_phy, - unsigned char N_rx, + unsigned char N_rx_ru, + unsigned char N_rx_ue, unsigned char transmission_mode, uint8_t extended_prefix_flag, - frame_t frame_type, + frame_t frame_type, uint16_t Nid_cell, uint8_t tdd_config, uint8_t N_RB_DL, + uint8_t pa, uint8_t threequarter_fs, uint8_t osf, uint32_t perfect_ce) @@ -49,13 +56,27 @@ void lte_param_init(unsigned char N_tx_port_eNB, LTE_DL_FRAME_PARMS *frame_parms; int i; - + PHY_VARS_eNB *eNB; + PHY_VARS_UE *UE; + RU_t *ru; printf("Start lte_param_init\n"); - eNB = malloc(sizeof(PHY_VARS_eNB)); - UE = malloc(sizeof(PHY_VARS_UE)); + *eNBp = malloc(sizeof(PHY_VARS_eNB)); + *UEp = malloc(sizeof(PHY_VARS_UE)); + *rup = malloc(sizeof(RU_t)); + eNB = *eNBp; + UE = *UEp; + ru = *rup; + printf("eNB %p, UE %p, ru %p\n",eNB,UE,ru); + + + memset((void*)eNB,0,sizeof(PHY_VARS_eNB)); memset((void*)UE,0,sizeof(PHY_VARS_UE)); + memset((void*)ru,0,sizeof(RU_t)); + ru->eNB_list[0] = eNB; + eNB->RU_list[0] = ru; + ru->num_eNB=1; srand(0); randominit(0); @@ -71,7 +92,7 @@ void lte_param_init(unsigned char N_tx_port_eNB, frame_parms->Nid_cell = Nid_cell; frame_parms->nushift = Nid_cell%6; frame_parms->nb_antennas_tx = N_tx_phy; - frame_parms->nb_antennas_rx = N_rx; + frame_parms->nb_antennas_rx = N_rx_ru; frame_parms->nb_antenna_ports_eNB = N_tx_port_eNB; frame_parms->phich_config_common.phich_resource = oneSixth; frame_parms->phich_config_common.phich_duration = normal; @@ -90,12 +111,18 @@ void lte_param_init(unsigned char N_tx_port_eNB, UE->is_secondary_ue = 0; UE->frame_parms = *frame_parms; - eNB->frame_parms = *frame_parms; + UE->frame_parms.nb_antennas_rx=N_rx_ue; + // eNB->frame_parms = *frame_parms; + ru->frame_parms = *frame_parms; + ru->nb_tx = N_tx_phy; + ru->nb_rx = N_rx_ru; + ru->if_south = LOCAL_RF; + + eNB->configured=1; eNB->transmission_mode[0] = transmission_mode; UE->transmission_mode[0] = transmission_mode; - init_lte_top(frame_parms); dump_frame_parms(frame_parms); UE->measurements.n_adj_cells=0; @@ -105,23 +132,24 @@ void lte_param_init(unsigned char N_tx_port_eNB, for (i=0; i<3; i++) lte_gold(frame_parms,UE->lte_gold_table[i],Nid_cell+i); - init_lte_ue(UE,1,0); + printf("Calling init_lte_ue_signal\n"); + init_lte_ue_signal(UE,1,0); + printf("Calling phy_init_lte_eNB\n"); phy_init_lte_eNB(eNB,0,0); - + printf("Calling phy_init_RU (%p)\n",ru); + phy_init_RU(ru); generate_pcfich_reg_mapping(&UE->frame_parms); generate_phich_reg_mapping(&UE->frame_parms); // DL power control init //if (transmission_mode == 1) { + UE->pdsch_config_dedicated->p_a = pa; + if (transmission_mode == 1 || transmission_mode ==7) { - eNB->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB ((eNB->frame_parms).pdsch_config_common).p_b = 0; - UE->pdsch_config_dedicated->p_a = dB0; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 0; } else { // rho_a = rhob - eNB->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((eNB->frame_parms).pdsch_config_common).p_b = 1; - UE->pdsch_config_dedicated->p_a = dBm3; // 4 = 0dB ((UE->frame_parms).pdsch_config_common).p_b = 1; } @@ -130,6 +158,13 @@ void lte_param_init(unsigned char N_tx_port_eNB, /* the UE code is multi-thread "aware", we need to setup this array */ for (i = 0; i < 10; i++) UE->current_thread_id[i] = i % 2; + if (eNB->frame_parms.frame_type == TDD) { + if (eNB->frame_parms.N_RB_DL == 100) ru->N_TA_offset = 624; + else if (eNB->frame_parms.N_RB_DL == 50) ru->N_TA_offset = 624/2; + else if (eNB->frame_parms.N_RB_DL == 25) ru->N_TA_offset = 624/4; + } + else ru->N_TA_offset=0; + printf("Done lte_param_init\n"); diff --git a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c index 74a844da8ad943806bbd0ffe7e04c52ff63f3c03..2c318d85e401d529bb78f5bdda5ffc6c74be5c05 100644 --- a/openair1/PHY/LTE_ESTIMATION/freq_equalization.c +++ b/openair1/PHY/LTE_ESTIMATION/freq_equalization.c @@ -306,7 +306,7 @@ void freq_equalization(LTE_DL_FRAME_PARMS *frame_parms, AssertFatal(symbol<frame_parms->symbols_per_tti,"symbol %d >= %d\n", symbol,frame_parms->symbols_per_tti); - AssertFatal(Msc_RS<frame_parms->N_RB_UL*12,"Msc_RS %d >= %d\n", + AssertFatal(Msc_RS<=frame_parms->N_RB_UL*12,"Msc_RS %d >= %d\n", Msc_RS,frame_parms->N_RB_UL*12); for (re=0; re<(Msc_RS>>2); re++) { diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c index c4df34638bf2a06fc5a0894d35bfae6a94c1eb5c..ce6cd869599087d1b4a1258d4d894bc1fbaec717 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c @@ -207,10 +207,8 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ((ue->frame_parms.frame_type == TDD) && ((subframe == 1) || (subframe == 6))) ) { // FDD PSS/SSS, compute noise in DTX REs - - if (ue->frame_parms.Ncp==NORMAL) { + if (ue->frame_parms.Ncp == NORMAL) { for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) { - if(ue->frame_parms.frame_type == FDD) { rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)]; @@ -266,7 +264,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue, ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx)); ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size); } else { - LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n"); + LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length == EXTENDED\n"); } } else if ((ue->frame_parms.frame_type == TDD) && diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index 18069f9759efcfdc3b48fea930d656843939ff77..9ef23f23d06ebcaee853c03d4d110de305ee4130 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -100,7 +100,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); return(-1); } - // LOG_I(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); + LOG_D(PHY,"subframe %d, Ns %d, l %d, Msc_RS = %d, Msc_RS_idx = %d, u %d, v %d, cyclic_shift %d\n",subframe,Ns,l,Msc_RS, Msc_RS_idx,u,v,cyclic_shift); #ifdef DEBUG_CH if (Ns==0) @@ -291,7 +291,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32))); #ifdef DEBUG_CH - if (aa==0) { + if (aa==1) { if (Ns == 0) { write_output("rxdataF_ext.m","rxF_ext",&rxdataF_ext[aa][symbol_offset],512*2,2,1); write_output("tmpin_ifft.m","drs_in",temp_in_ifft_0,512,1,1); diff --git a/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..8f0b7b8c4ce7fb48a2dcabc360d9756ddae98d7e --- /dev/null +++ b/openair1/PHY/LTE_REFSIG/defs_NB_IoT.h @@ -0,0 +1,60 @@ +/******************************************************************************* + + *******************************************************************************/ +/*! \file PHY/LTE_REFSIG/defs_NB_IoT.c +* \function called by lte_dl_cell_spec_NB_IoT.c , TS 36-211, V13.4.0 2017-02 +* \author M. KANJ +* \date 2017 +* \version 0.0 +* \company bcom +* \email: matthieu.kanj@b-com.com +* \note +* \warning +*/ + +/* Definitions for NB_IoT Reference signals */ + +#ifndef __LTE_REFSIG_DEFS_NB_IOT__H__ +#define __LTE_REFSIG_DEFS_NB_IOT__H__ + +#include "PHY/defs_L1_NB_IoT.h" + +/** @ingroup _PHY_REF_SIG + * @{ +*/ +/*!\brief This function generates the LTE Gold sequence (36-211, Sec 7.2), specifically for DL reference signals. +@param frame_parms LTE DL Frame parameters +@param lte_gold_table pointer to table where sequences are stored +@param Nid_cell Cell Id for NB_IoT (to compute sequences for local and adjacent cells) */ + +void lte_gold_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, + uint32_t lte_gold_table_NB_IoT[20][2][14], + uint16_t Nid_cell); + +/*! \brief This function generates the Narrowband reference signal (NRS) sequence (36-211, Sec 6.10.1.1) +@param phy_vars_eNB Pointer to eNB variables +@param output Output vector for OFDM symbol (Frequency Domain) +@param amp Q15 amplitude +@param Ns Slot number (0..19) +@param l symbol (0,1) - Note 1 means 3! +@param p antenna index +@param RB_IoT_ID the ID of the RB dedicated for NB_IoT +*/ +int lte_dl_cell_spec_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + int32_t *output, + short amp, + unsigned char Ns, + unsigned char l, + unsigned char p, + unsigned short RB_IoT_ID); + + +unsigned int lte_gold_generic_NB_IoT(unsigned int *x1, + unsigned int *x2, + unsigned char reset); + +void generate_ul_ref_sigs_rx_NB_IoT(void); + +void free_ul_ref_sigs_NB_IoT(void); + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 18860d729c0059e9e73e641b3725de328b302eac..ded49d1c73a8c53d0574dfdc8f43aa46a3e001e0 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -35,10 +35,10 @@ #include "PHY/defs.h" #include "PHY/extern.h" #include "SCHED/defs.h" -#include "SIMULATION/TOOLS/defs.h" // for taus +#include "SIMULATION/TOOLS/defs.h" // for taus #include "PHY/sse_intrin.h" -#include "assertions.h" +#include "assertions.h" #include "T.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -152,7 +152,7 @@ uint16_t extract_crc(uint8_t *dci,uint8_t dci_len) // dci[(dci_len>>3)+1] = 0; // dci[(dci_len>>3)+2] = 0; return((uint16_t)crc16); - + } @@ -177,7 +177,7 @@ void dci_encoding(uint8_t *a, // encode dci #ifdef DEBUG_DCI_ENCODING - printf("Doing DCI encoding for %d bits, e %p, rnti %x\n",A,e,rnti); + printf("Doing DCI encoding for %d bits, e %p, rnti %x, E %d\n",A,e,rnti,E); #endif memset((void *)d,LTE_NULL,96); @@ -215,10 +215,10 @@ uint8_t *generate_dci0(uint8_t *dci, uint16_t coded_bits; uint8_t dci_flip[8]; - AssertFatal((aggregation_level==1) || - (aggregation_level==2) || - (aggregation_level==4) || - (aggregation_level==8) + AssertFatal((aggregation_level==1) || + (aggregation_level==2) || + (aggregation_level==4) || + (aggregation_level==8) #ifdef Rel14 // Added for EPDCCH/MPDCCH || (aggregation_level==16) || @@ -227,22 +227,27 @@ uint8_t *generate_dci0(uint8_t *dci, #endif , "generate_dci FATAL, illegal aggregation_level %d\n",aggregation_level); - + coded_bits = 72 * aggregation_level; - /* + #ifdef DEBUG_DCI_ENCODING - for (i=0;i<1+((DCI_LENGTH+16)/8);i++) + for (int i=0;i<1+((DCI_LENGTH+16)/8);i++) printf("i %d : %x\n",i,dci[i]); #endif - */ + if (DCI_LENGTH<=32) { dci_flip[0] = dci[3]; dci_flip[1] = dci[2]; dci_flip[2] = dci[1]; dci_flip[3] = dci[0]; +#ifdef DEBUG_DCI_ENCODING + printf("DCI => %x,%x,%x,%x\n", + dci_flip[0],dci_flip[1],dci_flip[2],dci_flip[3]); + +#endif } else { dci_flip[0] = dci[7]; dci_flip[1] = dci[6]; @@ -472,7 +477,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t wptr[1] = wptr2[1]; wptr[2] = wptr2[2]; wptr[3] = wptr2[3]; - /* + /* printf("pdcch_deinterleaving (%p,%p): quad %d (%d) -> (%d,%d %d,%d %d,%d %d,%d)\n",wptr,wptr2,i,(i+frame_parms->Nid_cell)%Mquad, ((char*)wptr2)[0], ((char*)wptr2)[1], @@ -511,7 +516,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t zptr[2] = wptr[2]; zptr[3] = wptr[3]; - /* + /* printf("deinterleaving ; k %d, index-Nd %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",k,(index-ND), ((int8_t *)wptr)[0], ((int8_t *)wptr)[1], @@ -532,7 +537,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t for (i=0; i<Mquad; i++) { zptr = &z[i<<2]; - /* + /* printf("deinterleaving ; quad %d => (%d,%d,%d,%d,%d,%d,%d,%d)\n",i, ((int8_t *)zptr)[0], ((int8_t *)zptr)[1], @@ -542,7 +547,7 @@ void pdcch_deinterleaving(LTE_DL_FRAME_PARMS *frame_parms,uint16_t *z, uint16_t ((int8_t *)zptr)[5], ((int8_t *)zptr)[6], ((int8_t *)zptr)[7]); - */ + */ } } @@ -1505,7 +1510,7 @@ void pdcch_channel_compensation(int32_t **rxdataF_ext, dl_ch128_2 = (__m128i *)&dl_ch_estimates_ext[2+aarx][symbol*frame_parms->N_RB_DL*12]; #elif defined(__arm__) - + #endif for (rb=0; rb<frame_parms->N_RB_DL; rb++) { #if defined(__x86_64__) || defined(__i386__) @@ -1869,12 +1874,6 @@ int32_t rx_pdcch(PHY_VARS_UE *ue, #endif //MU_RECEIVER -#if T_TRACER - T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), - T_INT(n_pdcch_symbols), - T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); -#endif - // decode pcfich here and find out pdcch ofdm symbol number n_pdcch_symbols = rx_pcfich(frame_parms, subframe, @@ -1885,6 +1884,12 @@ int32_t rx_pdcch(PHY_VARS_UE *ue, if (n_pdcch_symbols>3) n_pdcch_symbols=1; +#if T_TRACER + T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL), + T_INT(n_pdcch_symbols), + T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4)); +#endif + #ifdef DEBUG_DCI_DECODING @@ -2106,7 +2111,7 @@ void pdcch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, reset = 0; } - + // printf("unscrambling %d : e %d, c %d => ",i,llr[i],((s>>(i&0x1f))&1)); if (((s>>(i%32))&1)==0) llr[i] = -llr[i]; @@ -2271,7 +2276,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, /* clear all bits, the above code may generate too much false detections * (not sure about this, to be checked somehow) */ - // memset(e, 0, DCI_BITS_MAX); + // memset(e, 0, DCI_BITS_MAX); e_ptr = e; @@ -2285,11 +2290,11 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, if (dci_alloc[i].L == (uint8_t)L) { #ifdef DEBUG_DCI_ENCODING - if (dci_alloc[i].rnti==0x02) - LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, + if (dci_alloc[i].rnti==0x1234) + LOG_D(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L, *(unsigned int*)dci_alloc[i].dci_pdu, dci_alloc[i].rnti); - //dump_dci(frame_parms,&dci_alloc[i]); + dump_dci(frame_parms,&dci_alloc[i]); #endif if (dci_alloc[i].firstCCE>=0) { @@ -2340,7 +2345,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols, for (i=0; i<Msymb2; i++) { - + //((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; //((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; ((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK; @@ -2654,15 +2659,15 @@ uint16_t get_nCCE_mac(uint8_t Mod_id,uint8_t CC_id,int num_pdcch_symbols,int sub // check for eNB only ! return(get_nCCE(num_pdcch_symbols, &RC.eNB[Mod_id][CC_id]->frame_parms, - get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe))); + get_mi(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe))); } int get_nCCE_offset_l1(int *CCE_table, - const unsigned char L, - const int nCCE, - const int common_dci, - const unsigned short rnti, + const unsigned char L, + const int nCCE, + const int common_dci, + const unsigned short rnti, const unsigned char subframe) { @@ -2692,7 +2697,7 @@ int get_nCCE_offset_l1(int *CCE_table, break; } } - + if (search_space_free == 1) { // printf("returning %d\n",m*L); @@ -2894,17 +2899,17 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, LOG_D(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n", pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask); else - LOG_D(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", - pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); + LOG_D(PHY,"[DCI search nPdcch %d - ue spec %x] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n", + pdcch_vars[eNB_id]->num_pdcch_symbols,pdcch_vars[eNB_id]->crnti,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c); dci_decoding(sizeof_bits, L, &pdcch_vars[eNB_id]->e_rx[CCEind*72], &dci_decoded_output[current_thread_id][0]); - /* + /* for (i=0;i<3+(sizeof_bits>>3);i++) - printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]); - */ + printf("dci_decoded_output[%d][%d] => %x\n",current_thread_id,i,dci_decoded_output[current_thread_id][i]); + */ crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits); #ifdef DEBUG_DCI_DECODING @@ -3015,7 +3020,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars, return; } // rnti match } // CCEmap_cand == 0 -/* +/* if ( agregationLevel != 0xFF && (format_c == format0 && m==0 && si_rnti != SI_RNTI)) { @@ -3823,7 +3828,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, } else if (tmode == 3) { - LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); + // LOG_D(PHY," Now check UE_SPEC format 2A_2A search aggregation 1 dci length: %d[bits] %d[bytes]\n",format2A_size_bits,format2A_size_bytes); // Now check UE_SPEC format 2A_2A search spaces at aggregation 1 old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, @@ -3895,7 +3900,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue, return(dci_cnt); // Now check UE_SPEC format 2_2A search spaces at aggregation 4 - LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n"); + // LOG_D(PHY," Now check UE_SPEC format 2_2A search spaces at aggregation 4 \n"); old_dci_cnt=dci_cnt; dci_decoding_procedure0(pdcch_vars,0,mode, subframe, diff --git a/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..60720e13b706c7112aa40e6a29bb0200200be355 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h @@ -0,0 +1,292 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/LTE_TRANSPORT/dci.h +* \brief typedefs for LTE DCI structures from 36-212, V8.6 2009-03. Limited to 5 MHz formats for the moment.Current LTE compliance V8.6 2009-03. +* \author R. Knopp +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr +* \note +* \warning +*/ +#ifndef __DCI_NB_IOT_H__ +#define __DCI_NB_IOT_H__ + +//#ifndef USER_MODE +//#include "PHY/types.h" +//#else +#include <stdint.h> +//#endif + +typedef enum +{ + DCIFormatN0 = 0, + DCIFormatN1, + DCIFormatN1_RA,//is for initial RA procedure (semi-static information) so maybe is not needed + DCIFormatN1_RAR, + DCIFormatN2, + DCIFormatN2_Ind, + DCIFormatN2_Pag, +}DCI_format_NB_IoT_t; + +/// DCI Format Type 0 (180 kHz, 23 bits) +struct DCIFormatN0{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type; + /// Subcarrier indication, 6 bits + uint8_t scind; + /// Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign; + /// Modulation and Coding Scheme, 4 bits + uint8_t mcs; + /// New Data Indicator, 1 bits + uint8_t ndi; + /// Scheduling Delay, 2 bits + uint8_t Scheddly; + /// Repetition Number, 3 bits + uint8_t RepNum; + /// Redundancy version for HARQ (only use 0 and 2), 1 bits + uint8_t rv; + /// DCI subframe repetition Number, 2 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN0 DCIFormatN0_t; + +/// DCI Format Type N1 for User data +struct DCIFormatN1{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits + uint8_t type; + //NPDCCH order indicator (set to 0), 1 bits + uint8_t orderIndicator; + // Scheduling Delay,3 bits + uint8_t Scheddly; + // Resourse Assignment (RU Assignment),3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme,4 bits + uint8_t mcs; + // Repetition Number,4 bits + uint8_t RepNum; + // New Data Indicator,1 bits + uint8_t ndi; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes; + // DCI subframe repetition Number,2 bits + uint8_t DCIRep; +}; + + +typedef struct DCIFormatN1 DCIFormatN1_t; + +/// DCI Format Type N1 for initial RA +struct DCIFormatN1_RA{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator; + // Start number of NPRACH repetiiton, 2 bits + uint8_t Scheddly; + // Subcarrier indication of NPRACH, 6 bits + uint8_t scind; + // All the remainging bits, 13 bits + uint8_t remaingingBits; +}; + +typedef struct DCIFormatN1_RA DCIFormatN1_RA_t; + +/// DCI Format Type N1 for User data +struct DCIFormatN1_RAR{ + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1,1bits + uint8_t type; + //NPDCCH order indicator (set to 0), 1 bits + uint8_t orderIndicator; + // Scheduling Delay,3 bits + uint8_t Scheddly; + // Resourse Assignment (RU Assignment),3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme,4 bits + uint8_t mcs; + // Repetition Number,4 bits + uint8_t RepNum; + // New Data Indicator,1 bits,reserved in the RAR + uint8_t ndi; + // HARQ-ACK resource,4 bits,reserved in the RAR + uint8_t HARQackRes; + // DCI subframe repetition Number,2 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN1_RAR DCIFormatN1_RAR_t; + +// DCI Format Type N2 for direct indication, 15 bits +struct DCIFormatN2_Ind{ + //Flag for paging(1)/direct indication(0), set to 0,1 bits + uint8_t type; + //Direct indication information, 8 bits + uint8_t directIndInf; + // Reserved information bits, 6 bits + uint8_t resInfoBits; +}; + +typedef struct DCIFormatN2_Ind DCIFormatN2_Ind_t; + +// DCI Format Type N2 for Paging, 15 bits +struct DCIFormatN2_Pag{ + //Flag for paging(1)/direct indication(0), set to 1,1 bits + uint8_t type; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs; + // Repetition Number, 4 bits + uint8_t RepNum; + // Reserved 3 bits + uint8_t DCIRep; +}; + +typedef struct DCIFormatN2_Pag DCIFormatN2_Pag_t; + +typedef union DCI_CONTENT { + // + DCIFormatN0_t DCIN0; + // + DCIFormatN1_t DCIN1; + // + DCIFormatN1_RA_t DCIN1_RA; + // + DCIFormatN1_RAR_t DCIN1_RAR; + // + DCIFormatN2_Ind_t DCIN2_Ind; + // + DCIFormatN2_Pag_t DCIN2_Pag; + + }DCI_CONTENT; + + /*Structure for packing*/ + + struct DCIN0{ + /// DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + /// New Data Indicator, 1 bits + uint8_t ndi:1; + /// Repetition Number, 3 bits + uint8_t RepNum:3; + /// Redundancy version for HARQ (only use 0 and 2), 1 bits + uint8_t rv:1; + /// Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + /// Scheduling Delay, 2 bits + uint8_t Scheddly:2; + /// Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + /// Subcarrier indication, 6 bits + uint8_t scind:6; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN0 DCIN0_t; +#define sizeof_DCIN0_t 23 + +struct DCIN1_RAR{ + // DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes:4; + // New Data Indicator,1 bits + uint8_t ndi:1; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + // Scheduling Delay, 3 bits + uint8_t Scheddly:3; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator:1; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN1_RAR DCIN1_RAR_t; +#define sizeof_DCIN1_RAR_t 23 + +struct DCIN1{ + // DCI subframe repetition Number, 2 bits + uint8_t DCIRep:2; + // HARQ-ACK resource,4 bits + uint8_t HARQackRes:4; + // New Data Indicator,1 bits + uint8_t ndi:1; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + // Scheduling Delay, 3 bits + uint8_t Scheddly:3; + //NPDCCH order indicator (set to 0),1 bits + uint8_t orderIndicator:1; + /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits + uint8_t type:1; + } __attribute__ ((__packed__)); + + typedef struct DCIN1 DCIN1_t; +#define sizeof_DCIN1_t 23 + +// DCI Format Type N2 for direct indication, 15 bits +struct DCIN2_Ind{ + // Reserved information bits, 6 bits + uint8_t resInfoBits:6; + //Direct indication information, 8 bits + uint8_t directIndInf:8; + //Flag for paging(1)/direct indication(0), set to 0,1 bits + uint8_t type:1; +} __attribute__ ((__packed__));; + +typedef struct DCIN2_Ind DCIN2_Ind_t; +#define sizeof_DCIN2_Ind_t 15 + +// DCI Format Type N2 for Paging, 15 bits +struct DCIN2_Pag{ + // Reserved 3 bits + uint8_t DCIRep:3; + // Repetition Number, 4 bits + uint8_t RepNum:4; + // Modulation and Coding Scheme, 4 bits + uint8_t mcs:4; + // Resourse Assignment (RU Assignment), 3 bits + uint8_t ResAssign:3; + //Flag for paging(1)/direct indication(0), set to 1,1 bits + uint8_t type:1; +} __attribute__ ((__packed__));; + +typedef struct DCIN2_Pag DCIN2_Pag_t; + +#define sizeof_DCIN2_Pag_t 15 + +#define MAX_DCI_SIZE_BITS_NB_IoT 23 + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 086f77e14cbda7dd83ba74923c46d323f2d60ed0..4b73de6fcc72864fa1a55d7924819dab46cd5e14 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -2660,11 +2660,12 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7) ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; - LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d\n", + LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, Subframe %d Programming PUSCH with n_DMRS2 %d (cshift %d) ulsch:ndi:%d ulsch_pdu:ndi:%d new_ulsch:%d status:%d ulsch_pdu:rvidx:%d\n", eNB->Mod_id,harq_pid,frame,subframe, ulsch->harq_processes[harq_pid]->n_DMRS2, ulsch->harq_processes[harq_pid]->n_DMRS, - ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status); + ulsch->harq_processes[harq_pid]->ndi, ulsch_pdu->ulsch_pdu_rel8.new_data_indication, new_ulsch, ulsch->harq_processes[harq_pid]->status, + ulsch_pdu->ulsch_pdu_rel8.redundancy_version); ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version; ulsch->harq_processes[harq_pid]->Qm = ulsch_pdu->ulsch_pdu_rel8.modulation_type; @@ -4680,13 +4681,13 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, if(harq_pid>=8) { - LOG_I(PHY,"bad harq id \n"); + // LOG_I(PHY,"bad harq id \n"); return(0); } if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) ) { - LOG_I(PHY,"bad dci format \n"); + // LOG_I(PHY,"bad dci format \n"); return(0); } @@ -4695,13 +4696,13 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, { if(pdlsch0_harq->round == 0) { - LOG_I(PHY,"bad dci mcs + round \n"); + // LOG_I(PHY,"bad dci mcs + round \n"); return(0); } if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { - LOG_I(PHY,"bad dci mcs + rnti \n"); + // LOG_I(PHY,"bad dci mcs + rnti \n"); return(0); } } @@ -4767,7 +4768,7 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, if(rballoc > RIV_max) { - LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); + // LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); // DCI false detection return(0); } @@ -4775,7 +4776,7 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, if(NPRB == 0) { // DCI false detection - LOG_I(PHY,"bad NPRB = 0 \n"); + // LOG_I(PHY,"bad NPRB = 0 \n"); return(0); } @@ -4894,13 +4895,13 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, // I- check dci content minimum coherency if(harq_pid>=8) { - LOG_I(PHY,"bad harq pid\n"); + // LOG_I(PHY,"bad harq pid\n"); return(0); } if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) ) { - LOG_I(PHY,"bad rnti\n"); + // LOG_I(PHY,"bad rnti\n"); return(0); } @@ -4909,7 +4910,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, { if(pdlsch0_harq->round == 0) { - LOG_I(PHY,"bad mcs1\n"); + // LOG_I(PHY,"bad mcs1\n"); return(0); } } @@ -4918,7 +4919,7 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, { if(pdlsch1_harq->round == 0) { - LOG_I(PHY,"bad mcs2\n"); + // LOG_I(PHY,"bad mcs2\n"); return(0); } } @@ -4927,14 +4928,14 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0)) { // DCI false detection - LOG_I(PHY,"bad rv1\n"); + // LOG_I(PHY,"bad rv1\n"); return(0); } if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0)) { // DCI false detection - LOG_I(PHY,"bad rv2\n"); + // LOG_I(PHY,"bad rv2\n"); return(0); } @@ -4995,14 +4996,14 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format, if( (rballoc > RIV_max) && (rah == 1) ) { // DCI false detection - LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); + // LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); return(0); } if(NPRB == 0) { // DCI false detection - LOG_I(PHY,"bad NPRB\n"); + // LOG_I(PHY,"bad NPRB\n"); return(0); } @@ -5026,7 +5027,7 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0; - //LOG_I(PHY,"compute_llr_offset: nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm); + LOG_I(PHY,"compute_llr_offset: nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm); //dlsch0_harq->rb_alloc_even; //dlsch0_harq->rb_alloc_odd; @@ -5056,15 +5057,15 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, if(symbol < (frame_parms->symbols_per_tti-1)) pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset; - // LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb); - // LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re); - // LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re); - // LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re); + LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb); + LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re); + LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re); + LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re); - //LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol, - // pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]); + LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol, + pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]); } } void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, @@ -5179,7 +5180,7 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, //packet was actually decoded in previous transmission (ACK was missed by eNB) //However, the round is not a good check as it might have been decoded in a retransmission prior to this one. { - LOG_D(PHY,"skip pdsch decoding and report ack\n"); + // LOG_D(PHY,"skip pdsch decoding and report ack\n"); // skip pdsch decoding and report ack //pdlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; @@ -5804,7 +5805,7 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n", // subframe,harq_pid,dlsch0_harq->round); if ( dlsch0_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); + // LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); dlsch0_harq->first_tx = 0; } } @@ -5852,7 +5853,7 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n", // subframe,harq_pid,dlsch0_harq->round); if (dlsch1_harq->first_tx==1) { - LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); + // LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); dlsch1_harq->first_tx = 0; } } diff --git a/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..3574ba67405c271fefe0a43d01936fb49010efd6 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h @@ -0,0 +1,787 @@ +/******************************************************************************* + + *******************************************************************************/ +/*! \file PHY/LTE_TRANSPORT/defs_NB_IoT.h +* \brief data structures for NPDSCH/NDLSCH/NPUSCH/NULSCH physical and transport channel descriptors (TX/RX) of NB-IoT +* \author M. KANJ +* \date 2017 +* \version 0.0 +* \company bcom +* \email: matthieu.kanj@b-com.com +* \note +* \warning +*/ +#ifndef __LTE_TRANSPORT_DEFS_NB_IOT__H__ +#define __LTE_TRANSPORT_DEFS_NB_IOT__H__ +////#include "PHY/defs.h" +//#include "PHY/defs_nb_iot.h" +#include "PHY/LTE_TRANSPORT/dci_NB_IoT.h" +#include "PHY/impl_defs_lte_NB_IoT.h" +#include "openair2/COMMON/platform_types.h" +//#include "dci.h" +#include "PHY/LTE_TRANSPORT/uci_NB_IoT.h" +//#include "dci.h" +//#include "uci.h" +//#ifndef STANDALONE_COMPILE +//#include "UTIL/LISTS/list.h" +//#endif + +//#include "dci_nb_iot.h" + +//#define MOD_TABLE_QPSK_OFFSET 1 +//#define MOD_TABLE_16QAM_OFFSET 5 +//#define MOD_TABLE_64QAM_OFFSET 21 +//#define MOD_TABLE_PSS_OFFSET 85 +// +//// structures below implement 36-211 and 36-212 +// +//#define NSOFT 1827072 +#define LTE_NULL_NB_IoT 2 +// +//// maximum of 3 segments before each coding block if data length exceeds 6144 bits. +// +#define MAX_NUM_DLSCH_SEGMENTS_NB_IoT 16 +//#define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS +//#define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768) +//#define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768) +// +//#define MAX_NUM_CHANNEL_BITS_NB_IOT (14*1200*6) // 14 symbols, 1200 REs, 12 bits/RE +//#define MAX_NUM_RE (14*1200) +// +//#if !defined(SI_RNTI) +//#define SI_RNTI (rnti_t)0xffff +//#endif +//#if !defined(M_RNTI) +//#define M_RNTI (rnti_t)0xfffd +//#endif +//#if !defined(P_RNTI) +//#define P_RNTI (rnti_t)0xfffe +//#endif +//#if !defined(CBA_RNTI) +//#define CBA_RNTI (rnti_t)0xfff4 +//#endif +//#if !defined(C_RNTI) +//#define C_RNTI (rnti_t)0x1234 +//#endif +// +//#define PMI_2A_11 0 +//#define PMI_2A_1m1 1 +//#define PMI_2A_1j 2 +//#define PMI_2A_1mj 3 +// +//// for NB-IoT +#define MAX_NUM_CHANNEL_BITS_NB_IoT 3360 //14 symbols * 12 sub-carriers * 10 SF * 2bits/RE // to check during real tests +#define MAX_DL_SIZE_BITS_NB_IoT 680 // in release 13 // in release 14 = 2048 // ??? **** not sure +////#define MAX_NUM_CHANNEL_BITS_NB_IOT 3*680 /// ??? ****not sure +// +//// to be created LTE_eNB_DLSCH_t --> is duplicated for each number of UE and then indexed in the table +// +//typedef struct { // LTE_DL_eNB_HARQ_t +// /// Status Flag indicating for this DLSCH (idle,active,disabled) +// SCH_status_t status; +// /// Transport block size +// uint32_t TBS; +// /// The payload + CRC size in bits, "B" from 36-212 +// uint32_t B; // keep this parameter +// /// Pointer to the payload +// uint8_t *b; // keep this parameter +// /// Pointers to transport block segments +// //uint8_t *c[MAX_NUM_DLSCH_SEGMENTS]; +// /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) +// // uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS]; +// /// Frame where current HARQ round was sent +// uint32_t frame; +// /// Subframe where current HARQ round was sent +// uint32_t subframe; +// /// Index of current HARQ round for this DLSCH +// uint8_t round; +// /// MCS format for this DLSCH +// uint8_t mcs; +// /// Redundancy-version of the current sub-frame +// uint8_t rvidx; +// /// MIMO mode for this DLSCH +// MIMO_mode_t mimo_mode; +// /// Current RB allocation +// uint32_t rb_alloc[4]; +// /// distributed/localized flag +// vrb_t vrb_type; +// /// Current subband PMI allocation +// uint16_t pmi_alloc; +// /// Current subband RI allocation +// uint32_t ri_alloc; +// /// Current subband CQI1 allocation +// uint32_t cqi_alloc1; +// /// Current subband CQI2 allocation +// uint32_t cqi_alloc2; +// /// Current Number of RBs +// uint16_t nb_rb; +// /// downlink power offset field +// uint8_t dl_power_off; +// /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) +// uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IOT]; +// /// data after scrambling +// uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IOT]; +// /// length of the table e +// uint16_t length_e // new parameter +// /// Tail-biting convolutional coding outputs +// uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IOT))]; // new parameter +// /// Sub-block interleaver outputs +// uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IOT+24)]; // new parameter +// /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17, TM3-4) +// uint8_t Nl; +// /// Number of layers for this PDSCH transmission (TM8-10) +// uint8_t Nlayers; +// /// First layer for this PSCH transmission +// uint8_t first_layer; +//} NB_IoT_DL_eNB_HARQ_t; + +typedef enum { + + SCH_IDLE_NB_IoT, + ACTIVE_NB_IoT, + CBA_ACTIVE_NB_IoT, + DISABLED_NB_IoT + +} SCH_status_NB_IoT_t; + + +typedef struct { + /// NB-IoT + SCH_status_NB_IoT_t status; + /// The scheduling the NPDCCH and the NPDSCH transmission TS 36.213 Table 16.4.1-1 + uint8_t scheduling_delay; + /// The number of the subframe to transmit the NPDSCH Table TS 36.213 Table 16.4.1.3-1 (Nsf) (NB. in this case is not the index Isf) + uint8_t resource_assignment; + /// is the index that determined the repeat number of NPDSCH through table TS 36.213 Table 16.4.1.3-2 / for SIB1-NB Table 16.4.1.3-3 + uint8_t repetition_number; + /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2 + uint8_t HARQ_ACK_resource; + /// Determined the repetition number value 0-3 (2 biut carried by the FAPI NPDCCH) + uint8_t dci_subframe_repetitions; + /// modulation always QPSK Qm = 2 + uint8_t modulation; + /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IoT]; + /// data after scrambling + uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IoT]; + //length of the table e + uint16_t length_e; // new parameter + /// Tail-biting convolutional coding outputs + uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IoT))]; // new parameter + /// Sub-block interleaver outputs + uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IoT+24)]; // new parameter + + /// Status Flag indicating for this DLSCH (idle,active,disabled) + //SCH_status_t status; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits, "B" from 36-212 + uint32_t B; + /// Pointer to the payload + uint8_t *b; + ///pdu of the ndlsch message + uint8_t *pdu; + /// Frame where current HARQ round was sent + uint32_t frame; + /// Subframe where current HARQ round was sent + uint32_t subframe; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// MCS format for this NDLSCH , TS 36.213 Table 16.4.1.5 + uint8_t mcs; + // we don't have code block segmentation / crc attachment / concatenation in NB-IoT R13 36.212 6.4.2 + // we don't have beamforming in NB-IoT + //this index will be used mainly for SI message buffer + uint8_t pdu_buffer_index; + +} NB_IoT_DL_eNB_HARQ_t; + + +typedef struct { // LTE_eNB_DLSCH_t + /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) + uint32_t *txdataF[8]; + /// Allocated RNTI (0 means DLSCH_t is not currently used) + uint16_t rnti; + /// Active flag for baseband transmitter processing + uint8_t active; + /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. + uint8_t subframe_tx[10]; + /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. + uint8_t nCCE[10]; + /// Current HARQ process id + uint8_t current_harq_pid; + /// Process ID's per subframe. Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids + uint8_t harq_ids[10]; + /// Window size (in outgoing transport blocks) for fine-grain rate adaptation + uint8_t ra_window_size; + /// First-round error threshold for fine-grain rate adaptation + uint8_t error_threshold; + /// Pointers to 8 HARQ processes for the DLSCH + NB_IoT_DL_eNB_HARQ_t harq_process; + /// circular list of free harq PIDs (the oldest come first) + /// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE) + int harq_pid_freelist[10]; + /// the head position of the free list (if list is free then head=tail) + int head_freelist; + /// the tail position of the free list + int tail_freelist; + /// Number of soft channel bits + uint32_t G; + /// Codebook index for this dlsch (0,1,2,3) + uint8_t codebook_index; + /// Maximum number of HARQ processes (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Mdlharq; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Kmimo; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + +} NB_IoT_eNB_DLSCH_t; + + +typedef struct { + /// HARQ process id + uint8_t harq_id; + /// ACK bits (after decoding) 0:NACK / 1:ACK / 2:DTX + uint8_t ack; + /// send status (for PUCCH) + uint8_t send_harq_status; + /// nCCE (for PUCCH) + uint8_t nCCE; + /// DAI value detected from DCI1/1a/1b/1d/2/2a/2b/2c. 0xff indicates not touched + uint8_t vDAI_DL; + /// DAI value detected from DCI0/4. 0xff indicates not touched + uint8_t vDAI_UL; +} harq_status_NB_IoT_t; + +typedef struct { + /// UL RSSI per receive antenna + int32_t UL_rssi[NB_ANTENNAS_RX]; + /// PUCCH1a/b power (digital linear) + uint32_t Po_PUCCH; + /// PUCCH1a/b power (dBm) + int32_t Po_PUCCH_dBm; + /// PUCCH1 power (digital linear), conditioned on below threshold + uint32_t Po_PUCCH1_below; + /// PUCCH1 power (digital linear), conditioned on above threshold + uint32_t Po_PUCCH1_above; + /// Indicator that Po_PUCCH has been updated by PHY + int32_t Po_PUCCH_update; + /// DL Wideband CQI index (2 TBs) + uint8_t DL_cqi[2]; + /// DL Subband CQI index (from HLC feedback) + uint8_t DL_subband_cqi[2][13]; + /// DL PMI Single Stream + uint16_t DL_pmi_single; + /// DL PMI Dual Stream + uint16_t DL_pmi_dual; + /// Current RI + uint8_t rank; + /// CRNTI of UE + uint16_t crnti; ///user id (rnti) of connected UEs + /// Initial timing offset estimate from PRACH for RAR + int32_t UE_timing_offset; + /// Timing advance estimate from PUSCH for MAC timing advance signalling + int32_t timing_advance_update; + /// Current mode of UE (NOT SYCHED, RAR, PUSCH) + UE_MODE_NB_IoT_t mode; + /// Current sector where UE is attached + uint8_t sector; + + /// dlsch l2 errors + uint32_t dlsch_l2_errors[8]; + /// dlsch trials per harq and round + uint32_t dlsch_trials[8][8]; + /// dlsch ACK/NACK per hard_pid and round + uint32_t dlsch_ACK[8][8]; + uint32_t dlsch_NAK[8][8]; + + /// ulsch l2 errors per harq_pid + uint32_t ulsch_errors[8]; + /// ulsch l2 consecutive errors per harq_pid + uint32_t ulsch_consecutive_errors; //[8]; + /// ulsch trials/errors/fer per harq and round + uint32_t nulsch_decoding_attempts[8][8]; + uint32_t ulsch_round_errors[8][8]; + uint32_t ulsch_decoding_attempts_last[8][8]; + uint32_t ulsch_round_errors_last[8][8]; + uint32_t ulsch_round_fer[8][8]; + uint32_t sr_received; + uint32_t sr_total; + + /// dlsch sliding count and total errors in round 0 are used to compute the dlsch_mcs_offset + uint32_t dlsch_sliding_cnt; + uint32_t dlsch_NAK_round0; + int8_t dlsch_mcs_offset; + + /// Target mcs1 after rate-adaptation (used by MAC layer scheduler) + uint8_t dlsch_mcs1; + /// Target mcs2 after rate-adaptation (used by MAC layer scheduler) + uint8_t dlsch_mcs2; + /// Total bits received from MAC on PDSCH + int total_TBS_MAC; + /// Total bits acknowledged on PDSCH + int total_TBS; + /// Total bits acknowledged on PDSCH (last interval) + int total_TBS_last; + /// Bitrate on the PDSCH [bps] + unsigned int dlsch_bitrate; + // unsigned int total_transmitted_bits; + +} NB_IoT_eNB_UE_stats; + +typedef struct { + /// Indicator of first transmission + uint8_t first_tx; + /// Last Ndi received for this process on DCI (used for C-RNTI only) + uint8_t DCINdi; + /// DLSCH status flag indicating + //SCH_status_t status; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits + uint32_t B; + /// Pointer to the payload + uint8_t *b; + /// Pointers to transport block segments + uint8_t *c[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15) + uint32_t RTC[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// Index of current HARQ round for this DLSCH + uint8_t round; + /// MCS format for this DLSCH + uint8_t mcs; + /// Qm (modulation order) for this DLSCH + uint8_t Qm; + /// Redundancy-version of the current sub-frame + uint8_t rvidx; + /// MIMO mode for this DLSCH + // MIMO_mode_t mimo_mode; + /// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t w[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)]; + /// for abstraction soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + double w_abs[MAX_NUM_DLSCH_SEGMENTS_NB_IoT][3*(6144+64)]; + /// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15) + int16_t *d[MAX_NUM_DLSCH_SEGMENTS_NB_IoT]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Number of MIMO layers (streams) (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Nl; + /// current delta_pucch + int8_t delta_PUCCH; + /// Number of soft channel bits + uint32_t G; + /// Current Number of RBs + uint16_t nb_rb; + /// Current subband PMI allocation + uint16_t pmi_alloc; + /// Current RB allocation (even slots) + uint32_t rb_alloc_even[4]; + /// Current RB allocation (odd slots) + uint32_t rb_alloc_odd[4]; + /// distributed/localized flag + //vrb_t vrb_type; + /// downlink power offset field + uint8_t dl_power_off; + /// trials per round statistics + uint32_t trials[8]; + /// error statistics per round + uint32_t errors[8]; + /// codeword this transport block is mapped to + uint8_t codeword; + +} NB_IoT_DL_UE_HARQ_t; + +typedef struct { + /// RNTI + uint16_t rnti; + /// Active flag for DLSCH demodulation + uint8_t active; + /// Transmission mode + uint8_t mode1_flag; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + /// Current HARQ process id threadRx Odd and threadRx Even + uint8_t current_harq_pid; + /// Current subband antenna selection + uint32_t antenna_alloc; + /// Current subband RI allocation + uint32_t ri_alloc; + /// Current subband CQI1 allocation + uint32_t cqi_alloc1; + /// Current subband CQI2 allocation + uint32_t cqi_alloc2; + /// saved subband PMI allocation from last PUSCH/PUCCH report + uint16_t pmi_alloc; + /// HARQ-ACKs + harq_status_NB_IoT_t harq_ack; + /// Pointers to up to 8 HARQ processes + NB_IoT_DL_UE_HARQ_t *harq_process; + /// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17 + uint8_t Mdlharq; + /// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17) + uint8_t Kmimo; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// Maximum number of Turbo iterations + uint8_t max_turbo_iterations; + /// number of iterations used in last turbo decoding + uint8_t last_iteration_cnt; + /// accumulated tx power adjustment for PUCCH + int8_t g_pucch; + +} NB_IoT_UE_DLSCH_t; + +//---------------------------------------------------------------------------------------------------------- +// NB-IoT +//---------------------------------------------------------------------------------------------------- + +//enum for distinguish the different type of ndlsch (may in the future will be not needed) +typedef enum +{ + + SIB1, + SI_Message, + RAR, + UE_Data + +}ndlsch_flag_t; + + + +typedef struct { + rnti_t rnti; + //array containing the pdus of DCI + uint8_t *a[2]; + //Array containing encoded DCI data + uint8_t *e[2]; + + //UE specific parameters + uint16_t npdcch_NumRepetitions; + + uint16_t repetition_number; + //indicate the corresponding subframe within the repetition (set to 0 when a new NPDCCH pdu is received) + uint16_t repetition_idx; + + // uint16_t npdcch_Offset_USS; + // uint16_t npdcch_StartSF_USS; + + +}NB_IoT_eNB_NPDCCH_t; + + +typedef struct{ + + //Number of repetitions (R) for common search space (RAR and PAGING) + uint16_t number_repetition_RA; + uint16_t number_repetition_PAg; + //index of the current subframe among the repetition (set to 0 when we receive the new NPDCCH) + uint16_t repetition_idx_RA; + uint16_t repetition_idx_Pag; + +}NB_IoT_eNB_COMMON_NPDCCH_t; + + +typedef struct { + + /// Length of DCI in bits + uint8_t dci_length; + /// Aggregation level only 1,2 in NB-IoT + uint8_t L; + /// Position of first CCE of the dci + int firstCCE; + /// flag to indicate that this is a RA response + boolean_t ra_flag; + /// rnti + rnti_t rnti; + /// Format + DCI_format_NB_IoT_t format; + /// DCI pdu + uint8_t dci_pdu[8]; + +} DCI_ALLOC_NB_IoT_t; + + +typedef struct { + //delete the count for the DCI numbers,NUM_DCI_MAX should set to 2 + uint32_t num_npdcch_symbols; + ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission + /// see FAPI/NFAPI specs Table 4-45 + uint8_t npdcch_start_symbol; + uint8_t Num_dci; + DCI_ALLOC_NB_IoT_t dci_alloc[2] ; + +} DCI_PDU_NB_IoT; + + + + +typedef struct { + /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding) + int32_t *txdataF[8]; + /// dl channel estimates (estimated from ul channel estimates) + int32_t **calib_dl_ch_estimates; + /// Allocated RNTI (0 means DLSCH_t is not currently used) + uint16_t rnti; + /// Active flag for baseband transmitter processing + uint8_t active; + /// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK. + uint8_t subframe_tx[10]; + /// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK. + uint8_t nCCE[10]; + /*in NB-IoT there is only 1 HARQ process for each UE therefore no pid is required*/ + /// The only HARQ process for the DLSCH + NB_IoT_DL_eNB_HARQ_t *harq_process; + /// Number of soft channel bits + uint32_t G; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Nsoft parameter related to UE Category + uint32_t Nsoft; + /// amplitude of PDSCH (compared to RS) in symbols without pilots + int16_t sqrt_rho_a; + /// amplitude of PDSCH (compared to RS) in symbols containing pilots + int16_t sqrt_rho_b; + ///NB-IoT + /// may use in the npdsch_procedures + uint16_t scrambling_sequence_intialization; + /// number of cell specific TX antenna ports assumed by the UE + uint8_t nrs_antenna_ports; + + //This indicate the current subframe within the subframe interval between the NPDSCH transmission (Nsf*Nrep) + uint16_t sf_index; + ///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDSCH transmission + /// see FAPI/NFAPI specs Table 4-47 + uint8_t npdsch_start_symbol; + /*SIB1-NB related parameters*/ + ///flag for indicate if the current frame is the start of a new SIB1-NB repetition within the SIB1-NB period (0 = FALSE, 1 = TRUE) + uint8_t sib1_rep_start; + ///the number of the frame within the 16 continuous frame in which sib1-NB is transmitted (1-8 = 1st, 2nd ecc..) (0 = not foresees a transmission) + uint8_t relative_sib1_frame; + //Flag used to discern among different NDLSCH structures (SIB1,SI,RA,UE-spec) + //(used inside the ndlsch procedure for distinguish the different type of data to manage also in term of repetitions and transmission over more subframes + ndlsch_flag_t ndlsch_type; + +} NB_IoT_eNB_NDLSCH_t; + +typedef struct { + /// Length of CQI data under RI=1 assumption(bits) + uint8_t Or1; + /// Rank information + uint8_t o_RI[2]; + /// Format of CQI data + UCI_format_NB_IoT_t uci_format; + /// The value of DAI in DCI format 0 + uint8_t V_UL_DAI; + /// Pointer to CQI data + uint8_t o[MAX_CQI_BYTES_NB_IoT]; + /// CQI CRC status + uint8_t cqi_crc_status; + /// PHICH active flag + uint8_t phich_active; + /// PHICH ACK + uint8_t phich_ACK; + /// Length of rank information (bits) + uint8_t O_RI; + /// First Allocated RB + uint16_t first_rb; + /// Current Number of RBs + uint16_t nb_rb; + /// Determined the subcarrier allocation for the NPUSCH.(15, 3.75 KHz) + uint8_t subcarrier_indication; + /// Determined the number of resource unit for the NPUSCH + uint8_t resource_assignment; + /// Determined the scheduling delay for NPUSCH + uint8_t scheduling_delay; + /// The number of the repetition number for NPUSCH Transport block + uint8_t repetition_number; + /// Determined the repetition number value 0-3 + uint8_t dci_subframe_repetitions; + /// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK) + uint8_t dci_alloc; + /// Flag indicating that this ULSCH has been allocated by a RAR (otherwise it is a retransmission based on PHICH NAK or DCI) + uint8_t rar_alloc; + /// Status Flag indicating for this ULSCH (idle,active,disabled) + SCH_status_NB_IoT_t status; + /// Subframe scheduling indicator (i.e. Transmission opportunity indicator) + uint8_t subframe_scheduling_flag; + /// Transport block size + uint32_t TBS; + /// The payload + CRC size in bits + uint32_t B; + /// Number of soft channel bits + uint32_t G; + /// Pointer to ACK + uint8_t o_ACK[4]; + /// Length of ACK information (bits) + uint8_t O_ACK; + /// coded ACK bits + int16_t q_ACK[MAX_ACK_PAYLOAD_NB_IoT]; + /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) + /// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18) + int16_t e[MAX_NUM_CHANNEL_BITS_NB_IoT] __attribute__((aligned(32))); + /// coded RI bits + int16_t q_RI[MAX_RI_PAYLOAD_NB_IoT]; + /// "q" sequences for CQI/PMI (for definition see 36-212 V8.6 2009-03, p.27) + int8_t q[MAX_CQI_PAYLOAD_NB_IoT]; + /// number of coded CQI bits after interleaving + uint8_t o_RCC; + /// coded and interleaved CQI bits + int8_t o_w[(MAX_CQI_BITS_NB_IoT+8)*3]; + /// coded CQI bits + int8_t o_d[96+((MAX_CQI_BITS_NB_IoT+8)*3)]; + /// + uint32_t C; + /// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cminus; + /// Number of "large" code segments (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Cplus; + /// Number of bits in "small" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kminus; + /// Number of bits in "large" code segments (<6144) (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t Kplus; + /// Number of "Filler" bits (for definition see 36-212 V8.6 2009-03, p.10) + uint32_t F; + /// Temporary h sequence to flag PUSCH_x/PUSCH_y symbols which are not scrambled + //uint8_t h[MAX_NUM_CHANNEL_BITS]; + /// SRS active flag + uint8_t srs_active; + /// Pointer to the payload + uint8_t *b; + /// Current Number of Symbols + uint8_t Nsymb_pusch; + /// Index of current HARQ round for this ULSCH + uint8_t round; + /// MCS format for this ULSCH + uint8_t mcs; + /// Redundancy-version of the current sub-frame (value 0->RV0,value 1 ->RV2) + uint8_t rvidx; + /// Msc_initial, Initial number of subcarriers for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint16_t Msc_initial; + /// Nsymb_initial, Initial number of symbols for ULSCH (36-212, v8.6 2009-03, p.26-27) + uint8_t Nsymb_initial; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) + uint8_t n_DMRS; + /// n_DMRS for cyclic shift of DMRS (36.213 Table 9.1.2-2) - previous scheduling + /// This is needed for PHICH generation which + /// is done after a new scheduling + uint8_t previous_n_DMRS; + /// n_DMRS 2 for cyclic shift of DMRS (36.211 Table 5.5.1.1.-1) + uint8_t n_DMRS2; + /// Flag to indicate that this ULSCH is for calibration information sent from UE (i.e. no MAC SDU to pass up) + // int calibration_flag; + /// delta_TF for power control + int32_t delta_TF; + ///////////////////////////////////////////// 4 parameter added by vincent /////////////////////////////////////////////// + // NB_IoT: Nsymb_UL and Nslot_UL are defined in 36.211, Section 10.1.2.3, Table 10.1.2.3-1 + // The number of symbol in a resource unit is given by Nsymb_UL*Nslot_UL + uint8_t Nsymb_UL; + // Number of NPUSCH slots + uint8_t Nslot_UL; + // Number of subcarrier for NPUSH, can be 1, 3, 6, 12 + uint8_t N_sc_RU; + // Index of UL NB_IoT resource block + uint32_t UL_RB_ID_NB_IoT; + // Subcarrier indication fields, obtained through DCI, Section 16.5.1.1 in 36.213 + uint16_t I_sc; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +} NB_IoT_UL_eNB_HARQ_t; + + +typedef struct { + /// Pointers to the HARQ processes for the NULSCH + NB_IoT_UL_eNB_HARQ_t *harq_process; + /// Maximum number of HARQ rounds + uint8_t Mlimit; + /// Value 0 = npush format 1 (data) value 1 = npusch format 2 (ACK/NAK) + uint8_t npusch_format; + /// Flag to indicate that eNB awaits UE Msg3 + uint8_t Msg3_active; + /// Flag to indicate that eNB should decode UE Msg3 + uint8_t Msg3_flag; + /// Subframe for Msg3 + uint8_t Msg3_subframe; + /// Frame for Msg3 + uint32_t Msg3_frame; + /// RNTI attributed to this ULSCH + uint16_t rnti; + /// cyclic shift for DM RS + uint8_t cyclicShift; + /// cooperation flag + uint8_t cooperation_flag; + /// (only in-band mode), indicate the resource block overlap the SRS configuration of LTE + uint8_t N_srs; + /// + uint8_t scrambling_re_intialization_batch_index; + /// number of cell specific TX antenna ports assumed by the UE + uint8_t nrs_antenna_ports; + /// + uint16_t scrambling_sequence_intialization; + /// + uint16_t sf_index; + /// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2 + uint8_t HARQ_ACK_resource; + + ///////////// kept from LTE /////////////////////////////////////////////////// + + /// Maximum number of iterations used in eNB turbo decoder + uint8_t max_turbo_iterations; + /// ACK/NAK Bundling flag + uint8_t bundling; + /// beta_offset_cqi times 8 + uint16_t beta_offset_cqi_times8; + /// beta_offset_ri times 8 + uint16_t beta_offset_ri_times8; + /// beta_offset_harqack times 8 + uint16_t beta_offset_harqack_times8; + /// num active cba group + uint8_t num_active_cba_groups; + /// allocated CBA RNTI for this ulsch + uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; + #ifdef LOCALIZATION + /// epoch timestamp in millisecond + int32_t reference_timestamp_ms; + /// aggregate physical states every n millisecond + int32_t aggregation_period_ms; + /// a set of lists used for localization + struct list loc_rss_list[10], loc_rssi_list[10], loc_subcarrier_rss_list[10], loc_timing_advance_list[10], loc_timing_update_list[10]; + struct list tot_loc_rss_list, tot_loc_rssi_list, tot_loc_subcarrier_rss_list, tot_loc_timing_advance_list, tot_loc_timing_update_list; + #endif + +} NB_IoT_eNB_NULSCH_t; + +#define NPBCH_A 34 + +typedef struct { + //the 2 LSB of the hsfn (the MSB are indicated by the SIB1-NB) + uint16_t h_sfn_lsb; + + uint8_t npbch_d[96+(3*(16+NPBCH_A))]; + uint8_t npbch_w[3*3*(16+NPBCH_A)]; + uint8_t npbch_e[1600]; + ///pdu of the npbch message + uint8_t *pdu; + +} NB_IoT_eNB_NPBCH_t; + + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index f1cb58ba26bdd83c27ef1f61bd9484f534ec199b..e91665e04eb19e23b7544ba94c1aefb2ab3806fc 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -286,13 +286,13 @@ int dlsch_encoding_2threads0(te_params *tep) { - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); dlsch->harq_processes[harq_pid]->RTC[r] = sub_block_interleaving_turbo(4+(Kr_bytes*8), &dlsch->harq_processes[harq_pid]->d[r][96], @@ -458,13 +458,13 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); start_meas(i_stats); @@ -579,7 +579,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, // if (dlsch->harq_processes[harq_pid]->Ndi == 1) { // this is a new packet if (dlsch->harq_processes[harq_pid]->round == 0) { // this is a new packet #ifdef DEBUG_DLSCH_CODING - printf("encoding thinks this is a new packet \n"); + printf("encoding thinks this is a new packet for harq_pid %d (%p) \n",harq_pid,dlsch->harq_processes[harq_pid]->b); #endif /* int i; @@ -589,6 +589,7 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, printf("\n"); */ // Add 24-bit crc (polynomial A) to payload + crc = crc24a(a, A)>>8; a[A>>3] = ((uint8_t*)&crc)[2]; @@ -650,13 +651,13 @@ int dlsch_encoding(PHY_VARS_eNB *eNB, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_DLSCH_CODING @@ -832,13 +833,13 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(dlsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &dlsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) - ); + encoder(dlsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &dlsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? dlsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36121-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36121-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_DLSCH_CODING diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c index 7acf6480eb40df1d7aef3e2c4be17bdcb2dc2fa4..4020056e6f68043a591f4792c287202e49a76ab0 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c @@ -37,8 +37,8 @@ #include "SCHED/extern.h" #include "SIMULATION/TOOLS/defs.h" //#define DEBUG_DLSCH_DECODING +//#define UE_DEBUG_TRACE 1 -extern double cpuf; void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { @@ -205,21 +205,7 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, time_stats_t *); #endif - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); +decoder_if_t tc; @@ -254,13 +240,13 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, #if 0 tc_2cw = phy_threegpplte_turbo_decoder16avx2; #endif - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; } else { AssertFatal (harq_process->TBS >= 256 , "Mismatch flag nbRB=%d TBS=%d mcs=%d Qm=%d RIV=%d round=%d \n", harq_process->nb_rb, harq_process->TBS,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round); - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; } @@ -489,7 +475,9 @@ uint32_t dlsch_decoding(PHY_VARS_UE *phy_vars_ue, LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1); ret = tc (&harq_process->d[r][96], + NULL, harq_process->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c index c805d9408f20781e88d0a07c1181c3465c9e3bbb..6284f279d895d04590cf44ca3d792c1fcda40f47 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c @@ -48,13 +48,10 @@ int16_t interf_unaw_shift = 13; //#define DEBUG_HARQ -//#undef LOG_D -//#define LOG_D LOG_I - -//#define DEBUG_PHY 1 +#define DEBUG_PHY 1 //#define DEBUG_DLSCH_DEMOD 1 - +//#define DISABLE_LOG_X // [MCS][i_mod (0,1,2) = (2,4,6)] unsigned char offset_mumimo_llr_drange_fix=0; @@ -370,7 +367,7 @@ int rx_pdsch(PHY_VARS_UE *ue, //printf("nb_rb = %d, eNB_id %d\n",nb_rb,eNB_id); if (nb_rb==0) { - LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); + // LOG_D(PHY,"dlsch_demodulation.c: nb_rb=0\n"); return(-1); } @@ -845,15 +842,15 @@ int rx_pdsch(PHY_VARS_UE *ue, pllr_symbol_cw1 = (int8_t*)pdsch_vars[eNB_id]->llr[1]; pllr_symbol_cw0 += llr_offset_symbol; pllr_symbol_cw1 += llr_offset_symbol; - /* - LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", + + LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %p @LLR Buff(symb) %p\n", frame, subframe,symbol, nb_rb,dlsch0_harq->Qm, pdsch_vars[eNB_id]->llr_length[symbol], pdsch_vars[eNB_id]->llr_offset[symbol], (int16_t*)pdsch_vars[eNB_id]->llr[0], pllr_symbol_cw0); - */ + switch (dlsch0_harq->Qm) { case 2 : if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c index 46689a9aaa0473a14cda15cedea92db8896c9a65..7682045ae1307ca6a10ee83ef071091f7e28528d 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c @@ -40,7 +40,7 @@ //#define DEBUG_LLR_SIC -int16_t zero[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; +int16_t zeros[8] __attribute__ ((aligned(16))) = {0,0,0,0,0,0,0,0}; int16_t ones[8] __attribute__ ((aligned(16))) = {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; #if defined(__x86_64__) || defined(__i386__) __m128i rho_rpi __attribute__ ((aligned(16))); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c index 49b41615f4cd91d43ed5b0f59ae6f2a1a90d3fca..f3a9a05ae5be7f7efe889d6fdafd34b4ad0b4345 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c @@ -2125,6 +2125,7 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB, amp_rho_b = (int16_t)(((int32_t)amp*dlsch1->sqrt_rho_b)>>13); } + if (mod_order0 == 4) for (i=0;i<4; i++) { qam16_table_a0[i] = (int16_t)(((int32_t)qam16_table[i]*amp_rho_a)>>15); diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index d90f4c66d255158e35a820602f3140c55e8b69bc..8d650bbe217db458bcacef79a463469c66c6813a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -124,14 +124,18 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } #ifdef DEBUG_SCRAMBLING +#ifdef Rel14 printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); +#else + printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); +#endif #endif s = lte_gold_scram(&x1, &x2, 1); for (n=0; n<(1+(G>>5)); n++) { #ifdef DEBUG_SCRAMBLING - printf("scrambling %d : %d => ",k,e[k]); + for (int k=0;k<32;k++) printf("scrambling %d : %d xor %d = %d\n",k+(n<<5),e[k],(s>>k)&1,e[k]^((s>>k)&1)); #endif @@ -171,9 +175,8 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, // This is not faster for some unknown reason // ((__m128i *)e)[0] = _mm_xor_si128(((__m128i *)e)[0],((__m128i *)scrambling_lut)[s&65535]); // ((__m128i *)e)[1] = _mm_xor_si128(((__m128i *)e)[1],((__m128i *)scrambling_lut)[s>>16]); -#ifdef DEBUG_SCRAMBLING - printf("%d\n",e[k]); -#endif + + s = lte_gold_scram(&x1, &x2, 0); @@ -213,7 +216,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms, for (i=0; i<(1+(G>>5)); i++) { for (j=0; j<32; j++,k++) { #ifdef DEBUG_SCRAMBLING - printf("unscrambling %d : %d => ",k,llr[k]); + printf("unscrambling %d : %d xor %d =",k,llr[k],(s>>j)&1); #endif llr[k] = ((2*((s>>j)&1))-1)*llr[k]; #ifdef DEBUG_SCRAMBLING diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c index a432cde4e4fb20ed7721e223475f57953623f7f5..a0bde219b57706e59b5d5746f8408bc1307f46be 100644 --- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c +++ b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c @@ -94,8 +94,10 @@ int generate_drs_pusch(PHY_VARS_UE *ue, l<frame_parms->symbols_per_tti; l += (7 - frame_parms->Ncp),u=u1,v=v1,cyclic_shift=cyclic_shift1) { - drs_offset = 0; // printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d\n",Msc_RS, Msc_RS_idx); - + drs_offset = 0; +#ifdef DEBUG_DRS + printf("drs_modulation: Msc_RS = %d, Msc_RS_idx = %d, u=%d,v=%d\n",Msc_RS, Msc_RS_idx,u,v); +#endif re_offset = frame_parms->first_carrier_offset; diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index 37b1c56349f3edbc727482e8301f47bdcbbf0c61..5caf5bcd710f6da6e42ded836e5eca0ed547082e 100755 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/LTE_TRANSPORT/mdci.h b/openair1/PHY/LTE_TRANSPORT/mdci.h index 1e278f8011b7e15201ff2d622b69ef6a44864bf8..060227eac033a3f979d32b29077b5de1f0aaa577 100644 --- a/openair1/PHY/LTE_TRANSPORT/mdci.h +++ b/openair1/PHY/LTE_TRANSPORT/mdci.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/PHY/LTE_TRANSPORT/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c index 10f0c1490c81d2e97fa08887a1c0f75ec4ee2825..36b2bfbeab81abcaac6287a9219898f24160742e 100644 --- a/openair1/PHY/LTE_TRANSPORT/power_control.c +++ b/openair1/PHY/LTE_TRANSPORT/power_control.c @@ -33,20 +33,20 @@ double ratioPB[2][4]={{ 0.00000, -0.96910, -2.21849, -3.97940}, //in db double pa_values[8]={-6.0,-4.77,-3.0,-1.77,0.0,1.0,2.0,3.0}; //reported by higher layers -double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated) +double get_pa_dB(uint8_t pa) { - if (pdsch_config_dedicated) - return(pa_values[ pdsch_config_dedicated->p_a]); - else - return(0.0); + AssertFatal(pa<8,"pa %d is not in (0...7)\n",pa); + + return(pa_values[pa]); + } -double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, +double computeRhoA_eNB(uint8_t pa, LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port){ double rho_a_dB; double sqrt_rho_a_lin; - rho_a_dB = get_pa_dB(pdsch_config_dedicated); + rho_a_dB = get_pa_dB(pa); if(!dl_power_off) //if dl_power_offset is 0, this is for MU-interference, TM5 rho_a_dB-=10*log10(2); @@ -59,14 +59,14 @@ double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, dlsch_eNB->sqrt_rho_a= (short) (sqrt_rho_a_lin*pow(2,13)); #if DEBUG_PC - printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",pdsch_config_dedicated->p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a); + printf("eNB: p_a=%d, value=%f, sqrt_rho_a=%d\n",p_a,pa_values[ pdsch_config_dedicated->p_a],dlsch_eNB->sqrt_rho_a); #endif return(rho_a_dB); } -double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - PDSCH_CONFIG_COMMON *pdsch_config_common, +double computeRhoB_eNB(uint8_t pa, + uint8_t pb, uint8_t n_antenna_port, LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off) @@ -75,19 +75,21 @@ double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB, rho_b_dB; double sqrt_rho_b_lin; - rho_a_dB= computeRhoA_eNB(pdsch_config_dedicated,dlsch_eNB,dl_power_off, n_antenna_port); + AssertFatal(pa<8,"pa %d is not in (0...7)\n",pa); + AssertFatal(pb<4,"pb %d is not in (0...3)\n",pb); + rho_a_dB= computeRhoA_eNB(pa,dlsch_eNB,dl_power_off, n_antenna_port); if(n_antenna_port>1) - rho_b_dB= ratioPB[1][pdsch_config_common->p_b] + rho_a_dB; + rho_b_dB= ratioPB[1][pb] + rho_a_dB; else - rho_b_dB= ratioPB[0][pdsch_config_common->p_b] + rho_a_dB; + rho_b_dB= ratioPB[0][pb] + rho_a_dB; sqrt_rho_b_lin= pow(10,(0.05*rho_b_dB)); dlsch_eNB->sqrt_rho_b= (short) (sqrt_rho_b_lin*pow(2,13)); #ifdef DEBUG_PC - printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pdsch_config_common->p_b,ratioPB[1][pdsch_config_common->p_b],dlsch_eNB->sqrt_rho_b); + printf("eNB: n_ant=%d, p_b=%d -> rho_b/rho_a=%f -> sqrt_rho_b=%d\n",n_antenna_port,pb,ratioPB[1][pb],dlsch_eNB->sqrt_rho_b); #endif return(rho_b_dB); } @@ -102,7 +104,7 @@ double computeRhoA_UE(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, double rho_a_dB; double sqrt_rho_a_lin; - rho_a_dB = get_pa_dB(pdsch_config_dedicated); + rho_a_dB = get_pa_dB(pdsch_config_dedicated->p_a); if(!dl_power_off) rho_a_dB-=10*log10(2); diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h index 199427cbc2fdb21c54b061ebd7a7a8340ce09dad..0e1a60c0b9ac1bc5105c73ebfe5b253769eb9d94 100644 --- a/openair1/PHY/LTE_TRANSPORT/proto.h +++ b/openair1/PHY/LTE_TRANSPORT/proto.h @@ -1789,7 +1789,7 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB, uint8_t use_srs); -void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id); +void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id,int round); int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci); @@ -2227,15 +2227,15 @@ uint32_t dlsch_decoding_abstraction(double *dlsch_MIPB, uint8_t num_pdcch_symbols); // DL power control functions -double get_pa_dB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated); +double get_pa_dB(uint8_t pa); -double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - LTE_eNB_DLSCH_t *dlsch_eNB, +double computeRhoA_eNB(uint8_t pa, + LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off, uint8_t n_antenna_port); -double computeRhoB_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - PDSCH_CONFIG_COMMON *pdsch_config_common, +double computeRhoB_eNB(uint8_t pa, + uint8_t pb, uint8_t n_antenna_port, LTE_eNB_DLSCH_t *dlsch_eNB, int dl_power_off); diff --git a/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..d8b17ff26386e5f825c514faee7d8a0cbfbae331 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/proto_NB_IoT.h @@ -0,0 +1,362 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/LTE_TRANSPORT/proto.h + * \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03 + * \author R. Knopp, F. Kaltenberger + * \date 2011 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr + * \note + * \warning + */ +#ifndef __LTE_TRANSPORT_PROTO_NB_IOT__H__ +#define __LTE_TRANSPORT_PROTO_NB_IOT__H__ +#include "PHY/defs_L1_NB_IoT.h" +//#include <math.h> + +//NPSS + +int generate_npss_NB_IoT(int32_t **txdataF, + short amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + unsigned short symbol_offset, // symbol_offset should equal to 3 for NB-IoT + unsigned short slot_offset, + unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE + +//NSSS + +int generate_sss_NB_IoT(int32_t **txdataF, + int16_t amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint16_t symbol_offset, // symbol_offset = 3 for NB-IoT + uint16_t slot_offset, + unsigned short frame_number, // new attribute (Get value from higher layer), it does not exist for LTE + unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE + +//*****************Vincent part for Cell ID estimation from NSSS ******************// + +int rx_nsss_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int32_t *tot_metric); + +int nsss_extract_NB_IoT(PHY_VARS_UE_NB_IoT *ue, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **nsss_ext, + int l); + +//NRS + +void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + int32_t **txdataF, + int16_t amp, + uint16_t Ntti, // Ntti = 10 + unsigned short RB_IoT_ID, // RB reserved for NB-IoT + unsigned short With_NSSS); // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal + + +//NPBCH + +int allocate_npbch_REs_in_RB(NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **txdataF, + uint32_t *jj, + uint32_t symbol_offset, + uint8_t *x0, + uint8_t pilots, + int16_t amp, + unsigned short id_offset, + uint32_t *re_allocated); + + +int generate_npbch(NB_IoT_eNB_NPBCH_t *eNB_npbch, + int32_t **txdataF, + int amp, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t *npbch_pdu, + uint8_t frame_mod64, + unsigned short NB_IoT_RB_ID); + + +void npbch_scrambling(NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t *npbch_e, + uint32_t length); + +// Functions below implement 36-211 and 36-212 + +/*Function to pack the DCI*/ +// newly added function for NB-IoT , does not exist for LTE +void add_dci_NB_IoT(DCI_PDU_NB_IoT *DCI_pdu, + void *pdu, + rnti_t rnti, + unsigned char dci_size_bytes, + unsigned char aggregation, + unsigned char dci_size_bits, + unsigned char dci_fmt, + uint8_t npdcch_start_symbol); + + +/*Use the UL DCI Information to configure PHY and also Pack the DCI*/ +int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + DCI_CONTENT *DCI_Content, + uint16_t rnti, + DCI_format_NB_IoT_t dci_format, + uint8_t UE_id, + uint8_t aggregation, + uint8_t npdcch_start_symbol); + + +/*Use the DL DCI Information to configure PHY and also Pack the DCI*/ +int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + int frame, + uint8_t subframe, + DCI_CONTENT *DCI_Content, + uint16_t rnti, + DCI_format_NB_IoT_t dci_format, + NB_IoT_eNB_NDLSCH_t *ndlsch, + NB_IoT_DL_FRAME_PARMS *frame_parms, + uint8_t aggregation, + uint8_t npdcch_start_symbol); + + +/*Function for DCI encoding, scrambling, modulation*/ +uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t *npdcch, + uint8_t Num_dci, + DCI_ALLOC_NB_IoT_t *dci_alloc, + int16_t amp, + NB_IoT_DL_FRAME_PARMS *fp, + int32_t **txdataF, + uint32_t subframe, + uint8_t npdcch_start_symbol); + +/*! + \brief Decoding of PUSCH/ACK/RI/ACK from 36-212. + @param phy_vars_eNB Pointer to eNB top-level descriptor + @param proc Pointer to RXTX proc variables + @param UE_id ID of UE transmitting this PUSCH + @param subframe Index of subframe for PUSCH + @param control_only_flag Receive PUSCH with control information only + @param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213 + @param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used + @returns 0 on success +*/ +unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + uint8_t UE_id, + uint8_t control_only_flag, + uint8_t Nbundled, + uint8_t llr8_flag); + +//NB-IoT version +NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(//unsigned char Kmimo, + //unsigned char Mdlharq, + uint32_t Nsoft, + //unsigned char N_RB_DL, + uint8_t abstraction_flag, + NB_IoT_DL_FRAME_PARMS* frame_parms); + + +NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t abstraction_flag); + + +uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe); + + +/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213. + @param I_MCS */ + +//uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS); +unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS, uint8_t N_sc_RU); + +/** \fn dlsch_encoding(PHY_VARS_eNB *eNB, + uint8_t *input_buffer, + LTE_DL_FRAME_PARMS *frame_parms, + uint8_t num_pdcch_symbols, + LTE_eNB_DLSCH_t *dlsch, + int frame, + uint8_t subframe) + \brief This function performs a subset of the bit-coding functions for LTE as described in 36-212, Release 8.Support is limited to turbo-coded channels (DLSCH/ULSCH). The implemented functions are: + - CRC computation and addition + - Code block segmentation and sub-block CRC addition + - Channel coding (Turbo coding) + - Rate matching (sub-block interleaving, bit collection, selection and transmission + - Code block concatenation + @param eNB Pointer to eNB PHY context + @param input_buffer Pointer to input buffer for sub-frame + @param frame_parms Pointer to frame descriptor structure + @param num_pdcch_symbols Number of PDCCH symbols in this subframe + @param dlsch Pointer to dlsch to be encoded + @param frame Frame number + @param subframe Subframe number + @param rm_stats Time statistics for rate-matching + @param te_stats Time statistics for turbo-encoding + @param i_stats Time statistics for interleaving + @returns status +*/ + +int32_t dlsch_encoding_NB_IoT(unsigned char *a, + NB_IoT_eNB_DLSCH_t *dlsch, + uint8_t Nsf, // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table) + unsigned int G, // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation) + time_stats_t *rm_stats, + time_stats_t *te_stats, + time_stats_t *i_stats); + + +void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB, + eNB_rxtx_proc_NB_IoT_t *proc, + uint8_t eNB_id, // this is the effective sector id + uint8_t UE_id, + NB_IoT_eNB_NULSCH_t **ulsch, + uint8_t cooperation_flag); + + + + +void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF, + int32_t **rxdataF_ext, + // uint32_t first_rb, + //uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block + uint8_t N_sc_RU, // number of subcarriers in UL + uint32_t I_sc, // subcarrier indication field + uint32_t nb_rb, + uint8_t l, + uint8_t Ns, + NB_IoT_DL_FRAME_PARMS *frame_parms); + +void extract_CQI_NB_IoT(void *o,UCI_format_NB_IoT_t uci_format,NB_IoT_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode); + +//*****************Vincent part for nprach ******************// +void RX_NPRACH_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_buffer); + +uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + int16_t *Rx_sub_sampled_buffer, + uint16_t sub_sampling_rate, + uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES, + uint32_t estimated_TA_coarse, + char coarse); + +uint8_t NPRACH_detection_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_sub_sampled_buffer, uint16_t sub_sampling_rate, uint32_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES); + +int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate); +//************************************************************// +//*****************Vincent part for ULSCH demodulation ******************// +uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc); + +void generate_grouphop_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); + +void init_ul_hopping_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms); + +void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol, + uint8_t Qm); + +void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol); + +int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *ulsch_llr, + uint8_t symbol, + uint8_t uint8_t, + int16_t **llrp); + + +int32_t ulsch_qpsk_llr_NB_IoT( + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *ulsch_llr, + uint8_t symbol, + uint8_t nb_rb, + int16_t **llrp); + +void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + uint8_t UE_id, + uint8_t symbol); +//************************************************************// + +//************************************************************// +//*****************Vincent part for DLSCH demodulation ******************// + +int rx_npdsch_NB_IoT(PHY_VARS_UE_NB_IoT *ue, + unsigned char eNB_id, + unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference + uint32_t frame, + uint8_t subframe, + unsigned char symbol, + unsigned char first_symbol_flag, + unsigned char i_mod, + unsigned char harq_pid); + +unsigned short dlsch_extract_rbs_single_NB_IoT(int **rxdataF, + int **dl_ch_estimates, + int **rxdataF_ext, + int **dl_ch_estimates_ext, + unsigned short pmi, + unsigned char *pmi_ext, + unsigned int *rb_alloc, + unsigned char symbol, + unsigned char subframe, + uint32_t frame, + uint32_t high_speed_flag, + NB_IoT_DL_FRAME_PARMS *frame_parms); + +void dlsch_channel_level_NB_IoT(int **dl_ch_estimates_ext, + NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t *avg, + uint8_t symbol, + unsigned short nb_rb); + +void dlsch_channel_compensation_NB_IoT(int **rxdataF_ext, + int **dl_ch_estimates_ext, + int **dl_ch_mag, + int **dl_ch_magb, + int **rxdataF_comp, + int **rho, + NB_IoT_DL_FRAME_PARMS *frame_parms, + unsigned char symbol, + uint8_t first_symbol_flag, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift, + PHY_MEASUREMENTS_NB_IoT *measurements); + +int dlsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, + int32_t **rxdataF_comp, + int16_t *dlsch_llr, + uint8_t symbol, + uint8_t first_symbol_flag, + uint16_t nb_rb, + int16_t **llr32p, + uint8_t beamforming_mode); + +//************************************************************// + + +#endif diff --git a/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..6f2dd0f989cb90fc65ac8a658a6ad9ca78db7051 --- /dev/null +++ b/openair1/PHY/LTE_TRANSPORT/uci_NB_IoT.h @@ -0,0 +1,324 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __UCI_NB_IOT__H__ +#define __UCI_NB_IOT__H__ +//#include "PHY/types_NB_IoT.h" + + + +typedef enum { + ue_selected_NB_IoT, + wideband_cqi_rank1_2A_NB_IoT, //wideband_cqi_rank1_2A, + wideband_cqi_rank2_2A_NB_IoT, //wideband_cqi_rank2_2A, + HLC_subband_cqi_nopmi_NB_IoT, //HLC_subband_cqi_nopmi, + HLC_subband_cqi_rank1_2A_NB_IoT, //HLC_subband_cqi_rank1_2A, + HLC_subband_cqi_rank2_2A_NB_IoT, //HLC_subband_cqi_rank2_2A, + HLC_subband_cqi_modes123_NB_IoT, //HLC_subband_cqi_modes123 + HLC_subband_cqi_mcs_CBA_NB_IoT, // MCS and RNTI, for contention-based acces + unknown_cqi_NB_IoT// +} UCI_format_NB_IoT_t; + +// **********************************************1.5 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t pmi:12; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_1_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint16_t padding:2; + uint16_t pmi:6; + uint16_t cqi2:4; + uint16_t cqi1:4; +} +wideband_cqi_rank2_2A_1_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_1_5MHz_NB_IoT 14 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t pmi:2; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_1_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:31; + uint64_t pmi:1; + uint64_t diffcqi2:12; + uint64_t cqi2:4; + uint64_t diffcqi1:12; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_1_5MHz_NB_IoT 33 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:16; + uint32_t diffcqi1:12; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_1_5MHz_NB_IoT 16 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz_NB_IoT 21 + + +// **********************************************5 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t pmi:14; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint16_t padding:1; + uint16_t pmi:7; + uint16_t cqi2:4; + uint16_t cqi1:4; +} +wideband_cqi_rank2_2A_5MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_5MHz_NB_IoT 15 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:12; + uint32_t pmi:2; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_5MHz_NB_IoT 20 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:27; + uint64_t pmi:1; + uint64_t diffcqi2:14; + uint64_t cqi2:4; + uint64_t diffcqi1:14; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_5MHz_NB_IoT 37 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:14; + uint32_t diffcqi1:14; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_5MHz_NB_IoT 18 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_5MHz_NB_IoT 21 + +// **********************************************10 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t pmi:18; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_10MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:15; + uint32_t pmi:9; + uint32_t cqi2:4; + uint32_t cqi1:4; +} +wideband_cqi_rank2_2A_10MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_10MHz_NB_IoT 17 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:8; + uint32_t pmi:2; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_10MHz_NB_IoT 24 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:19; + uint64_t pmi:1; + uint64_t diffcqi2:18; + uint64_t cqi2:4; + uint64_t diffcqi1:18; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_10MHz_NB_IoT 45 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:10; + uint32_t diffcqi1:18; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_10MHz_NB_IoT 22 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_mcs_CBA_10MHz_NB_IoT 21 + +// **********************************************20 MHz*************************************************************************** +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t pmi:26; + uint32_t cqi1:4; +} +wideband_cqi_rank1_2A_20MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank1_2A_20MHz_NB_IoT 20 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t pmi:13; + uint32_t cqi2:4; + uint32_t cqi1:4; +} +wideband_cqi_rank2_2A_20MHz_NB_IoT ; +#define sizeof_wideband_cqi_rank2_2A_20MHz_NB_IoT 21 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_nopmi_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_nopmi_20MHz_NB_IoT 30 + +typedef struct __attribute__((packed)) +{ + // uint32_t padding:12; + uint32_t pmi:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_rank1_2A_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank1_2A_20MHz_NB_IoT 32 + +typedef struct __attribute__((packed)) +{ + uint64_t padding:3; + uint64_t pmi:1; + uint64_t diffcqi2:26; + uint64_t cqi2:4; + uint64_t diffcqi1:26; + uint64_t cqi1:4; +} +HLC_subband_cqi_rank2_2A_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_rank2_2A_20MHz_NB_IoT 61 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:2; + uint32_t diffcqi1:26; + uint32_t cqi1:4; +} +HLC_subband_cqi_modes123_20MHz_NB_IoT; +#define sizeof_HLC_subband_cqi_modes123_20MHz_NB_IoT 30 + +typedef struct __attribute__((packed)) +{ + uint32_t padding:11; + uint32_t crnti:16; + uint32_t mcs:5; +} +HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT; + +#define sizeof_HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT 21 + +#define MAX_CQI_PAYLOAD_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8*20) +#define MAX_CQI_BITS_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)*8) +#define MAX_CQI_BYTES_NB_IoT (sizeof(HLC_subband_cqi_rank2_2A_20MHz_NB_IoT)) +#define MAX_ACK_PAYLOAD_NB_IoT 18 +#define MAX_RI_PAYLOAD_NB_IoT 6 + +#endif \ No newline at end of file diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c index 9b761f3cc3b4065ba462aa52f18299b62443fa94..09420f48ab1a7029fdbbb2015fd7f28f47ffcd8c 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c @@ -371,13 +371,13 @@ uint32_t ulsch_encoding(uint8_t *a, printf("Encoding ... iind %d f1 %d, f2 %d\n",iind,f1f2mat_old[iind*2],f1f2mat_old[(iind*2)+1]); #endif start_meas(te_stats); - threegpplte_turbo_encoder(ulsch->harq_processes[harq_pid]->c[r], - Kr>>3, - &ulsch->harq_processes[harq_pid]->d[r][96], - (r==0) ? ulsch->harq_processes[harq_pid]->F : 0, - f1f2mat_old[iind*2], // f1 (see 36212-820, page 14) - f1f2mat_old[(iind*2)+1] // f2 (see 36212-820, page 14) - ); + encoder(ulsch->harq_processes[harq_pid]->c[r], + Kr>>3, + &ulsch->harq_processes[harq_pid]->d[r][96], + (r==0) ? ulsch->harq_processes[harq_pid]->F : 0, + f1f2mat_old[iind*2], // f1 (see 36212-820, page 14) + f1f2mat_old[(iind*2)+1] // f2 (see 36212-820, page 14) + ); stop_meas(te_stats); #ifdef DEBUG_ULSCH_CODING diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 57087051d3c9d251382809eb3425189d88625872..0d9bf8fd7611b89703fcfed195490a30294570ed 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -242,27 +242,12 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { uint32_t E=0; uint32_t Gp,GpmodC,Nl=1; uint32_t C = ulsch_harq->C; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; @@ -385,7 +370,9 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -463,22 +450,7 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr int G = ulsch_harq->G; unsigned int E; int Cby2; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; struct timespec wait; @@ -487,9 +459,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = decoder8; if (ulsch_harq->C>1) { // wakeup worker if more than 1 segment if (pthread_mutex_timedlock(&proc->mutex_td,&wait) != 0) { @@ -608,7 +580,9 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr start_meas(&eNB->ulsch_turbo_decoding_stats); ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], @@ -670,27 +644,12 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) int G = ulsch_harq->G; unsigned int E; - - uint8_t (*tc)(int16_t *y, - uint8_t *, - uint16_t, - uint16_t, - uint16_t, - uint8_t, - uint8_t, - uint8_t, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *, - time_stats_t *); + decoder_if_t tc; if (llr8_flag == 0) - tc = phy_threegpplte_turbo_decoder16; + tc = *decoder16; else - tc = phy_threegpplte_turbo_decoder8; + tc = *decoder8; for (r=0; r<ulsch_harq->C; r++) { @@ -773,7 +732,9 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) start_meas(&eNB->ulsch_turbo_decoding_stats); ret = tc(&ulsch_harq->d[r][96], + NULL, ulsch_harq->c[r], + NULL, Kr, f1f2mat_old[iind*2], f1f2mat_old[(iind*2)+1], diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 93c1af8d9184db6cce5e16e5ab36117f949e6833..920d8ff3fdbdfd1505d6f7e059217ec844bd632e 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -725,8 +725,8 @@ void ulsch_extract_rbs_single(int32_t **rxdataF, //uint8_t symbol = l+Ns*frame_parms->symbols_per_tti/2; uint8_t symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame - AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<3), - "nb_antennas_rx not in (1-2)\n"); + AssertFatal((frame_parms->nb_antennas_rx>0) && (frame_parms->nb_antennas_rx<5), + "nb_antennas_rx not in (1-4)\n"); for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { @@ -1127,7 +1127,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, uint32_t l,i; int32_t avgs; uint8_t log2_maxh=0,aarx; - int32_t avgU[2]; + int32_t avgU[eNB->frame_parms.nb_antennas_rx]; // uint8_t harq_pid = ( ulsch->RRCConnRequest_flag== 0) ? subframe2harq_pid_tdd(frame_parms->tdd_config,subframe) : 0; @@ -1212,7 +1212,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, avgs = 0; for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) - avgs = cmax(avgs,avgU[(aarx<<1)]); + avgs = cmax(avgs,avgU[aarx]); // log2_maxh = 4+(log2_approx(avgs)/2); @@ -1349,35 +1349,54 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, } - void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id) { + void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id,int round) { uint32_t nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12; uint8_t harq_pid; + char fname[100],vname[100]; harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe); - printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", - subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, + printf("Dumping ULSCH in subframe %d with harq_pid %d, round %d for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", + subframe,harq_pid,round,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb, eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm, eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch); - write_output("/tmp/ulsch_d.m","ulsch_dseq",&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], + sprintf(fname,"/tmp/ulsch_r%d_d",round); + sprintf(vname,"/tmp/ulsch_r%d_dseq",round); + write_output(fname,vname,&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96], eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus*3,1,0); - if (eNB->common_vars.rxdata) write_output("/tmp/rxsig0.m","rxs0", &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1); + if (eNB->common_vars.rxdata) { + sprintf(fname,"/tmp/rxsig0_r%d.m",round); + sprintf(vname,"rxs0_r%d",round); + write_output(fname,vname, &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) - if (eNB->common_vars.rxdata) write_output("/tmp/rxsig1.m","rxs1", &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1); - - - write_output("/tmp/rxsigF0.m","rxsF0", &eNB->common_vars.rxdataF[0][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) + if (eNB->common_vars.rxdata) { + sprintf(fname,"/tmp/rxsig1_r%d.m",round); + sprintf(vname,"rxs1_r%d",round); + write_output(fname,vname, &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1); + } + } - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/rxsigF1.m","rxsF1", &eNB->common_vars.rxdataF[1][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + sprintf(fname,"/tmp/rxsigF0_r%d.m",round); + sprintf(vname,"rxsF0_r%d",round); + write_output(fname,vname, (void*)&eNB->common_vars.rxdataF[0][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); - write_output("/tmp/rxsigF0_ext.m","rxsF0_ext", &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/rxsigF1_r%d.m",round); + sprintf(vname,"rxsF1_r%d",round); + write_output(vname,fname, &eNB->common_vars.rxdataF[1][0],eNB->frame_parms.ofdm_symbol_size*nsymb,1,1); + } - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/rxsigF1_ext.m","rxsF1_ext", &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/rxsigF0_ext_r%d.m",round); + sprintf(vname,"rxsF0_ext_r%d",round); + write_output(fname,vname, &eNB->pusch_vars[UE_id]->rxdataF_ext[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/rxsigF1_ext_r%d.m",round); + sprintf(vname,"rxsF1_ext_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_ext[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + } /* if (eNB->srs_vars[UE_id].srs_ch_estimates) write_output("/tmp/srs_est0.m","srsest0",eNB->srs_vars[UE_id].srs_ch_estimates[0],eNB->frame_parms.ofdm_symbol_size,1,1); @@ -1385,17 +1404,28 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB, if (eNB->srs_vars[UE_id].srs_ch_estimates) write_output("/tmp/srs_est1.m","srsest1",eNB->srs_vars[UE_id].srs_ch_estimates[1],eNB->frame_parms.ofdm_symbol_size,1,1); */ - write_output("/tmp/drs_est0.m","drsest0",eNB->pusch_vars[UE_id]->drs_ch_estimates[0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/drs_est0_r%d.m",round); + sprintf(vname,"drsest0_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); - if (eNB->frame_parms.nb_antennas_rx>1) - write_output("/tmp/drs_est1.m","drsest1",eNB->pusch_vars[UE_id]->drs_ch_estimates[1],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) { + sprintf(fname,"/tmp/drs_est1_r%d.m",round); + sprintf(vname,"drsest1_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->drs_ch_estimates[1],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + } - write_output("/tmp/ulsch_rxF_comp0.m","ulsch0_rxF_comp0",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/ulsch0_rxF_comp0_r%d.m",round); + sprintf(vname,"ulsch0_rxF_comp0_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->rxdataF_comp[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_rxF_comp1.m","ulsch0_rxF_comp1",&eNB->pusch_vars[UE_id]->rxdataF_comp[0][1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); - write_output("/tmp/ulsch_rxF_llr.m","ulsch_llr",eNB->pusch_vars[UE_id]->llr, + sprintf(fname,"/tmp/ulsch_rxF_llr_r%d.m",round); + sprintf(vname,"ulsch_llr_r%d",round); + write_output(fname,vname,eNB->pusch_vars[UE_id]->llr, eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb*12*eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm *eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch,1,0); - write_output("/tmp/ulsch_ch_mag.m","ulsch_ch_mag",&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); + sprintf(fname,"/tmp/ulsch_ch_mag_r%d.m",round); + sprintf(vname,"ulsch_ch_mag_r%d",round); + write_output(fname,vname,&eNB->pusch_vars[UE_id]->ul_ch_mag[0][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); // write_output("ulsch_ch_mag1.m","ulsch_ch_mag1",&eNB->pusch_vars[UE_id]->ul_ch_mag[1][0],eNB->frame_parms.N_RB_UL*12*nsymb,1,1); //#endif } diff --git a/openair1/PHY/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c index 1f2963017e137e940e1c0cbacc5db6c567ae8029..5beb7eccfdc14880ee953d10b198422a8b30a525 100644 --- a/openair1/PHY/MODULATION/slot_fep_ul.c +++ b/openair1/PHY/MODULATION/slot_fep_ul.c @@ -24,6 +24,8 @@ #include "defs.h" //#define DEBUG_FEP + + int slot_fep_ul(RU_t *ru, unsigned char l, unsigned char Ns, @@ -134,7 +136,7 @@ int slot_fep_ul(RU_t *ru, } #ifdef DEBUG_FEP - LOG_D(PHY,"slot_fep: done\n"); + // LOG_D(PHY,"slot_fep: done\n"); #endif return(0); } diff --git a/openair1/PHY/MODULATION/ul_7_5_kHz.c b/openair1/PHY/MODULATION/ul_7_5_kHz.c index 80efc70c40cbe1159cdb18ea5414b21287684027..d92dc1c8b3203bf5c0d103ec3d7fd09ce220f138 100644 --- a/openair1/PHY/MODULATION/ul_7_5_kHz.c +++ b/openair1/PHY/MODULATION/ul_7_5_kHz.c @@ -188,7 +188,7 @@ void remove_7_5_kHz(RU_t *ru,uint8_t slot) } - slot_offset = (uint32_t)slot * frame_parms->samples_per_tti/2-ru->N_TA_offset; + slot_offset = ((uint32_t)slot * frame_parms->samples_per_tti/2)-ru->N_TA_offset; slot_offset2 = (uint32_t)(slot&1) * frame_parms->samples_per_tti/2; len = frame_parms->samples_per_tti/2; diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index e0e171f6bfc601fd839fe40e4b8ead6a29a69b23..47b39ea7d2666154005d4086e0fdea4c82d8d628 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -2047,6 +2047,8 @@ const static int16_t tw16c[24] __attribute__((aligned(32))) = { 0,32767,12540,30 0,32767,30273,12539,23170,-23170,-12539,-30273 }; +#ifdef __AVX2__ + const static int16_t tw16rep[48] __attribute__((aligned(32))) = { 32767,0,30272,-12540,23169 ,-23170,12539 ,-30273,32767,0,30272,-12540,23169 ,-23170,12539 ,-30273, 32767,0,23169,-23170,0 ,-32767,-23170,-23170,32767,0,23169,-23170,0 ,-32767,-23170,-23170, 32767,0,12539,-30273,-23170,-23170,-30273,12539,32767,0,12539,-30273,-23170,-23170,-30273,12539 @@ -2067,6 +2069,8 @@ const static int16_t tw16crep[48] __attribute__((aligned(32))) = { 0,32767,12540 0,32767,30273,12539,23170,-23170,-12539,-30273,0,32767,30273,12539,23170,-23170,-12539,-30273 }; +#endif /* __AVX2__ */ + static inline void dft16(int16_t *x,int16_t *y) __attribute__((always_inline)); diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c index 30e57c1c62530e80a22c22d979e9a887f297231f..eb86af916597fe0869af11ada340788751f301be 100644 --- a/openair1/PHY/TOOLS/lte_phy_scope.c +++ b/openair1/PHY/TOOLS/lte_phy_scope.c @@ -162,7 +162,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, int16_t **chest_t; int16_t **chest_f; int16_t *pusch_llr; - int16_t *pusch_comp; + int32_t *pusch_comp; int32_t *pucch1_comp; int32_t *pucch1_thres; int32_t *pucch1ab_comp; @@ -200,7 +200,7 @@ void phy_scope_eNB(FD_lte_phy_scope_enb *form, chest_t = (int16_t**) phy_vars_enb->srs_vars[UE_id].srs_ch_estimates[eNB_id]; chest_f = (int16_t**) phy_vars_enb->pusch_vars[UE_id]->drs_ch_estimates[eNB_id]; pusch_llr = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->llr; - pusch_comp = (int16_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[eNB_id][0]; + pusch_comp = (int32_t*) phy_vars_enb->pusch_vars[UE_id]->rxdataF_comp[0]; pucch1_comp = (int32_t*) phy_vars_enb->pucch1_stats[UE_id]; pucch1_thres = (int32_t*) phy_vars_enb->pucch1_stats_thres[UE_id]; pucch1ab_comp = (int32_t*) phy_vars_enb->pucch1ab_stats[UE_id]; diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h index 46f37e943102c0a986302f2264c91bcf9da841eb..9ca33c9404d610cc29d4c1eac6f9210147db6790 100644 --- a/openair1/PHY/defs.h +++ b/openair1/PHY/defs.h @@ -738,6 +738,8 @@ typedef struct RU_t_s{ void (*fh_south_asynch_in)(struct RU_t_s *ru,int *frame, int *subframe); /// function pointer to initialization function for radio interface int (*start_rf)(struct RU_t_s *ru); + /// function pointer to release function for radio interface + int (*stop_rf)(struct RU_t_s *ru); /// function pointer to initialization function for radio interface int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL) @@ -1461,6 +1463,53 @@ extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; + +#define MODE_DECODE_NONE 0 +#define MODE_DECODE_SSE 1 +#define MODE_DECODE_C 2 +#define MODE_DECODE_AVX2 3 + +#define DECODE_INITTD8_SSE_FPTRIDX 0 +#define DECODE_INITTD16_SSE_FPTRIDX 1 +#define DECODE_INITTD_AVX2_FPTRIDX 2 +#define DECODE_TD8_SSE_FPTRIDX 3 +#define DECODE_TD16_SSE_FPTRIDX 4 +#define DECODE_TD_C_FPTRIDX 5 +#define DECODE_TD16_AVX2_FPTRIDX 6 +#define DECODE_FREETD8_FPTRIDX 7 +#define DECODE_FREETD16_FPTRIDX 8 +#define DECODE_FREETD_AVX2_FPTRIDX 9 +#define ENCODE_SSE_FPTRIDX 10 +#define ENCODE_C_FPTRIDX 11 +#define ENCODE_INIT_SSE_FPTRIDX 12 +#define DECODE_NUM_FPTR 13 + + +typedef uint8_t(*decoder_if_t)(int16_t *y, + int16_t *y2, + uint8_t *decoded_bytes, + uint8_t *decoded_bytes2, + uint16_t n, + uint16_t f1, + uint16_t f2, + uint8_t max_iterations, + uint8_t crc_type, + uint8_t F, + time_stats_t *init_stats, + time_stats_t *alpha_stats, + time_stats_t *beta_stats, + time_stats_t *gamma_stats, + time_stats_t *ext_stats, + time_stats_t *intl1_stats, + time_stats_t *intl2_stats); + +typedef uint8_t(*encoder_if_t)(uint8_t *input, + uint16_t input_length_bytes, + uint8_t *output, + uint8_t F, + uint16_t interleaver_f1, + uint16_t interleaver_f2); + #define MAX_RRU_CONFIG_SIZE 1024 typedef enum { RAU_tick=0, diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..25ee6465482012c0c42a9457cb6dbac02b075dd3 --- /dev/null +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -0,0 +1,1031 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/defs.h + \brief Top-level defines and structure definitions + \author R. Knopp, F. Kaltenberger + \date 2011 + \version 0.1 + \company Eurecom + \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr + \note + \warning +*/ +#ifndef __PHY_DEFS_NB_IOT__H__ +#define __PHY_DEFS_NB_IOT__H__ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <malloc.h> +#include <string.h> +#include <math.h> +#include "common_lib.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" + +//#include <complex.h> +#include "assertions.h" +#ifdef MEX +# define msg mexPrintf +#else +# ifdef OPENAIR2 +# if ENABLE_RAL +# include "collection/hashtable/hashtable.h" +# include "COMMON/ral_messages_types.h" +# include "UTIL/queue.h" +# endif +# include "log.h" +# define msg(aRGS...) LOG_D(PHY, ##aRGS) +# else +# define msg printf +# endif +#endif +//use msg in the real-time thread context +#define msg_nrt printf +//use msg_nrt in the non real-time context (for initialization, ...) +#ifndef malloc16 +# ifdef __AVX2__ +# define malloc16(x) memalign(32,x) +# else +# define malloc16(x) memalign(16,x) +# endif +#endif +#define free16(y,x) free(y) +#define bigmalloc malloc +#define bigmalloc16 malloc16 +#define openair_free(y,x) free((y)) +#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. +//! If no more memory is available, this function will terminate the program with an assertion error. +//****************************************************************************************************** +/* +static inline void* malloc16_clear( size_t size ) +{ +#ifdef __AVX2__ + void* ptr = memalign(32, size); +#else + void* ptr = memalign(16, size); +#endif + DevAssert(ptr); + memset( ptr, 0, size ); + return ptr; +} + +*/ + + +// #define PAGE_MASK 0xfffff000 +// #define virt_to_phys(x) (x) + +// #define openair_sched_exit() exit(-1) + + +// #define max(a,b) ((a)>(b) ? (a) : (b)) +// #define min(a,b) ((a)<(b) ? (a) : (b)) + + +// #define bzero(s,n) (memset((s),0,(n))) + +// #define cmax(a,b) ((a>b) ? (a) : (b)) +// #define cmin(a,b) ((a<b) ? (a) : (b)) + +// #define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c)) + +// /// suppress compiler warning for unused arguments +// #define UNUSED(x) (void)x; + + +#include "PHY/impl_defs_top_NB_IoT.h" +//#include "impl_defs_top.h" +//#include "impl_defs_lte.h" +#include "PHY/impl_defs_lte_NB_IoT.h" + +#include "PHY/TOOLS/time_meas.h" +//#include "PHY/CODING/defs.h" +#include "PHY/CODING/defs_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +//#include "PHY/TOOLS/defs.h" +//#include "platform_types.h" +///#include "openair1/PHY/LTE_TRANSPORT/defs_nb_iot.h" + +////////////////////////////////////////////////////////////////////#ifdef OPENAIR_LTE (check if this is required) + +//#include "PHY/LTE_TRANSPORT/defs.h" +#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include <pthread.h> + +#include "targets/ARCH/COMMON/common_lib.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#define NUM_DCI_MAX_NB_IoT 32 + +#define NUMBER_OF_eNB_SECTORS_MAX_NB_IoT 3 + +#define NB_BANDS_MAX_NB_IoT 8 + + +#ifdef OCP_FRAMEWORK +#include <enums.h> +#else +typedef enum {normal_txrx_NB_IoT=0,rx_calib_ue_NB_IoT=1,rx_calib_ue_med_NB_IoT=2,rx_calib_ue_byp_NB_IoT=3,debug_prach_NB_IoT=4,no_L2_connect_NB_IoT=5,calib_prach_tx_NB_IoT=6,rx_dump_frame_NB_IoT=7,loop_through_memory_NB_IoT=8} runmode_NB_IoT_t; +#endif +/* +enum transmission_access_mode { + NO_ACCESS=0, + POSTPONED_ACCESS, + CANCELED_ACCESS, + UNKNOWN_ACCESS, + SCHEDULED_ACCESS, + CBA_ACCESS}; + +typedef enum { + eNodeB_3GPP=0, // classical eNodeB function + eNodeB_3GPP_BBU, // eNodeB with NGFI IF5 + NGFI_RCC_IF4p5, // NGFI_RCC (NGFI radio cloud center) + NGFI_RAU_IF4p5, + NGFI_RRU_IF5, // NGFI_RRU (NGFI remote radio-unit,IF5) + NGFI_RRU_IF4p5 // NGFI_RRU (NGFI remote radio-unit,IF4p5) +} eNB_func_t; + +typedef enum { + synch_to_ext_device=0, // synch to RF or Ethernet device + synch_to_other // synch to another source (timer, other CC_id) +} eNB_timing_t; +#endif +*/ +typedef struct UE_SCAN_INFO_NB_IoT_s { + /// 10 best amplitudes (linear) for each pss signals + int32_t amp[3][10]; + /// 10 frequency offsets (kHz) corresponding to best amplitudes, with respect do minimum DL frequency in the band + int32_t freq_offset_Hz[3][10]; + +} UE_SCAN_INFO_NB_IoT_t; + +/// Top-level PHY Data Structure for RN +typedef struct { + /// Module ID indicator for this instance + uint8_t Mod_id; + uint32_t frame; + // phy_vars_eNB_NB_IoT + // phy_vars ue + // cuurently only used to store and forward the PMCH + uint8_t mch_avtive[10]; + uint8_t sync_area[10]; // num SF + NB_IoT_UE_DLSCH_t *dlsch_rn_MCH[10]; + +} PHY_VARS_RN_NB_IoT; +/* +#ifdef OCP_FRAMEWORK +#include <enums.h> +#else +//typedef enum {normal_txrx=0,rx_calib_ue=1,rx_calib_ue_med=2,rx_calib_ue_byp=3,debug_prach=4,no_L2_connect=5,calib_prach_tx=6,rx_dump_frame=7,loop_through_memory=8} runmode_t; +*/ +// enum transmission_access_mode { +// NO_ACCESS=0, +// POSTPONED_ACCESS, +// CANCELED_ACCESS, +// UNKNOWN_ACCESS, +// SCHEDULED_ACCESS, +// CBA_ACCESS}; + +typedef enum { + eNodeB_3GPP_NB_IoT=0, // classical eNodeB function + eNodeB_3GPP_BBU_NB_IoT, // eNodeB with NGFI IF5 + NGFI_RCC_IF4p5_NB_IoT, // NGFI_RCC (NGFI radio cloud center) + NGFI_RAU_IF4p5_NB_IoT, + NGFI_RRU_IF5_NB_IoT, // NGFI_RRU (NGFI remote radio-unit,IF5) + NGFI_RRU_IF4p5_NB_IoT // NGFI_RRU (NGFI remote radio-unit,IF4p5) +} eNB_func_NB_IoT_t; + +typedef enum { + + synch_to_ext_device_NB_IoT=0, // synch to RF or Ethernet device + synch_to_other_NB_IoT // synch to another source (timer, other CC_id) + +} eNB_timing_NB_IoT_t; +////////////////////////////////////////////////////////////////////#endif + + +typedef struct { + + struct PHY_VARS_eNB_NB_IoT_s *eNB; + NB_IoT_eNB_NDLSCH_t *dlsch; + int G; + +} te_params_NB_IoT; + + +typedef struct { + + struct PHY_VARS_eNB_NB_IoT_s *eNB; + int UE_id; + int harq_pid; + int llr8_flag; + int ret; + +} td_params_NB_IoT; + + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_rxtx; + /// scheduling parameters for RXn-TXnp4 thread + struct sched_param sched_param_rxtx; + /// NB-IoT for IF_Module + pthread_t pthread_l2; + pthread_cond_t cond_l2; + pthread_mutex_t mutex_l2; + int instance_cnt_l2; + pthread_attr_t attr_l2; + +} eNB_rxtx_proc_NB_IoT_t; +/* +typedef struct { + struct PHY_VARS_eNB_NB_IoT_s *eNB; + int UE_id; + int harq_pid; + int llr8_flag; + int ret; +} td_params; + +typedef struct { + struct PHY_VARS_eNB_NB_IoT_s *eNB; + LTE_eNB_DLSCH_t *dlsch; + int G; +} te_params; +*/ + +/// Context data structure for eNB subframe processing +typedef struct eNB_proc_NB_IoT_t_s { + /// thread index + int thread_index; + /// timestamp received from HW + openair0_timestamp timestamp_rx; + /// timestamp to send to "slave rru" + openair0_timestamp timestamp_tx; + /// subframe to act upon for reception + int subframe_rx; + /// symbol mask for IF4p5 reception per subframe + uint32_t symbol_mask[10]; + /// subframe to act upon for PRACH + int subframe_prach; + /// frame to act upon for reception + int frame_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame offset for secondary eNBs (to correct for frame asynchronism at startup) + int frame_offset; + /// frame to act upon for PRACH + int frame_prach; + /// \internal This variable is protected by \ref mutex_fep. + int instance_cnt_fep; + /// \internal This variable is protected by \ref mutex_td. + int instance_cnt_td; + /// \internal This variable is protected by \ref mutex_te. + int instance_cnt_te; + /// \brief Instance count for FH processing thread. + /// \internal This variable is protected by \ref mutex_FH. + int instance_cnt_FH; + /// \brief Instance count for rx processing thread. + /// \internal This variable is protected by \ref mutex_prach. + int instance_cnt_prach; + // instance count for over-the-air eNB synchronization + int instance_cnt_synch; + /// \internal This variable is protected by \ref mutex_asynch_rxtx. + int instance_cnt_asynch_rxtx; + /// pthread structure for FH processing thread + pthread_t pthread_FH; + /// pthread structure for eNB single processing thread + pthread_t pthread_single; + /// pthread structure for asychronous RX/TX processing thread + pthread_t pthread_asynch_rxtx; + /// flag to indicate first RX acquisition + int first_rx; + /// flag to indicate first TX transmission + int first_tx; + /// pthread attributes for parallel fep thread + pthread_attr_t attr_fep; + /// pthread attributes for parallel turbo-decoder thread + pthread_attr_t attr_td; + /// pthread attributes for parallel turbo-encoder thread + pthread_attr_t attr_te; + /// pthread attributes for FH processing thread + pthread_attr_t attr_FH; + /// pthread attributes for single eNB processing thread + pthread_attr_t attr_single; + /// pthread attributes for prach processing thread + pthread_attr_t attr_prach; + /// pthread attributes for over-the-air synch thread + pthread_attr_t attr_synch; + /// pthread attributes for asynchronous RX thread + pthread_attr_t attr_asynch_rxtx; + /// scheduling parameters for parallel fep thread + struct sched_param sched_param_fep; + /// scheduling parameters for parallel turbo-decoder thread + struct sched_param sched_param_td; + /// scheduling parameters for parallel turbo-encoder thread + struct sched_param sched_param_te; + /// scheduling parameters for FH thread + struct sched_param sched_param_FH; + /// scheduling parameters for single eNB thread + struct sched_param sched_param_single; + /// scheduling parameters for prach thread + struct sched_param sched_param_prach; + /// scheduling parameters for over-the-air synchronization thread + struct sched_param sched_param_synch; + /// scheduling parameters for asynch_rxtx thread + struct sched_param sched_param_asynch_rxtx; + /// pthread structure for parallel fep thread + pthread_t pthread_fep; + /// pthread structure for parallel turbo-decoder thread + pthread_t pthread_td; + /// pthread structure for parallel turbo-encoder thread + pthread_t pthread_te; + /// pthread structure for PRACH thread + pthread_t pthread_prach; + /// pthread structure for eNB synch thread + pthread_t pthread_synch; + /// condition variable for parallel fep thread + pthread_cond_t cond_fep; + /// condition variable for parallel turbo-decoder thread + pthread_cond_t cond_td; + /// condition variable for parallel turbo-encoder thread + pthread_cond_t cond_te; + /// condition variable for FH thread + pthread_cond_t cond_FH; + /// condition variable for PRACH processing thread; + pthread_cond_t cond_prach; + // condition variable for over-the-air eNB synchronization + pthread_cond_t cond_synch; + /// condition variable for asynch RX/TX thread + pthread_cond_t cond_asynch_rxtx; + /// mutex for RU access to processing (NPDSCH/PUSCH) + pthread_mutex_t mutex_RU; + /// mutex for parallel fep thread + pthread_mutex_t mutex_fep; + /// mutex for parallel turbo-decoder thread + pthread_mutex_t mutex_td; + /// mutex for parallel turbo-encoder thread + pthread_mutex_t mutex_te; + /// mutex for FH + pthread_mutex_t mutex_FH; + /// mutex for PRACH thread + pthread_mutex_t mutex_prach; + // mutex for over-the-air eNB synchronization + pthread_mutex_t mutex_synch; + /// mutex for RU access to NB-IoT processing (NPRACH) + pthread_mutex_t mutex_RU_PRACH; + /// mutex for asynch RX/TX thread + pthread_mutex_t mutex_asynch_rxtx; + /// mask for RUs serving nbiot (NPDSCH/NPUSCH) + int RU_mask; + /// mask for RUs serving nbiot (PRACH) + int RU_mask_prach; +#ifdef Rel14 + /// mask for RUs serving eNB (PRACH) + int RU_mask_prach_br; +#endif + /// parameters for turbo-decoding worker thread + td_params_NB_IoT tdp; + /// parameters for turbo-encoding worker thread + te_params_NB_IoT tep; + /// number of slave threads + int num_slaves; + /// array of pointers to slaves + struct eNB_proc_NB_IoT_t_s **slave_proc; + /// set of scheduling variables RXn-TXnp4 threads + // newly added for NB_IoT + eNB_rxtx_proc_NB_IoT_t proc_rxtx[2]; + +} eNB_proc_NB_IoT_t; + + +/// Context data structure for RX/TX portion of subframe processing +typedef struct { + /// index of the current UE RX/TX proc + int proc_id; + /// timestamp transmitted to HW + openair0_timestamp timestamp_tx; + /// subframe to act upon for transmission + int subframe_tx; + /// subframe to act upon for reception + int subframe_rx; + /// frame to act upon for transmission + int frame_tx; + /// frame to act upon for reception + int frame_rx; + /// \brief Instance count for RXn-TXnp4 processing thread. + /// \internal This variable is protected by \ref mutex_rxtx. + int instance_cnt_rxtx; + /// pthread structure for RXn-TXnp4 processing thread + pthread_t pthread_rxtx; + /// pthread attributes for RXn-TXnp4 processing thread + pthread_attr_t attr_rxtx; + /// condition variable for tx processing thread + pthread_cond_t cond_rxtx; + /// mutex for RXn-TXnp4 processing thread + pthread_mutex_t mutex_rxtx; + /// scheduling parameters for RXn-TXnp4 thread + struct sched_param sched_param_rxtx; + /// + int sub_frame_start; + /// + int sub_frame_step; + /// + unsigned long long gotIQs; + +} UE_rxtx_proc_NB_IoT_t; + +/// Context data structure for eNB subframe processing +typedef struct { + /// Last RX timestamp + openair0_timestamp timestamp_rx; + /// pthread attributes for main UE thread + pthread_attr_t attr_ue; + /// scheduling parameters for main UE thread + struct sched_param sched_param_ue; + /// pthread descriptor main UE thread + pthread_t pthread_ue; + /// \brief Instance count for synch thread. + /// \internal This variable is protected by \ref mutex_synch. + int instance_cnt_synch; + /// pthread attributes for synch processing thread + pthread_attr_t attr_synch; + /// scheduling parameters for synch thread + struct sched_param sched_param_synch; + /// pthread descriptor synch thread + pthread_t pthread_synch; + /// condition variable for UE synch thread; + pthread_cond_t cond_synch; + /// mutex for UE synch thread + pthread_mutex_t mutex_synch; + /// set of scheduling variables RXn-TXnp4 threads + UE_rxtx_proc_NB_IoT_t proc_rxtx[2]; + +} UE_proc_NB_IoT_t; + + + +/// Top-level PHY Data Structure for eNB +typedef struct PHY_VARS_eNB_NB_IoT_s { + /// Module ID indicator for this instance + module_id_t Mod_id; + uint8_t configured; + eNB_proc_NB_IoT_t proc; + int num_RU; + RU_t *RU_list[MAX_NUM_RU_PER_eNB]; + /// Ethernet parameters for northbound midhaul interface (L1 to Mac) + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface (upper L1 to Radio head) + eth_params_t eth_params; + int single_thread_flag; + openair0_rf_map rf_map; + int abstraction_flag; + openair0_timestamp ts_offset; + // indicator for synchronization state of eNB + int in_synch; + // indicator for master/slave (RRU) + int is_slave; + // indicator for precoding function (eNB,3GPP_eNB_BBU) + int do_precoding; + IF_Module_NB_IoT_t *if_inst_NB_IoT; + UL_IND_NB_IoT_t UL_INFO_NB_IoT; + pthread_mutex_t UL_INFO_mutex; + void (*do_prach)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int frame,int subframe); + void (*fep)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc); + int (*td)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int UE_id,int harq_pid,int llr8_flag); + int (*te)(struct PHY_VARS_eNB_NB_IoT_s *,uint8_t *,uint8_t,NB_IoT_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *); + void (*proc_uespec_rx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,const relaying_type_t_NB_IoT r_type); + void (*proc_tx)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc,relaying_type_t_NB_IoT r_type,PHY_VARS_RN_NB_IoT *rn); + void (*tx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc); + void (*rx_fh)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe); + int (*start_rf)(struct PHY_VARS_eNB_NB_IoT_s *eNB); + int (*start_if)(struct PHY_VARS_eNB_NB_IoT_s *eNB); + void (*fh_asynch)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int *frame, int *subframe); + uint8_t local_flag; + uint32_t rx_total_gain_dB; + NB_IoT_DL_FRAME_PARMS frame_parms; + PHY_MEASUREMENTS_eNB_NB_IoT measurements[NUMBER_OF_eNB_SECTORS_MAX_NB_IoT]; /// Measurement variables + NB_IoT_eNB_COMMON common_vars; + NB_IoT_eNB_SRS srs_vars[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_PBCH pbch; + NB_IoT_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_PRACH prach_vars; + //LTE_eNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX_NB_IoT][2]; // Nusers times two spatial streams + NB_IoT_eNB_NULSCH_t *ulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; // Nusers + number of RA (the ulsch[0] contains RAR) + //LTE_eNB_DLSCH_t *dlsch_SI,*dlsch_ra; + //LTE_eNB_DLSCH_t *dlsch_MCH; + NB_IoT_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX_NB_IoT]; + //LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX_NB_IoT]; + /// cell-specific reference symbols + uint32_t lte_gold_table_NB_IoT[20][2][14]; + /// UE-specific reference symbols (p=5), TM 7 + uint32_t lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX_NB_IoT][20][38]; + /// UE-specific reference symbols (p=7...14), TM 8/9/10 + uint32_t lte_gold_uespec_table[2][20][2][21]; + /// mbsfn reference symbols + uint32_t lte_gold_mbsfn_table[10][3][42]; + /// + uint32_t X_u[64][839]; + /// + uint8_t pbch_pdu[4]; //PBCH_PDU_SIZE + /// + char eNB_generate_rar; + /// Indicator set to 0 after first SR + uint8_t first_sr[NUMBER_OF_UE_MAX_NB_IoT]; + + uint32_t max_peak_val; + /// + int max_eNB_id, max_sync_pos; + /// + int N_TA_offset; ///timing offset used in TDD + /// \brief sinr for all subcarriers of the current link (used only for abstraction). + /// first index: ? [0..N_RB_DL*12[ + double *sinr_dB; + /// N0 (used for abstraction) + double N0; + /// + unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX_NB_IoT]; + unsigned char first_run_I0_measurements; + + unsigned char cooperation_flag; // for cooperative communication + + unsigned char is_secondary_eNB; // primary by default + unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system. + unsigned char has_valid_precoder; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created. + unsigned char PeNB_id; /// id of Primary eNB + int rx_offset; /// Timing offset (used if is_secondary_eNB) + + /// hold the precoder for NULL beam to the primary user + int **dl_precoder_SeNB[3]; + /// + char log2_maxp; /// holds the maximum channel/precoder coefficient + /// if ==0 enables phy only test mode + int mac_enabled; + /// For emulation only (used by UE abstraction to retrieve DCI) + uint8_t num_common_dci[2]; // num_dci in even/odd subframes + /// + uint8_t num_ue_spec_dci[2]; // num_dci in even/odd subframes + /// + DCI_ALLOC_NB_IoT_t dci_alloc[2][NUM_DCI_MAX_NB_IoT]; // dci_alloc from even/odd subframes + ///////////// + // PDSCH Variables + PDSCH_CONFIG_DEDICATED_NB_IoT pdsch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // PUSCH Variables + PUSCH_CONFIG_DEDICATED_NB_IoT pusch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // PUCCH variables + PUCCH_CONFIG_DEDICATED_NB_IoT pucch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // UL-POWER-Control + UL_POWER_CONTROL_DEDICATED_NB_IoT ul_power_control_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + // TPC + TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX_NB_IoT]; + /// + TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX_NB_IoT]; + // CQI reporting + CQI_REPORT_CONFIG_NB_IoT cqi_report_config[NUMBER_OF_UE_MAX_NB_IoT]; + // SRS Variables + SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT]; + /// + uint8_t ncs_cell[20][7]; + // Scheduling Request Config + SCHEDULING_REQUEST_CONFIG_NB_IoT scheduling_request_config[NUMBER_OF_UE_MAX_NB_IoT]; + // Transmission mode per UE + uint8_t transmission_mode[NUMBER_OF_UE_MAX_NB_IoT]; + /// cba_last successful reception for each group, used for collision detection + uint8_t cba_last_reception[4]; + // Pointers for active physicalConfigDedicated to be applied in current subframe + struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX_NB_IoT]; + //Pointers for actve physicalConfigDedicated for NB-IoT to be applied in current subframe + struct PhysicalConfigDedicated_NB_r13 *phy_config_dedicated_NB_IoT[NUMBER_OF_UE_MAX_NB_IoT]; + /// + uint32_t rb_mask_ul[4]; + /// Information regarding TM5 + MU_MIMO_mode_NB_IoT mu_mimo_mode[NUMBER_OF_UE_MAX_NB_IoT]; + /// target_ue_dl_mcs : only for debug purposes + uint32_t target_ue_dl_mcs; + /// target_ue_ul_mcs : only for debug purposes + uint32_t target_ue_ul_mcs; + /// target_ue_dl_rballoc : only for debug purposes + uint32_t ue_dl_rb_alloc; + /// target ul PRBs : only for debug + uint32_t ue_ul_nb_rb; + ///check for Total Transmissions + uint32_t check_for_total_transmissions; + ///check for MU-MIMO Transmissions + uint32_t check_for_MUMIMO_transmissions; + ///check for SU-MIMO Transmissions + uint32_t check_for_SUMIMO_transmissions; + ///check for FULL MU-MIMO Transmissions + uint32_t FULL_MUMIMO_transmissions; + /// Counter for total bitrate, bits and throughput in downlink + uint32_t total_dlsch_bitrate; + /// + uint32_t total_transmitted_bits; + /// + uint32_t total_system_throughput; + /// + int hw_timing_advance; + /// + time_stats_t phy_proc; + time_stats_t phy_proc_tx; + time_stats_t phy_proc_rx; + time_stats_t rx_prach; + + time_stats_t ofdm_mod_stats; + time_stats_t dlsch_encoding_stats; + time_stats_t dlsch_modulation_stats; + time_stats_t dlsch_scrambling_stats; + time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_interleaving_stats; + + time_stats_t ofdm_demod_stats; + time_stats_t rx_dft_stats; + time_stats_t ulsch_channel_estimation_stats; + time_stats_t ulsch_freq_offset_estimation_stats; + time_stats_t ulsch_decoding_stats; + time_stats_t ulsch_demodulation_stats; + time_stats_t ulsch_rate_unmatching_stats; + time_stats_t ulsch_turbo_decoding_stats; + time_stats_t ulsch_deinterleaving_stats; + time_stats_t ulsch_demultiplexing_stats; + time_stats_t ulsch_llr_stats; + time_stats_t ulsch_tc_init_stats; + time_stats_t ulsch_tc_alpha_stats; + time_stats_t ulsch_tc_beta_stats; + time_stats_t ulsch_tc_gamma_stats; + time_stats_t ulsch_tc_ext_stats; + time_stats_t ulsch_tc_intl1_stats; + time_stats_t ulsch_tc_intl2_stats; + + #ifdef LOCALIZATION + /// time state for localization + time_stats_t localization_stats; + #endif + + int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10]; + int32_t pucch1_stats[NUMBER_OF_UE_MAX_NB_IoT][10*1024]; + int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX_NB_IoT][10*1024]; + int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10]; + int32_t pucch1ab_stats[NUMBER_OF_UE_MAX_NB_IoT][2*10*1024]; + int32_t pusch_stats_rb[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_round[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX_NB_IoT][10240]; + int32_t pusch_stats_BO[NUMBER_OF_UE_MAX_NB_IoT][10240]; + + /// RF and Interface devices per CC + openair0_device rfdevice; + openair0_device ifdevice; + /// Pointer for ifdevice buffer struct + if_buffer_t ifbuffer; + + //------------------------ + // NB-IoT + //------------------------ + + /* + * NUMBER_OF_UE_MAX_NB_IoT maybe in the future should be dynamic because could be very large and the memory may explode + * (is almost the indication of the number of UE context that we are storing at PHY layer) + * + * reasoning: the following data structure (ndlsch, nulsch ecc..) are used to store the context that should be transmitted in at least n+4 subframe later + * (the minimum interval between NPUSCH and the ACK for this) + * the problem is that in NB_IoT the ACK for the UPLINK is contained in the DCI through the NDI field (if this value change from the previous one then it means ACK) + * but may we could schedule this DCI long time later so may lots of contents shuld be stored (there is no concept of phich channel in NB-IoT) + * For the DL transmission the UE send a proper ACK/NACK message + * + * *the HARQ process should be killed when the NDI change + * + * *In the Structure for nulsch we should also store the information related to the subframe (because each time we should read it and understand what should be done + * in that subframe) + * + */ + + + /* + * TIMING + * the entire transmission and scheduling are done for the "subframe" concept but the subframe = proc->subframe_tx (that in reality is the subframe_rx +4) + * (see USER/lte-enb/wakeup_rxtx ) + * + * Related to FAPI: + * DCI and DL_CONFIG.request (also more that 1) and MAC_PDU are transmitted in the same subframe (our assumption) so will be all contained in the schedule_response getting from the scheduler + * DCI0 and UL_CONFIG.request are transmitted in the same subframe (our assumption) so contained in the schedule_response + * + */ + + //TODO: check what should be NUMBER_OF_UE_MAX_NB_IoT value + NB_IoT_eNB_NPBCH_t *npbch; + NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX_NB_IoT]; + NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT][2]; + NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR + NB_IoT_eNB_NDLSCH_t *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1; + + NB_IoT_DL_FRAME_PARMS frame_parms_NB_IoT; + // DCI for at most 2 DCI pdus + DCI_PDU_NB_IoT *DCI_pdu; + + + +} PHY_VARS_eNB_NB_IoT; + +//#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg + +/// Top-level PHY Data Structure for UE +typedef struct { + /// \brief Module ID indicator for this instance + uint8_t Mod_id; + /// \brief Mapping of CC_id antennas to cards + openair0_rf_map rf_map; + //uint8_t local_flag; + /// \brief Indicator of current run mode of UE (normal_txrx, rx_calib_ue, no_L2_connect, debug_prach) + runmode_NB_IoT_t mode; + /// \brief Indicator that UE should perform band scanning + int UE_scan; + /// \brief Indicator that UE should perform coarse scanning around carrier + int UE_scan_carrier; + /// \brief Indicator that UE is synchronized to an eNB + int is_synchronized; + /// Data structure for UE process scheduling + UE_proc_NB_IoT_t proc; + /// Flag to indicate the UE shouldn't do timing correction at all + int no_timing_correction; + /// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna) + uint32_t tx_total_gain_dB; + /// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card. + uint32_t rx_total_gain_dB; + /// \brief Total gains with maximum RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_max[4]; + /// \brief Total gains with medium RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_med[4]; + /// \brief Total gains with bypassed RF gain stage (ExpressMIMO2/Lime) + uint32_t rx_gain_byp[4]; + /// \brief Current transmit power + int16_t tx_power_dBm[10]; + /// \brief Total number of REs in current transmission + int tx_total_RE[10]; + /// \brief Maximum transmit power + int8_t tx_power_max_dBm; + /// \brief Number of eNB seen by UE + uint8_t n_connected_eNB; + /// \brief indicator that Handover procedure has been initiated + uint8_t ho_initiated; + /// \brief indicator that Handover procedure has been triggered + uint8_t ho_triggered; + /// \brief Measurement variables. + PHY_MEASUREMENTS_NB_IoT measurements; + NB_IoT_DL_FRAME_PARMS frame_parms; + /// \brief Frame parame before ho used to recover if ho fails. + NB_IoT_DL_FRAME_PARMS frame_parms_before_ho; + NB_IoT_UE_COMMON common_vars; + + NB_IoT_UE_PDSCH *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads + NB_IoT_UE_DLSCH_t *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads + //Paging parameters + uint32_t IMSImod1024; + uint32_t PF; + uint32_t PO; + // For abstraction-purposes only + uint8_t sr[10]; + uint8_t pucch_sel[10]; + uint8_t pucch_payload[22]; + //UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + //cell-specific reference symbols + uint32_t lte_gold_table[7][20][2][14]; + //UE-specific reference symbols (p=5), TM 7 + uint32_t lte_gold_uespec_port5_table[20][38]; + //ue-specific reference symbols + uint32_t lte_gold_uespec_table[2][20][2][21]; + //mbsfn reference symbols + uint32_t lte_gold_mbsfn_table[10][3][42]; + /// + uint32_t X_u[64][839]; + /// + uint32_t high_speed_flag; + uint32_t perfect_ce; + int16_t ch_est_alpha; + int generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX]; + /// + UE_SCAN_INFO_NB_IoT_t scan_info[NB_BANDS_MAX_NB_IoT]; + /// + char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX]; + +/* + + unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX]; + uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX]; + PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX]; + int turbo_iterations, turbo_cntl_iterations; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX]; + /// \brief ?. + /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded) + uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; + int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; + unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; + uint8_t generate_prach; + uint8_t prach_cnt; + uint8_t prach_PreambleIndex; + // uint8_t prach_timer; + uint8_t decode_SIB; + uint8_t decode_MIB; + int rx_offset; /// Timing offset + int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP + int timing_advance; ///timing advance signalled from eNB + int hw_timing_advance; + int N_TA_offset; ///timing offset used in TDD + /// Flag to tell if UE is secondary user (cognitive mode) + unsigned char is_secondary_ue; + /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from. + unsigned char has_valid_precoder; + /// hold the precoder for NULL beam to the primary eNB + int **ul_precoder_S_UE; + /// holds the maximum channel/precoder coefficient + char log2_maxp; +*/ + /// if ==0 enables phy only test mode + int mac_enabled; + /// Flag to initialize averaging of PHY measurements + int init_averaging; + /// \brief sinr for all subcarriers of the current link (used only for abstraction). + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_dB; + /// \brief sinr for all subcarriers of first symbol for the CQI Calculation. + /// - first index: ? [0..12*N_RB_DL[ + double *sinr_CQI_dB; + /// sinr_effective used for CQI calulcation + double sinr_eff; + /// N0 (used for abstraction) + double N0; +/* + /// PDSCH Varaibles + PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH Varaibles + PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// PUSCH contention-based access vars + PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola + + /// PUCCH variables + + PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + uint8_t ncs_cell[20][7]; + + /// UL-POWER-Control + UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// TPC + TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX]; + TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// CQI reporting + CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SRS Variables + SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Scheduling Request Config + SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// Transmission mode per eNB + uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX]; + + time_stats_t phy_proc; + time_stats_t phy_proc_tx; + time_stats_t phy_proc_rx[2]; + + uint32_t use_ia_receiver; + + time_stats_t ofdm_mod_stats; + time_stats_t ulsch_encoding_stats; + time_stats_t ulsch_modulation_stats; + time_stats_t ulsch_segmentation_stats; + time_stats_t ulsch_rate_matching_stats; + time_stats_t ulsch_turbo_encoding_stats; + time_stats_t ulsch_interleaving_stats; + time_stats_t ulsch_multiplexing_stats; + + time_stats_t generic_stat; + time_stats_t pdsch_procedures_stat; + time_stats_t dlsch_procedures_stat; + + time_stats_t ofdm_demod_stats; + time_stats_t dlsch_rx_pdcch_stats; + time_stats_t rx_dft_stats; + time_stats_t dlsch_channel_estimation_stats; + time_stats_t dlsch_freq_offset_estimation_stats; + time_stats_t dlsch_decoding_stats[2]; + time_stats_t dlsch_demodulation_stats; + time_stats_t dlsch_rate_unmatching_stats; + time_stats_t dlsch_turbo_decoding_stats; + time_stats_t dlsch_deinterleaving_stats; + time_stats_t dlsch_llr_stats; + time_stats_t dlsch_unscrambling_stats; + time_stats_t dlsch_rate_matching_stats; + time_stats_t dlsch_turbo_encoding_stats; + time_stats_t dlsch_interleaving_stats; + time_stats_t dlsch_tc_init_stats; + time_stats_t dlsch_tc_alpha_stats; + time_stats_t dlsch_tc_beta_stats; + time_stats_t dlsch_tc_gamma_stats; + time_stats_t dlsch_tc_ext_stats; + time_stats_t dlsch_tc_intl1_stats; + time_stats_t dlsch_tc_intl2_stats; + time_stats_t tx_prach; + + /// RF and Interface devices per CC + openair0_device rfdevice; + time_stats_t dlsch_encoding_SIC_stats; + time_stats_t dlsch_scrambling_SIC_stats; + time_stats_t dlsch_modulation_SIC_stats; + time_stats_t dlsch_llr_stripping_unit_SIC_stats; + time_stats_t dlsch_unscrambling_SIC_stats; + +#if ENABLE_RAL + hash_table_t *ral_thresholds_timed; + SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; + SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; +#endif +*/ +} PHY_VARS_UE_NB_IoT; + + + +#include "PHY/INIT/defs_NB_IoT.h" +#include "PHY/LTE_REFSIG/defs_NB_IoT.h" +#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h" +#endif // __PHY_DEFS__H__ diff --git a/openair1/PHY/extern.h b/openair1/PHY/extern.h index 3ff2d64da05cfd8ed124e217020e340ba0ffdf59..5868c1c0221ce345d81aa10267d76bfe211be1a2 100644 --- a/openair1/PHY/extern.h +++ b/openair1/PHY/extern.h @@ -126,6 +126,6 @@ extern unsigned short Nb_81_110[8][4]; extern uint16_t hundred_times_log10_NPRB[100]; extern uint8_t alpha_lut[8]; - +extern uint8_t max_turbo_iterations; #endif /*__PHY_EXTERN_H__ */ diff --git a/openair1/PHY/impl_defs_lte_NB_IoT.h b/openair1/PHY/impl_defs_lte_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..1167323174e1a3048df10768afd2ca481841c97a --- /dev/null +++ b/openair1/PHY/impl_defs_lte_NB_IoT.h @@ -0,0 +1,813 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/impl_defs_lte.h +* \brief LTE Physical channel configuration and variable structure definitions +* \author R. Knopp, F. Kaltenberger +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +#ifndef __PHY_IMPL_DEFS_NB_IOT__H__ +#define __PHY_IMPL_DEFS_NB_IOT__H__ + +#include "types_NB_IoT.h" +//#include "defs.h" + +typedef enum {TDD_NB_IoT=1,FDD_NB_IoT=0} NB_IoT_frame_type_t; +typedef enum {EXTENDED_NB_IoT=1,NORMAL_NB_IoT=0} NB_IoT_prefix_type_t; +typedef enum {SF_DL_NB_IoT, SF_UL_NB_IoT, SF_S_NB_IoT} NB_IoT_subframe_t; + +#define A_SEQUENCE_OF(type) A_SET_OF(type) + +#define A_SET_OF(type) \ + struct { \ + type **array; \ + int count; /* Meaningful size */ \ + int size; /* Allocated size */ \ + void (*free)(type *); \ + } + + +///////////////////////// + /// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. +typedef union { + /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} + uint8_t indexOfFormat3; + /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} + uint8_t indexOfFormat3A; +} TPC_INDEX_NB_IoT_t; + +/// TPC-PDCCH-Config Information Element from 36.331 RRC spec +typedef struct { + /// RNTI for power control using DCI format 3/3A, see TS 36.212. \vr{[0..65535]} + uint16_t rnti; + /// Index of N or M, see TS 36.212 (5.3.3.1.6 and 5.3.3.1.7), where N or M is dependent on the used DCI format (i.e. format 3 or 3a). + TPC_INDEX_NB_IoT_t tpc_Index; +} TPC_PDCCH_CONFIG_NB_IoT; + /// Enumeration for parameter \f$N_\text{ANRep}\f$ \ref PUCCH_CONFIG_DEDICATED::repetitionFactor. +typedef enum { + //n2=0, + n4_n, + n6_n +} ACKNAKREP_NB_IoT_t; + +/// Enumeration for \ref PUCCH_CONFIG_DEDICATED::tdd_AckNackFeedbackMode. +typedef enum { + bundling_N=0, + multiplexing_N +} ANFBmode_NB_IoT_t; + +/// PUCCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Flag to indicate ACK NAK repetition activation, see TS 36.213 (10.1). \vr{[0..1]} + uint8_t ackNackRepetition; + /// Parameter: \f$N_\text{ANRep}\f$, see TS 36.213 (10.1). + ACKNAKREP_NB_IoT_t repetitionFactor; + /// Parameter: \f$n^{(1)}_\text{PUCCH,ANRep}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t n1PUCCH_AN_Rep; + /// Feedback mode, see TS 36.213 (7.3). \details Applied to both PUCCH and PUSCH feedback. For TDD, should always be set to bundling. + ANFBmode_NB_IoT_t tdd_AckNackFeedbackMode; +} PUCCH_CONFIG_DEDICATED_NB_IoT; + // UE specific PUSCH configuration. +typedef struct { + /// Parameter: \f$I^\text{HARQ-ACK}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-1). \vr{[0..15]} + uint16_t betaOffset_ACK_Index; + /// Parameter: \f$I^{RI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-2). \vr{[0..15]} + uint16_t betaOffset_RI_Index; + /// Parameter: \f$I^{CQI}_\text{offset}\f$, see TS 36.213 (Table 8.6.3-3). \vr{[0..15]} + uint16_t betaOffset_CQI_Index; +} PUSCH_CONFIG_DEDICATED_NB_IoT; +/// Enumeration for Parameter \f$P_A\f$ \ref PDSCH_CONFIG_DEDICATED::p_a. +typedef enum { + //dBm6=0, ///< (dB-6) corresponds to -6 dB + // dBm477, ///< (dB-4dot77) corresponds to -4.77 dB + // dBm3, ///< (dB-3) corresponds to -3 dB + //dBm177, ///< (dB-1dot77) corresponds to -1.77 dB + //dB0, ///< corresponds to 0 dB + // dB1, ///< corresponds to 1 dB + dB2_NB, ///< corresponds to 2 dB + dB3_NB ///< corresponds to 3 dB +} PA_NB_IoT_t; + +/// PDSCH-ConfigDedicated from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_A\f$, see TS 36.213 (5.2). + PA_NB_IoT_t p_a; +} PDSCH_CONFIG_DEDICATED_NB_IoT; + +/// UplinkPowerControlDedicated Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$P_\text{0\_UE\_PUSCH}(1)\f$, see TS 36.213 (5.1.1.1), unit dB. \vr{[-8..7]}\n This field is applicable for non-persistent scheduling, only. + int8_t p0_UE_PUSCH; + /// Parameter: Ks, see TS 36.213 (5.1.1.1). \vr{[0..1]}\n en0 corresponds to value 0 corresponding to state “disabledâ€. en1 corresponds to value 1.25 corresponding to “enabledâ€. \note the specification sais it is an enumerated value. \warning the enumeration values do not correspond to the given values in the specification (en1 should be 1.25). + uint8_t deltaMCS_Enabled; + /// Parameter: Accumulation-enabled, see TS 36.213 (5.1.1.1). \vr{[0..1]} 1 corresponds to "enabled" whereas 0 corresponds to "disabled". + uint8_t accumulationEnabled; + /// Parameter: \f$P_\text{0\_UE\_PUCCH}(1)\f$, see TS 36.213 (5.1.2.1), unit dB. \vr{[-8..7]} + int8_t p0_UE_PUCCH; + /// Parameter: \f$P_\text{SRS\_OFFSET}\f$, see TS 36.213 (5.1.3.1). \vr{[0..15]}\n For Ks=1.25 (\ref deltaMCS_Enabled), the actual parameter value is pSRS_Offset value - 3. For Ks=0, the actual parameter value is -10.5 + 1.5*pSRS_Offset value. + int8_t pSRS_Offset; + /// Specifies the filtering coefficient for RSRP measurements used to calculate path loss, as specified in TS 36.213 (5.1.1.1).\details The same filtering mechanism applies as for quantityConfig described in 5.5.3.2. \note the specification sais it is an enumerated value. + uint8_t filterCoefficient; +} UL_POWER_CONTROL_DEDICATED_NB_IoT; + +/// Union for \ref TPC_PDCCH_CONFIG::tpc_Index. +//typedef union { + /// Index of N when DCI format 3 is used. See TS 36.212 (5.3.3.1.6). \vr{[1..15]} + // uint8_t indexOfFormat3; + /// Index of M when DCI format 3A is used. See TS 36.212 (5.3.3.1.7). \vr{[1..31]} + // uint8_t indexOfFormat3A; +//} TPC_INDEX_NB_IoT_t; + +/// CQI-ReportPeriodic +typedef struct { + /// Parameter: \f$n^{(2)}_\text{PUCCH}\f$, see TS 36.213 (7.2). \vr{[0..1185]}, -1 indicates inactivity + int16_t cqi_PUCCH_ResourceIndex; + /// Parameter: CQI/PMI Periodicity and Offset Configuration Index \f$I_\text{CQI/PMI}\f$, see TS 36.213 (tables 7.2.2-1A and 7.2.2-1C). \vr{[0..1023]} + int16_t cqi_PMI_ConfigIndex; + /// Parameter: K, see 36.213 (4.2.2). \vr{[1..4]} + uint8_t K; + /// Parameter: RI Config Index \f$I_\text{RI}\f$, see TS 36.213 (7.2.2-1B). \vr{[0..1023]}, -1 indicates inactivity + int16_t ri_ConfigIndex; + /// Parameter: Simultaneous-AN-and-CQI, see TS 36.213 (10.1). \vr{[0..1]} 1 indicates that simultaneous transmission of ACK/NACK and CQI is allowed. + uint8_t simultaneousAckNackAndCQI; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t Npd; + /// parameter computed from Tables 7.2.2-1A and 7.2.2-1C + uint16_t N_OFFSET_CQI; +} CQI_REPORTPERIODIC_NB_IoT; + +/// Enumeration for parameter reporting mode \ref CQI_REPORT_CONFIG::cqi_ReportModeAperiodic. +typedef enum { + //rm12=0, + //rm20=1, + //rm22=2, + rm30_N=3, + rm31_N=4 +} CQI_REPORTMODEAPERIODIC_NB_IoT; + +/// CQI-ReportConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: reporting mode. Value rm12 corresponds to Mode 1-2, rm20 corresponds to Mode 2-0, rm22 corresponds to Mode 2-2 etc. PUSCH reporting modes are described in TS 36.213 [23, 7.2.1]. + CQI_REPORTMODEAPERIODIC_NB_IoT cqi_ReportModeAperiodic; + /// Parameter: \f$\Delta_\text{offset}\f$, see TS 36.213 (7.2.3). \vr{[-1..6]}\n Actual value = IE value * 2 [dB]. + int8_t nomPDSCH_RS_EPRE_Offset; + CQI_REPORTPERIODIC_NB_IoT CQI_ReportPeriodic; +} CQI_REPORT_CONFIG_NB_IoT; + +/// SoundingRS-UL-ConfigDedicated Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$B_\text{SRS}\f$, see TS 36.211 (table 5.5.3.2-1, 5.5.3.2-2, 5.5.3.2-3 and 5.5.3.2-4). \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_Bandwidth; + /// Parameter: SRS hopping bandwidth \f$b_\text{hop}\in\{0,1,2,3\}\f$, see TS 36.211 (5.5.3.2) \vr{[0..3]} \note the specification sais it is an enumerated value. + uint8_t srs_HoppingBandwidth; + /// Parameter: \f$n_\text{RRC}\f$, see TS 36.211 (5.5.3.2). \vr{[0..23]} + uint8_t freqDomainPosition; + /// Parameter: Duration, see TS 36.213 (8.2). \vr{[0..1]} 0 corresponds to "single" and 1 to "indefinite". + uint8_t duration; + /// Parameter: \f$k_\text{TC}\in\{0,1\}\f$, see TS 36.211 (5.5.3.2). \vr{[0..1]} + uint8_t transmissionComb; + /// Parameter: \f$I_\text{SRS}\f$, see TS 36.213 (table 8.2-1). \vr{[0..1023]} + uint16_t srs_ConfigIndex; + /// Parameter: \f$n^\text{CS}_\text{SRS}\f$. See TS 36.211 (5.5.3.1). \vr{[0..7]} \note the specification sais it is an enumerated value. + uint8_t cyclicShift; + // Parameter: internal implementation: UE SRS configured + uint8_t srsConfigDedicatedSetup; + // Parameter: cell srs subframe for internal implementation + uint8_t srsCellSubframe; + // Parameter: ue srs subframe for internal implementation + uint8_t srsUeSubframe; +} SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT; + + +/// Enumeration for parameter SR transmission \ref SCHEDULING_REQUEST_CONFIG::dsr_TransMax. +typedef enum { + //sr_n4=0, + // sr_n8=1, + // sr_n16=2, + sr_n32_N=3, + sr_n64_N=4 +} DSR_TRANSMAX_NB_IoT_t; + +/// SchedulingRequestConfig Information Element from 36.331 RRC spec +typedef struct { + /// Parameter: \f$n^{(1)}_\text{PUCCH,SRI}\f$, see TS 36.213 (10.1). \vr{[0..2047]} + uint16_t sr_PUCCH_ResourceIndex; + /// Parameter: \f$I_\text{SR}\f$, see TS 36.213 (10.1). \vr{[0..155]} + uint8_t sr_ConfigIndex; + /// Parameter for SR transmission in TS 36.321 (5.4.4). \details The value n4 corresponds to 4 transmissions, n8 corresponds to 8 transmissions and so on. + DSR_TRANSMAX_NB_IoT_t dsr_TransMax; +} SCHEDULING_REQUEST_CONFIG_NB_IoT; + +typedef struct { + /// Downlink Power offset field + uint8_t dl_pow_off; + ///Subband resource allocation field + uint8_t rballoc_sub[50]; + ///Total number of PRBs indicator + uint8_t pre_nb_available_rbs; +} MU_MIMO_mode_NB_IoT; +//////////////////////// + +typedef struct { + + /// \brief Holds the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..28*ofdm_symbol_size[ + int32_t **rxdataF; + + /// \brief Hold the channel estimates in frequency domain. + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_ch_estimates[7]; + + /// \brief Hold the channel estimates in time domain (used for tracking). + /// - first index: eNB id [0..6] (hard coded) + /// - second index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - third index: samples? [0..2*ofdm_symbol_size[ + int32_t **dl_ch_estimates_time[7]; +}NB_IoT_UE_COMMON_PER_THREAD; + +typedef struct { + /// \brief Holds the transmit data in time domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->tx_vars[a].TX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES[ + int32_t **txdata; + /// \brief Holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX[ + int32_t **txdataF; + + /// \brief Holds the received data in time domain. + /// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[ + int32_t **rxdata; + + NB_IoT_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[2]; + + /// holds output of the sync correlator + int32_t *sync_corr; + /// estimated frequency offset (in radians) for all subcarriers + int32_t freq_offset; + /// eNb_id user is synched to + int32_t eNb_id; +} NB_IoT_UE_COMMON; + +typedef struct { + /// \brief Received frequency-domain signal after extraction. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_ext; + /// \brief Received frequency-domain ue specific pilots. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..12*N_RB_DL[ + int32_t **rxdataF_uespec_pilots; + /// \brief Received frequency-domain signal after extraction and channel compensation. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp0; + /// \brief Received frequency-domain signal after extraction and channel compensation for the second stream. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **rxdataF_comp1[8][8]; + /// \brief Downlink channel estimates extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. For the SIC receiver we need to store the history of this for each harq process and round + /// - first index: ? [0..7] (hard coded) accessed via \c harq_pid + /// - second index: ? [0..7] (hard coded) accessed via \c round + /// - third index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - fourth index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho_ext[8][8]; + /// \brief Downlink beamforming channel estimates in frequency domain. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[ + int32_t **dl_bf_ch_estimates; + /// \brief Downlink beamforming channel estimates. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_bf_ch_estimates_ext; + /// \brief Downlink cross-correlation of MIMO channel estimates (unquantized PMI) extracted in PRBS. + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_rho2_ext; + /// \brief Downlink PMIs extracted in PRBS and grouped in subbands. + /// - first index: ressource block [0..N_RB_DL[ + uint8_t *pmi_ext; + /// \brief Magnitude of Downlink Channel first layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag0; + /// \brief Magnitude of Downlink Channel second layer (16QAM level/First 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_mag1[8][8]; + /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb0; + /// \brief Magnitude of Downlink Channel second layer (2nd 64QAM level). + /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx + /// - second index: ? [0..168*N_RB_DL[ + int32_t **dl_ch_magb1[8][8]; + /// \brief Cross-correlation of two eNB signals. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: symbol [0..] + int32_t **rho; + /// never used... always send dl_ch_rho_ext instead... + int32_t **rho_i; + /// \brief Pointers to llr vectors (2 TBs). + /// - first index: ? [0..1] (hard coded) + /// - second index: ? [0..1179743] (hard coded) + int16_t *llr[2]; + /// \f$\log_2(\max|H_i|^2)\f$ + int16_t log2_maxh; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation + int16_t log2_maxh0; + /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation + int16_t log2_maxh1; + /// \brief LLR shifts for subband scaling. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts; + /// \brief Pointer to LLR shifts. + /// - first index: ? [0..168*N_RB_DL[ + uint8_t *llr_shifts_p; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128; + /// \brief Pointers to llr vectors (128-bit alignment). + /// - first index: ? [0..0] (hard coded) + /// - second index: ? [0..] + int16_t **llr128_2ndstream; + //uint32_t *rb_alloc; + //uint8_t Qm[2]; + //MIMO_mode_t mimo_mode; +} NB_IoT_UE_PDSCH; + +/// NPRACH-ParametersList-NB-r13 from 36.331 RRC spec +typedef struct NPRACH_Parameters_NB_IoT{ + /// the period time for nprach + uint16_t nprach_Periodicity; + /// for the start time for the NPRACH resource from 40ms-2560ms + uint16_t nprach_StartTime; + /// for the subcarrier of set to the NPRACH preamble from n0 - n34 + uint16_t nprach_SubcarrierOffset; + ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) + uint16_t nprach_NumSubcarriers; + /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 + uint16_t nprach_SubcarrierMSG3_RangeStart; + /// The max preamble transmission attempt for the CE level from 1 - 128 + uint16_t maxNumPreambleAttemptCE; + /// Number of NPRACH repetitions per attempt for each NPRACH resource + uint16_t numRepetitionsPerPreambleAttempt; + /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) + uint16_t npdcch_NumRepetitions_RA; + /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) + uint16_t npdcch_StartSF_CSS_RA; + /// Fractional period offset of starting subframe for NPDCCH common search space + uint16_t npdcch_Offset_RA; +} nprach_parameters_NB_IoT_t; + +typedef struct{ + nprach_parameters_NB_IoT_t list[3]; +}NPRACH_List_NB_IoT_t; + +typedef long RSRP_Range_t; + +typedef struct { + A_SEQUENCE_OF(RSRP_Range_t) list; +}rsrp_ThresholdsNPrachInfoList; + + +/// NPRACH_ConfigSIB-NB from 36.331 RRC spec +typedef struct { + /// nprach_CP_Length_r13, for the CP length(unit us) only 66.7 and 266.7 is implemented + uint16_t nprach_CP_Length; + /// The criterion for UEs to select a NPRACH resource. Up to 2 RSRP threshold values can be signalled. \vr{[1..2]} + struct rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList; + /// NPRACH Parameters List + NPRACH_List_NB_IoT_t nprach_ParametersList; + +} NPRACH_CONFIG_COMMON; + +/// NPDSCH-ConfigCommon from 36.331 RRC spec +typedef struct { + ///see TS 36.213 (16.2). \vr{[-60..50]}\n Provides the downlink reference-signal EPRE. The actual value in dBm. + uint16_t nrs_Power; +} NPDSCH_CONFIG_COMMON; + +typedef struct{ + /// The base sequence of DMRS sequence in a cell for 3 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 12. Value 12 is not used. + uint16_t threeTone_BaseSequence; + /// Define 3 cyclic shifts for the 3-tone case, see TS 36.211 [21, 10.1.4.1.2]. + uint16_t threeTone_CyclicShift; + /// The base sequence of DMRS sequence in a cell for 6 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 14. Value 14 is not used. + uint16_t sixTone_BaseSequence; + /// Define 4 cyclic shifts for the 6-tone case, see TS 36.211 [21, 10.1.4.1.2]. + uint16_t sixTone_CyclicShift; + /// The base sequence of DMRS sequence in a cell for 12 tones transmission; see TS 36.211 [21, 10.1.4.1.2]. If absent, it is given by NB-IoT CellID mod 30. Value 30 is not used. + uint16_t twelveTone_BaseSequence; + +}DMRS_CONFIG_t; + +/// UL-ReferenceSignalsNPUSCH from 36.331 RRC spec +typedef struct { + /// Parameter: Group-hopping-enabled, see TS 36.211 (5.5.1.3). \vr{[0..1]} + uint8_t groupHoppingEnabled; + /// , see TS 36.211 (5.5.1.3). \vr{[0..29]} + uint8_t groupAssignmentNPUSCH; + /// Parameter: cyclicShift, see TS 36.211 (Table 5.5.2.1.1-2). \vr{[0..7]} + uint8_t cyclicShift; + /// nPRS for cyclic shift of DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t nPRS[20]; + /// group hopping sequence for DMRS, 36.211, Section 10.1.4.1.3. Second index corresponds to the four possible subcarrier configurations + uint8_t grouphop[20][4]; + /// sequence hopping sequence for DRS \note not part of offical UL-ReferenceSignalsPUSCH ASN1 specification. + uint8_t seqhop[20]; +} UL_REFERENCE_SIGNALS_NPUSCH_t; + + +/// PUSCH-ConfigCommon from 36.331 RRC spec. +typedef struct { + /// Number of repetitions for ACK/NACK HARQ response to NPDSCH containing Msg4 per NPRACH resource, see TS 36.213 [23, 16.4.2]. + uint8_t ack_NACK_NumRepetitions_Msg4[3]; + /// SRS SubframeConfiguration. See TS 36.211 [21, table 5.5.3.3-1]. Value sc0 corresponds to value 0, sc1 to value 1 and so on. + uint8_t srs_SubframeConfig; + /// Parameter: \f$N^{HO}_{RB}\f$, see TS 36.211 (5.3.4). \vr{[0..98]} + DMRS_CONFIG_t dmrs_Config; + /// Ref signals configuration + UL_REFERENCE_SIGNALS_NPUSCH_t ul_ReferenceSignalsNPUSCH; + +} NPUSCH_CONFIG_COMMON; + + +typedef struct{ + /// See TS 36.213 [23, 16.2.1.1], unit dBm. + uint8_t p0_NominalNPUSCH; + /// See TS 36.213 [23, 16.2.1.1] where al0 corresponds to 0, al04 corresponds to value 0.4, al05 to 0.5, al06 to 0.6, al07 to 0.7, al08 to 0.8, al09 to 0.9 and al1 corresponds to 1. + uint8_t alpha; + /// See TS 36.213 [23, 16.2.1.1]. Actual value = IE value * 2 [dB]. + uint8_t deltaPreambleMsg3; +}UplinkPowerControlCommon_NB_IoT; + + +/* DL-GapConfig-NB-r13 */ +typedef struct { + uint16_t dl_GapThreshold; + uint16_t dl_GapPeriodicity; + uint16_t dl_GapDurationCoeff; +} DL_GapConfig_NB_IoT; + +#define NBIOT_INBAND_LTEPCI 0 +#define NBIOT_INBAND_IOTPCI 1 +#define NBIOT_INGUARD 2 +#define NBIOT_STANDALONE 3 + + +typedef struct { + /// for inband, lte bandwidth + uint8_t LTE_N_RB_DL; + uint8_t LTE_N_RB_UL; + /// Cell ID + uint16_t Nid_cell; + /// shift of pilot position in one RB + uint8_t nushift; + /// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0). + uint8_t node_id; + /// Frequency index of CBMIMO1 card + uint8_t freq_idx; + /// RX Frequency for ExpressMIMO/LIME + uint32_t carrier_freq[4]; + /// TX Frequency for ExpressMIMO/LIME + uint32_t carrier_freqtx[4]; + /// RX gain for ExpressMIMO/LIME + uint32_t rxgain[4]; + /// TX gain for ExpressMIMO/LIME + uint32_t txgain[4]; + /// RF mode for ExpressMIMO/LIME + uint32_t rfmode[4]; + /// RF RX DC Calibration for ExpressMIMO/LIME + uint32_t rxdc[4]; + /// RF TX DC Calibration for ExpressMIMO/LIME + uint32_t rflocal[4]; + /// RF VCO calibration for ExpressMIMO/LIME + uint32_t rfvcolocal[4]; + /// Turns on second TX of CBMIMO1 card + uint8_t dual_tx; + /// flag to indicate SISO transmission + uint8_t mode1_flag; + /// Indicator that 20 MHz channel uses 3/4 sampling frequency + //uint8_t threequarter_fs; + /// Size of FFT + uint16_t ofdm_symbol_size; + /// Number of prefix samples in all but first symbol of slot + uint16_t nb_prefix_samples; + /// Number of prefix samples in first symbol of slot + uint16_t nb_prefix_samples0; + /// Carrier offset in FFT buffer for first RE in PRB0 + uint16_t first_carrier_offset; + /// Number of samples in a subframe + uint32_t samples_per_tti; + /// Number of OFDM/SC-FDMA symbols in one subframe (to be modified to account for potential different in UL/DL) + uint16_t symbols_per_tti; + /// Number of Physical transmit antennas in node + uint8_t nb_antennas_tx; + /// Number of Receive antennas in node + uint8_t nb_antennas_rx; + /// Number of common transmit antenna ports in eNodeB (1 or 2) + uint8_t nb_antenna_ports_eNB; + /// Number of common receiving antenna ports in eNodeB (1 or 2) + uint8_t nb_antenna_ports_rx_eNB; + /// NPRACH Config Common (from 36-331 RRC spec) + NPRACH_CONFIG_COMMON nprach_config_common; + /// NPDSCH Config Common (from 36-331 RRC spec) + NPDSCH_CONFIG_COMMON npdsch_config_common; + /// PUSCH Config Common (from 36-331 RRC spec) + NPUSCH_CONFIG_COMMON npusch_config_common; + /// UL Power Control (from 36-331 RRC spec) + UplinkPowerControlCommon_NB_IoT ul_power_control_config_common; + /// DL Gap + DL_GapConfig_NB_IoT DL_gap_config; + /// Size of SI windows used for repetition of one SI message (in frames) + uint8_t SIwindowsize; + /// Period of SI windows used for repetition of one SI message (in frames) + uint16_t SIPeriod; + int eutra_band; + uint32_t dl_CarrierFreq; + uint32_t ul_CarrierFreq; + // CE level to determine the NPRACH Configuration (one CE for each NPRACH config.) + uint8_t CE; + + /* + * index of the PRB assigned to NB-IoT carrier in in-band/guard-band operating mode + */ + unsigned short NB_IoT_RB_ID; + + + /*Following FAPI approach: + * 0 = in-band with same PCI + * 1 = in-band with diff PCI + * 2 = guard band + * 3 =stand alone + */ + uint16_t operating_mode; + /* + * Only for In-band operating mode with same PCI + * its measured in number of OFDM symbols + * allowed values: + * 1, 2, 3, 4(this value is written in FAPI specs but not exist in TS 36.331 v14.2.1 pag 587) + * -1 (we put this value when is not defined - other operating mode) + */ + uint16_t control_region_size; + + /*Number of EUTRA CRS antenna ports (AP) + * valid only for in-band different PCI mode + * value 0 = indicates the same number of AP as NRS APs + * value 1 = four CRS APs + */ + uint16_t eutra_NumCRS_ports; + + /* Subcarrier bandwidth + 0 -> 3.75 kHz + 1 -> 15 kHz + */ + uint8_t subcarrier_spacing; + +} NB_IoT_DL_FRAME_PARMS; + +typedef struct { + /// \brief Pointers (dynamic) to the received data in the time domain. + /// - first index: rx antenna [0..nb_antennas_rx] + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti] + int32_t **rxdata; + /// \brief Pointers (dynamic) to the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti] + int32_t **rxdataF; + /// \brief holds the transmit data in the frequency domain. + /// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //? + /// - first index: eNB id [0..2] (hard coded) + /// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports. + /// - third index: sample [0..] + int32_t **txdataF; +} NB_IoT_eNB_COMMON; + +typedef struct { + /// \brief Holds the transmit data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **txdata; + /// \brief Holds the receive data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdata[3]; + /// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: sample [0..samples_per_tti[ + int32_t **rxdata_7_5kHz[3]; + /// \brief Holds the received data in the frequency domain. + /// - first index: rx antenna [0..nb_antennas_rx[ + /// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[ + int32_t **rxdataF[3]; + /// \brief Holds output of the sync correlator. + /// - first index: sample [0..samples_per_tti*10[ + uint32_t *sync_corr[3]; +} NB_IoT_RU_COMMON; + +typedef struct { + /// \brief Hold the channel estimates in frequency domain based on SRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..ofdm_symbol_size[ + int32_t **srs_ch_estimates[3]; + /// \brief Hold the channel estimates in time domain based on SRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..2*ofdm_symbol_size[ + int32_t **srs_ch_estimates_time[3]; + /// \brief Holds the SRS for channel estimation at the RX. + /// - first index: ? [0..ofdm_symbol_size[ + int32_t *srs; +} NB_IoT_eNB_SRS; + +typedef struct { + /// \brief Holds the received data in the frequency domain for the allocated RBs in repeated format. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..2*ofdm_symbol_size[ + /// - third index (definition from phy_init_lte_eNB()): ? [0..24*N_RB_UL*frame_parms->symbols_per_tti[ + /// \warning inconsistent third index definition + int32_t **rxdataF_ext[3]; + /// \brief Holds the received data in the frequency domain for the allocated RBs in normal format. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index (definition from phy_init_lte_eNB()): ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_ext2[3]; + /// \brief Hold the channel estimates in time domain based on DRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..4*ofdm_symbol_size[ + int32_t **drs_ch_estimates_time[3]; + /// \brief Hold the channel estimates in frequency domain based on DRS. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates[3]; + /// \brief Hold the channel estimates for UE0 in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates_0[3]; + /// \brief Hold the channel estimates for UE1 in case of Distributed Almouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **drs_ch_estimates_1[3]; + /// \brief Holds the compensated signal. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp[3]; + /// \brief Hold the compensated data (y)*(h0*) in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp_0[3]; + /// \brief Hold the compensated data (y*)*(h1) in case of Distributed Alamouti Scheme. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **rxdataF_comp_1[3]; + /// \brief ?. + /// - first index: sector id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag[3]; + /// \brief ?. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb[3]; + /// \brief Hold the channel mag for UE0 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag_0[3]; + /// \brief Hold the channel magb for UE0 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb_0[3]; + /// \brief Hold the channel mag for UE1 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_mag_1[3]; + /// \brief Hold the channel magb for UE1 in case of Distributed Alamouti Scheme. + /// - first index: eNB id [0..2] (hard coded) + /// - second index: rx antenna id [0..nb_antennas_rx[ + /// - third index: ? [0..12*N_RB_UL*frame_parms->symbols_per_tti[ + int32_t **ul_ch_magb_1[3]; + /// measured RX power based on DRS + int ulsch_power[2]; + /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme + int ulsch_power_0[2]; + /// measured RX power based on DRS for UE0 in case of Distributed Alamouti Scheme + int ulsch_power_1[2]; + /// \brief llr values. + /// - first index: ? [0..1179743] (hard coded) + int16_t *llr; +#ifdef LOCALIZATION + /// number of active subcarrier for a specific UE + int32_t active_subcarrier; + /// subcarrier power in dBm + int32_t *subcarrier_power; +#endif +} NB_IoT_eNB_PUSCH; + +#define PBCH_A_NB_IoT 24 +typedef struct { + uint8_t pbch_d[96+(3*(16+PBCH_A_NB_IoT))]; + uint8_t pbch_w[3*3*(16+PBCH_A_NB_IoT)]; + uint8_t pbch_e[1920]; +} NB_IoT_eNB_PBCH; + + +typedef enum { + /// TM1 + SISO_NB_IoT=0, + /// TM2 + ALAMOUTI_NB_IoT=1, + /// TM3 + LARGE_CDD_NB_IoT=2, + /// the next 6 entries are for TM5 + UNIFORM_PRECODING11_NB_IoT=3, + UNIFORM_PRECODING1m1_NB_IoT=4, + UNIFORM_PRECODING1j_NB_IoT=5, + UNIFORM_PRECODING1mj_NB_IoT=6, + PUSCH_PRECODING0_NB_IoT=7, + PUSCH_PRECODING1_NB_IoT=8, + /// the next 3 entries are for TM4 + DUALSTREAM_UNIFORM_PRECODING1_NB_IoT=9, + DUALSTREAM_UNIFORM_PRECODINGj_NB_IoT=10, + DUALSTREAM_PUSCH_PRECODING_NB_IoT=11, + TM7_NB_IoT=12, + TM8_NB_IoT=13, + TM9_10_NB_IoT=14 +} MIMO_mode_NB_IoT_t; + +typedef struct { + /// \brief ?. + /// first index: ? [0..1023] (hard coded) + int16_t *prachF; + /// \brief ?. + /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// second index: ? [0..ofdm_symbol_size*12[ + int16_t *rxsigF[64]; + /// \brief local buffer to compute prach_ifft (necessary in case of multiple CCs) + /// first index: rx antenna [0..63] (hard coded) \note Hard coded array size indexed by \c nb_antennas_rx. + /// second index: ? [0..2047] (hard coded) + int16_t *prach_ifft[64]; +} NB_IoT_eNB_PRACH; + +typedef enum { + NOT_SYNCHED_NB_IoT=0, + PRACH_NB_IoT=1, + RA_RESPONSE_NB_IoT=2, + PUSCH_NB_IoT=3, + RESYNCH_NB_IoT=4 +} UE_MODE_NB_IoT_t; + + +#endif diff --git a/openair1/PHY/impl_defs_top_NB_IoT.h b/openair1/PHY/impl_defs_top_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..f7e0c7ff7fceff153f24d5e82e39eb4aeca3d1f8 --- /dev/null +++ b/openair1/PHY/impl_defs_top_NB_IoT.h @@ -0,0 +1,541 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file PHY/impl_defs_top.h +* \brief More defines and structure definitions +* \author R. Knopp, F. Kaltenberger +* \date 2011 +* \version 0.1 +* \company Eurecom +* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr +* \note +* \warning +*/ + +#ifndef __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ +#define __PHY_IMPLEMENTATION_DEFS_NB_IOT_H__ + + +#include "openairinterface5g_limits.h" +/** @defgroup _ref_implementation_ OpenAirInterface LTE Implementation + * @{ + + * @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 + * @defgroup _LMSSDR_PHY_RF_INTERFACE_ PHY - LMSSDR RF Interface + * @} + * + * @ingroup _ref_implementation_ + * @{ + * This module is responsible for defining the generic interface between PHY and RF Target + * @} + + * @defgroup _openair1_ openair1 Reference Implementation + * @ingroup _ref_implementation_ + * @{ + + + * @defgroup _physical_layer_ref_implementation_ Physical Layer Reference Implementation + * @ingroup _openair1_ + * @{ + + + * @defgroup _PHY_STRUCTURES_ Basic Structures and Memory Initialization + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and initializing the PHY variables during static configuration of OpenAirInterface. + * @} + + * @defgroup _PHY_DSP_TOOLS_ DSP Tools + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for basic signal processing related to inner-MODEM processing. + * @} + + * @defgroup _PHY_MODULATION_ Modulation and Demodulation + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to OFDMA modulation and demodulation. + * @} + + * @defgroup _PHY_PARAMETER_ESTIMATION_BLOCKS_ Parameter Estimation + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to OFDMA frequency-domain channel estimation for LTE Downlink Channels. + * @} + + * @defgroup _PHY_CODING_BLOCKS_ Channel Coding/Decoding Functions + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for procedures related to channel coding/decoding, rate-matching, segementation and interleaving. + * @} + + * @defgroup _PHY_TRANSPORT_ Transport/Physical Channel Processing + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels. + * @} + + * @defgroup _PHY_PROCEDURES_ Physical Layer Procedures + * @ingroup _physical_layer_ref_implementation_ + * @{ + * This module is responsible for defining and processing the PHY procedures (TX/RX) related to transport and physical channels. + * @} + + * @} + * @} + * @} + */ + +//#include "types.h" + +/* + + +#define NUMBER_OF_OFDM_CARRIERS (frame_parms->ofdm_symbol_size) +#define NUMBER_OF_SYMBOLS_PER_FRAME (frame_parms->symbols_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) +#define NUMBER_OF_USEFUL_CARRIERS (12*frame_parms->N_RB_DL) +#define NUMBER_OF_ZERO_CARRIERS (NUMBER_OF_OFDM_CARRIERS-NUMBER_OF_USEFUL_CARRIERS) +#define NUMBER_OF_USEFUL_CARRIERS_BYTES (NUMBER_OF_USEFUL_CARRIERS>>2) +#define HALF_NUMBER_OF_USEFUL_CARRIERS (NUMBER_OF_USEFUL_CARRIERS>>1) +#define HALF_NUMBER_OF_USEFUL_CARRIERS_BYTES (HALF_NUMBER_OF_USEFUL_CARRIERS>>2) +#define FIRST_CARRIER_OFFSET (HALF_NUMBER_OF_USEFUL_CARRIERS+NUMBER_OF_ZERO_CARRIERS) +#define NUMBER_OF_OFDM_SYMBOLS_PER_SLOT (NUMBER_OF_SYMBOLS_PER_FRAME/LTE_SLOTS_PER_FRAME) + +#ifdef EMOS +#define EMOS_SCH_INDEX 1 +#endif //EMOS + +#define EXTENSION_TYPE (PHY_config->PHY_framing.Extension_type) + +#define NUMBER_OF_OFDM_CARRIERS_BYTES NUMBER_OF_OFDM_CARRIERS*4 +//#define NUMBER_OF_USEFUL_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS*4 +#define HALF_NUMBER_OF_USER_CARRIERS_BYTES NUMBER_OF_USEFUL_CARRIERS/2 + +#define CYCLIC_PREFIX_LENGTH (frame_parms->nb_prefix_samples) +#define CYCLIC_PREFIX_LENGTH_SAMPLES (CYCLIC_PREFIX_LENGTH*2) +#define CYCLIC_PREFIX_LENGTH_BYTES (CYCLIC_PREFIX_LENGTH*4) +#define CYCLIC_PREFIX_LENGTH0 (frame_parms->nb_prefix_samples0) +#define CYCLIC_PREFIX_LENGTH_SAMPLES0 (CYCLIC_PREFIX_LENGTH0*2) +#define CYCLIC_PREFIX_LENGTH_BYTES0 (CYCLIC_PREFIX_LENGTH0*4) + +#define OFDM_SYMBOL_SIZE_SAMPLES ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH)*2) // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_SAMPLES0 ((NUMBER_OF_OFDM_CARRIERS + CYCLIC_PREFIX_LENGTH0)*2) // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_SAMPLES_MAX 4096 // 16-bit units (i.e. real samples) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES (OFDM_SYMBOL_SIZE_SAMPLES/2) // 32-bit units (i.e. complex samples) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0 (OFDM_SYMBOL_SIZE_SAMPLES0/2) // 32-bit units (i.e. complex samples) +#define OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX ((NUMBER_OF_OFDM_CARRIERS)*2) +#define OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX/2) +#define OFDM_SYMBOL_SIZE_BYTES (OFDM_SYMBOL_SIZE_SAMPLES*2) +#define OFDM_SYMBOL_SIZE_BYTES0 (OFDM_SYMBOL_SIZE_SAMPLES0*2) +#define OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX*2) + +#define SLOT_LENGTH_BYTES (frame_parms->samples_per_tti<<1) // 4 bytes * samples_per_tti/2 +#define SLOT_LENGTH_BYTES_NO_PREFIX (OFDM_SYMBOL_SIZE_BYTES_NO_PREFIX * NUMBER_OF_OFDM_SYMBOLS_PER_SLOT) + +#define FRAME_LENGTH_COMPLEX_SAMPLES (frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME) +#define FRAME_LENGTH_SAMPLES (FRAME_LENGTH_COMPLEX_SAMPLES*2) +#define FRAME_LENGTH_SAMPLES_NO_PREFIX (NUMBER_OF_SYMBOLS_PER_FRAME*OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX) +#define FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX (FRAME_LENGTH_SAMPLES_NO_PREFIX/2) + +#define NUMBER_OF_CARRIERS_PER_GROUP (NUMBER_OF_USEFUL_CARRIERS/NUMBER_OF_FREQUENCY_GROUPS) + +#define RX_PRECISION (16) +#define LOG2_RX_PRECISION (4) +#define RX_OUTPUT_SHIFT (4) + + +#define SAMPLE_SIZE_BYTES 2 // 2 bytes/real sample + +#define FRAME_LENGTH_BYTES (FRAME_LENGTH_SAMPLES * SAMPLE_SIZE_BYTES) // frame size in bytes +#define FRAME_LENGTH_BYTES_NO_PREFIX (FRAME_LENGTH_SAMPLES_NO_PREFIX * SAMPLE_SIZE_BYTES) // frame size in bytes + + +#define FFT_SCALE_FACTOR 8 // Internal Scaling for FFT +#define DMA_BLKS_PER_SLOT (SLOT_LENGTH_BYTES/2048) // Number of DMA blocks per slot +#define SLOT_TIME_NS (SLOT_LENGTH_SAMPLES*(1e3)/7.68) // slot time in ns + +#define NB_ANTENNA_PORTS_ENB 6 // total number of eNB antenna ports + +#ifdef EXMIMO +#define TARGET_RX_POWER 55 // Target digital power for the AGC +#define TARGET_RX_POWER_MAX 55 // Maximum digital power, such that signal does not saturate (value found by simulation) +#define TARGET_RX_POWER_MIN 50 // Minimum digital power, anything below will be discarded (value found by simulation) +#else +#define TARGET_RX_POWER 50 // Target digital power for the AGC +#define TARGET_RX_POWER_MAX 65 // Maximum digital power, such that signal does not saturate (value found by simulation) +#define TARGET_RX_POWER_MIN 35 // Minimum digital power, anything below will be discarded (value found by simulation) +#endif + +//the min and max gains have to match the calibrated gain table +//#define MAX_RF_GAIN 160 +//#define MIN_RF_GAIN 96 +#define MAX_RF_GAIN 200 +#define MIN_RF_GAIN 80 + +#define PHY_SYNCH_OFFSET ((OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)-1) // OFFSET of BEACON SYNCH +#define PHY_SYNCH_MIN_POWER 1000 +#define PHY_SYNCH_THRESHOLD 100 + +*/ + +#define ONE_OVER_SQRT2_Q15_NB_IoT 23170 + +/* +#define ONE_OVER_2_Q15 16384 + +// QAM amplitude definitions + +/// First Amplitude for QAM16 (\f$ 2^{15} \times 2/\sqrt{10}\f$) +#define QAM16_n1 20724 +/// Second Amplitude for QAM16 (\f$ 2^{15} \times 1/\sqrt{10}\f$) +#define QAM16_n2 10362 + +///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{42}\f$) +#define QAM64_n1 20225 +///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{42}\f$) +#define QAM64_n2 10112 +///Third Amplitude for QAM64 (\f$ 2^{15} \times 1/\sqrt{42}\f$) +#define QAM64_n3 5056 + +/// First Amplitude for QAM16 for TM5 (\f$ 2^{15} \times 2/sqrt(20)\f$) +#define QAM16_TM5_n1 14654 +/// Second Amplitude for QAM16 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{20}\f$) +#define QAM16_TM5_n2 7327 + +///First Amplitude for QAM64 (\f$ 2^{15} \times 4/\sqrt{84}\f$) +#define QAM64_TM5_n1 14301 +///Second Amplitude for QAM64 (\f$ 2^{15} \times 2/\sqrt{84}\f$) +#define QAM64_TM5_n2 7150 +///Third Amplitude for QAM64 for TM5 Receiver (\f$ 2^{15} \times 1/\sqrt{84}\f$) +#define QAM64_TM5_n3 3575 + + +#ifdef BIT8_RXMUX +#define PERROR_SHIFT 0 +#else +#define PERROR_SHIFT 10 +#endif + +#define BIT8_TX_SHIFT 2 +#define BIT8_TX_SHIFT_DB 12 + +//#define CHBCH_RSSI_MIN -75 + +#ifdef BIT8_TX +#define AMP 128 +#else +#define AMP 512//1024 //4096 +#endif + +#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15) +#define AMP_OVER_2 (AMP>>1) + +/// Threshold for PUCCH Format 1 detection +#define PUCCH1_THRES 0 +/// Threshold for PUCCH Format 1a/1b detection +#define PUCCH1a_THRES 4 + +/// Data structure for transmission. +typedef struct { + /// RAW TX sample buffer + char *TX_DMA_BUFFER[2]; +} TX_VARS ; + +/// Data structure for reception. +typedef struct { + /// RAW TX sample buffer + char *TX_DMA_BUFFER[2]; + /// RAW RX sample buffer + int *RX_DMA_BUFFER[2]; +} TX_RX_VARS; + +//! \brief Extension Type / +typedef enum { + CYCLIC_PREFIX, + CYCLIC_SUFFIX, + ZEROS, + NONE +} Extension_t; + +/// Measurement Variables +*/ +#define NUMBER_OF_SUBBANDS_MAX_NB_IoT 13 +/* +#define NUMBER_OF_HARQ_PID_MAX 8 + +#define MAX_FRAME_NUMBER 0x400 +#include "openairinterface5g_limits.h" + +#define NUMBER_OF_RN_MAX 3 +typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t; + +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // RRC measurements + uint32_t rssi; + int n_adj_cells; + unsigned int adj_cell_id[6]; + uint32_t rsrq[7]; + uint32_t rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! total estimated noise power (dB) + unsigned short n0_power_tot_dB; + //! average estimated noise power (linear) + unsigned int n0_power_avg; + //! average estimated noise power (dB) + unsigned short n0_power_avg_dB; + //! total estimated noise power (dBm) + short n0_power_tot_dBm; + + // UE measurements + //! estimated received spatial signal power (linear) + int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + + /// estimated received signal power (sum over all TX/RX antennas) + int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + /// estimated received signal power (sum over all TX/RX antennas) + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + + //! estimated received signal power (sum of all TX/RX antennas, time average) + int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SINR (sum of all TX/RX antennas, in dB) + int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + /// SINR (sum of all TX/RX antennas, time average, in dB) + int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + + /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) + int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + /// Subband CQI per RX antenna (= SINR) + int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI (= SINR) + int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Subband CQI in dB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX]; + /// Total Subband CQI + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX][NB_ANTENNAS_RX]; + /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX]; + /// Wideband Rank indication + unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Number of RX Antennas + unsigned char nb_antennas_rx; + /// DLSCH error counter + // short dlsch_errors; + +} PHY_MEASUREMENTS; +*/ +typedef enum {no_relay_NB_IoT=1,unicast_relay_type1_NB_IoT,unicast_relay_type2_NB_IoT, multicast_relay_NB_IoT} relaying_type_t_NB_IoT; +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // RRC measurements + uint32_t rssi; + int n_adj_cells; + unsigned int adj_cell_id[6]; + uint32_t rsrq[7]; + uint32_t rsrp[7]; + float rsrp_filtered[7]; // after layer 3 filtering + float rsrq_filtered[7]; + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! total estimated noise power (dB) + unsigned short n0_power_tot_dB; + //! average estimated noise power (linear) + unsigned int n0_power_avg; + //! average estimated noise power (dB) + unsigned short n0_power_avg_dB; + //! total estimated noise power (dBm) + short n0_power_tot_dBm; + + // UE measurements + //! estimated received spatial signal power (linear) + int rx_spatial_power[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][2][2]; + + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// estimated received signal power (sum over all TX antennas) + //int wideband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + + /// estimated received signal power (sum over all TX/RX antennas) + int rx_power_tot[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + /// estimated received signal power (sum over all TX/RX antennas) + unsigned short rx_power_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //NEW + + //! estimated received signal power (sum of all TX/RX antennas, time average) + int rx_power_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated received signal power (sum of all TX/RX antennas, time average, in dB) + unsigned short rx_power_avg_dB[NUMBER_OF_CONNECTED_eNB_MAX]; + + /// SINR (sum of all TX/RX antennas, in dB) + int wideband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX]; + /// SINR (sum of all TX/RX antennas, time average, in dB) + int wideband_cqi_avg[NUMBER_OF_CONNECTED_eNB_MAX]; + + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_CONNECTED_eNB_MAX]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_CONNECTED_eNB_MAX][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_CONNECTED_eNB_MAX][2]; + + /// Wideband CQI (sum of all RX antennas, in dB, for precoded transmission modes (3,4,5,6), up to 4 spatial streams) + int precoded_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX+1][4]; + /// Subband CQI per RX antenna (= SINR) + int subband_cqi[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Total Subband CQI (= SINR) + int subband_cqi_tot[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Subband CQI in dB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Total Subband CQI + int subband_cqi_tot_dB[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Wideband PMI for each RX antenna + int wideband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + /// Wideband PMI for each RX antenna + int wideband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_re[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX]; + ///Subband PMI for each RX antenna + int subband_pmi_im[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// chosen RX antennas (1=Rx antenna 1, 2=Rx antenna 2, 3=both Rx antennas) + unsigned char selected_rx_antennas[NUMBER_OF_CONNECTED_eNB_MAX][NUMBER_OF_SUBBANDS_MAX_NB_IoT]; + /// Wideband Rank indication + unsigned char rank[NUMBER_OF_CONNECTED_eNB_MAX]; + /// Number of RX Antennas + unsigned char nb_antennas_rx; + /// DLSCH error counter + // short dlsch_errors; + +} PHY_MEASUREMENTS_NB_IoT; + + +typedef struct { + //unsigned int rx_power[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (linear) + //unsigned short rx_power_dB[NUMBER_OF_CONNECTED_eNB_MAX][NB_ANTENNAS_RX]; //! estimated received signal power (dB) + //unsigned short rx_avg_power_dB[NUMBER_OF_CONNECTED_eNB_MAX]; //! estimated avg received signal power (dB) + + // common measurements + //! estimated noise power (linear) + unsigned int n0_power[NB_ANTENNAS_RX]; + //! estimated noise power (dB) + unsigned short n0_power_dB[NB_ANTENNAS_RX]; + //! total estimated noise power (linear) + unsigned int n0_power_tot; + //! estimated avg noise power (dB) + unsigned short n0_power_tot_dB; + //! estimated avg noise power (dB) + short n0_power_tot_dBm; + //! estimated avg noise power per RB per RX ant (lin) + unsigned short n0_subband_power[NB_ANTENNAS_RX][100]; + //! estimated avg noise power per RB per RX ant (dB) + unsigned short n0_subband_power_dB[NB_ANTENNAS_RX][100]; + //! estimated avg noise power per RB (dB) + short n0_subband_power_tot_dB[100]; + //! estimated avg noise power per RB (dBm) + short n0_subband_power_tot_dBm[100]; + // eNB measurements (per user) + //! estimated received spatial signal power (linear) + unsigned int rx_spatial_power[NUMBER_OF_UE_MAX_NB_IoT][2][2]; + //! estimated received spatial signal power (dB) + unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX_NB_IoT][2][2]; + //! estimated rssi (dBm) + short rx_rssi_dBm[NUMBER_OF_UE_MAX_NB_IoT]; + //! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation) + int rx_correlation[NUMBER_OF_UE_MAX_NB_IoT][2]; + //! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation) + int rx_correlation_dB[NUMBER_OF_UE_MAX_NB_IoT][2]; + + /// Wideband CQI (= SINR) + int wideband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// Wideband CQI in dB (= SINR dB) + int wideband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX]; + /// Wideband CQI (sum of all RX antennas, in dB) + char wideband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT]; + /// Subband CQI per RX antenna and RB (= SINR) + int subband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100]; + /// Total Subband CQI and RB (= SINR) + int subband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT][100]; + /// Subband CQI in dB and RB (= SINR dB) + int subband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100]; + /// Total Subband CQI and RB + int subband_cqi_tot_dB[NUMBER_OF_UE_MAX_NB_IoT][100]; + +} PHY_MEASUREMENTS_eNB_NB_IoT; +/* +#define MCS_COUNT 28 +#define MCS_TABLE_LENGTH_MAX 64 +*/ +#endif //__PHY_IMPLEMENTATION_DEFS_H__ +/**@} +*/ diff --git a/openair1/PHY/types_NB_IoT.h b/openair1/PHY/types_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..6735092583ce8916ac19ea4966e9dd6a55a30b38 --- /dev/null +++ b/openair1/PHY/types_NB_IoT.h @@ -0,0 +1,32 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef __openair_TYPES_NB_IOT_H__ +#define __openair_TYPES_NB_IOT_H__ + +#ifdef USER_MODE +#include <stdint.h> +#else +#include <linux/types.h> +#endif + + +#endif /*__openair_TYPES_NB_IOT_H__ */ diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h index f78cb92bcd394bd57394ed73fcba6819375c4169..e8f4e27de13e6c5c0c818b1a721981536f3f7b3b 100644 --- a/openair1/PHY/vars.h +++ b/openair1/PHY/vars.h @@ -24,6 +24,7 @@ #include "PHY/types.h" #include "PHY/defs.h" +#include "common/ran_context.h" char* namepointer_chMag ; char fmageren_name2[512]; @@ -148,5 +149,5 @@ int16_t unscrambling_lut[65536*16] __attribute__((aligned(32))); /// lookup table for scrambling in TX uint8_t scrambling_lut[65536*16] __attribute__((aligned(32))); - +uint8_t max_turbo_iterations=4; #endif /*__PHY_VARS_H__ */ diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 9c855d0ac844c0790b4f2eec9f7add5444f21835..df01fad13622307d0c14c65fbd302744d23453e2 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -190,12 +190,12 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa; if (dlsch0->active){ - computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); - computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); + computeRhoA_eNB(rel8->pa, dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); + computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off); } if (dlsch1->active){ - computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); - computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); + computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB); + computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off); } dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols; @@ -537,7 +537,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) { AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, "No existing UE ULSCH for rnti %x\n",rel8->rnti); - //LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d\n", UE_id,rel8->rnti,frame,subframe); + LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d, modulation %d, rvidx %d\n", UE_id,rel8->rnti,frame,subframe,rel8->modulation_type,rel8->redundancy_version); fill_ulsch(eNB,&ul_config_pdu->ulsch_pdu,frame,subframe); diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index 725bb31c455fdf6e11c4b917ac0801bfb9d1faa1..f04e8581dba863b9ede033cae45810df1ede99ea 100644 --- a/openair1/SCHED/fapi_l1.h +++ b/openair1/SCHED/fapi_l1.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 9aaf6752fb23835471e674384e137de434d08268..6c2e580947da2ebde0616ccd04a83174e2ceefa4 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -395,6 +395,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, + void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, relaying_type_t r_type, @@ -416,7 +417,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, int offset = eNB->CC_id;//proc == &eNB->proc.proc_rxtx[0] ? 0 : 1; - + if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)==SF_UL)) return; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1); @@ -429,6 +430,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } + if (nfapi_mode == 0 || nfapi_mode == 1) { if (is_pmch_subframe(frame,subframe,fp)) { pmch_procedures(eNB,proc,rn,r_type); @@ -439,6 +441,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } } + // clear existing ulsch dci allocations before applying info from MAC (this is table ul_subframe = pdcch_alloc2ul_subframe(fp,subframe); ul_frame = pdcch_alloc2ul_frame(fp,frame,subframe); @@ -647,7 +650,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0}; - int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric; + int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric=0; const int subframe = proc->subframe_rx; const int frame = proc->frame_rx; int i; @@ -894,7 +897,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) harq_ack[0] = 4; // DTX harq_ack[1] = 6; // NACK/DTX harq_ack[2] = 6; // NACK/DTX - + max_metric = 0; } else { @@ -977,7 +980,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) harq_ack[1] = 6; // NACK/DTX harq_ack[2] = 6; // NACK/DTX harq_ack[3] = 6; // NACK/DTX - + max_metric = 0; } else { max_metric = max(metric[0],max(metric[1],max(metric[2],metric[3]))); @@ -1206,7 +1209,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) start_meas(&eNB->ulsch_demodulation_stats); - rx_ulsch(eNB,proc, i); + rx_ulsch(eNB,proc, i); stop_meas(&eNB->ulsch_demodulation_stats); @@ -1259,7 +1262,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n", eNB->Mod_id,harq_pid, frame,subframe, i, - ulsch_harq->round-1, + ulsch_harq->round, ulsch->Mlimit, ulsch_harq->o_ACK[0], ulsch_harq->o_ACK[1]); diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c index 2e6bdc8a14c9b39637c9d7c179c05a2431548596..2635649589643575b027439581079c63b1527ba9 100644 --- a/openair1/SCHED/phy_procedures_lte_ue.c +++ b/openair1/SCHED/phy_procedures_lte_ue.c @@ -81,7 +81,7 @@ extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; #endif -#define DEBUG_UE_TRACE 1 +#define UE_DEBUG_TRACE 1 void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid) { @@ -1266,7 +1266,7 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt } //#endif - if ((frame_tx%100) == 0) +// if ((frame_tx%100) == 0) LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n", ue->Mod_id,frame_tx,subframe_tx, ulsch_start, @@ -1288,16 +1288,25 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt nsymb, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); - else + else { normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - dummy_tx_buffer, + dummy_tx_buffer, #else - &ue->common_vars.txdata[aa][ulsch_start], + &ue->common_vars.txdata[aa][ulsch_start], #endif - nsymb, - &ue->frame_parms); + nsymb>>1, + &ue->frame_parms); + normal_prefix_mod(&ue->common_vars.txdataF[aa][((subframe_tx*nsymb)+(nsymb>>1))*frame_parms->ofdm_symbol_size], +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + dummy_tx_buffer+(frame_parms->samples_per_tti>>1), +#else + &ue->common_vars.txdata[aa][ulsch_start+(frame_parms->samples_per_tti>>1)], +#endif + nsymb>>1, + &ue->frame_parms); + } #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) apply_7_5_kHz(ue,dummy_tx_buffer,0); @@ -1373,7 +1382,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin if (ue->mac_enabled==1){ // ask L2 for RACH transport if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { - LOG_D(PHY,"Getting PRACH resources\n"); + //LOG_D(PHY,"Getting PRACH resources\n"); ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id, ue->CC_id, @@ -1590,7 +1599,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1)) { - LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); + // LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; } @@ -2070,10 +2079,10 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin (bundling_flag==bundling) || ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) { format = pucch_format1a; - LOG_D(PHY,"[UE] PUCCH 1a\n"); + // LOG_D(PHY,"[UE] PUCCH 1a\n"); } else { format = pucch_format1b; - LOG_D(PHY,"[UE] PUCCH 1b\n"); + // LOG_D(PHY,"[UE] PUCCH 1b\n"); } // Part - I @@ -3108,7 +3117,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs int ret=0; if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { - LOG_D(PHY,"ue calling pmch subframe ..\n "); + // LOG_D(PHY,"ue calling pmch subframe ..\n "); LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx); diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index f3b5644b922d2f24b3aec0c43bd5624208c0a5b9..4730eed613198c04a2ced09ae6e6b6d3fc947fcc 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -36,6 +36,7 @@ #include "SCHED/extern.h" #include "nfapi_interface.h" #include "fapi_l1.h" +#include "nfapi_pnf.h" #include "UTIL/LOG/log.h" #include "UTIL/LOG/vcd_signal_dumper.h" @@ -52,6 +53,8 @@ extern uint32_t nfapi_mode; +extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); + void prach_procedures(PHY_VARS_eNB *eNB #ifdef Rel14 , diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index dcab55d66f6686eea679b871150bbeb4c1d942a8..534023632c2cdc9354efcdaa0f617d9f79bf4fab 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -539,6 +539,7 @@ void fep_full(RU_t *ru) { remove_7_5_kHz(ru,proc->subframe_rx<<1); remove_7_5_kHz(ru,1+(proc->subframe_rx<<1)); + for (l=0; l<fp->symbols_per_tti/2; l++) { slot_fep_ul(ru, l, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 34055517b24507482545f26ac4357882a4ea3a72..885d29cc4e1c8caee548a5f376c8f7b4daa8632e 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -54,8 +54,9 @@ #include "PHY/TOOLS/lte_phy_scope.h" -PHY_VARS_eNB *eNB; -PHY_VARS_UE *UE; +#include "dummy_functions.c" + + double cpuf; @@ -123,7 +124,7 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_ } -void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], +void DL_channel(RU_t *ru,PHY_VARS_UE *UE,uint subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], double *s_re[2],double *s_im[2],double *r_re[2],double *r_im[2],FILE *csv_fd) { int i,u; @@ -134,18 +135,18 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou // printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { - for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { + for (aa=0; aa<ru->frame_parms.nb_antennas_tx; aa++) { if (awgn_flag == 0) { - s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); - s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]); + s_im[aa][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } else { for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) { if (aa==0) { - r_re[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] = ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } else { - r_re[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); - r_im[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); + r_re[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]); + r_im[aarx][i] += ((double)(((short *)ru->common.txdata[aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]); } } @@ -180,11 +181,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou if(abstx) { if (trials==0 && round==0) { // calculate freq domain representation to compute SINR - freq_channel(eNB2UE[0], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[0], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); // snr=pow(10.0,.1*SNR); fprintf(csv_fd,"%f,",SNR); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) { channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x; @@ -195,9 +196,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } if(num_rounds>1) { - freq_channel(eNB2UE[1], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[1], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) { channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x; @@ -207,9 +208,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } - freq_channel(eNB2UE[2], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[2], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) { channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x; @@ -219,9 +220,9 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } - freq_channel(eNB2UE[3], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1); + freq_channel(eNB2UE[3], ru->frame_parms.N_RB_DL,2*ru->frame_parms.N_RB_DL + 1); - for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) { + for (u=0; u<2*ru->frame_parms.N_RB_DL; u++) { for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) { for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) { channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x; @@ -237,11 +238,11 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou //AWGN // tx_lev is the average energy over the whole subframe // but SNR should be better defined wrt the energy in the reference symbols - sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR; + sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)ru->frame_parms.ofdm_symbol_size/(double)(ru->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) { - for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { + for (aa=0; aa<UE->frame_parms.nb_antennas_rx; aa++) { //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]); ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] = (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); @@ -251,28 +252,118 @@ void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,dou } } +uint16_t +fill_tx_req(nfapi_tx_request_body_t *tx_req_body, + uint16_t absSF, + uint16_t pdu_length, + uint16_t pdu_index, + uint8_t *pdu) +{ + nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus]; + LOG_D(MAC, "Filling TX_req %d for pdu length %d\n", + tx_req_body->number_of_pdus, pdu_length); + + TX_req->pdu_length = pdu_length; + TX_req->pdu_index = pdu_index; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pdu_length; + TX_req->segments[0].segment_data = pdu; + tx_req_body->tl.tag = NFAPI_TX_REQUEST_BODY_TAG; + tx_req_body->number_of_pdus++; + + return (((absSF / 10) << 4) + (absSF % 10)); +} + +void +fill_dlsch_config(nfapi_dl_config_request_body_t * dl_req, + uint16_t length, + uint16_t pdu_index, + uint16_t rnti, + uint8_t resource_allocation_type, + uint8_t virtual_resource_block_assignment_flag, + uint16_t resource_block_coding, + uint8_t modulation, + uint8_t redundancy_version, + uint8_t transport_blocks, + uint8_t transport_block_to_codeword_swap_flag, + uint8_t transmission_scheme, + uint8_t number_of_layers, + uint8_t number_of_subbands, + // uint8_t codebook_index, + uint8_t ue_category_capacity, + uint8_t pa, + uint8_t delta_power_offset_index, + uint8_t ngap, + uint8_t nprb, + uint8_t transmission_mode, + uint8_t num_bf_prb_per_subband, + uint8_t num_bf_vector) +{ + nfapi_dl_config_request_pdu_t *dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DLSCH_PDU_REL8_TAG; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.length = length; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = pdu_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = rnti; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = resource_allocation_type; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = virtual_resource_block_assignment_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = resource_block_coding; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = modulation; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = redundancy_version; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = transport_blocks; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = transport_block_to_codeword_swap_flag; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = transmission_scheme; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = number_of_layers; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = number_of_subbands; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = codebook_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = ue_category_capacity; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = pa; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = delta_power_offset_index; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = ngap; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = nprb; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_req->number_pdu++; +} void fill_DCI(PHY_VARS_eNB *eNB, - DCI_ALLOC_t *dci_alloc, + int frame, int subframe, + Sched_Rsp_t *sched_resp, + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000], int n_rnti, int n_users, int transmission_mode, + int retrans, int common_flag, + int NB_RB, int DLSCH_RB_ALLOC, int TPC, int mcs1, int mcs2, int ndi, int rv, + int pa, int *num_common_dci, int *num_ue_spec_dci, int *num_dci) { int k; - int dci_length = -1,dci_length_bytes = -1; - // printf("Generating DCIs for %d users, TM %d, mcs1 %d\n",n_users,transmission_mode,mcs1); + nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body; + + dl_req->number_dci=0; + dl_req->number_pdu=0; + TX_req->number_of_pdus=0; + for(k=0; k<n_users; k++) { switch(transmission_mode) { case 1: @@ -282,903 +373,106 @@ void fill_DCI(PHY_VARS_eNB *eNB, case 7: if (common_flag == 0) { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t); - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_TDD_t); - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_TDD_t); - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 100: - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - dci_length = sizeof_DCI1_20MHz_TDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_TDD_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t); - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 25: - dci_length = sizeof_DCI1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_5MHz_FDD_t); - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 50: - dci_length = sizeof_DCI1_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_10MHz_FDD_t); - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - - case 100: - dci_length = sizeof_DCI1_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1_20MHz_FDD_t); - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = ndi; - ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = rv; - break; - } - } + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = n_rnti+k; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = DLSCH_RB_ALLOC; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = 0; + + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + + + fill_dlsch_config(dl_req, + get_TBS_DL(mcs1,NB_RB), + (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ + n_rnti, + 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + DLSCH_RB_ALLOC, // resource_block_coding, + get_Qm(mcs1), + rv, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + transmission_mode == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + pa, // pa + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + transmission_mode, + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + fill_tx_req(TX_req, + (frame * 10) + subframe, + get_TBS_DL(mcs1,NB_RB), + 0, + input_buffer[k]); + } + else { - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format1; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - // printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format1, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci+1; - *num_ue_spec_dci = *num_ue_spec_dci+1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } + } - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci=*num_common_dci+1; - *num_dci = *num_dci + 1; + break; - } + case 3: + if (common_flag == 0) { - break; + if (eNB->frame_parms.nb_antennas_tx == 2) { - case 3: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t); - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t); - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t); - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - dci_length = sizeof_DCI2A_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t); - break; - } - } + if (eNB->frame_parms.frame_type == TDD) { - else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t); - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2A_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t); - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2A_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t); - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - dci_length = sizeof_DCI2A_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t); - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - } - } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { + } + else { - } + } + } + } + break; - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format2A; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - //printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci + 1; - *num_ue_spec_dci = *num_ue_spec_dci + 1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } + case 4: + if (common_flag == 0) { - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - //printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci = *num_common_dci + 1; - *num_dci = *num_dci + 1; + if (eNB->frame_parms.nb_antennas_tx == 2) { - } + if (eNB->frame_parms.frame_type == TDD) { - //printf("Generated DCI format 2A (Transmission Mode 3)\n"); - break; - case 4: - if (common_flag == 0) { - - if (eNB->frame_parms.nb_antennas_tx == 2) { - - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t); - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t); - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t); - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - dci_length = sizeof_DCI2_20MHz_2A_TDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t); - break; - } - } + } - else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t); - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 25: - dci_length = sizeof_DCI2_5MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t); - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 50: - dci_length = sizeof_DCI2_10MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t); - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - - case 100: - dci_length = sizeof_DCI2_20MHz_2A_FDD_t; - dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t); - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = DLSCH_RB_ALLOC; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1 = mcs1; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1 = ndi; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1 = rv; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2 = mcs2; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2 = ndi; - ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2 = rv; - break; - } - } - } else if (eNB->frame_parms.nb_antennas_tx == 4) { + else { - } + } + } else if (eNB->frame_parms.nb_antennas_tx == 4) { - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format2; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - n_rnti+k, - format2, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_dci = *num_dci + 1; - *num_ue_spec_dci = *num_ue_spec_dci + 1; - } else { - if (eNB->frame_parms.frame_type == TDD) { - - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t; - dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t); - break; - } - } else { - switch (eNB->frame_parms.N_RB_DL) { - case 6: - dci_length = sizeof_DCI1A_1_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 25: - dci_length = sizeof_DCI1A_5MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 50: - dci_length = sizeof_DCI1A_10MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - - case 100: - dci_length = sizeof_DCI1A_20MHz_FDD_t; - dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type = 1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc = computeRIV(eNB->frame_parms.N_RB_DL,0,9); - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC = TPC; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs = mcs1; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi = 0; - ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv = 0; - break; - } - } + } - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes); - dci_alloc[*num_dci].dci_length = dci_length; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = SI_RNTI; - dci_alloc[*num_dci].format = format1A; - dci_alloc[*num_dci].firstCCE = 0; - dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE; - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu_1[0], - SI_RNTI, - format1A, - eNB->dlsch[0], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[0].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - *num_common_dci = *num_common_dci + 1; - *num_dci = *num_dci + 1; + } + else { } @@ -1186,90 +480,31 @@ void fill_DCI(PHY_VARS_eNB *eNB, case 5: case 6: - memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t)); - dci_alloc[*num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t; - dci_alloc[*num_dci].L = 1; - dci_alloc[*num_dci].rnti = n_rnti+k; - dci_alloc[*num_dci].format = format1E_2A_M10PRB; - dci_alloc[*num_dci].firstCCE = 4*k; - dci_alloc[*num_dci].search_space = DCI_UE_SPACE; - printf("Generating dlsch params for user %d\n",k); - generate_eNB_dlsch_params_from_dci(0, - subframe, - &DLSCH_alloc_pdu2_1E[k], - n_rnti+k, - format1E_2A_M10PRB, - eNB->dlsch[k], - &eNB->frame_parms, - eNB->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - eNB->UE_stats[k].DL_pmi_single, - transmission_mode>=7?transmission_mode:0); - - dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]); - *num_ue_spec_dci = *num_ue_spec_dci + 1; - *num_dci = *num_dci + 1; break; - default: - printf("Unsupported Transmission Mode!!!"); - exit(-1); - break; - } + default: + printf("Unsupported Transmission Mode %d!!!\n",transmission_mode); + exit(-1); + break; } + } + *num_dci = dl_req->number_dci; + *num_ue_spec_dci = dl_req->number_dci; + *num_common_dci = 0; } int n_users = 1; sub_frame_t subframe=7; -DCI_PDU DCI_pdu; int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1; - - -DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) { - - if (subframeP == subframe) { - DCI_pdu.Num_dci = num_ue_spec_dci + num_common_dci; - DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; - } else { - DCI_pdu.Num_dci = 0; - DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; - } - - return &DCI_pdu; -} - -void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) { - - return; -} - uint16_t n_rnti=0x1234; -unsigned char *input_buffer0[2],*input_buffer1[2]; -unsigned short input_buffer_length0,input_buffer_length1; - -uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex) { - - int k; - - for (k=0;k<n_users;k++) - if (rnti == n_rnti+k) - break; - if (k<n_users) - return(TBindex==0 ? input_buffer0[k] : input_buffer1[k]); - else { - printf("RNTI not found,exiting\n"); - exit(-1); - } -} + int nfapi_mode=0; int main(int argc, char **argv) { int c; - int k,i,aa; + int k,i,j,aa; int re; int s,Kr,Kr_bytes; @@ -1300,12 +535,19 @@ int main(int argc, char **argv) SCM_t channel_model=Rayleigh1; // unsigned char *input_data,*decoded_output; - DCI_ALLOC_t *dci_alloc = &DCI_pdu.dci_alloc[0]; + DCI_ALLOC_t da; + DCI_ALLOC_t *dci_alloc = &da; unsigned int ret; unsigned int coded_bits_per_codeword=0,nsymb; //,tbs=0; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors[4]={0,0,0,0};//,num_layers; + unsigned int tx_lev=0,tx_lev_dB=0,trials; + unsigned int errs[4],errs2[4],round_trials[4],dci_errors[4];//,num_layers; + memset(errs,0,4*sizeof(unsigned int)); + memset(errs2,0,4*sizeof(unsigned int)); + memset(round_trials,0,4*sizeof(unsigned int)); + memset(dci_errors,0,4*sizeof(unsigned int)); + //int re_allocated; char fname[32],vname[32]; FILE *bler_fd; @@ -1392,6 +634,7 @@ int main(int argc, char **argv) int threequarter_fs=0; + opp_enabled=1; // to enable the time meas FILE *csv_fd=NULL; @@ -1402,6 +645,17 @@ int main(int argc, char **argv) int log_level = LOG_ERR; int dci_received; + PHY_VARS_eNB *eNB; + RU_t *ru; + PHY_VARS_UE *UE; + nfapi_dl_config_request_t DL_req; + nfapi_ul_config_request_t UL_req; + nfapi_hi_dci0_request_t HI_DCI0_req; + nfapi_dl_config_request_pdu_t dl_config_pdu_list[MAX_NUM_DL_PDU]; + nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; + nfapi_tx_request_t TX_req; + Sched_Rsp_t sched_resp; + int pa=dB0; #if defined(__arm__) FILE *proc_fd = NULL; @@ -1420,6 +674,18 @@ int main(int argc, char **argv) cpu_freq_GHz = get_cpu_freq_GHz(); #endif printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + memset((void*)&sched_resp,0,sizeof(sched_resp)); + sched_resp.DL_req = &DL_req; + sched_resp.UL_req = &UL_req; + sched_resp.HI_DCI0_req = &HI_DCI0_req; + sched_resp.TX_req = &TX_req; + memset((void*)&DL_req,0,sizeof(DL_req)); + memset((void*)&UL_req,0,sizeof(UL_req)); + memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void*)&TX_req,0,sizeof(TX_req)); + + DL_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdu_list; + TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; cpuf = cpu_freq_GHz; @@ -1612,7 +878,7 @@ int main(int argc, char **argv) channel_model=AWGN; break; default: - msg("Unsupported channel model!\n"); + printf("Unsupported channel model!\n"); exit(-1); } @@ -1634,7 +900,7 @@ int main(int argc, char **argv) UE->use_ia_receiver = 1; if ((n_tx_port!=2) || (transmission_mode!=5)) { - msg("IA receiver only supported for TM5!"); + printf("IA receiver only supported for TM5!"); exit(-1); } @@ -1644,7 +910,7 @@ int main(int argc, char **argv) i_mod = atoi(optarg); if (i_mod!=2 && i_mod!=4 && i_mod!=6) { - msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); + printf("Wrong i_mod %d, should be 2,4 or 6\n",i_mod); exit(-1); } @@ -1658,7 +924,7 @@ int main(int argc, char **argv) n_tx_port=atoi(optarg); if ((n_tx_port==0) || ((n_tx_port>2))) { - msg("Unsupported number of cell specific antennas ports %d\n",n_tx_port); + printf("Unsupported number of cell specific antennas ports %d\n",n_tx_port); exit(-1); } @@ -1675,7 +941,7 @@ int main(int argc, char **argv) (transmission_mode!=5) && (transmission_mode!=6) && (transmission_mode!=7)) { - msg("Unsupported transmission mode %d\n",transmission_mode); + printf("Unsupported transmission mode %d\n",transmission_mode); exit(-1); } @@ -1689,17 +955,17 @@ int main(int argc, char **argv) n_tx_phy=atoi(optarg); if (n_tx_phy < n_tx_port) { - msg("n_tx_phy mush not be smaller than n_tx_port"); + printf("n_tx_phy mush not be smaller than n_tx_port"); exit(-1); } if ((transmission_mode>1 && transmission_mode<7) && n_tx_port<2) { - msg("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); + printf("n_tx_port must be >1 for transmission_mode %d\n",transmission_mode); exit(-1); } if (transmission_mode==7 && (n_tx_phy!=1 && n_tx_phy!=2 && n_tx_phy!=4 && n_tx_phy!=8 && n_tx_phy!=16 && n_tx_phy!=64 && n_tx_phy!=128)) { - msg("Physical number of antennas not supported for TM7.\n"); + printf("Physical number of antennas not supported for TM7.\n"); exit(-1); } @@ -1718,7 +984,7 @@ int main(int argc, char **argv) n_rx=atoi(optarg); if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); + printf("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } @@ -1770,9 +1036,14 @@ int main(int argc, char **argv) } } + if (transmission_mode>1) pa=dBm3; + printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); + + AssertFatal(load_configmodule(argc,argv) != NULL, + "cannot load configuration module, exiting\n"); logInit(); // enable these lines if you need debug info - set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1); + set_comp_log(PHY,LOG_INFO,LOG_HIGH,1); set_glog(log_level,LOG_HIGH); // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore @@ -1822,30 +1093,40 @@ int main(int argc, char **argv) n_users = 2; printf("dual_stream_UE=%d\n", dual_stream_UE); } + RC.nb_L1_inst = 1; + RC.nb_RU = 1; - lte_param_init(n_tx_port, + lte_param_init(&eNB,&UE,&ru, + n_tx_port, n_tx_phy, - n_rx, + 1, + n_rx, transmission_mode, extended_prefix_flag, frame_type, Nid_cell, tdd_config, N_RB_DL, + pa, threequarter_fs, osf, perfect_ce); - + RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); + RC.ru = (RU_t **)malloc(sizeof(RC.ru)); + RC.eNB[0][0] = eNB; + RC.ru[0] = ru; + printf("lte_param_init done\n"); if ((transmission_mode==1) || (transmission_mode==7)) { - for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) - for (re=0; re<eNB->frame_parms.ofdm_symbol_size; re++) - eNB->common_vars.beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; + for (aa=0; aa<ru->nb_tx; aa++) + for (re=0; re<ru->frame_parms.ofdm_symbol_size; re++) + ru->beam_weights[0][0][aa][re] = 0x00007fff/eNB->frame_parms.nb_antennas_tx; } if (transmission_mode<7) - eNB->do_precoding=0; + ru->do_precoding=0; else - eNB->do_precoding=1; + ru->do_precoding=1; eNB->mac_enabled=1; if (two_thread_flag == 0) { @@ -1860,9 +1141,6 @@ int main(int argc, char **argv) } // callback functions required for phy_procedures_tx - mac_xface->get_dci_sdu = get_dci_sdu; - mac_xface->get_dlsch_sdu = get_dlsch_sdu; - mac_xface->eNB_dlsch_ulsch_scheduler = eNB_dlsch_ulsch_scheduler; // eNB_id_i = UE->n_connected_eNB; @@ -1875,7 +1153,10 @@ int main(int argc, char **argv) snr1 = snr0+snr_int; printf("SNR0 %f, SNR1 %f\n",snr0,snr1); + uint8_t input_buffer[NUMBER_OF_UE_MAX][20000]; + for (i=0;i<n_users;i++) + for (j=0;j<20000;j++) input_buffer[i][j] = (uint8_t)((taus())&255); frame_parms = &eNB->frame_parms; @@ -2024,48 +1305,7 @@ int main(int argc, char **argv) UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti; - // Fill in UL_alloc - UL_alloc_pdu.type = 0; - UL_alloc_pdu.hopping = 0; - UL_alloc_pdu.rballoc = UL_RB_ALLOC; - UL_alloc_pdu.mcs = 1; - UL_alloc_pdu.ndi = 1; - UL_alloc_pdu.TPC = 0; - UL_alloc_pdu.cqi_req = 1; - - CCCH_alloc_pdu.type = 0; - CCCH_alloc_pdu.vrb_type = 0; - CCCH_alloc_pdu.rballoc = CCCH_RB_ALLOC; - CCCH_alloc_pdu.ndi = 1; - CCCH_alloc_pdu.mcs = 1; - CCCH_alloc_pdu.harq_pid = 0; - - DLSCH_alloc_pdu2_1E[0].rah = 0; - DLSCH_alloc_pdu2_1E[0].rballoc = DLSCH_RB_ALLOC; - DLSCH_alloc_pdu2_1E[0].TPC = 0; - DLSCH_alloc_pdu2_1E[0].dai = 0; - DLSCH_alloc_pdu2_1E[0].harq_pid = 0; - //DLSCH_alloc_pdu2_1E[0].tb_swap = 0; - DLSCH_alloc_pdu2_1E[0].mcs = mcs1; - DLSCH_alloc_pdu2_1E[0].ndi = 1; - DLSCH_alloc_pdu2_1E[0].rv = 0; - // Forget second codeword - DLSCH_alloc_pdu2_1E[0].tpmi = (transmission_mode>=5 ? 5 : 0); // precoding - DLSCH_alloc_pdu2_1E[0].dl_power_off = (transmission_mode==5 ? 0 : 1); - - DLSCH_alloc_pdu2_1E[1].rah = 0; - DLSCH_alloc_pdu2_1E[1].rballoc = DLSCH_RB_ALLOC; - DLSCH_alloc_pdu2_1E[1].TPC = 0; - DLSCH_alloc_pdu2_1E[1].dai = 0; - DLSCH_alloc_pdu2_1E[1].harq_pid = 0; - //DLSCH_alloc_pdu2_1E[1].tb_swap = 0; - DLSCH_alloc_pdu2_1E[1].mcs = mcs_i; - DLSCH_alloc_pdu2_1E[1].ndi = 1; - DLSCH_alloc_pdu2_1E[1].rv = 0; - // Forget second codeword - DLSCH_alloc_pdu2_1E[1].tpmi = (transmission_mode>=5 ? 5 : 0) ; // precoding - DLSCH_alloc_pdu2_1E[1].dl_power_off = (transmission_mode==5 ? 0 : 1); - + printf("Allocating %dx%d eNB->UE channel descriptor\n",eNB->frame_parms.nb_antennas_tx,UE->frame_parms.nb_antennas_rx); eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, UE->frame_parms.nb_antennas_rx, channel_model, @@ -2088,7 +1328,7 @@ int main(int argc, char **argv) } if (eNB2UE[0]==NULL) { - msg("Problem generating channel model. Exiting.\n"); + printf("Problem generating channel model. Exiting.\n"); exit(-1); } @@ -2114,7 +1354,7 @@ int main(int argc, char **argv) break; } - for (k=0; k<n_users; k++) { + for (k=0; k<NUMBER_OF_UE_MAX; k++) { // Create transport channel structures for 2 transport blocks (MIMO) for (i=0; i<2; i++) { eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0,&eNB->frame_parms); @@ -2166,24 +1406,31 @@ int main(int argc, char **argv) eNB->UE_stats[1].DL_pmi_single = 0; } + eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]]; if (input_fd==NULL) { - + DL_req.dl_config_request_body.number_pdcch_ofdm_symbols = num_pdcch_symbols; + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; // UE specific DCI fill_DCI(eNB, - &dci_alloc[0], - subframe, + proc_eNB->frame_tx,subframe, + &sched_resp, + input_buffer, n_rnti, n_users, transmission_mode, + 0, common_flag, + NB_RB, DLSCH_RB_ALLOC, TPC, mcs1, mcs2, 1, 0, + pa, &num_common_dci, &num_ue_spec_dci, &num_dci); @@ -2194,65 +1441,8 @@ int main(int argc, char **argv) - - for (k=0; k<n_users; k++) { - - input_buffer_length0 = eNB->dlsch[k][0]->harq_processes[0]->TBS/8; - input_buffer0[k] = (unsigned char *)malloc(input_buffer_length0+4); - memset(input_buffer0[k],0,input_buffer_length0+4); - input_buffer_length1 = eNB->dlsch[k][1]->harq_processes[0]->TBS/8; - input_buffer1[k] = (unsigned char *)malloc(input_buffer_length1+4); - memset(input_buffer1[k],0,input_buffer_length1+4); - - if (input_trch_file==0) { - for (i=0; i<input_buffer_length0; i++) { - //input_buffer0[k][i] = (unsigned char)(i&0xff); - input_buffer0[k][i] = (unsigned char)(taus()&0xff); - } - - for (i=0; i<input_buffer_length1; i++) { - input_buffer1[k][i]= (unsigned char)(taus()&0xff); - } - } - - else { - i=0; - - while ((!feof(input_trch_fd)) && (i<input_buffer_length0<<3)) { - ret=fscanf(input_trch_fd,"%s",input_trch_val); - if (ret != 1) printf("ERROR: error reading file\n"); - - if (input_trch_val[0] == '1') - input_buffer0[k][i>>3]+=(1<<(7-(i&7))); - - if (i<16) - printf("input_trch_val %d : %c\n",i,input_trch_val[0]); - - i++; - - if (((i%8) == 0) && (i<17)) - printf("%x\n",input_buffer0[k][(i-1)>>3]); - } - - printf("Read in %d bits\n",i); - } - } } - // this is for user 0 only - coded_bits_per_codeword = get_G(&eNB->frame_parms, - eNB->dlsch[0][0]->harq_processes[0]->nb_rb, - eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, - get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), - eNB->dlsch[0][0]->harq_processes[0]->Nl, - num_pdcch_symbols, - 0, - subframe, - transmission_mode>=7?transmission_mode:0); - - uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); - printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); - snr_step = input_snr_step; UE->high_speed_flag = 1; UE->ch_est_alpha=0; @@ -2332,7 +1522,7 @@ int main(int argc, char **argv) struct list time_vector_rx_dec; initialize(&time_vector_rx_dec); - eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[UE->current_thread_id[subframe]]; + for (trials = 0; trials<n_frames; trials++) { //printf("Trial %d\n",trials); @@ -2365,7 +1555,7 @@ int main(int argc, char **argv) // printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback); for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { - memset(&eNB->common_vars.txdataF[eNB_id][aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); + memset(&eNB->common_vars.txdataF[aa][0],0,FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX*sizeof(int32_t)); } if (input_fd==NULL) { @@ -2383,108 +1573,73 @@ int main(int argc, char **argv) TB0_active = 1; eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3; - - fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC, - mcs1,mcs2,!(trials&1),round&3,&num_common_dci,&num_ue_spec_dci,&num_dci); + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,0,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + mcs1,mcs2,!(trials&1),round&3,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); } else { - fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC, - (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,&num_common_dci,&num_ue_spec_dci,&num_dci); + DL_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + TX_req.sfn_sf = (proc_eNB->frame_tx<<4)+subframe; + fill_DCI(eNB,proc_eNB->frame_tx,subframe,&sched_resp,input_buffer,n_rnti,n_users,transmission_mode,1,common_flag,NB_RB,DLSCH_RB_ALLOC,TPC, + (TB0_active==1)?mcs1:0,mcs2,!(trials&1),(TB0_active==1)?round&3:0,pa,&num_common_dci,&num_ue_spec_dci,&num_dci); } - for (i=num_common_dci; i<num_dci; i++) { - - dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table, - 1<<dci_alloc[i].L, - numCCE, - (dci_alloc[i].rnti==SI_RNTI)? 1 : 0, - dci_alloc[i].rnti, - subframe); - - if (dci_alloc[i].firstCCE < 0) { - printf("firstCCE <0 !! dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format, - dci_alloc[i].firstCCE,numCCE); - exit(-1); - } - if (n_frames==1) - printf("dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format, - dci_alloc[i].firstCCE,numCCE); - } - - } // common_flag == 0 - - - - /* - else { // Read signal from file - i=0; - while (!feof(input_fd)) { - fscanf(input_fd,"%s %s",input_val_str,input_val_str2); - - if ((i%4)==0) { - ((short*)txdata[0])[i/2] = (short)((1<<15)*strtod(input_val_str,NULL)); - ((short*)txdata[0])[(i/2)+1] = (short)((1<<15)*strtod(input_val_str2,NULL)); - if ((i/4)<100) - printf("sample %d => %e + j%e (%d +j%d)\n",i/4,strtod(input_val_str,NULL),strtod(input_val_str2,NULL),((short*)txdata[0])[i/4],((short*)txdata[0])[(i/4)+1]);//1,input_val2,); - } - i++; - if (i>(FRAME_LENGTH_SAMPLES)) - break; - } - printf("Read in %d samples\n",i/4); - write_output("txsig0.m","txs0", txdata[0],2*frame_parms->samples_per_tti,1,1); - // write_output("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); - tx_lev = signal_energy(&txdata[0][0], - OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES); - tx_lev_dB = (unsigned int) dB_fixed(tx_lev); - } - */ - + } proc_eNB->subframe_tx = subframe; - eNB->abstraction_flag=0; - - phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1,dci_flag); + sched_resp.subframe=subframe; + sched_resp.frame=proc_eNB->frame_tx; + eNB->abstraction_flag=0; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1); + + if (uncoded_ber_bit == NULL) { + // this is for user 0 only + printf("nb_rb %d, rb_alloc %x, mcs %d\n", + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, + eNB->dlsch[0][0]->harq_processes[0]->mcs); + + coded_bits_per_codeword = get_G(&eNB->frame_parms, + eNB->dlsch[0][0]->harq_processes[0]->nb_rb, + eNB->dlsch[0][0]->harq_processes[0]->rb_alloc, + get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs), + eNB->dlsch[0][0]->harq_processes[0]->Nl, + num_pdcch_symbols, + 0, + subframe, + transmission_mode>=7?transmission_mode:0); + + uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword); + printf("uncoded_ber_bit=%p\n",uncoded_ber_bit); + } start_meas(&eNB->ofdm_mod_stats); - /* - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2), - &eNB->frame_parms); - - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2)+1, - &eNB->frame_parms); - */ + ru->proc.subframe_tx=subframe; + memcpy((void*)&ru->frame_parms,(void*)&eNB->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + feptx_prec(ru); + feptx_ofdm(ru); - do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2), - &eNB->frame_parms, - eNB->do_precoding); - - do_OFDM_mod_symbol(&eNB->common_vars, - eNB_id, - (subframe*2)+1, - &eNB->frame_parms, - eNB->do_precoding); + stop_meas(&eNB->ofdm_mod_stats); - stop_meas(&eNB->ofdm_mod_stats); // generate next subframe for channel estimation + DL_req.dl_config_request_body.number_dci=0; + DL_req.dl_config_request_body.number_pdu=0; + TX_req.tx_request_body.number_of_pdus=0; proc_eNB->subframe_tx = subframe+1; + sched_resp.subframe=subframe+1; + schedule_response(&sched_resp); + phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0); - phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0,dci_flag); - do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id], - eNB->common_vars.txdata[eNB_id], - (subframe*2)+2, - &eNB->frame_parms); + ru->proc.subframe_tx=(subframe+1)%10; + feptx_prec(ru); + feptx_ofdm(ru); proc_eNB->frame_tx++; @@ -2492,7 +1647,7 @@ int main(int argc, char **argv) tx_lev = 0; for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) { - tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa] + tx_lev += signal_energy(&ru->common.txdata[aa] [subframe*eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti); } @@ -2500,21 +1655,22 @@ int main(int argc, char **argv) tx_lev_dB = (unsigned int) dB_fixed(tx_lev); + if (n_frames==1) { printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB); - write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); + write_output("txsig0.m","txs0", &ru->common.txdata[0][subframe* eNB->frame_parms.samples_per_tti], eNB->frame_parms.samples_per_tti,1,1); if (transmission_mode<7) { - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0.m","txsF0x", &ru->common.txdataF_BF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); } else if (transmission_mode == 7) { - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); - write_output("txsigF0_BF.m","txsF0_BF", &eNB->common_vars.txdataF_BF[eNB_id][0][0],eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0.m","txsF0", &ru->common.txdataF_BF[5][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("txsigF0_BF.m","txsF0_BF", &ru->common.txdataF_BF[0][0],eNB->frame_parms.ofdm_symbol_size,1,1); } } } - DL_channel(eNB,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); + DL_channel(ru,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd); UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]]; @@ -2532,6 +1688,8 @@ int main(int argc, char **argv) if (n_frames==1) printf("Running phy_procedures_UE_RX\n"); if (dci_flag==0) { + memcpy(dci_alloc,eNB->pdcch_vars[subframe&1].dci_alloc,num_dci*sizeof(DCI_ALLOC_t)); + UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols; if (n_frames==1) printf("bypassing PDCCH/DCI detection\n"); if (generate_ue_dlsch_params_from_dci(proc->frame_rx, @@ -2541,7 +1699,7 @@ int main(int argc, char **argv) dci_alloc[0].format, UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], - UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], + UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0], &UE->frame_parms, UE->pdsch_config_dedicated, SI_RNTI, @@ -2570,26 +1728,50 @@ int main(int argc, char **argv) dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received; if (dci_flag && (dci_received == 0)) { - //printf("DCI not received\n"); + printf("DCI not received\n"); dci_errors[round]++; - /* - write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); - write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],12*UE->frame_parms.N_RB_DL*3,1,1); + write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1); - write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*12*UE->frame_parms.N_RB_DL,1,1); - write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,12*UE->frame_parms.N_RB_DL*4*2,1,4); - write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size], - nsymb*eNB->frame_parms.ofdm_symbol_size,1,1); + write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[0][eNB_id]->rxdataF_comp[0],4*300,1,1); + write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[0][eNB_id]->llr,2400,1,4); write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1); - write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1); + exit(-1); - */ + } + int bit_errors=0; if ((test_perf ==0 ) && (n_frames==1)) { + + dlsch_unscrambling(&eNB->frame_parms, + 0, + UE->dlsch[UE->current_thread_id[subframe]][0][0], + coded_bits_per_codeword, + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0], + 0, + subframe<<1); + for (i=0;i<coded_bits_per_codeword;i++) + if ((eNB->dlsch[0][0]->harq_processes[0]->e[i]==1 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] > 0)|| + (eNB->dlsch[0][0]->harq_processes[0]->e[i]==0 && UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i] < 0)) { + uncoded_ber_bit[bit_errors++] = 1; + printf("error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + } + else { + /* + printf("no error in pos %d : %d => %d\n",i, + eNB->dlsch[0][0]->harq_processes[0]->e[i], + UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]); + */ + } + + write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0); write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8); if (eNB->frame_parms.nb_antennas_tx>1) @@ -2625,6 +1807,7 @@ int main(int argc, char **argv) UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1); //pdsch_vars + printf("coded_bits_per_codeword %d\n",coded_bits_per_codeword); dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid); @@ -2648,7 +1831,7 @@ int main(int argc, char **argv) iter_trials++; if (n_frames==1) - printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber); + printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS; TB0_active = 0; @@ -2662,8 +1845,10 @@ int main(int argc, char **argv) iter_trials++; if (n_frames==1) { + + //if ((n_frames==1) || (SNR>=30)) { - printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber); + printf("DLSCH errors found (round %d), uncoded ber %f\n",round,(double)bit_errors/coded_bits_per_codeword); for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) { if (s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus) @@ -3292,13 +2477,6 @@ int main(int argc, char **argv) uncoded_ber_bit = NULL; - for (k=0; k<n_users; k++) { - free(input_buffer0[k]); - free(input_buffer1[k]); - input_buffer0[k]=NULL; - input_buffer1[k]=NULL; - } - printf("Freeing dlsch structures\n"); for (i=0; i<2; i++) { @@ -3310,7 +2488,7 @@ int main(int argc, char **argv) if (test_perf && !test_passed) return(-1); - else + else return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c new file mode 100644 index 0000000000000000000000000000000000000000..dc86e76113aa7c5dd32c79b0146f1f2596cd8aa3 --- /dev/null +++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c @@ -0,0 +1,84 @@ + +PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, + frame_t frameP, uint8_t new_Msg3, + sub_frame_t subframe){ return(NULL);} + +void ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * ulsch_buffer, uint16_t buflen, + uint8_t * access_mode){} + +void Msg1_transmitted(module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t eNB_id){} + +void Msg3_transmitted(module_id_t module_idP, uint8_t CC_id, + frame_t frameP, uint8_t eNB_id){} + +uint32_t ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, + uint8_t eNB_id, rnti_t rnti, sub_frame_t subframe){ return(0);} + +void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index) +{} + +UE_L2_STATE_t ue_scheduler(const module_id_t module_idP, + const frame_t rxFrameP, + const sub_frame_t rxSubframe, + const frame_t txFrameP, + const sub_frame_t txSubframe, + const lte_subframe_t direction, + const uint8_t eNB_index, const int CC_id){ return(0);} + +void ue_decode_p(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len){} + +void ue_decode_si(module_id_t module_idP, int CC_id, frame_t frame, + uint8_t CH_index, void *pdu, uint16_t len){} + +void ue_send_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frame, + sub_frame_t subframe, uint8_t * sdu, uint16_t sdu_len, + uint8_t CH_index){} + +uint16_t +ue_process_rar(const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const rnti_t ra_rnti, + uint8_t * const dlsch_buffer, + rnti_t * const t_crnti, + const uint8_t preamble_index, + uint8_t * selected_rar_buffer){ return(0);} + +void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, + uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index, + uint8_t sync_area){} + +int ue_query_mch(uint8_t Mod_id, uint8_t CC_id, uint32_t frame, + sub_frame_t subframe, uint8_t eNB_index, + uint8_t * sync_area, uint8_t * mcch_active){ return(0);} + +void dl_phy_sync_success(module_id_t module_idP, + frame_t frameP, + unsigned char eNB_index, uint8_t first_sync){} + +uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn) { return(0);} + +int32_t get_uldl_offset(int eutra_bandP) { return(0);} + +IF_Module_t *IF_Module_init(int Mod_id) { return(NULL);} + +int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id) { return(0);} + +int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id) { return(0);} + +void thread_top_init(char *thread_name, + int affinity, + uint64_t runtime, + uint64_t deadline, + uint64_t period) {} + +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0);} +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } + +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } + +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index cabe9664917882cc1ca26c4aee7fbf9c3eec6725..fc782be07a05db17d3a78dbe2464bd6a10a3e0b5 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -47,9 +47,7 @@ #include "unitary_defs.h" #include "PHY/TOOLS/lte_phy_scope.h" - -PHY_VARS_eNB *eNB; -PHY_VARS_UE *UE; +#include "dummy_functions.c" double cpuf; @@ -78,9 +76,112 @@ double t_tx_min = 1000000000; /*!< \brief initial min process time for tx */ double t_rx_min = 1000000000; /*!< \brief initial min process time for tx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ +int nfapi_mode = 0; + +extern void fep_full(RU_t *ru); +extern void ru_fep_full_2thread(RU_t *ru); + +nfapi_dl_config_request_t DL_req; +nfapi_ul_config_request_t UL_req; +nfapi_hi_dci0_request_t HI_DCI0_req; +nfapi_ul_config_request_pdu_t ul_config_pdu_list[MAX_NUM_DL_PDU]; +nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; +nfapi_tx_request_t TX_req; +Sched_Rsp_t sched_resp; + +void +fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, + uint8_t cqi_req, + uint8_t p_eNB, + uint8_t cqi_ReportModeAperiodic, + uint8_t betaOffset_CQI_Index, + uint8_t betaOffset_RI_Index, + uint8_t dl_cqi_pmi_size, + uint8_t tmode, + uint32_t handle, + uint16_t rnti, + uint8_t resource_block_start, + uint8_t number_of_resource_blocks, + uint8_t modulation_type, + uint8_t cyclic_shift_2_for_drms, + uint8_t frequency_hopping_enabled_flag, + uint8_t frequency_hopping_bits, + uint8_t new_data_indication, + uint8_t redundancy_version, + uint8_t harq_process_number, + uint8_t ul_tx_mode, + uint8_t current_tx_nb, + uint8_t n_srs, + uint16_t size) +{ + memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t)); + + // printf("filling ul_config_pdu: modulation type %d, rvidx %d\n",modulation_type,redundancy_version); + + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu)); + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = handle; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = rnti; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = resource_block_start; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = number_of_resource_blocks; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = modulation_type; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = cyclic_shift_2_for_drms; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = frequency_hopping_enabled_flag; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = frequency_hopping_bits; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = new_data_indication; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = redundancy_version; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = harq_process_number; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = ul_tx_mode; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = current_tx_nb; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = n_srs; + ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = size; + + if (cqi_req == 1) { + // Add CQI portion + ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; + ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu)); + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type = 1; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1; + LOG_D(MAC, "report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type); + + if (p_eNB <= 2 + && (tmode == 3 || tmode == 4 || tmode == 8 || tmode == 9 || tmode == 10)) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1; + else if (p_eNB <= 2) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0; + else if (p_eNB == 4) ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2; + + for (int ri = 0; + ri < (1 << ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size); + ri++) + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = dl_cqi_pmi_size; + + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi = betaOffset_CQI_Index; + ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri = betaOffset_RI_Index; + } +} - -void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mcs,int ndi,int cqi_flag) { +void fill_ulsch_dci(PHY_VARS_eNB *eNB, + int frame, + int subframe, + Sched_Rsp_t *sched_resp, + uint16_t rnti, + void *UL_dci, + int first_rb, + int nb_rb, + int mcs, + int modulation_type, + int ndi, + int cqi_flag, + uint8_t beta_CQI, + uint8_t beta_RI, + uint8_t cqi_size) { + + nfapi_ul_config_request_body_t *ul_req=&sched_resp->UL_req->ul_config_request_body; + int harq_pid = ((frame*10)+subframe)&7; + + // printf("ulsch in frame %d, subframe %d => harq_pid %d, mcs %d, ndi %d\n",frame,subframe,harq_pid,mcs,ndi); switch (eNB->frame_parms.N_RB_UL) { case 6: @@ -162,6 +263,36 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB,void *UL_dci,int first_rb,int nb_rb,int mc break; } + fill_nfapi_ulsch_config_request(&ul_req->ul_config_pdu_list[0], + cqi_flag&1, + 1, // p_eNB + 0, // reportmode Aperiodic + beta_CQI, + beta_RI, + cqi_size, + //cc, + //UE_template->physicalConfigDedicated, + 1, + 0, + 14, // rnti + first_rb, // resource_block_start + nb_rb, // number_of_resource_blocks + modulation_type, + 0, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + mcs>28?(mcs-28):0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL(mcs,nb_rb)); + + sched_resp->UL_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req->number_of_pdus=1; + ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + } extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); @@ -172,22 +303,26 @@ int main(int argc, char **argv) char c; int i,j,aa,u; - + PHY_VARS_eNB *eNB; + PHY_VARS_UE *UE; + RU_t *ru; int aarx,aatx; double channelx,channely; double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0; double input_snr_step=.2,snr_int=30; double blerr; - + int rvidx[8]={0,2,3,1,0,2,3,1}; int **txdata; LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720],s_im0[30720],r_re0[30720],r_im0[30720]; double s_re1[30720],s_im1[30720],r_re1[30720],r_im1[30720]; + double r_re2[30720],r_im2[30720]; + double r_re3[30720],r_im3[30720]; double *s_re[2]={s_re0,s_re1}; double *s_im[2]={s_im0,s_im1}; - double *r_re[2]={r_re0,r_re1}; - double *r_im[2]={r_im0,r_im1}; + double *r_re[4]={r_re0,r_re1,r_re2,r_re3}; + double *r_im[4]={r_im0,r_im1,r_im2,r_im3}; double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel double iqim=0.0; uint8_t extended_prefix_flag=0; @@ -254,8 +389,7 @@ int main(int argc, char **argv) uint8_t N_RB_DL=25,osf=1; //uint8_t cyclic_shift = 0; - uint8_t cooperation_flag = 0; //0 no cooperation, 1 delay diversity, 2 Alamouti - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2,cqi_size=11; uint8_t tdd_config=3,frame_type=FDD; uint8_t N0=30; @@ -282,10 +416,24 @@ int main(int argc, char **argv) opp_enabled=1; // to enable the time meas + sched_resp.DL_req = &DL_req; + sched_resp.UL_req = &UL_req; + sched_resp.HI_DCI0_req = &HI_DCI0_req; + sched_resp.TX_req = &TX_req; + memset((void*)&DL_req,0,sizeof(DL_req)); + memset((void*)&UL_req,0,sizeof(UL_req)); + memset((void*)&HI_DCI0_req,0,sizeof(HI_DCI0_req)); + memset((void*)&TX_req,0,sizeof(TX_req)); + + UL_req.ul_config_request_body.ul_config_pdu_list = ul_config_pdu_list; + TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; + cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); + AssertFatal(load_configmodule(argc,argv) != NULL, + "cannot load configuration module, exiting\n"); logInit(); /* @@ -565,20 +713,44 @@ int main(int argc, char **argv) break; } } + RC.nb_L1_inst = 1; + RC.nb_RU = 1; - lte_param_init(1, - 1, + lte_param_init(&eNB,&UE,&ru, + 1, + 1, n_rx, + 1, 1, extended_prefix_flag, frame_type, 0, tdd_config, N_RB_DL, + 4, threequarter_fs, osf, 0); + RC.eNB = (PHY_VARS_eNB ***)malloc(sizeof(PHY_VARS_eNB **)); + RC.eNB[0] = (PHY_VARS_eNB **)malloc(sizeof(PHY_VARS_eNB *)); + RC.ru = (RU_t **)malloc(sizeof(RC.ru)); + RC.eNB[0][0] = eNB; + RC.ru[0] = ru; + for (int k=0;k<eNB->RU_list[0]->nb_rx;k++) eNB->common_vars.rxdataF[k] = eNB->RU_list[0]->common.rxdataF[k]; + + memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); + + printf("Setting indication lists\n"); + eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; + eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; + + printf("lte_param_init done\n"); + // for a call to phy_reset_ue later we need PHY_vars_UE_g allocated and pointing to UE PHY_vars_UE_g = (PHY_VARS_UE***)malloc(sizeof(PHY_VARS_UE**)); PHY_vars_UE_g[0] = (PHY_VARS_UE**) malloc(sizeof(PHY_VARS_UE*)); @@ -587,7 +759,7 @@ int main(int argc, char **argv) if (nb_rb_set == 0) nb_rb = eNB->frame_parms.N_RB_UL; - printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0][0]); + printf("1 . rxdataF_comp[0] %p\n",eNB->pusch_vars[0]->rxdataF_comp[0]); printf("Setting mcs = %d\n",mcs); printf("n_frames = %d\n", n_frames); @@ -670,7 +842,6 @@ int main(int argc, char **argv) eNB->soundingrs_ul_config_dedicated[UE_id].freqDomainPosition = 0; eNB->soundingrs_ul_config_dedicated[UE_id].cyclicShift = 0; - eNB->cooperation_flag = cooperation_flag; eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index = beta_ACK; eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index = beta_RI; @@ -688,8 +859,8 @@ int main(int argc, char **argv) printf("PUSCH Beta : ACK %f, RI %f, CQI %f\n",(double)beta_ack[beta_ACK]/8,(double)beta_ri[beta_RI]/8,(double)beta_cqi[beta_CQI]/8); - UE2eNB = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx, - UE->frame_parms.nb_antennas_rx, + UE2eNB = new_channel_desc_scm(1, + n_rx, channel_model, N_RB2sampling_rate(eNB->frame_parms.N_RB_UL), N_RB2channel_bandwidth(eNB->frame_parms.N_RB_UL), @@ -700,7 +871,7 @@ int main(int argc, char **argv) UE2eNB->max_Doppler = maxDoppler; // NN: N_RB_UL has to be defined in ulsim - eNB->ulsch[0] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); + for (int k=0;k<NUMBER_OF_UE_MAX;k++) eNB->ulsch[k] = new_eNB_ulsch(max_turbo_iterations,N_RB_DL,0); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); if (parallel_flag == 1) { @@ -751,7 +922,7 @@ int main(int argc, char **argv) UE->mac_enabled=0; - + eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; @@ -761,9 +932,9 @@ int main(int argc, char **argv) proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; - proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; - proc_rxtx_ue->subframe_rx = proc_rxtx->subframe_tx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; printf("Init UL hopping UE\n"); init_ul_hopping(&UE->frame_parms); @@ -915,7 +1086,6 @@ int main(int argc, char **argv) reset_meas(&UE->ulsch_multiplexing_stats); reset_meas(&eNB->phy_proc_rx); - reset_meas(&eNB->ofdm_demod_stats); reset_meas(&eNB->ulsch_channel_estimation_stats); reset_meas(&eNB->ulsch_freq_offset_estimation_stats); reset_meas(&eNB->rx_dft_stats); @@ -932,7 +1102,7 @@ int main(int argc, char **argv) reset_meas(&eNB->ulsch_tc_intl1_stats); reset_meas(&eNB->ulsch_tc_intl2_stats); - // initialization + // initialization struct list time_vector_tx; initialize(&time_vector_tx); struct list time_vector_tx_ifft; @@ -965,19 +1135,38 @@ int main(int argc, char **argv) round=0; while (round < 4) { + proc_rxtx->frame_rx=1; + proc_rxtx->subframe_rx=subframe; + + proc_rxtx->frame_tx=pdcch_alloc2ul_frame(&eNB->frame_parms,1,subframe); + proc_rxtx->subframe_tx=pdcch_alloc2ul_subframe(&eNB->frame_parms,subframe); + + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; + proc_rxtx_ue->frame_rx = (subframe<4)?(proc_rxtx->frame_tx-1):(proc_rxtx->frame_tx); + proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; + proc_rxtx_ue->subframe_rx = (proc_rxtx->subframe_tx+6)%10; + eNB->ulsch[0]->harq_processes[harq_pid]->round=round; UE->ulsch[0]->harq_processes[harq_pid]->round=round; - // printf("Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_rx,proc_rxtx_ue->frame_rx); + if (n_frames==1) printf("filling ulsch: Trial %d : Round %d (subframe %d, frame %d)\n",trials,round,proc_rxtx_ue->subframe_tx,proc_rxtx_ue->frame_tx); round_trials[round]++; + UL_req.sfn_sf = (1<<4)+subframe; + if (n_frames==1) printf("filling ulsch: eNB prog frame %d, subframe %d (%d,%d)\n",proc_rxtx->frame_rx,subframe,sched_resp.frame,sched_resp.subframe); - fill_ulsch_dci(eNB,(void*)&UL_alloc_pdu,first_rb,nb_rb,mcs,ndi,cqi_flag); + int modulation_type; + if (mcs < 11) modulation_type = 2; + else if (mcs < 21) modulation_type = 4; + else if (mcs < 29) modulation_type = 6; + + fill_ulsch_dci(eNB,proc_rxtx->frame_rx,subframe,&sched_resp,14,(void*)&UL_alloc_pdu,first_rb,nb_rb,(round==0)?mcs:(28+rvidx[round]),modulation_type,ndi,cqi_flag,beta_CQI,beta_RI,cqi_size); UE->ulsch_Msg3_active[eNB_id] = 0; UE->ul_power_control_dedicated[eNB_id].accumulationEnabled=1; + if (n_frames==1) printf("filling ulsch: ue prog SFN/SF %d/%d\n",proc_rxtx_ue->frame_rx,proc_rxtx_ue->subframe_rx); generate_ue_ulsch_params_from_dci((void *)&UL_alloc_pdu, 14, - proc_rxtx->subframe_tx, + (subframe+6)%10, format0, UE, proc_rxtx_ue, @@ -988,17 +1177,11 @@ int main(int argc, char **argv) 0, srs_flag); - generate_eNB_ulsch_params_from_dci(eNB,proc_rxtx, - (void *)&UL_alloc_pdu, - 14, - format0, - 0, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - srs_flag); - eNB->ulsch[0]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; + sched_resp.subframe=(subframe+6)%10; + sched_resp.frame=(1024+eNB->proc.frame_rx+((subframe<4)?-1:0))&1023; + + schedule_response(&sched_resp); + ///////////////////// if (abstx) { @@ -1020,6 +1203,9 @@ int main(int argc, char **argv) eNB->proc.frame_rx = 1; eNB->proc.subframe_rx = subframe; + ru->proc.frame_rx = 1; + ru->proc.subframe_rx = subframe; + proc_rxtx_ue->frame_tx = proc_rxtx->frame_rx; proc_rxtx_ue->frame_rx = proc_rxtx->frame_tx; proc_rxtx_ue->subframe_tx = proc_rxtx->subframe_rx; @@ -1027,83 +1213,19 @@ int main(int argc, char **argv) phy_procedures_UE_TX(UE,proc_rxtx_ue,0,0,normal_txrx,no_relay); - /* - if (srs_flag) - generate_srs_tx(UE,0,AMP,subframe); - - generate_drs_pusch(UE,proc_rxtx_ue,0, - AMP,subframe, - UE->ulsch[0]->harq_processes[harq_pid]->first_rb, - UE->ulsch[0]->harq_processes[harq_pid]->nb_rb, - 0); - - if ((cqi_flag == 1) && (n_frames == 1) ) { - printf("CQI information (O %d) %d %d\n",UE->ulsch[0]->O, - UE->ulsch[0]->o[0],UE->ulsch[0]->o[1]); - print_CQI(UE->ulsch[0]->o,UE->ulsch[0]->uci_format,UE->frame_parms.N_RB_DL,0); - } - - UE->ulsch[0]->o_ACK[0] = taus()&1; - - start_meas(&UE->ulsch_encoding_stats); - - if (ulsch_encoding(input_buffer, - UE, - harq_pid, - eNB_id, - 2, // transmission mode - control_only_flag, - 1// Nbundled - )==-1) { - printf("ulsim.c Problem with ulsch_encoding\n"); - exit(-1); - } - - stop_meas(&UE->ulsch_encoding_stats); - - start_meas(&UE->ulsch_modulation_stats); - ulsch_modulation(UE->common_vars.txdataF,AMP, - proc_rxtx_ue->frame_tx,subframe,&UE->frame_parms, - UE->ulsch[0]); - stop_meas(&UE->ulsch_modulation_stats); - */ - - - - - /* - for (aa=0; aa<1; aa++) { - if (frame_parms->Ncp == EXTENDED) - PHY_ofdm_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX], // input - &txdata[aa][eNB->frame_parms.samples_per_tti*subframe], // output - UE->frame_parms.ofdm_symbol_size, - nsymb, // number of symbols - UE->frame_parms.nb_prefix_samples, // number of prefix samples - CYCLIC_PREFIX); - else - normal_prefix_mod(&UE->common_vars.txdataF[aa][subframe*nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX], - &txdata[aa][eNB->frame_parms.samples_per_tti*subframe], - nsymb, - frame_parms); - - - apply_7_5_kHz(UE,UE->common_vars.txdata[aa],subframe<<1); - apply_7_5_kHz(UE,UE->common_vars.txdata[aa],1+(subframe<<1)); - -*/ tx_lev = signal_energy(&UE->common_vars.txdata[0][eNB->frame_parms.samples_per_tti*subframe], eNB->frame_parms.samples_per_tti); - - + + if (n_frames==1) { write_output("txsigF0UL.m","txsF0", &UE->common_vars.txdataF[0][eNB->frame_parms.ofdm_symbol_size*nsymb*subframe],eNB->frame_parms.ofdm_symbol_size*nsymb,1, 1); //write_output("txsigF1.m","txsF1", UE->common_vars.txdataF[0],FRAME_LENGTH_COMPLEX_SAMPLES_NO_PREFIX,1,1); } - + } // input_fd == NULL - + tx_lev_dB = (unsigned int) dB_fixed_times10(tx_lev); if (n_frames==1) { @@ -1113,11 +1235,11 @@ int main(int argc, char **argv) //AWGN //Set target wideband RX noise level to N0 - sigma2_dB = N0;//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; + sigma2_dB = N0;//-10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12));//10*log10((double)tx_lev) +10*log10(UE->frame_parms.ofdm_symbol_size/(UE->frame_parms.N_RB_DL*12)) - SNR; sigma2 = pow(10,sigma2_dB/10); // compute tx_gain to achieve target SNR (per resource element!) - tx_gain = sqrt(pow(10.0,.1*(N0+SNR))*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); + tx_gain = sqrt(pow(10.0,.1*(N0+SNR))/(double)tx_lev);//*(nb_rb*12/(double)UE->frame_parms.ofdm_symbol_size)/(double)tx_lev); if (n_frames==1) @@ -1128,8 +1250,8 @@ int main(int argc, char **argv) for (i=0; i<OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &eNB->common_vars.rxdata[0][aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &ru->common.rxdata[aa][(frame_parms->samples_per_tti<<1) -frame_parms->ofdm_symbol_size])[2*i+1] = (short) ((sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } @@ -1186,37 +1308,37 @@ int main(int argc, char **argv) for (i=0; i<eNB->frame_parms.samples_per_tti; i++) { for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) { - ((short*) &eNB->common_vars.rxdata[0][aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); - ((short*) &eNB->common_vars.rxdata[0][aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( + ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i] = (short) ((tx_gain*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0)); + ((short*) &ru->common.rxdata[aa][eNB->frame_parms.samples_per_tti*subframe])[2*i+1] = (short) ((tx_gain*r_im[aa][i]) + (iqim*tx_gain*r_re[aa][i]) + sqrt( sigma2/2)*gaussdouble(0.0,1.0)); } } - if (n_frames==1) { + if (n_frames<=10) { printf("rx_level Null symbol %f\n",10*log10((double)signal_energy((int*) - &eNB->common_vars.rxdata[0][0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); - printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&eNB->common_vars.rxdata[0][0][160+(eNB->frame_parms.samples_per_tti*subframe)], + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); + printf("rx_level data symbol %f\n",10*log10(signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))); } - SNRmeas = 10*log10(((double)signal_energy((int*)&eNB->common_vars.rxdata[0][0][160+(eNB->frame_parms.samples_per_tti*subframe)], + SNRmeas = 10*log10(((double)signal_energy((int*)&ru->common.rxdata[0][160+(eNB->frame_parms.samples_per_tti*subframe)], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2))/((double)signal_energy((int*) - &eNB->common_vars.rxdata[0][0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], + &ru->common.rxdata[0][(eNB->frame_parms.samples_per_tti<<1) -eNB->frame_parms.ofdm_symbol_size], OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)) - 1)+10*log10(eNB->frame_parms.N_RB_UL/nb_rb); - if (n_frames==1) { + if (n_frames<=10) { printf("SNRmeas %f\n",SNRmeas); - // write_output("rxsig0UL.m","rxs0", &eNB->common_vars.rxdata[0][0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); - //write_output("rxsig1UL.m","rxs1", &eNB->common_vars.rxdata[0][0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + write_output("rxsig0UL.m","rxs0", &ru->common.rxdata[0][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); + if (eNB->frame_parms.nb_antennas_rx>1) write_output("rxsig1UL.m","rxs1", &ru->common.rxdata[1][eNB->frame_parms.samples_per_tti*subframe],eNB->frame_parms.samples_per_tti,1,1); } - eNB->fep = (parallel_flag == 1) ? eNB_fep_full_2thread : eNB_fep_full; + ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->do_prach = NULL; - phy_procedures_eNB_common_RX(eNB,proc_rxtx); + + ru->feprx(ru); phy_procedures_eNB_uespec_RX(eNB,proc_rxtx,no_relay); @@ -1249,10 +1371,10 @@ int main(int argc, char **argv) // printf("ulsch_coding: O[%d] %d\n",i,o_flip[i]); - + // if (ret <= eNB->ulsch[0]->max_turbo_iterations) { - - if (eNB->ulsch[0]->harq_processes[harq_pid]->round == 0) { + + if (eNB->ulsch[0]->harq_processes[harq_pid]->status == SCH_IDLE) { // avg_iter += ret; iter_trials++; @@ -1264,7 +1386,7 @@ int main(int argc, char **argv) print_CQI(eNB->ulsch[0]->harq_processes[harq_pid]->o, eNB->ulsch[0]->harq_processes[harq_pid]->uci_format,0,eNB->frame_parms.N_RB_DL); - dump_ulsch(eNB,proc_rxtx,0); + dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); exit(-1); } @@ -1293,18 +1415,17 @@ int main(int argc, char **argv) eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]); } - dump_ulsch(eNB,proc_rxtx,0); - exit(-1); + dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); + if (round == 4) exit(-1); } - // printf("round %d errors %d/%d\n",round,errs[round],trials); + if (n_frames==1) printf("round %d errors %d/%d\n",round,errs[round],trials); round++; if (n_frames==1) { printf("ULSCH in error in round %d\n",round); } } // ulsch error - } // round @@ -1324,7 +1445,7 @@ int main(int argc, char **argv) double t_rx = (double)eNB->phy_proc_rx.p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)eNB->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = (double)ru->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_demod = (double)eNB->ulsch_demodulation_stats.p_time/cpu_freq_GHz/1000.0; double t_rx_dec = (double)eNB->ulsch_decoding_stats.p_time/cpu_freq_GHz/1000.0; @@ -1449,12 +1570,12 @@ int main(int argc, char **argv) tx_lev_dB, 20*log10(tx_gain), (double)N0, - eNB->measurements[0].n0_power_tot_dB, + eNB->measurements.n0_power_tot_dB, get_hundred_times_delta_IF(UE,eNB_id,harq_pid) , dB_fixed(eNB->pusch_vars[0]->ulsch_power[0]), dB_fixed(eNB->pusch_vars[0]->ulsch_power[1]), - eNB->measurements->n0_power_dB[0], - eNB->measurements->n0_power_dB[1]); + eNB->measurements.n0_power_dB[0], + eNB->measurements.n0_power_dB[1]); effective_rate = ((double)(round_trials[0])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); @@ -1548,10 +1669,10 @@ int main(int argc, char **argv) printf("Total PHY proc rx :%f us (%d trials)\n",(double)eNB->phy_proc_rx.diff/eNB->phy_proc_rx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_rx.trials); printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - std_phy_proc_rx_fft = sqrt((double)eNB->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ofdm_demod_stats.trials - pow((double)eNB->ofdm_demod_stats.diff/eNB->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_demod time :%f us (%d trials)\n",(double)eNB->ofdm_demod_stats.diff/eNB->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, - eNB->ofdm_demod_stats.trials); + std_phy_proc_rx_fft = sqrt((double)ru->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, + 2)/ru->ofdm_demod_stats.trials - pow((double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); + printf("OFDM_demod time :%f us (%d trials)\n",(double)ru->ofdm_demod_stats.diff/ru->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, + ru->ofdm_demod_stats.trials); printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); std_phy_proc_rx_demod = sqrt((double)eNB->ulsch_demodulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, 2)/eNB->ulsch_demodulation_stats.trials - pow((double)eNB->ulsch_demodulation_stats.diff/eNB->ulsch_demodulation_stats.trials/cpu_freq_GHz/1000,2)); @@ -1672,7 +1793,7 @@ int main(int argc, char **argv) UE->ulsch_modulation_stats.trials, UE->ulsch_encoding_stats.trials, eNB->phy_proc_rx.trials, - eNB->ofdm_demod_stats.trials, + ru->ofdm_demod_stats.trials, eNB->ulsch_demodulation_stats.trials, eNB->ulsch_decoding_stats.trials ); @@ -1682,7 +1803,7 @@ int main(int argc, char **argv) get_time_meas_us(&UE->ulsch_modulation_stats), get_time_meas_us(&UE->ulsch_encoding_stats), get_time_meas_us(&eNB->phy_proc_rx), - get_time_meas_us(&eNB->ofdm_demod_stats), + get_time_meas_us(&ru->ofdm_demod_stats), get_time_meas_us(&eNB->ulsch_demodulation_stats), get_time_meas_us(&eNB->ulsch_decoding_stats) ); @@ -1733,7 +1854,7 @@ int main(int argc, char **argv) oai_exit=1; - pthread_cond_signal(&eNB->proc.cond_fep); + pthread_cond_signal(&ru->proc.cond_fep); if (abstx) { // ABSTRACTION fprintf(csv_fdUL,"];"); diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index f4004bdbf991c4c87bec639aacfb13d3071caf76..4debccc7b05075ce37e830420336551a29c6c323 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -77,6 +77,10 @@ #define MAX_MANAGED_ENB_PER_MOBILE 2 +///NB-IOT +#define NB_RB_MAX_NB_IOT (maxDRB_NB_r13 + 3) //MP: NB_IoT --> 2(DRB)+3(SRBs - 2 is not used) = 5 + + #define DEFAULT_RAB_ID 1 #define NB_RB_MAX (maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */ diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index be3d18c996126583c79b6df83f84754a34116dac..08ea93f427add5aa6dbd032e54180848cb3e85da 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -54,6 +54,7 @@ MESSAGE_DEF(RRC_STATE_IND, MESSAGE_PRIORITY_MED, RrcStateInd, //-------------------------------------------------------------------------------------------// // eNB: ENB_APP -> RRC messages MESSAGE_DEF(RRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED, RrcConfigurationReq, rrc_configuration_req) +MESSAGE_DEF(NBIOTRRC_CONFIGURATION_REQ, MESSAGE_PRIORITY_MED, NbIoTRrcConfigurationReq, nbiotrrc_configuration_req) // UE: NAS -> RRC messages MESSAGE_DEF(NAS_KENB_REFRESH_REQ, MESSAGE_PRIORITY_MED, NasKenbRefreshReq, nas_kenb_refresh_req) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 6fd0a0411363a1d0903dad4d5a45f223aeb37183..9bd25d3b3aa52075eaf3acf5f5c51b0f9f7581b5 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -62,6 +62,8 @@ typedef UL_DCCH_Message_t RrcUlDcchMessage; #define RRC_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_configuration_req +#define NBIOTRRC_CONFIGURATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nbiotrrc_configuration_req + #define NAS_KENB_REFRESH_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_kenb_refresh_req #define NAS_CELL_SELECTION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_cell_selection_req #define NAS_CONN_ESTABLI_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_establi_req @@ -167,6 +169,77 @@ typedef struct RrcConfigurationReq_s { long ue_TimersAndConstants_n311[MAX_NUM_CCs]; long ue_TransmissionMode[MAX_NUM_CCs]; } RrcConfigurationReq; +#define MAX_NUM_NBIOT_CELEVELS 3 +typedef struct NbIoTRrcConfigurationReq_s { + uint32_t cell_identity; + + uint16_t tac; + + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + lte_frame_type_t frame_type; + uint8_t tdd_config; + uint8_t tdd_config_s; + lte_prefix_type_t prefix_type; + lte_prefix_type_t prefix_type_UL; + int16_t eutra_band; + uint32_t downlink_frequency; + int32_t uplink_frequency_offset; + int16_t Nid_cell;// for testing, change later + int16_t N_RB_DL;// for testing, change later + //RACH + long rach_raResponseWindowSize_NB; + long rach_macContentionResolutionTimer_NB; + long rach_powerRampingStep_NB; + long rach_preambleInitialReceivedTargetPower_NB; + long rach_preambleTransMax_CE_NB; + //BCCH + long bcch_modificationPeriodCoeff_NB; + //PCCH + long pcch_defaultPagingCycle_NB; + long pcch_nB_NB; + long pcch_npdcch_NumRepetitionPaging_NB; + //NPRACH + long nprach_CP_Length; + long nprach_rsrp_range; + long nprach_Periodicity[MAX_NUM_NBIOT_CELEVELS]; + long nprach_StartTime[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierOffset[MAX_NUM_NBIOT_CELEVELS]; + long nprach_NumSubcarriers[MAX_NUM_NBIOT_CELEVELS]; + long numRepetitionsPerPreambleAttempt_NB[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierMSG3_RangeStart; + long maxNumPreambleAttemptCE_NB; + long npdcch_NumRepetitions_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_StartSF_CSS_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_Offset_RA[MAX_NUM_NBIOT_CELEVELS]; + //NPDSCH + long npdsch_nrs_Power; + //NPUSCH + long npusch_ack_nack_numRepetitions_NB; + long npusch_srs_SubframeConfig_NB; + long npusch_threeTone_CyclicShift_r13; + long npusch_sixTone_CyclicShift_r13; + BOOLEAN_t npusch_groupHoppingEnabled; + long npusch_groupAssignmentNPUSCH_r13; + + //DL_GapConfig + long dl_GapThreshold_NB; + long dl_GapPeriodicity_NB; + long dl_GapDurationCoeff_NB; + //Uplink power control Common + long npusch_p0_NominalNPUSCH; + long npusch_alpha; + long deltaPreambleMsg3; + //UE timers and constants + long ue_TimersAndConstants_t300_NB; + long ue_TimersAndConstants_t301_NB; + long ue_TimersAndConstants_t310_NB; + long ue_TimersAndConstants_t311_NB; + long ue_TimersAndConstants_n310_NB; + long ue_TimersAndConstants_n311_NB; +} NbIoTRrcConfigurationReq; + // UE: NAS -> RRC messages typedef kenb_refresh_req_t NasKenbRefreshReq; diff --git a/openair2/COMMON/tasks_def.h b/openair2/COMMON/tasks_def.h index 530365828dbaca39d594d5d278efb3cc73b29727..92d1ff4128fb5413dbd71de4e98eed9157eac15b 100644 --- a/openair2/COMMON/tasks_def.h +++ b/openair2/COMMON/tasks_def.h @@ -40,6 +40,10 @@ SUB_TASK_DEF(TASK_L2L1, TASK_PDCP_ENB, 200) /// Radio Resource Control task TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200) + +// Define here for now +TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200) + /// S1ap task /// RAL task for ENB TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 230917f673e33af455b864cd06d4cd50b56fd4b8..6cb79efb11ce90b8410bb2d14e7659711b5d0b2f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -17,7 +17,7 @@ *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org - */ + */ /*! \file flexran_agent_mac.c * \brief FlexRAN agent message handler for MAC layer @@ -40,7 +40,6 @@ #include "log.h" - /*Flags showing if a mac agent has already been registered*/ unsigned int mac_agent_registered[NUM_MAX_ENB]; @@ -54,7 +53,7 @@ struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; -int flexran_agent_mac_stats_reply(mid_t mod_id, +int flexran_agent_mac_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report) { @@ -62,38 +61,39 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // Protocol__FlexHeader *header; int i, j, k; - // int cc_id = 0; + int cc_id = 0; int enb_id = mod_id; /* Allocate memory for list of UE reports */ if (report_config->nr_ue > 0) { - - for (i = 0; i < report_config->nr_ue; i++) { + for (i = 0; i < report_config->nr_ue; i++) { + ue_report[i]->rnti = report_config->ue_report_type[i].ue_rnti; + ue_report[i]->has_rnti = 1; /* Check flag for creation of buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_BSR) { //TODO should be automated - ue_report[i]->n_bsr = 4; + ue_report[i]->n_bsr = 4; uint32_t *elem; elem = (uint32_t *) malloc(sizeof(uint32_t)*ue_report[i]->n_bsr); if (elem == NULL) goto error; for (j = 0; j < ue_report[i]->n_bsr; j++) { - // NN: we need to know the cc_id here, consider the first one + // NN: we need to know the cc_id here, consider the first one elem[j] = flexran_get_ue_bsr_ul_buffer_info (enb_id, i, j); } - + ue_report[i]->bsr = elem; } - + /* Check flag for creation of PHR report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_PHR) { ue_report[i]->phr = flexran_get_ue_phr (enb_id, i); // eNB_UE_list->UE_template[UE_PCCID(enb_id,i)][i].phr_info; ue_report[i]->has_phr = 1; - + } /* Check flag for creation of RLC buffer status report */ @@ -134,19 +134,19 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (ue_report[i]->n_rlc_report > 0) ue_report[i]->rlc_report = rlc_reports; - + } /* Check flag for creation of MAC CE buffer status report */ if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_CE_BS) { // TODO: Fill in the actual MAC CE buffer status report - ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; + ue_report[i]->pending_mac_ces = (flexran_get_MAC_CE_bitmap_TA(enb_id,i,0) | (0 << 1) | (0 << 2) | (0 << 3)) & 15; // Use as bitmap. Set one or more of the; /* Use as bitmap. Set one or more of the // PROTOCOL__FLEX_CE_TYPE__FLPCET_ values // found in stats_common.pb-c.h. See - // flex_ce_type in FlexRAN specification + // flex_ce_type in FlexRAN specification ue_report[i]->has_pending_mac_ces = 1; - + } /* Check flag for creation of DL CQI report */ @@ -167,7 +167,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, Protocol__FlexDlCsi **csi_reports; csi_reports = malloc(sizeof(Protocol__FlexDlCsi *)*dl_report->n_csi_report); if (csi_reports == NULL) - goto error; + goto error; for (j = 0; j < dl_report->n_csi_report; j++) { csi_reports[j] = malloc(sizeof(Protocol__FlexDlCsi)); @@ -211,18 +211,18 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (csi11 == NULL) goto error; protocol__flex_csi_p11__init(csi11); - - csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); + + csi11->wb_cqi = malloc(sizeof(csi11->wb_cqi)); csi11->n_wb_cqi = 1; - csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); - // According To spec 36.213 - + csi11->wb_cqi[0] = flexran_get_ue_wcqi (enb_id, i); + // According To spec 36.213 + if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 1) { // TODO PMI csi11->wb_pmi = flexran_get_ue_wpmi(enb_id, i, 0); csi11->has_wb_pmi = 1; - } + } else if (flexran_get_antenna_ports(enb_id, j) == 2 && csi_reports[j]->ri == 2){ // TODO PMI @@ -239,14 +239,14 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } - csi11->has_wb_pmi = 0; + csi11->has_wb_pmi = 0; csi_reports[j]->p11csi = csi11; } - - + + else if(csi_reports[j]->report_case == PROTOCOL__FLEX_DL_CSI__REPORT_P20CSI){ @@ -256,16 +256,16 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, if (csi20 == NULL) goto error; protocol__flex_csi_p20__init(csi20); - - csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); csi20->has_wb_cqi = 1; - + csi20->bandwidth_part_index = 1 ;//TODO csi20->has_bandwidth_part_index = 1; csi20->sb_index = 1 ;//TODO - csi20->has_sb_index = 1 ; + csi20->has_sb_index = 1 ; csi_reports[j]->p20csi = csi20; @@ -280,20 +280,20 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // if (csi21 == NULL) // goto error; // protocol__flex_csi_p21__init(csi21); - - // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); - - + + // csi21->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi21->wb_pmi = flexran_get_ue_pmi(enb_id); //TDO inside // csi21->has_wb_pmi = 1; - // csi21->sb_cqi = 1; // TODO - + // csi21->sb_cqi = 1; // TODO + // csi21->bandwidth_part_index = 1 ; //TDO inside - // csi21->has_bandwidth_part_index = 1 ; + // csi21->has_bandwidth_part_index = 1 ; // csi21->sb_index = 1 ;//TODO - // csi21->has_sb_index = 1 ; + // csi21->has_sb_index = 1 ; // csi_reports[j]->p20csi = csi21; @@ -308,10 +308,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // if (csi12 == NULL) // goto error; // protocol__flex_csi_a12__init(csi12); - - // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); - - // csi12->sb_pmi = 1 ; //TODO inside + + // csi12->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi12->sb_pmi = 1 ; //TODO inside // TODO continou } @@ -323,18 +323,18 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // if (csi22 == NULL) // goto error; // protocol__flex_csi_a22__init(csi22); - - // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); - - // csi22->sb_cqi = 1 ; //TODO inside - // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i); + // csi22->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + + // csi22->sb_cqi = 1 ; //TODO inside + + // csi22->wb_pmi = flexran_get_ue_wcqi (enb_id, i); // csi22->has_wb_pmi = 1; - - // csi22->sb_pmi = 1 ; //TODO inside + + // csi22->sb_pmi = 1 ; //TODO inside // csi22->has_wb_pmi = 1; - // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i); + // csi22->sb_list = flexran_get_ue_wcqi (enb_id, i); } @@ -347,10 +347,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, // goto error; // protocol__flex_csi_a20__init(csi20); - // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); + // csi20->wb_cqi = flexran_get_ue_wcqi (enb_id, i); // csi20->has_wb_cqi = 1; - // csi20>sb_cqi = 1 ; //TODO inside + // csi20>sb_cqi = 1 ; //TODO inside // csi20>has_sb_cqi = 1 ; // csi20->sb_list = 1; // TODO inside @@ -371,7 +371,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, dl_report->csi_report = csi_reports; //Add the DL CQI report to the stats report ue_report[i]->dl_cqi_report = dl_report; - + } /* Check flag for creation of paging buffer status report */ @@ -463,7 +463,7 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, //TODO: Set the servCellIndex for this report ul_report[j]->serv_cell_index = 0; ul_report[j]->has_serv_cell_index = 1; - + //Set the list of UL reports of this UE to the full UL report full_ul_report->cqi_meas = ul_report; @@ -487,24 +487,119 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, } // Add full UL CQI report to the UE report ue_report[i]->ul_cqi_report = full_ul_report; - - } - - - - } + } + if (report_config->ue_report_type[i].ue_report_flags & PROTOCOL__FLEX_UE_STATS_TYPE__FLUST_MAC_STATS) { + + Protocol__FlexMacStats *macstats; + macstats = malloc(sizeof(Protocol__FlexMacStats)); + if (macstats == NULL) + goto error; + protocol__flex_mac_stats__init(macstats); + + + macstats->total_bytes_sdus_dl = flexran_get_total_size_dl_mac_sdus(mod_id, i, cc_id); + macstats->has_total_bytes_sdus_dl = 1; + + macstats->total_bytes_sdus_ul = flexran_get_total_size_ul_mac_sdus(mod_id, i, cc_id); + macstats->has_total_bytes_sdus_ul = 1; + + macstats->tbs_dl = flexran_get_TBS_dl(mod_id, i, cc_id); + macstats->has_tbs_dl = 1; + + macstats->tbs_ul = flexran_get_TBS_ul(mod_id, i, cc_id); + macstats->has_tbs_ul = 1; + + macstats->prb_retx_dl = flexran_get_num_prb_retx_dl_per_ue(mod_id, i, cc_id); + macstats->has_prb_retx_dl = 1; + + macstats->prb_retx_ul = flexran_get_num_prb_retx_ul_per_ue(mod_id, i, cc_id); + macstats->has_prb_retx_ul = 1; + + macstats->prb_dl = flexran_get_num_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->has_prb_dl = 1; + + macstats->prb_ul = flexran_get_num_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->has_prb_ul = 1; + + macstats->mcs1_dl = flexran_get_mcs1_dl(mod_id, i, cc_id); + macstats->has_mcs1_dl = 1; + + macstats->mcs2_dl = flexran_get_mcs2_dl(mod_id, i, cc_id); + macstats->has_mcs2_dl = 1; + + macstats->mcs1_ul = flexran_get_mcs1_ul(mod_id, i, cc_id); + macstats->has_mcs1_ul = 1; + + macstats->mcs2_ul = flexran_get_mcs2_ul(mod_id, i, cc_id); + macstats->has_mcs2_ul = 1; + + macstats->total_prb_dl = flexran_get_total_prb_dl_tx_per_ue(mod_id, i, cc_id); + macstats->has_total_prb_dl = 1; + + macstats->total_prb_ul = flexran_get_total_prb_ul_rx_per_ue(mod_id, i, cc_id); + macstats->has_total_prb_ul = 1; + + macstats->total_pdu_dl = flexran_get_total_num_pdu_dl(mod_id, i, cc_id); + macstats->has_total_pdu_dl = 1; - - - - } + macstats->total_pdu_ul = flexran_get_total_num_pdu_ul(mod_id, i, cc_id); + macstats->has_total_pdu_ul = 1; + + macstats->total_tbs_dl = flexran_get_total_TBS_dl(mod_id, i, cc_id); + macstats->has_total_tbs_dl = 1; + + macstats->total_tbs_ul = flexran_get_total_TBS_ul(mod_id, i, cc_id); + macstats->has_total_tbs_ul = 1; + + macstats->harq_round = flexran_get_harq_round(mod_id, cc_id, i); + macstats->has_harq_round = 1; + + Protocol__FlexMacSdusDl ** mac_sdus; + mac_sdus = malloc(sizeof(Protocol__FlexMacSdusDl) * flexran_get_num_mac_sdu_tx(mod_id, i, cc_id)); + if (mac_sdus == NULL) + goto error; + + macstats->n_mac_sdus_dl = flexran_get_num_mac_sdu_tx(mod_id, i, cc_id); + + for (j = 0; j < macstats->n_mac_sdus_dl; j++){ + + + mac_sdus[j] = malloc(sizeof(Protocol__FlexMacSdusDl)); + protocol__flex_mac_sdus_dl__init(mac_sdus[j]); + + mac_sdus[j]->lcid = flexran_get_mac_sdu_lcid_index(mod_id, i, cc_id, j); + mac_sdus[j]->has_lcid = 1; + + mac_sdus[j]->sdu_length = flexran_get_mac_sdu_size(mod_id, i, cc_id, mac_sdus[j]->lcid); + mac_sdus[j]->has_sdu_length = 1; + + + } + + + macstats->mac_sdus_dl = mac_sdus; + + + ue_report[i]->mac_stats = macstats; + + } + + + + + } + + + + + } /* Allocate memory for list of cell reports */ if (report_config->nr_cc > 0) { - - + + // Fill in the Cell reports for (i = 0; i < report_config->nr_cc; i++) { @@ -532,10 +627,10 @@ int flexran_agent_mac_stats_reply(mid_t mod_id, cell_report[i]->noise_inter_report = ni_report; } } - - - + + + } return 0; @@ -740,9 +835,9 @@ int flexran_agent_mac_destroy_sr_info(Protocol__FlexranMessage *msg) { int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__FlexranMessage **msg) { Protocol__FlexHeader *header = NULL; int i, j, UE_id; - + int available_harq[NUMBER_OF_UE_MAX]; - + const int xid = *((int *)params); @@ -764,12 +859,12 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle } int ahead_of_time = 0; - + frame = (frame_t) flexran_get_current_system_frame_num(mod_id); subframe = (sub_frame_t) flexran_get_current_subframe(mod_id); subframe = ((subframe + ahead_of_time) % 10); - + if (subframe < flexran_get_current_subframe(mod_id)) { frame = (frame + 1) % 1024; } @@ -792,7 +887,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle } } } - + // LOG_I(FLEXRAN_AGENT, "Sending subframe trigger for frame %d and subframe %d\n", flexran_get_current_frame(mod_id), (flexran_get_current_subframe(mod_id) + 1) % 10); @@ -825,8 +920,8 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle // uint8_t harq_id; //uint8_t harq_status; // flexran_get_harq(mod_id, UE_PCCID(mod_id,i), i, frame, subframe, &harq_id, &harq_status); - - + + dl_info[i]->harq_process_id = available_harq[UE_id]; if (RC.mac && RC.mac[mod_id]) RC.mac[mod_id]->UE_list.eNB_UE_stats[UE_PCCID(mod_id,i)][UE_id].harq_pid = 0; @@ -915,7 +1010,7 @@ int flexran_agent_mac_sf_trigger(mid_t mod_id, const void *params, Protocol__Fle for (i = 0; i < sf_trigger_msg->n_dl_info; i++) { free(sf_trigger_msg->dl_info[i]->harq_status); } - free(sf_trigger_msg->dl_info); + free(sf_trigger_msg->dl_info); free(sf_trigger_msg->ul_info); free(sf_trigger_msg); } @@ -1089,7 +1184,7 @@ int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { free(msg->ul_mac_config_msg->header); for (i = 0; i < msg->ul_mac_config_msg->n_ul_ue_data; i++) { // TODO uplink rlc ... - // free(msg->ul_mac_config_msg->dl_ue_data[i]->ce_bitmap); + // free(msg->ul_mac_config_msg->dl_ue_data[i]->ce_bitmap); // for (j = 0; j < msg->ul_mac_config_msg->ul_ue_data[i]->n_rlc_pdu; j++) { // for (k = 0; k < msg->ul_mac_config_msg->ul_ue_data[i]->rlc_pdu[j]->n_rlc_pdu_tb; k++) { // free(msg->ul_mac_config_msg->dl_ue_data[i]->rlc_pdu[j]->rlc_pdu_tb[k]); @@ -1107,7 +1202,7 @@ int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { // free(msg->ul_mac_config_msg->ul_ue_data[i]); } free(msg->ul_mac_config_msg->ul_ue_data); - + free(msg->ul_mac_config_msg); free(msg); @@ -1121,10 +1216,10 @@ int flexran_agent_mac_destroy_ul_config(Protocol__FlexranMessage *msg) { void flexran_agent_get_pending_dl_mac_config(mid_t mod_id, Protocol__FlexranMessage **msg) { struct lfds700_misc_prng_state ls; - + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; lfds700_misc_prng_init(&ls); - + if (lfds700_ringbuffer_read(&ringbuffer_state[mod_id], NULL, (void **) msg, &ls) == 0) { *msg = NULL; } @@ -1135,10 +1230,10 @@ int flexran_agent_mac_handle_dl_mac_config(mid_t mod_id, const void *params, Pro struct lfds700_misc_prng_state ls; enum lfds700_misc_flag overwrite_occurred_flag; Protocol__FlexranMessage *overwritten_dl_config; - + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; lfds700_misc_prng_init(&ls); - + lfds700_ringbuffer_write( &ringbuffer_state[mod_id], NULL, (void *) params, @@ -1252,7 +1347,7 @@ int flexran_agent_register_mac_xface(mid_t mod_id, AGENT_MAC_xface *xface) { xface->flexran_agent_send_sf_trigger = flexran_agent_send_sf_trigger; //xface->flexran_agent_send_update_mac_stats = flexran_agent_send_update_mac_stats; xface->flexran_agent_get_pending_dl_mac_config = flexran_agent_get_pending_dl_mac_config; - + xface->dl_scheduler_loaded_lib = NULL; xface->ul_scheduler_loaded_lib = NULL; mac_agent_registered[mod_id] = 1; diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c index 25ec91912742b7a3fd38f026edd2da40395fce63..43455fa32a4043edeac6eda7c869b0fe2c783348 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h index a962390c00eaea5560f8717293ee76e40d49c76e..83aac45406e17b5f5526898e45a5212475cd2e9b 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h index 46bdf744de1a03008551f2e2193c339dc25d3ab1..f2da72545af810f801ff8d65b5b9f8579a5f8184 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/PDCP/flexran_agent_pdcp_defs.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index e88c4eaccfaa773eb98fcc7f5a3e2bb466f15d46..43951ee95afb6adfb2dfd8febb70aa4326198f5e 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h index ae26b4162116268f8de7227a8c532539a0ca7081..780976893e575f32c22edcf8066191e47d981ed3 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index cf20c477de83cea1304d540a254f16b0a5c22aa2..8c336abef1a54e3acf3e2f571251d697a595a373 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/L1_paramdef.h b/openair2/ENB_APP/L1_paramdef.h new file mode 100644 index 0000000000000000000000000000000000000000..b062235ff69b6aaefb5cc40bff392419df524df3 --- /dev/null +++ b/openair2/ENB_APP/L1_paramdef.h @@ -0,0 +1,73 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/L1_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/* L1 configuration parameters names */ +#define CONFIG_STRING_L1_CC "num_cc" +#define CONFIG_STRING_L1_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_L1_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_L1_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_L1_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_L1_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* L1 configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define L1PARAMS_DESC { \ +{CONFIG_STRING_L1_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ +{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ +} +#define L1_CC_IDX 0 +#define L1_TRANSPORT_N_PREFERENCE_IDX 1 +#define L1_LOCAL_N_IF_NAME_IDX 2 +#define L1_LOCAL_N_ADDRESS_IDX 3 +#define L1_REMOTE_N_ADDRESS_IDX 4 +#define L1_LOCAL_N_PORTC_IDX 5 +#define L1_REMOTE_N_PORTC_IDX 6 +#define L1_LOCAL_N_PORTD_IDX 7 +#define L1_REMOTE_N_PORTD_IDX 8 + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h new file mode 100644 index 0000000000000000000000000000000000000000..4e732fe942bee9528bf6bde32e60e4b2cd2cbba6 --- /dev/null +++ b/openair2/ENB_APP/MACRLC_paramdef.h @@ -0,0 +1,98 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/MACRLC_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + + + +/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +/* MACRLC configuration parameters names */ +#define CONFIG_STRING_MACRLC_CC "num_cc" +#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference" +#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc" +#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" +#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" +#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" +#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME "local_s_if_name" +#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" +#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" +#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" +#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* MacRLC configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define MACRLCPARAMS_DESC { \ +{CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_L1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_RRC", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +} +#define MACRLC_CC_IDX 0 +#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 +#define MACRLC_LOCAL_N_IF_NAME_IDX 2 +#define MACRLC_LOCAL_N_ADDRESS_IDX 3 +#define MACRLC_REMOTE_N_ADDRESS_IDX 4 +#define MACRLC_LOCAL_N_PORTC_IDX 5 +#define MACRLC_REMOTE_N_PORTC_IDX 6 +#define MACRLC_LOCAL_N_PORTD_IDX 7 +#define MACRLC_REMOTE_N_PORTD_IDX 8 +#define MACRLC_TRANSPORT_S_PREFERENCE_IDX 9 +#define MACRLC_LOCAL_S_IF_NAME_IDX 10 +#define MACRLC_LOCAL_S_ADDRESS_IDX 11 +#define MACRLC_REMOTE_S_ADDRESS_IDX 12 +#define MACRLC_LOCAL_S_PORTC_IDX 13 +#define MACRLC_REMOTE_S_PORTC_IDX 14 +#define MACRLC_LOCAL_S_PORTD_IDX 15 +#define MACRLC_REMOTE_S_PORTD_IDX 16 +/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto index f651195ab14c51359788acf770a9bc9df42890c6..ee286981f52f89bf4fe979d1b165fb220b7efa4e 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto @@ -269,3 +269,39 @@ message flex_pdcp_stats { optional uint64 sfn=17; } + +// +// MAC Stats +// + +message flex_mac_stats { + + optional uint32 tbs_dl = 1; + optional uint32 tbs_ul = 2; + optional uint32 prb_retx_dl = 3; + optional uint32 prb_retx_ul = 4; + optional uint32 prb_dl = 5; + optional uint32 prb_ul = 6; + optional uint32 mcs1_dl = 7; + optional uint32 mcs2_dl = 8; + optional uint32 mcs1_ul = 9; + optional uint32 mcs2_ul = 10; + optional uint32 total_bytes_sdus_ul = 11; + optional uint32 total_bytes_sdus_dl = 12; + optional uint32 total_prb_retx_dl = 13; + optional uint32 total_prb_retx_ul = 14; + optional uint32 total_prb_dl = 15; + optional uint32 total_prb_ul = 16; + optional uint32 total_pdu_dl = 17; + optional uint32 total_pdu_ul = 18; + optional uint32 total_tbs_dl = 19; + optional uint32 total_tbs_ul = 20; + repeated flex_mac_sdus_dl mac_sdus_dl = 21; + optional uint32 harq_round = 22; +} + +message flex_mac_sdus_dl { + + optional uint32 sdu_length = 1; + optional uint32 lcid = 2; +} diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto index b8126c55f221a1d8733436a86d42b742391074fd..8eb6510de3ca0c78a3a90bdec955616a29924875 100644 --- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto @@ -48,7 +48,8 @@ message flex_ue_stats_report { optional flex_paging_buffer_report pbr = 8; optional flex_ul_cqi_report ul_cqi_report = 9; optional flex_rrc_measurements rrc_measurements = 10; - optional flex_pdcp_stats pdcp_stats = 11; + optional flex_pdcp_stats pdcp_stats = 11; + optional flex_mac_stats mac_stats = 12; } // @@ -85,9 +86,11 @@ enum flex_ue_stats_type { FLUST_DL_CQI = 16; FLUST_PBS = 32; FLUST_UL_CQI = 64; + FLUST_MAC_STATS = 128; FLUST_PDCP_STATS = 1024; FLUST_RRC_MEASUREMENTS = 65536; // To be extended with more types of stats - + + } diff --git a/openair2/ENB_APP/NB_IoT_config.c b/openair2/ENB_APP/NB_IoT_config.c new file mode 100644 index 0000000000000000000000000000000000000000..09e22ef8457b17578be6f03b9a17e4d3b8988607 --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_config.c @@ -0,0 +1,286 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + nbiot_config.c + ------------------- + AUTHOR : Francois Taburet + COMPANY : NOKIA + EMAIL : francois.taburet@nokia-bell-labs.com +*/ + +#include <string.h> +#include <inttypes.h> + +#include "log.h" +#include "log_extern.h" +#include "assertions.h" +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# if defined(ENABLE_USE_MME) +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# endif +#endif +#include "SystemInformationBlockType2.h" + +#include "PHY/extern.h" +#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h" +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "RRC_paramsvalues.h" +#include "NB_IoT_paramdef.h" +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" +#include "LAYER2/MAC/proto_NB_IoT.h" + + +void RCconfig_NbIoTL1(void) { + paramdef_t NbIoT_L1_Params[] = L1PARAMS_DESC; + paramlist_def_t NbIoT_L1_ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0}; + +/* No component carrier for NbIoT, ignore number of CC */ +// NbIoT_L1_Params[L1_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + + config_getlist( &NbIoT_L1_ParamList,NbIoT_L1_Params,sizeof(NbIoT_L1_Params)/sizeof(paramdef_t), NULL); + if (NbIoT_L1_ParamList.numelt > 0) { + if (RC.L1_NB_IoT == NULL) { + RC.L1_NB_IoT = (PHY_VARS_eNB_NB_IoT **)malloc(RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); + LOG_I(PHY,"RC.L1_NB_IoT = %p\n",RC.L1_NB_IoT); + memset(RC.L1_NB_IoT,0,RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *)); + } + + + for(int j = 0; j <NbIoT_L1_ParamList.numelt ; j++) { + if (RC.L1_NB_IoT[j] == NULL) { + RC.L1_NB_IoT[j] = (PHY_VARS_eNB_NB_IoT *)malloc(sizeof(PHY_VARS_eNB_NB_IoT)); + LOG_I(PHY,"RC.L1_NB_IoT[%d] = %p\n",j,RC.L1_NB_IoT[j]); + memset(RC.L1_NB_IoT[j],0,sizeof(PHY_VARS_eNB_NB_IoT)); + } + if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) { + + } + else if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) { + RC.L1_NB_IoT[j]->eth_params_n.local_if_name = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.remote_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr)); + RC.L1_NB_IoT[j]->eth_params_n.my_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.my_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.remote_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr); + RC.L1_NB_IoT[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + } + + else { // other midhaul + } + }// j=0..num_inst + printf("Initializing northbound interface for NB-IoT L1\n"); + l1_north_init_NB_IoT(); + } else { + LOG_I(PHY,"No " NBIOT_L1LIST_CONFIG_STRING " configuration found"); + } +} + +void RCconfig_NbIoTmacrlc(void) { + + + + paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC; + paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; + + +/* No component carrier for NbIoT, ignore number of CC */ +// NbIoT_MacRLC_Params[MACRLC_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD; + + config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params,sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), NULL); + + + if ( NbIoT_MacRLC_ParamList.numelt > 0) { + mac_top_init_eNB_NB_IoT(); + for (int j=0;j<RC.nb_nb_iot_macrlc_inst;j++) { + + if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) { + // check number of instances is same as RRC/PDCP + + } else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) { + RC.nb_iot_mac[j]->eth_params_n.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_n.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_n.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);; + RC.nb_iot_mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE; + } else { // other midhaul + AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr)); + } + + if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) { + + + } else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) { + RC.nb_iot_mac[j]->eth_params_s.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr)); + RC.nb_iot_mac[j]->eth_params_s.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); + RC.nb_iot_mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; + } else { // other midhaul + AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); + } + }// j=0..num_inst */ + } else {// MacRLC_ParamList.numelt > 0 + AssertFatal (0, + "No " NBIOT_MACRLCLIST_CONFIG_STRING " configuration found"); + } +} + + + + +int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc) { + + + char instprefix[MAX_OPTNAME_SIZE*3 + 32]; + + + checkedparam_t NBIoTCheckParams[] = NBIOT_RRCPARAMS_CHECK_DESC; + paramdef_t NBIoTParams[] = NBIOTRRCPARAMS_DESC; + + paramdef_t NBIoTPrachParams[] = NBIOTRRC_NPRACH_PARAMS_DESC; + checkedparam_t NBIoTPrachCheckParams[] = NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC; + + paramdef_t NBIoTRRCRefParams[] = NBIOTRRCPARAMS_RRCREF_DESC; + + paramdef_t NBIoTLteCCParams[] = NBIOT_LTECCPARAMS_DESC; + checkedparam_t NBIoTLteCCCheckParams[] = NBIOT_LTECCPARAMS_CHECK_DESC; +/* map parameter checking array instances to parameter definition array instances */ + for (int i=0; (i<sizeof(NBIoTParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTCheckParams)/sizeof(checkedparam_t)); i++ ) { + NBIoTParams[i].chkPptr = &(NBIoTCheckParams[i]); + } + for (int i=0; (i<sizeof(NBIoTPrachParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTPrachCheckParams)/sizeof(checkedparam_t)); i++ ) { + NBIoTPrachParams[i].chkPptr = &(NBIoTPrachCheckParams[i]); + } + +/* brut force itti message fields assignment, to be redesigned with itti replacement */ + NBIoTParams[NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize_NB); + NBIoTParams[NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer_NB); + NBIoTParams[NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep_NB); + NBIoTParams[NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower_NB); + NBIoTParams[NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax_CE_NB); + NBIoTParams[NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff_NB); + NBIoTParams[NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle_NB); + NBIoTParams[NBIOT_NPRACH_CP_LENGTH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_CP_Length); + NBIoTParams[NBIOT_NPRACH_RSRP_RANGE_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_rsrp_range); + + + + NBIoTParams[NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).maxNumPreambleAttemptCE_NB); + + NBIoTParams[NBIOT_NPDSCH_NRS_POWER_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdsch_nrs_Power); + NBIoTParams[NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_ack_nack_numRepetitions_NB); + NBIoTParams[NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_srs_SubframeConfig_NB); + NBIoTParams[NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_threeTone_CyclicShift_r13); + NBIoTParams[NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_sixTone_CyclicShift_r13); + + NBIoTParams[NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupAssignmentNPUSCH_r13); + NBIoTParams[NBIOT_DL_GAPTHRESHOLD_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapThreshold_NB); + NBIoTParams[NBIOT_DL_GAPPERIODICITY_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapPeriodicity_NB); + + NBIoTParams[NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_p0_NominalNPUSCH); + + NBIoTParams[NBIOT_DELTAPREAMBLEMSG3_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).deltaPreambleMsg3); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310_NB); + NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311_NB); + + sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]",nbiotrrc_id); + config_get( NBIoTParams,sizeof(NBIoTParams)/sizeof(paramdef_t),instprefix); + + NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierMSG3_RangeStart = config_get_processedint( &(NBIoTParams[NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX]) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupHoppingEnabled = config_get_processedint( &(NBIoTParams[NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX] ) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapDurationCoeff_NB = config_get_processedint( &(NBIoTParams[NBIOT_DL_GAPDURATIONCOEFF_NB_IDX] ) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_alpha = config_get_processedint( &(NBIoTParams[NBIOT_NPUSCH_ALPHA_IDX] ) ); + for (int i=0; i<MAX_NUM_NBIOT_CELEVELS; i++) { + char *tmpptr=NULL; + NBIoTPrachParams[NBIOT_NPRACH_PERIODICITY_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_Periodicity[i]); + NBIoTPrachParams[NBIOT_NPRACH_STARTTIME_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_StartTime[i]); + NBIoTPrachParams[NBIOT_NPRACH_SUBCARRIEROFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierOffset[i]); + NBIoTPrachParams[NBIOT_NPRACH_NUMSUBCARRIERS_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_NumSubcarriers[i]); + NBIoTPrachParams[NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).numRepetitionsPerPreambleAttempt_NB[i]); + NBIoTParams[NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_NumRepetitions_RA[i]); + NBIoTParams[NBIOT_NPDCCH_STARTSF_CSS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_StartSF_CSS_RA[i]); + NBIoTParams[NBIOT_NPDCCH_OFFSET_RA_IDX].strptr = &tmpptr; + sprintf(instprefix, "%s.[%i].%s.[%i]",NBIOT_RRCLIST_CONFIG_STRING, nbiotrrc_id,NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING,i); + config_get( NBIoTPrachParams,sizeof(NBIoTPrachParams)/sizeof(paramdef_t),instprefix); + NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_Offset_RA[i] = config_get_processedint( &(NBIoTPrachParams[NBIOT_NPDCCH_OFFSET_RA_IDX]) ); + } +/* get the LTE RRC and CC this NB-IoT RRC instance is attached to */ + sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]." NBIOT_LTERRCREF_CONFIG_STRING, nbiotrrc_id ); + config_get( NBIoTRRCRefParams,sizeof(NBIoTRRCRefParams)/sizeof(paramdef_t),instprefix); + +/* read SIB1 parameters in the LTE RRC and CC sections */ + sprintf(instprefix, ENB_CONFIG_STRING_ENB_LIST ".[%i]." ENB_CONFIG_STRING_COMPONENT_CARRIERS ".[%i]", + *(NBIoTRRCRefParams[NBIOT_RRCINST_IDX].uptr), *(NBIoTRRCRefParams[NBIOT_CCINST_IDX].uptr)); + + NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config); + NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_S_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config_s); + NBIoTLteCCParams[LTECCPARAMS_EUTRA_BAND_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).eutra_band); + NBIoTLteCCParams[LTECCPARAMS_DOWNLINK_FREQUENCY_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).downlink_frequency); + NBIoTLteCCParams[LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset); + NBIoTLteCCParams[LTECCPARAMS_NID_CELL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).Nid_cell); + NBIoTLteCCParams[LTECCPARAMS_N_RB_DL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).N_RB_DL); + + for (int i=0; (i<sizeof(NBIoTLteCCParams)/sizeof(paramdef_t)) && (i<sizeof(NBIoTLteCCCheckParams)/sizeof(checkedparam_t)); i++ ) { + NBIoTLteCCParams[i].chkPptr = &(NBIoTLteCCCheckParams[i]); + } + config_get( NBIoTLteCCParams,sizeof(NBIoTLteCCParams)/sizeof(paramdef_t),instprefix); + NBIOTRRC_CONFIGURATION_REQ (msg_p).frame_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_FRAME_TYPE_IDX]) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_IDX]) ); + NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint( &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_UL_IDX]) ); +return 0; +} + +void RCConfig_NbIoT(RAN_CONTEXT_t *RC) { + + paramlist_def_t NbIoT_MACRLCParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; + paramlist_def_t NbIoT_L1ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0}; + paramlist_def_t NbIoT_ParamList = {NBIOT_RRCLIST_CONFIG_STRING,NULL,0}; + + + config_getlist( &NbIoT_ParamList,NULL,0,NULL); + RC->nb_nb_iot_rrc_inst = NbIoT_ParamList.numelt; + + + + + config_getlist( &NbIoT_MACRLCParamList,NULL,0, NULL); + RC->nb_nb_iot_macrlc_inst = NbIoT_MACRLCParamList.numelt; + // Get num L1 instances + config_getlist( &NbIoT_L1ParamList,NULL,0, NULL); + RC->nb_nb_iot_L1_inst = NbIoT_L1ParamList.numelt; + +} diff --git a/openair2/ENB_APP/NB_IoT_config.h b/openair2/ENB_APP/NB_IoT_config.h new file mode 100644 index 0000000000000000000000000000000000000000..314fca81802124b8258e99af1616e1455a840607 --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_config.h @@ -0,0 +1,37 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + nbiot_config.h + ------------------- + AUTHOR : Francois Taburet + COMPANY : NOKIA + EMAIL : francois.taburet@nokia-bell-labs.com +*/ +#ifndef INCLUDE_NBIOT_CONFIG_H +#define INCLUDE_NBIOT_CONFIG_H + + +extern void RCconfig_NbIoTL1(void) ; +extern void RCconfig_NbIoTmacrlc(void); +extern int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc); +extern void RCConfig_NbIoT(RAN_CONTEXT_t *RC); +#endif diff --git a/openair2/ENB_APP/NB_IoT_interface.c b/openair2/ENB_APP/NB_IoT_interface.c new file mode 100644 index 0000000000000000000000000000000000000000..30ffbb3bb550f6fdcb1cc19075e120df2dac5d9b --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_interface.c @@ -0,0 +1,58 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/NB_IoT_interface.c + * \brief: load library implementing coding/decoding algorithms + * \date 2018 + * \version 0.1 + * \note + * \warning + */ +#define _GNU_SOURCE +#include <sys/types.h> + + +#include "openair1/PHY/extern.h" +#include "common/utils/load_module_shlib.h" +#define NBIOT_INTERFACE_SOURCE +#include "NB_IoT_interface.h" + + + + +int load_NB_IoT(void) { + int ret; + RCConfig_NbIoT_f_t RCConfig; + loader_shlibfunc_t shlib_fdesc[]=NBIOT_INTERFACE_FLIST; + + ret=load_module_shlib(NBIOT_MODULENAME,shlib_fdesc,sizeof(shlib_fdesc)/sizeof(loader_shlibfunc_t)); + if (ret) { + return ret; + } + RCConfig = get_shlibmodule_fptr(NBIOT_MODULENAME,NBIOT_RCCONFIG_FNAME ); + if (RCConfig == NULL) { + return -1; + } + + RCConfig(&RC); +return 0; +} + diff --git a/openair2/ENB_APP/NB_IoT_interface.h b/openair2/ENB_APP/NB_IoT_interface.h new file mode 100644 index 0000000000000000000000000000000000000000..b3454b077bc1cc64aa514c5abed78c7a8c53138e --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_interface.h @@ -0,0 +1,50 @@ +/* + *Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/NB_IoT_interface.h + * \brief: api interface for nb-iot application + * \date 2018 + * \version 0.1 + * \note + * \warning + */ +#ifndef NBIOT_INTERFACE_H +#define NBIOT_INTERFACE_H + + +#define NBIOT_MODULENAME "NB_IoT" + +typedef void(*RCConfig_NbIoT_f_t)(RAN_CONTEXT_t *RC); +#define NBIOT_RCCONFIG_FNAME "RCConfig_NbIoT" + +#ifdef NBIOT_INTERFACE_SOURCE + +#define NBIOT_INTERFACE_FLIST {\ +{NBIOT_RCCONFIG_FNAME,NULL},\ +} + +#else /* NBIOT_INTERFACE_SOURCE */ + +extern int load_NB_IoT(void); + +#endif + +#endif diff --git a/openair2/ENB_APP/NB_IoT_paramdef.h b/openair2/ENB_APP/NB_IoT_paramdef.h new file mode 100644 index 0000000000000000000000000000000000000000..6409fe63ee56479b9cc1fca486b9d63bd77f8bda --- /dev/null +++ b/openair2/ENB_APP/NB_IoT_paramdef.h @@ -0,0 +1,400 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/enb_paramdef.f + * \brief definition of configuration parameters for all eNodeB modules + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + +#include "common/config/config_paramdesc.h" +#include "SystemInformationBlockType2.h" +#include "DL-GapConfig-NB-r13.h" +#include "NPRACH-Parameters-NB-r13.h" +#include "PowerRampingParameters.h" +#include "BCCH-Config-NB-r13.h" +#include "PCCH-Config-NB-r13.h" +#include "ACK-NACK-NumRepetitions-NB-r13.h" +#include "TDD-Config.h" + + + + + +/* + int16_t eutra_band; + uint32_t downlink_frequency; + int32_t uplink_frequency_offset; + int16_t Nid_cell;// for testing, change later + int16_t N_RB_DL;// for testing, change later +*/ +/*-------------------------------------------------------------------------------------------------------------------*/ +/* SIB1 parameters possibly coming from LTE RRC (in band deployment) */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* component carriers configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOT_LTECCPARAMS_CHECK_DESC { \ + { .s3a= { config_checkstr_assign_integer, FRAMETYPE_OKVALUES, FRAMETYPE_MODVALUES,2}} , \ + { .s2= { config_check_intrange, TDDCONFIG_OKRANGE}}, \ + { .s2= { config_check_intrange, TDDCONFIGS_OKRANGE}}, \ + { .s3a= { config_checkstr_assign_integer, PREFIX_OKVALUES, PREFIX_MODVALUES,2}} , \ + { .s3a= { config_checkstr_assign_integer, PREFIXUL_OKVALUES, PREFIXUL_MODVALUES,2}} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s1= { config_check_intval, NRBDL_OKVALUES,6}} , \ +} + + +#define NBIOT_LTECCPARAMS_DESC { \ +{ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:NULL, defstrval:"FDD", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:NULL, defintval:3, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_PREFIX_TYPE, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_PREFIX_TYPE_UL, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \ +{ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:NULL, defintval:7, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:NULL, defint64val:2680000000, TYPE_UINT64, 0}, \ +{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:NULL, defintval:-120000000, TYPE_INT, 0}, \ +{ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:NULL, defintval:25, TYPE_UINT, 0}, \ +} +#define LTECCPARAMS_FRAME_TYPE_IDX 0 +#define LTECCPARAMS_TDD_CONFIG_IDX 1 +#define LTECCPARAMS_TDD_CONFIG_S_IDX 2 +#define LTECCPARAMS_PREFIX_TYPE_IDX 3 +#define LTECCPARAMS_PREFIX_TYPE_UL_IDX 4 +#define LTECCPARAMS_EUTRA_BAND_IDX 5 +#define LTECCPARAMS_DOWNLINK_FREQUENCY_IDX 6 +#define LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX 7 +#define LTECCPARAMS_NID_CELL_IDX 8 +#define LTECCPARAMS_N_RB_DL_IDX 9 + + +/*-------------------------------------------------------------------------------------------------------------------*/ + +/* NB-Iot RRC list section name */ +#define NBIOT_RRCLIST_CONFIG_STRING "NB-IoT_RRCs" + + +#define RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES {20,50,80,120,180,240,320,400} +#define PREF1(A) RACH_CE_LevelInfo_r13__ra_ResponseWindowSize_r13_ ## A +#define RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES { PREF1(sf20),PREF1(sf50),PREF1(sf80),PREF1(sf120), \ + PREF1(sf180),PREF1(sf240),PREF1(sf320),PREF1(sf400) } + + +#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES {80,100,120,160,200,240,480,960} +#define PREF2(A) RACH_CE_LevelInfo_r13__mac_ContentionResolutionTimer_r13_ ## A +#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES { PREF2(sf80),PREF2(sf100),PREF2(sf120),PREF2(sf160), \ + PREF2(sf200),PREF2(sf240),PREF2(sf480),PREF2(sf960) } + + +#define RACH_POWERRAMPINGSTEP_NB_OKVALUES {0,2,4,6} +#define PREF3(A) PowerRampingParameters__powerRampingStep_ ## A +#define RACH_POWERRAMPINGSTEP_NB_MODVALUES { PREF3(dB0),PREF3(dB2),PREF3(dB4),PREF3(dB6) } + + +#define RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE {-120, -90} + +#define RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES {3,4,5,6,7,8,10,20,50,100,200} +#define PREF4(A) PreambleTransMax_ ## A +#define RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES { PREF4(n3), PREF4(n4), PREF4(n5), PREF4(n6), PREF4(n7), PREF4(n8), \ + PREF4(n10),PREF4(n20),PREF4(n50),PREF4(n100),PREF4(n200) } + +#define BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES {16,32,64,128} +#define PREF5(A) BCCH_Config_NB_r13__modificationPeriodCoeff_r13_ ## A +#define BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES { PREF5(n16), PREF5(n32), PREF5(n64),PREF5(n128) } + +#define PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES {128,256,512,1024} +#define PREF6(A) PCCH_Config_NB_r13__defaultPagingCycle_r13_ ## A +#define PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES { PREF6(rf128), PREF6(rf256), PREF6(rf512), PREF6(rf1024) } + +#define NPRACH_CP_LENGTH_OKVALUES {0,1} +#define NPRACH_RSRP_RANGE_OKVALUES {0,96} + +#define MSG3RANGESTART_OKVALUES {"zero","oneThird","twoThird","one"} +#define MSG3RANGESTART_MODVALUES {NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_zero, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_oneThird, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_twoThird, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_one} + + +#define MAXNUMPREAMBLEATTEMPTCE_OKVALUES {3,4,5,6,7,8,10} +#define MAXNUMPREAMBLEATTEMPTCE_MODVALUES { NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n3, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n4, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n5, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n6, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n7, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n8, \ + NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n10 } + +#define NPDSCH_NRS_POWER_OKRANGE {-60,50} + +#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES {1,2,4,8,16,32,64,128} +#define PREF9(A) ACK_NACK_NumRepetitions_NB_r13_ ## A +#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES { PREF9(r1), PREF9(r2), PREF9(r4), PREF9(r8), \ + PREF9(r16), PREF9(r32), PREF9(r64), PREF9(r128) } + +#define NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE {0,15} +#define NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE {0,2} +#define NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE {0,3} + +#define NPUSCH_GROUPHOPPINGENABLED_OKVALUES {"enable","disable"} +#define NPUSCH_GROUPHOPPINGENABLED_MODVALUES {1,0} + +#define NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE {0,29} + +#define DLGAPTHRESHOLD_OKVALUES {32,64,128,256} +#define DLGAPTHRESHOLD_MODVALUES { DL_GapConfig_NB_r13__dl_GapThreshold_r13_n32, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n64, \ + DL_GapConfig_NB_r13__dl_GapThreshold_r13_n128, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n256} \ + +#define DLGAPPERIODICITY_OKVALUES {64,128,256,512} +#define DLGAPPERIODICITY_MODVALUES { DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf64, DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf128, \ + DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf256,DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf512} + +#define DLGAPDURATION_OKVALUES {"oneEighth","oneFourth","threeEighth","oneHalf"} +#define DLGAPDURATION_MODVALUES {DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneFourth, \ + DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_threeEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneHalf} + +#define NPUSCH_P0_NOMINALNPUSCH_OKRANGE {-126,24} + +#define NPUSCH_ALPHA_OKVALUES {"AL0","AL04","AL05","AL06","AL07","AL08","AL09","AL1"} +#define NPUSCH_ALPHA_MODVALUES { Alpha_r12_al0, Alpha_r12_al04, Alpha_r12_al05, Alpha_r12_al06, \ + Alpha_r12_al07, Alpha_r12_al08, Alpha_r12_al09, Alpha_r12_al1} + +#define DELTAPREAMBLEMSG3_OKRANGE {-1,6} + + + + + +#define NBIOT_RRCPARAMS_CHECK_DESC { \ + { .s1a= { config_check_modify_integer, RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES, RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES, 8}}, \ + { .s1a= { config_check_modify_integer, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES, 8}}, \ + { .s1a= { config_check_modify_integer, RACH_POWERRAMPINGSTEP_NB_OKVALUES, RACH_POWERRAMPINGSTEP_NB_MODVALUES, 4}} , \ + { .s2= { config_check_intrange, RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE}}, \ + { .s1a= { config_check_modify_integer, RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES, RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES, 11}} , \ + { .s1a= { config_check_modify_integer, BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES, BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES, PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES, 4}} , \ + { .s1= { NULL, NPRACH_CP_LENGTH_OKVALUES ,4}} , \ + { .s2= { config_check_intrange, NPRACH_RSRP_RANGE_OKVALUES}} , \ + { .s3a= { config_checkstr_assign_integer, MSG3RANGESTART_OKVALUES, MSG3RANGESTART_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, MAXNUMPREAMBLEATTEMPTCE_OKVALUES, MAXNUMPREAMBLEATTEMPTCE_MODVALUES, 7}} , \ + { .s1= { config_check_intval, NPDSCH_NRS_POWER_OKRANGE,4}} , \ + { .s1a= { config_check_modify_integer, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES, 8}} , \ + { .s2= { config_check_intrange, NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE}} , \ + { .s2= { config_check_intrange, NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE}} , \ + { .s2= { config_check_intrange, NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE}} , \ + { .s3a= { config_checkstr_assign_integer, NPUSCH_GROUPHOPPINGENABLED_OKVALUES, NPUSCH_GROUPHOPPINGENABLED_MODVALUES, 2}} , \ + { .s2= { config_check_intrange, NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE}} , \ + { .s1a= { config_check_modify_integer, DLGAPTHRESHOLD_OKVALUES, DLGAPTHRESHOLD_MODVALUES, 4}} , \ + { .s1a= { config_check_modify_integer, DLGAPPERIODICITY_OKVALUES, DLGAPPERIODICITY_MODVALUES, 4}} , \ + { .s3a= { config_checkstr_assign_integer, DLGAPDURATION_OKVALUES, DLGAPDURATION_MODVALUES , 4}} , \ + { .s2= { config_check_intrange, NPUSCH_P0_NOMINALNPUSCH_OKRANGE}} , \ + { .s3a= { config_checkstr_assign_integer, NPUSCH_ALPHA_OKVALUES, NPUSCH_ALPHA_MODVALUES, 8}} , \ + { .s2= { config_check_intrange, DELTAPREAMBLEMSG3_OKRANGE}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \ +} +/*-----------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT RRC configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-----------------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRCPARAMS_DESC { \ +{"rach_raResponseWindowSize_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \ +{"rach_macContentionResolutionTimer_NB", NULL, 0, uptr:NULL, defintval:80, TYPE_UINT, 0}, \ +{"rach_powerRampingStep_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"rach_preambleInitialReceivedTargetPower_NB", NULL, 0, iptr:NULL, defintval:-112, TYPE_INT32, 0}, \ +{"rach_preambleTransMax_CE_NB", NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0}, \ +{"bcch_modificationPeriodCoeff_NB", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \ +{"pcch_defaultPagingCycle_NB", NULL, 0, uptr:NULL, defintval:256, TYPE_UINT, 0}, \ +{"nprach_CP_Length", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_rsrp_range", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_SubcarrierMSG3_RangeStart", NULL, 0, strptr:NULL, defstrval:"one", TYPE_STRING, 0}, \ +{"maxNumPreambleAttemptCE_NB", NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \ +{"npdsch_nrs_Power", NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \ +{"npusch_ack_nack_numRepetitions_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +{"npusch_srs_SubframeConfig_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_threeTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_sixTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"npusch_groupHoppingEnabled", NULL, 0, strptr:NULL, defstrval:"disable", TYPE_STRING, 0}, \ +{"npusch_groupAssignmentNPUSCH_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"dl_GapThreshold_NB", NULL, 0, uptr:NULL, defintval:32, TYPE_UINT, 0}, \ +{"dl_GapPeriodicity_NB", NULL, 0, uptr:NULL, defintval:64, TYPE_UINT, 0}, \ +{"dl_GapDurationCoeff_NB", NULL, 0, strptr:NULL, defstrval:"oneEighth", TYPE_STRING, 0}, \ +{"npusch_p0_NominalNPUSCH", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \ +{"npusch_alpha", NULL, 0, strptr:NULL, defstrval:"AL0", TYPE_STRING, 0}, \ +{"deltaPreambleMsg3", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \ +{"ue_TimersAndConstants_t300_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t301_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t310_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_t311_NB", NULL, 0, uptr:NULL, defintval:10000, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_n310_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \ +{"ue_TimersAndConstants_n311_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +} + +#define NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX 0 +#define NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX 1 +#define NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX 2 +#define NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX 3 +#define NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX 4 +#define NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX 5 +#define NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX 6 +#define NBIOT_NPRACH_CP_LENGTH_IDX 7 +#define NBIOT_NPRACH_RSRP_RANGE_IDX 8 +#define NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX 9 +#define NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX 10 +#define NBIOT_NPDSCH_NRS_POWER_IDX 11 +#define NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX 12 +#define NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX 13 +#define NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX 14 +#define NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX 15 +#define NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX 16 +#define NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX 17 +#define NBIOT_DL_GAPTHRESHOLD_NB_IDX 18 +#define NBIOT_DL_GAPPERIODICITY_NB_IDX 19 +#define NBIOT_DL_GAPDURATIONCOEFF_NB_IDX 20 +#define NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX 21 +#define NBIOT_NPUSCH_ALPHA_IDX 22 +#define NBIOT_DELTAPREAMBLEMSG3_IDX 23 +#define NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX 24 +#define NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX 25 +#define NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX 26 +#define NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX 27 +#define NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX 28 +#define NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX 29 + +/* NB-Iot RRC: link to LTE RRC section name */ +#define NBIOT_LTERRCREF_CONFIG_STRING "LTERRC_Ref" +/*---------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT RRC configuration parameters to link to a LTE RRC instance (in-guard, in-band) */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRCPARAMS_RRCREF_DESC { \ +{"RRC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"CC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +} +/*--------------------------------------------------------------------------------------------------------------*/ +#define NBIOT_RRCINST_IDX 0 +#define NBIOT_CCINST_IDX 1 + +#define NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING "NPRACH-NB-r13" + + +#define NPRACH_PERIODICITY_OKVALUES {40,80,160,240,320,640,1280,2560} +#define NPRACH_PERIODICITY_MODVALUES { NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms40, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms80, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms160, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms240, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms320, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms640, \ + NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms1280, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms2560 } + +#define NPRACH_STARTTIME_OKVALUES {8,16,32,64,128,256,512,1024} +#define NPRACH_STARTTIME_MODVALUES { NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms8, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms16, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms32, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms64, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms128, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms256, \ + NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms512, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms1024 } + +#define NPRACH_SUBCARRIEROFFSET_OKVALUES {0,12,24,36,2,18,34} +#define NPRACH_SUBCARRIEROFFSET_MODVALUES { NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n0, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n12, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n24, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n36, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n2, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n18, \ + NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n34 } + +#define NPRACH_NUMSUBCARRIERS_OKVALUES {12,24,36,48} +#define NPRACH_NUMSUBCARRIERS_MODVALUES { NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n12, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n24, \ + NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n36, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n48 } + + +#define NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES {1,2,4,8,16,32,64,128} +#define NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES { NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n1, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n2, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n4, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n8, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n16, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n32, \ + NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n64, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n128} + +#define NPDCCHNUMREPETITIONSRA_OKVALUES {1,2,4,8,16,32,64,128,256,512,1024,2048} +#define NPDCCHNUMREPETITIONSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r4, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r8, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r16, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r32, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r64, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r128, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r256, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r512, \ + NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1024,NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2048} + +#define NPDCCHSTARTSFCSSRA_OKVALUES {1,2,4,8,16,32,48,64} +#define NPDCCHSTARTSFCSSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v1dot5, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v2, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v4, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v8, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v16, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v32, \ + NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v48, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v64} + +#define NPDCCHOFFSETRA_OKVALUES {"zero","oneEighth","oneFourth","threeEighth"} +#define NPDCCHOFFSETRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_zero, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneEighth, \ + NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneFourth, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_threeEighth} + + + +#define NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC { \ + { .s1a= { config_check_modify_integer, NPRACH_PERIODICITY_OKVALUES, NPRACH_PERIODICITY_MODVALUES, 8 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_STARTTIME_OKVALUES, NPRACH_STARTTIME_MODVALUES, 8 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_SUBCARRIEROFFSET_OKVALUES, NPRACH_SUBCARRIEROFFSET_MODVALUES, 7 }}, \ + { .s1a= { config_check_modify_integer, NPRACH_NUMSUBCARRIERS_OKVALUES, NPRACH_NUMSUBCARRIERS_MODVALUES, 4 }}, \ + { .s1a= { config_check_modify_integer, NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES, NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES,8 }}, \ + { .s1a= { config_check_modify_integer, NPDCCHNUMREPETITIONSRA_OKVALUES, NPDCCHNUMREPETITIONSRA_MODVALUES, 12}}, \ + { .s1a= { config_check_modify_integer, NPDCCHSTARTSFCSSRA_OKVALUES, NPDCCHSTARTSFCSSRA_MODVALUES, 8 }}, \ + { .s3a= { config_checkstr_assign_integer, NPDCCHOFFSETRA_OKVALUES, NPDCCHOFFSETRA_MODVALUES, 4 }}, \ +} + + + +/*------------------------------------------------------------------------------------------------------------------------------*/ +/* NB-IoT NPrach parameters, there will be three ocuurences of these parameters in each RRC instance */ + /* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------------------------*/ +#define NBIOTRRC_NPRACH_PARAMS_DESC { \ +{"nprach_Periodicity", NULL, 0, uptr:NULL, defintval:320, TYPE_UINT, 0}, \ +{"nprach_StartTime", NULL, 0, uptr:NULL, defintval:8, TYPE_UINT, 0}, \ +{"nprach_SubcarrierOffset", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{"nprach_NumSubcarriers", NULL, 0, uptr:NULL, defintval:12, TYPE_UINT, 0}, \ +{"numRepetitionsPerPreambleAttempt", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \ +{"npdcch_NumRepetitions_RA", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \ +{"npdcch_StartSF_CSS_RA", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \ +{"npdcch_Offset_RA", NULL, 0, strptr:NULL, defstrval:"zero", TYPE_STRING, 0}, \ +} + +#define NBIOT_NPRACH_PERIODICITY_IDX 0 +#define NBIOT_NPRACH_STARTTIME_IDX 1 +#define NBIOT_NPRACH_SUBCARRIEROFFSET_IDX 2 +#define NBIOT_NPRACH_NUMSUBCARRIERS_IDX 3 +#define NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX 4 +#define NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX 5 +#define NBIOT_NPDCCH_STARTSF_CSS_RA_IDX 6 +#define NBIOT_NPDCCH_OFFSET_RA_IDX 7 + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB IoT MACRLC configuration list section name */ +#define NBIOT_MACRLCLIST_CONFIG_STRING "NB-IoT_MACRLCs" + + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* NB IoT L1 configuration list section name */ +#define NBIOT_L1LIST_CONFIG_STRING "NB-IoT_L1s" diff --git a/openair2/ENB_APP/RRC_config_tools.c b/openair2/ENB_APP/RRC_config_tools.c new file mode 100644 index 0000000000000000000000000000000000000000..17fbad1e18c542a38fe72c0b8f68f4a7078116c0 --- /dev/null +++ b/openair2/ENB_APP/RRC_config_tools.c @@ -0,0 +1,123 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + RRC_config_tools.c + ------------------- + AUTHOR : Francois TABURET + COMPANY : NOKIA BellLabs France + EMAIL : francois.taburet@nokia-bell-labs.com + +*/ + +#include <string.h> +#include <inttypes.h> + +#include "log.h" +#include "log_extern.h" +#include "assertions.h" +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +# if defined(ENABLE_USE_MME) +# include "s1ap_eNB.h" +# include "sctp_eNB_task.h" +# endif +#endif +#include "SystemInformationBlockType2.h" +#include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "DL-GapConfig-NB-r13.h" +#include "NPRACH-Parameters-NB-r13.h" + +static const eutra_band_t eutra_bands[] = { + { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, + { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, + { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, + { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, + { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, + { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, + { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, + { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, + {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, + {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, + {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, + {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, + {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, + + {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, + {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, + {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, + {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, + {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, + {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, + {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, + {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, + {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, + {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, + {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, + {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, + {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, +}; + + +int config_check_band_frequencies( int ind, + int16_t band, + uint32_t downlink_frequency, + int32_t uplink_frequency_offset, + uint32_t frame_type) +{ + int errors = 0; + + if (band > 0) { + int band_index; + + for (band_index = 0; band_index < sizeof (eutra_bands) / sizeof (eutra_bands[0]); band_index++) { + if (band == eutra_bands[band_index].band) { + uint32_t uplink_frequency = downlink_frequency + uplink_frequency_offset; + + AssertError (eutra_bands[band_index].dl_min < downlink_frequency, errors ++, + "enb %d downlink frequency %u too low (%u) for band %d!", + ind, downlink_frequency, eutra_bands[band_index].dl_min, band); + AssertError (downlink_frequency < eutra_bands[band_index].dl_max, errors ++, + "enb %d downlink frequency %u too high (%u) for band %d!", + ind, downlink_frequency, eutra_bands[band_index].dl_max, band); + + AssertError (eutra_bands[band_index].ul_min < uplink_frequency, errors ++, + "enb %d uplink frequency %u too low (%u) for band %d!", + ind, uplink_frequency, eutra_bands[band_index].ul_min, band); + AssertError (uplink_frequency < eutra_bands[band_index].ul_max, errors ++, + "enb %d uplink frequency %u too high (%u) for band %d!", + ind, uplink_frequency, eutra_bands[band_index].ul_max, band); + + AssertError (eutra_bands[band_index].frame_type == frame_type, errors ++, + "enb %d invalid frame type (%d/%d) for band %d!", + ind, eutra_bands[band_index].frame_type, frame_type, band); + } + } + } + + + return errors; +} + diff --git a/openair2/ENB_APP/RRC_config_tools.h b/openair2/ENB_APP/RRC_config_tools.h new file mode 100644 index 0000000000000000000000000000000000000000..a44da1f90c5d93a706f7a29e575cedd2989645ff --- /dev/null +++ b/openair2/ENB_APP/RRC_config_tools.h @@ -0,0 +1,50 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/* + RRC_config_tools.h + ------------------- + AUTHOR : Francois TABURET + COMPANY : NOKIA BellLabs France + EMAIL : francois.taburet@nokia-bell-labs.com +*/ +#ifndef RRC_CONFIG_TOOLS_H_ +#define RRC_CONFIG_TOOLS_H_ + +#define KHz (1000UL) +#define MHz (1000 * KHz) + +typedef struct eutra_band_s { + int16_t band; + uint32_t ul_min; + uint32_t ul_max; + uint32_t dl_min; + uint32_t dl_max; + lte_frame_type_t frame_type; +} eutra_band_t; + + +extern int config_check_band_frequencies(int ind, int16_t band, uint32_t downlink_frequency, + int32_t uplink_frequency_offset, uint32_t frame_type); + +extern int config_check_assign_DLGap_NB(paramdef_t *param); +extern int config_check_assign_rach_NB(paramdef_t *param); +#endif diff --git a/openair2/ENB_APP/RRC_paramsvalues.h b/openair2/ENB_APP/RRC_paramsvalues.h new file mode 100644 index 0000000000000000000000000000000000000000..06fee0e172515ed105adb6dc54fa5d808af07491 --- /dev/null +++ b/openair2/ENB_APP/RRC_paramsvalues.h @@ -0,0 +1,94 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file openair2/ENB_APP/RRC_paramsvalues.h + * \brief macro definitions for RRC authorized and asn1 parameters values, to be used in paramdef_t/chechedparam_t structure initializations + * \author Francois TABURET + * \date 2017 + * \version 0.1 + * \company NOKIA BellLabs France + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ +#ifndef __RRC_PARAMSVALUES__H__ +#define __RRC_PARAMSVALUES__H__ +/* cell configuration section name */ +#define ENB_CONFIG_STRING_ENB_LIST "eNBs" +/* component carriers configuration section name */ +#define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" + +#define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" +#define ENB_CONFIG_STRING_PBCH_REPETITION "pbch_repetition" +#define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" +#define ENB_CONFIG_STRING_TDD_CONFIG_S "tdd_config_s" +#define ENB_CONFIG_STRING_PREFIX_TYPE "prefix_type" +#define ENB_CONFIG_STRING_PREFIX_TYPE_UL "prefix_type_UL" +#define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" +#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" +#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" +#define ENB_CONFIG_STRING_NID_CELL "Nid_cell" +#define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" +#define ENB_CONFIG_STRING_CELL_MBSFN "Nid_cell_mbsfn" + + +#define FRAMETYPE_OKVALUES {"FDD","TDD"} +#define FRAMETYPE_MODVALUES { FDD, TDD} + +#define TDDCFG(A) TDD_Config__subframeAssignment_ ## A +#define TDDCONFIG_OKRANGE { TDDCFG(sa0), TDDCFG(sa6)} + +#define TDDCFGS(A) TDD_Config__specialSubframePatterns_ ## A +#define TDDCONFIGS_OKRANGE { TDDCFGS(ssp0), TDDCFGS(ssp8)} + +#define PREFIX_OKVALUES {"NORMAL","EXTENDED"} +#define PREFIX_MODVALUES { NORMAL, EXTENDED} + +#define PREFIXUL_OKVALUES {"NORMAL","EXTENDED"} +#define PREFIXUL_MODVALUES { NORMAL, EXTENDED} + +#define NRBDL_OKVALUES {6,15,25,50,75,100} + +#define UETIMER_T300_OKVALUES {100,200,300,400,600,1000,1500,2000} +#define UETT300(A) UE_TimersAndConstants__t300_ ## A +#define UETIMER_T300_MODVALUES { UETT300(ms100), UETT300(ms200),UETT300(ms300),UETT300(ms400),UETT300(ms600),UETT300(ms1000),UETT300(ms1500),UETT300(ms2000)} + +#define UETIMER_T301_OKVALUES {100,200,300,400,600,1000,1500,2000} +#define UETT301(A) UE_TimersAndConstants__t301_ ## A +#define UETIMER_T301_MODVALUES { UETT301(ms100), UETT301(ms200),UETT301(ms300),UETT301(ms400),UETT301(ms600),UETT301(ms1000),UETT301(ms1500),UETT301(ms2000)} + +#define UETIMER_T310_OKVALUES {0,50,100,200,500,1000,2000} +#define UETT310(A) UE_TimersAndConstants__t310_ ## A +#define UETIMER_T310_MODVALUES { UETT310(ms0), UETT310(ms50),UETT310(ms100),UETT310(ms200),UETT310(ms500),UETT310(ms1000),UETT310(ms2000)} + +#define UETIMER_T311_OKVALUES {1000,3110,5000,10000,15000,20000,31100} +#define UETT311(A) UE_TimersAndConstants__t311_ ## A +#define UETIMER_T311_MODVALUES { UETT311(ms1000), UETT311(ms3000),UETT311(ms5000),UETT311(ms10000),UETT311(ms15000),UETT311(ms20000),UETT311(ms30000)} + +#define UETIMER_N310_OKVALUES {1,2,3,4,6,8,10,20} +#define UETN310(A) UE_TimersAndConstants__n310_ ## A +#define UETIMER_N310_MODVALUES { UETN310(n1), UETN310(n2),UETN310(n3),UETN310(n4),UETN310(n6),UETN310(n8),UETN310(n10),UETN310(n20)} + +#define UETIMER_N311_OKVALUES {1,2,3,4,5,6,8,10} +#define UETN311(A) UE_TimersAndConstants__n311_ ## A +#define UETIMER_N311_MODVALUES { UETN311(n1), UETN311(n2),UETN311(n3),UETN311(n4),UETN311(n5),UETN311(n6),UETN311(n8),UETN311(n10)} + +#endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index a30dc28c941d2df60b277c5386004a0050ce1281..5e9c320f57a0caf5caec567b50c4841316517751 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -52,51 +52,14 @@ #include "nfapi_vnf.h" #include "nfapi_pnf.h" -#include "enb_paramdef.h" +#include "L1_paramdef.h" +#include "MACRLC_paramdef.h" #include "common/config/config_userapi.h" +#include "RRC_config_tools.h" +#include "enb_paramdef.h" extern uint16_t sf_ahead; -static int enb_check_band_frequencies(char* lib_config_file_name_pP, - int ind, - int16_t band, - uint32_t downlink_frequency, - int32_t uplink_frequency_offset, - lte_frame_type_t frame_type) -{ - int errors = 0; - - if (band > 0) { - int band_index; - - for (band_index = 0; band_index < sizeof (eutra_bands) / sizeof (eutra_bands[0]); band_index++) { - if (band == eutra_bands[band_index].band) { - uint32_t uplink_frequency = downlink_frequency + uplink_frequency_offset; - - AssertError (eutra_bands[band_index].dl_min < downlink_frequency, errors ++, - "Failed to parse eNB configuration file %s, enb %d downlink frequency %u too low (%u) for band %d!", - lib_config_file_name_pP, ind, downlink_frequency, eutra_bands[band_index].dl_min, band); - AssertError (downlink_frequency < eutra_bands[band_index].dl_max, errors ++, - "Failed to parse eNB configuration file %s, enb %d downlink frequency %u too high (%u) for band %d!", - lib_config_file_name_pP, ind, downlink_frequency, eutra_bands[band_index].dl_max, band); - - AssertError (eutra_bands[band_index].ul_min < uplink_frequency, errors ++, - "Failed to parse eNB configuration file %s, enb %d uplink frequency %u too low (%u) for band %d!", - lib_config_file_name_pP, ind, uplink_frequency, eutra_bands[band_index].ul_min, band); - AssertError (uplink_frequency < eutra_bands[band_index].ul_max, errors ++, - "Failed to parse eNB configuration file %s, enb %d uplink frequency %u too high (%u) for band %d!", - lib_config_file_name_pP, ind, uplink_frequency, eutra_bands[band_index].ul_max, band); - - AssertError (eutra_bands[band_index].frame_type == frame_type, errors ++, - "Failed to parse eNB configuration file %s, enb %d invalid frame type (%d/%d) for band %d!", - lib_config_file_name_pP, ind, eutra_bands[band_index].frame_type, frame_type, band); - } - } - } - - - return errors; -} void RCconfig_flexran() { @@ -420,14 +383,16 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { paramdef_t ENBParams[] = ENBPARAMS_DESC; paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; paramdef_t CCsParams[] = CCPARAMS_DESC; paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0}; paramdef_t SRB1Params[] = SRB1PARAMS_DESC; - - - +/* map parameter checking array instances to parameter definition array instances */ + for (int I=0; I< ( sizeof(CCsParams)/ sizeof(paramdef_t) ) ; I++) { + CCsParams[I].chkPptr = &(config_check_CCparams[I]); + } /* get global parameters, defined outside any section in the config file */ config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); @@ -562,43 +527,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { nb_cc++; - /* - if (strcmp(cc_node_function, "eNodeB_3GPP") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP; - } else if (strcmp(cc_node_function, "eNodeB_3GPP_BBU") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP_BBU; - } else if (strcmp(cc_node_function, "NGFI_RCC_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RCC_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RAU_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RAU_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RRU_IF4p5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF4p5; - } else if (strcmp(cc_node_function, "NGFI_RRU_IF5") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF5; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: eNodeB_3GPP or eNodeB_3GPP_BBU or NGFI_IF4_RCC or NGFI_IF4_RRU or NGFI_IF5_RRU !\n", - lib_config_file_name_pP, i, cc_node_function); - } - - if (strcmp(cc_node_timing, "synch_to_ext_device") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_ext_device; - } else if (strcmp(cc_node_timing, "synch_to_other") == 0) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_other; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: SYNCH_TO_DEVICE or SYNCH_TO_OTHER !\n", - lib_config_file_name_pP, i, cc_node_timing); - } - - if ((cc_node_synch_ref >= -1) && (cc_node_synch_ref < num_component_carriers)) { - enb_properties_loc.properties[enb_properties_loc_index]->cc_node_synch_ref[j] = (int16_t) cc_node_synch_ref; - } else { - AssertError (0, parse_errors ++, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for node_synch_ref choice: valid CC_id or -1 !\n", - lib_config_file_name_pP, i, cc_node_synch_ref); - } - */ + RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; @@ -710,8 +639,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j] = (unsigned int) uplink_frequency_offset; - if (enb_check_band_frequencies(RC.config_file_name, - j, + if (config_check_band_frequencies(j, RRC_CONFIGURATION_REQ (msg_p).eutra_band[j], RRC_CONFIGURATION_REQ (msg_p).downlink_frequency[j], RRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset[j], @@ -1385,244 +1313,13 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { break; } - - switch (ue_TimersAndConstants_t300) { - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms200; - break; - - case 300: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms300; - break; - - case 400: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms400; - break; - - case 600: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms600; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms1000; - break; - - case 1500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms1500; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = UE_TimersAndConstants__t300_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t300 choice: 100,200,300,400,600,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t300); - break; - - } - - switch (ue_TimersAndConstants_t301) { - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms200; - break; - - case 300: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms300; - break; - - case 400: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms400; - break; - - case 600: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms600; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms1000; - break; - - case 1500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms1500; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = UE_TimersAndConstants__t301_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t301 choice: 100,200,300,400,600,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t301); - break; - - } - - switch (ue_TimersAndConstants_t310) { - case 0: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms0; - break; - - case 50: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms50; - break; - - case 100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms100; - break; - - case 200: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms200; - break; - - case 500: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms500; - break; - - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms1000; - break; - - case 2000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = UE_TimersAndConstants__t310_ms2000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t310 choice: 0,50,100,200,500,1000,1500,2000 ", - RC.config_file_name, i, ue_TimersAndConstants_t310); - break; - - } - - switch (ue_TimersAndConstants_t311) { - case 1000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms1000; - break; - - case 3110: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms3000; - break; - - case 5000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms5000; - break; - - case 10000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms10000; - break; - - case 15000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms15000; - break; - - case 20000: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms20000; - break; - - case 31100: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = UE_TimersAndConstants__t311_ms30000; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t311 choice: 1000,3000,5000,10000,150000,20000,30000", - RC.config_file_name, i, ue_TimersAndConstants_t311); - break; - - } - - switch (ue_TimersAndConstants_n310) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n1; - break; - - case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n2; - break; - - case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n3; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n4; - break; - - case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n6; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n8; - break; - - case 10: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n10; - break; - - case 20: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = UE_TimersAndConstants__n310_n20; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_n310 choice: 1,2,3,4,6,6,8,10,20", - RC.config_file_name, i, ue_TimersAndConstants_n311); - break; - - } - - switch (ue_TimersAndConstants_n311) { - case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n1; - break; - - case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n2; - break; - - case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n3; - break; - - case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n4; - break; - - case 5: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n5; - break; - - case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n6; - break; - - case 8: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n8; - break; - - case 10: - RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = UE_TimersAndConstants__n311_n10; - break; - - default: - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_TimersAndConstants_t311 choice: 1,2,3,4,5,6,8,10", - RC.config_file_name, i, ue_TimersAndConstants_t311); - break; - - } + + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300[j] = ue_TimersAndConstants_t300; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301[j] = ue_TimersAndConstants_t301; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310[j] = ue_TimersAndConstants_t310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311[j] = ue_TimersAndConstants_t311; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310[j] = ue_TimersAndConstants_n310; + RRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311[j] = ue_TimersAndConstants_n311; switch (ue_TransmissionMode) { case 1: @@ -1965,275 +1662,32 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { } /* - // OTG _CONFIG - setting_otg = config_setting_get_member (setting_enb, ENB_CONF_STRING_OTG_CONFIG); - - if (setting_otg != NULL) { - num_otg_elements = config_setting_length(setting_otg); - printf("num otg elements %d \n", num_otg_elements); - enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements = 0; - - for (j = 0; j < num_otg_elements; j++) { - subsetting_otg=config_setting_get_elem(setting_otg, j); - - if (config_setting_lookup_int(subsetting_otg, ENB_CONF_STRING_OTG_UE_ID, &otg_ue_id)) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = otg_ue_id; - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = 1; - } - - if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_APP_TYPE, (const char **)&otg_app_type)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = map_str_to_int(otg_app_type_names,otg_app_type))== -1) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = BCBR; - } - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = NO_PREDEFINED_TRAFFIC; // 0 - } - - if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_BG_TRAFFIC, (const char **)&otg_bg_traffic)) { - - if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = map_str_to_int(switch_names,otg_bg_traffic)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j]=0; - } - } else { - enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = 0; - printf("otg bg %s\n", otg_bg_traffic); - } - - enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements+=1; - - } - } - - // log_config - subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_LOG_CONFIG); + // Network Controller + subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG); if (subsetting != NULL) { - // global - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL, (const char **) &glog_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_level = map_str_to_int(log_level_names, glog_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; - } - - //printf( "\tGlobal log level :\t%s->%d\n",glog_level, enb_properties_loc.properties[enb_properties_loc_index]->glog_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY,(const char **) &glog_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = map_str_to_int(log_verbosity_names, glog_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - } - - //printf( "\tGlobal log verbosity:\t%s->%d\n",glog_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - } - - // HW - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_LEVEL, (const char **) &hw_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = map_str_to_int(log_level_names,hw_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - } - - //printf( "\tHW log level :\t%s->%d\n",hw_log_level,enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_VERBOSITY, (const char **) &hw_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = map_str_to_int(log_verbosity_names,hw_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - } - - //printf( "\tHW log verbosity:\t%s->%d\n",hw_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - } - - // phy - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_LEVEL,(const char **) &phy_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = map_str_to_int(log_level_names,phy_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - } - - //printf( "\tPHY log level :\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_VERBOSITY, (const char **)&phy_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = map_str_to_int(log_verbosity_names,phy_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - } - - //printf( "\tPHY log verbosity:\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - } - - //mac - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_LEVEL, (const char **)&mac_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = map_str_to_int(log_level_names,mac_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - } - - //printf( "\tMAC log level :\t%s->%d\n",mac_log_level,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_VERBOSITY, (const char **)&mac_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = map_str_to_int(log_verbosity_names,mac_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - } - - //printf( "\tMAC log verbosity:\t%s->%d\n",mac_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - } - - //rlc - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_LEVEL, (const char **)&rlc_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = map_str_to_int(log_level_names,rlc_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - } - - //printf( "\tRLC log level :\t%s->%d\n",rlc_log_level, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_VERBOSITY, (const char **)&rlc_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = map_str_to_int(log_verbosity_names,rlc_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - } - - //printf( "\tRLC log verbosity:\t%s->%d\n",rlc_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - } - - //pdcp - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_LEVEL, (const char **)&pdcp_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = map_str_to_int(log_level_names,pdcp_log_level)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - } - - //printf( "\tPDCP log level :\t%s->%d\n",pdcp_log_level, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY, (const char **)&pdcp_log_verbosity)) { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = map_str_to_int(log_verbosity_names,pdcp_log_verbosity); - //printf( "\tPDCP log verbosity:\t%s->%d\n",pdcp_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED; - } - - //rrc - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_LEVEL, (const char **)&rrc_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = map_str_to_int(log_level_names,rrc_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - } - - //printf( "\tRRC log level :\t%s->%d\n",rrc_log_level,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_VERBOSITY, (const char **)&rrc_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = map_str_to_int(log_verbosity_names,rrc_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - } - - //printf( "\tRRC log verbosity:\t%s->%d\n",rrc_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_LEVEL, (const char **)>pu_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = map_str_to_int(log_level_names,gtpu_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - } - - //printf( "\tGTPU log level :\t%s->%d\n",gtpu_log_level,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY, (const char **)>pu_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = map_str_to_int(log_verbosity_names,gtpu_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - } - - //printf( "\tGTPU log verbosity:\t%s->%d\n",gtpu_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_LEVEL, (const char **)&udp_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = map_str_to_int(log_level_names,udp_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - } - - //printf( "\tUDP log level :\t%s->%d\n",udp_log_level,enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_VERBOSITY, (const char **)&udp_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = map_str_to_int(log_verbosity_names,udp_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - } - - //printf( "\tUDP log verbosity:\t%s->%d\n",udp_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_LEVEL, (const char **)&osa_log_level)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = map_str_to_int(log_level_names,osa_log_level)) == -1 ) { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - } - - //printf( "\tOSA log level :\t%s->%d\n",osa_log_level,enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - } - - if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_VERBOSITY, (const char **)&osa_log_verbosity)) { - if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = map_str_to_int(log_verbosity_names,osa_log_verbosity)) == -1) { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; + if ( ( + config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME, + (const char **)&flexran_agent_interface_name) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS, + (const char **)&flexran_agent_ipv4_address) + && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT, + &flexran_agent_port) + && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE, + (const char **)&flexran_agent_cache) + ) + ) { + enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name); + cidr = flexran_agent_ipv4_address; + address = strtok(cidr, "/"); + //enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address = strdup(address); + if (address) { + IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" ); } - //printf( "\tOSA log verbosity:\t%s->%d\n",osa_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gosa_log_verbosity); - } else { - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; + enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_port = flexran_agent_port; + enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache); } - - } else { // not configuration is given - enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED; - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO; - enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED; } */ break; diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 2d65e09b58b038ac2dd0b3f6cbdebf9f3e607354..a8379c259f948882e6a17c4b98b5daccbfe2067f 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -31,7 +31,7 @@ */ #include "common/config/config_paramdesc.h" - +#include "RRC_paramsvalues.h" @@ -56,52 +56,6 @@ -#define KHz (1000UL) -#define MHz (1000 * KHz) - -typedef struct eutra_band_s { - int16_t band; - uint32_t ul_min; - uint32_t ul_max; - uint32_t dl_min; - uint32_t dl_max; - lte_frame_type_t frame_type; -} eutra_band_t; - -static const eutra_band_t eutra_bands[] = { - { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - { 2, 1850 * MHz, 1910 * MHz, 1930 * MHz, 1990 * MHz, FDD}, - { 3, 1710 * MHz, 1785 * MHz, 1805 * MHz, 1880 * MHz, FDD}, - { 4, 1710 * MHz, 1755 * MHz, 2110 * MHz, 2155 * MHz, FDD}, - { 5, 824 * MHz, 849 * MHz, 869 * MHz, 894 * MHz, FDD}, - { 6, 830 * MHz, 840 * MHz, 875 * MHz, 885 * MHz, FDD}, - { 7, 2500 * MHz, 2570 * MHz, 2620 * MHz, 2690 * MHz, FDD}, - { 8, 880 * MHz, 915 * MHz, 925 * MHz, 960 * MHz, FDD}, - { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD}, - {10, 1710 * MHz, 1770 * MHz, 2110 * MHz, 2170 * MHz, FDD}, - {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD}, - {12, 698 * MHz, 716 * MHz, 728 * MHz, 746 * MHz, FDD}, - {13, 777 * MHz, 787 * MHz, 746 * MHz, 756 * MHz, FDD}, - {14, 788 * MHz, 798 * MHz, 758 * MHz, 768 * MHz, FDD}, - - {17, 704 * MHz, 716 * MHz, 734 * MHz, 746 * MHz, FDD}, - {20, 832 * MHz, 862 * MHz, 791 * MHz, 821 * MHz, FDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {33, 1900 * MHz, 1920 * MHz, 1900 * MHz, 1920 * MHz, TDD}, - {34, 2010 * MHz, 2025 * MHz, 2010 * MHz, 2025 * MHz, TDD}, - {35, 1850 * MHz, 1910 * MHz, 1850 * MHz, 1910 * MHz, TDD}, - {36, 1930 * MHz, 1990 * MHz, 1930 * MHz, 1990 * MHz, TDD}, - {37, 1910 * MHz, 1930 * MHz, 1910 * MHz, 1930 * MHz, TDD}, - {38, 2570 * MHz, 2620 * MHz, 2570 * MHz, 2630 * MHz, TDD}, - {39, 1880 * MHz, 1920 * MHz, 1880 * MHz, 1920 * MHz, TDD}, - {40, 2300 * MHz, 2400 * MHz, 2300 * MHz, 2400 * MHz, TDD}, - {41, 2496 * MHz, 2690 * MHz, 2496 * MHz, 2690 * MHz, TDD}, - {42, 3400 * MHz, 3600 * MHz, 3400 * MHz, 3600 * MHz, TDD}, - {43, 3600 * MHz, 3800 * MHz, 3600 * MHz, 3800 * MHz, TDD}, - {44, 703 * MHz, 803 * MHz, 703 * MHz, 803 * MHz, TDD}, -}; - - @@ -152,7 +106,7 @@ typedef enum { #define CONFIG_STRING_RU_MAX_RS_EPRE "max_pdschReferenceSignalPower" #define CONFIG_STRING_RU_MAX_RXGAIN "max_rxgain" #define CONFIG_STRING_RU_IF_COMPRESSION "if_compression" - +#define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -171,14 +125,10 @@ typedef enum { #define RU_ENB_LIST_IDX 14 #define RU_ATT_TX_IDX 15 #define RU_ATT_RX_IDX 16 +#define RU_NBIOTRRC_LIST_IDX 17 - -static int DEFBANDS[] = {7}; -static int DEFENBS[] = {0}; - - /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -200,7 +150,8 @@ static int DEFENBS[] = {0}; {CONFIG_STRING_RU_BAND_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFBANDS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ENB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0} \ +{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ +{CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ @@ -237,8 +188,7 @@ static int DEFENBS[] = {0}; /*------------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------*/ -/* cell configuration section name */ -#define ENB_CONFIG_STRING_ENB_LIST "eNBs" + /* cell configuration parameters names */ #define ENB_CONFIG_STRING_ENB_ID "eNB_ID" @@ -293,21 +243,9 @@ static int DEFENBS[] = {0}; /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* component carriers configuration section name */ -#define ENB_CONFIG_STRING_COMPONENT_CARRIERS "component_carriers" /* component carries configuration parameters name */ -#define ENB_CONFIG_STRING_FRAME_TYPE "frame_type" -#define ENB_CONFIG_STRING_PBCH_REPETITION "pbch_repetition" -#define ENB_CONFIG_STRING_TDD_CONFIG "tdd_config" -#define ENB_CONFIG_STRING_TDD_CONFIG_S "tdd_config_s" -#define ENB_CONFIG_STRING_PREFIX_TYPE "prefix_type" -#define ENB_CONFIG_STRING_EUTRA_BAND "eutra_band" -#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY "downlink_frequency" -#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET "uplink_frequency_offset" -#define ENB_CONFIG_STRING_NID_CELL "Nid_cell" -#define ENB_CONFIG_STRING_N_RB_DL "N_RB_DL" -#define ENB_CONFIG_STRING_CELL_MBSFN "Nid_cell_mbsfn" + #define ENB_CONFIG_STRING_NB_ANT_PORTS "nb_antenna_ports" #define ENB_CONFIG_STRING_NB_ANT_TX "nb_antennas_tx" #define ENB_CONFIG_STRING_NB_ANT_RX "nb_antennas_rx" @@ -371,11 +309,83 @@ static int DEFENBS[] = {0}; #define ENB_CONFIG_STRING_UETIMERS_N310 "ue_TimersAndConstants_n310" #define ENB_CONFIG_STRING_UETIMERS_N311 "ue_TimersAndConstants_n311" #define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE "ue_TransmissionMode" - -/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* component carriers configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +/* init for checkedparam_t structure */ + +#define CCPARAMS_CHECK { \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s5= {NULL }} , \ + { .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \ + { .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \ + { .s5= {NULL }} , \ +} +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* component carriers configuration parameters */ +/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */ +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CCPARAMS_DESC { \ {ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:&frame_type, defstrval:"FDD", TYPE_STRING, 0}, \ {ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:&tdd_config, defintval:3, TYPE_UINT, 0}, \ @@ -447,6 +457,75 @@ static int DEFENBS[] = {0}; {ENB_CONFIG_STRING_UE_TRANSMISSION_MODE, NULL, 0, iptr:&ue_TransmissionMode, defintval:1, TYPE_UINT, 0} \ } +#define ENB_CONFIG_FRAME_TYPE_IDX 0 +#define ENB_CONFIG_TDD_CONFIG_IDX 1 +#define ENB_CONFIG_TDD_CONFIG_S_IDX 2 +#define ENB_CONFIG_PREFIX_TYPE_IDX 3 +#define ENB_CONFIG_PBCH_REPETITION_IDX 4 +#define ENB_CONFIG_EUTRA_BAND_IDX 5 +#define ENB_CONFIG_DOWNLINK_FREQUENCY_IDX 6 +#define ENB_CONFIG_UPLINK_FREQUENCY_OFFSET_IDX 7 +#define ENB_CONFIG_NID_CELL_IDX 8 +#define ENB_CONFIG_N_RB_DL_IDX 9 +#define ENB_CONFIG_CELL_MBSFN_IDX 10 +#define ENB_CONFIG_NB_ANT_PORTS_IDX 11 +#define ENB_CONFIG_PRACH_ROOT_IDX 12 +#define ENB_CONFIG_PRACH_CONFIG_INDEX_IDX 13 +#define ENB_CONFIG_PRACH_HIGH_SPEED_IDX 14 +#define ENB_CONFIG_PRACH_ZERO_CORRELATION_IDX 15 +#define ENB_CONFIG_PRACH_FREQ_OFFSET_IDX 16 +#define ENB_CONFIG_PUCCH_DELTA_SHIFT_IDX 17 +#define ENB_CONFIG_PUCCH_NRB_CQI_IDX 18 +#define ENB_CONFIG_PUCCH_NCS_AN_IDX 19 +#define ENB_CONFIG_PUCCH_N1_AN_IDX 20 +#define ENB_CONFIG_PDSCH_RS_EPRE_IDX 21 +#define ENB_CONFIG_PDSCH_PB_IDX 22 +#define ENB_CONFIG_PUSCH_N_SB_IDX 23 +#define ENB_CONFIG_PUSCH_HOPPINGMODE_IDX 24 +#define ENB_CONFIG_PUSCH_HOPPINGOFFSET_IDX 25 +#define ENB_CONFIG_PUSCH_ENABLE64QAM_IDX 26 +#define ENB_CONFIG_PUSCH_GROUP_HOPPING_EN_IDX 27 +#define ENB_CONFIG_PUSCH_GROUP_ASSIGNMENT_IDX 28 +#define ENB_CONFIG_PUSCH_SEQUENCE_HOPPING_EN_IDX 29 +#define ENB_CONFIG_PUSCH_NDMRS1_IDX 30 +#define ENB_CONFIG_PHICH_DURATION_IDX 31 +#define ENB_CONFIG_PHICH_RESOURCE_IDX 32 +#define ENB_CONFIG_SRS_ENABLE_IDX 33 +#define ENB_CONFIG_SRS_BANDWIDTH_CONFIG_IDX 34 +#define ENB_CONFIG_SRS_SUBFRAME_CONFIG_IDX 35 +#define ENB_CONFIG_SRS_ACKNACKST_CONFIG_IDX 36 +#define ENB_CONFIG_SRS_MAXUPPTS_IDX 37 +#define ENB_CONFIG_PUSCH_PO_NOMINAL_IDX 38 +#define ENB_CONFIG_PUSCH_ALPHA_IDX 39 +#define ENB_CONFIG_PUCCH_PO_NOMINAL_IDX 40 +#define ENB_CONFIG_MSG3_DELTA_PREAMBLE_IDX 41 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1_IDX 42 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT1b_IDX 43 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2_IDX 44 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2A_IDX 45 +#define ENB_CONFIG_PUCCH_DELTAF_FORMAT2B_IDX 46 +#define ENB_CONFIG_RACH_NUM_RA_PREAMBLES_IDX 47 +#define ENB_CONFIG_RACH_PREAMBLESGROUPACONFIG_IDX 48 +#define ENB_CONFIG_RACH_SIZEOFRA_PREAMBLESGROUPA_IDX 49 +#define ENB_CONFIG_RACH_MESSAGESIZEGROUPA_IDX 50 +#define ENB_CONFIG_RACH_MESSAGEPOWEROFFSETGROUPB_IDX 51 +#define ENB_CONFIG_RACH_POWERRAMPINGSTEP_IDX 52 +#define ENB_CONFIG_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_IDX 53 +#define ENB_CONFIG_RACH_PREAMBLETRANSMAX_IDX 54 +#define ENB_CONFIG_RACH_RARESPONSEWINDOWSIZE_IDX 55 +#define ENB_CONFIG_RACH_MACCONTENTIONRESOLUTIONTIMER_IDX 56 +#define ENB_CONFIG_RACH_MAXHARQMSG3TX_IDX 57 +#define ENB_CONFIG_PCCH_DEFAULT_PAGING_CYCLE_IDX 58 +#define ENB_CONFIG_PCCH_NB_IDX 59 +#define ENB_CONFIG_BCCH_MODIFICATIONPERIODCOEFF_IDX 60 +#define ENB_CONFIG_UETIMERS_T300_IDX 61 +#define ENB_CONFIG_UETIMERS_T301_IDX 62 +#define ENB_CONFIG_UETIMERS_T310_IDX 63 +#define ENB_CONFIG_UETIMERS_T311_IDX 64 +#define ENB_CONFIG_UETIMERS_N310_IDX 65 +#define ENB_CONFIG_UETIMERS_N311_IDX 66 +#define ENB_CONFIG_UE_TRANSMISSION_MODE_IDX 67 + /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* SRB1 configuration parameters section name */ @@ -573,43 +652,8 @@ static int DEFENBS[] = {0}; -/* L1 configuration parameters names */ -#define CONFIG_STRING_L1_CC "num_cc" -#define CONFIG_STRING_L1_LOCAL_N_IF_NAME "local_n_if_name" -#define CONFIG_STRING_L1_LOCAL_N_ADDRESS "local_n_address" -#define CONFIG_STRING_L1_REMOTE_N_ADDRESS "remote_n_address" -#define CONFIG_STRING_L1_LOCAL_N_PORTC "local_n_portc" -#define CONFIG_STRING_L1_REMOTE_N_PORTC "remote_n_portc" -#define CONFIG_STRING_L1_LOCAL_N_PORTD "local_n_portd" -#define CONFIG_STRING_L1_REMOTE_N_PORTD "remote_n_portd" -#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE "tr_n_preference" - /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* L1 configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define L1PARAMS_DESC { \ -{CONFIG_STRING_L1_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_mac", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50030, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -{CONFIG_STRING_L1_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50031, TYPE_UINT, 0}, \ -} -#define L1_CC_IDX 0 -#define L1_TRANSPORT_N_PREFERENCE_IDX 1 -#define L1_LOCAL_N_IF_NAME_IDX 2 -#define L1_LOCAL_N_ADDRESS_IDX 3 -#define L1_REMOTE_N_ADDRESS_IDX 4 -#define L1_LOCAL_N_PORTC_IDX 5 -#define L1_REMOTE_N_PORTC_IDX 6 -#define L1_LOCAL_N_PORTD_IDX 7 -#define L1_REMOTE_N_PORTD_IDX 8 -/*----------------------------------------------------------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CONFIG_STRING_NETWORK_CONTROLLER_CONFIG "NETWORK_CONTROLLER" @@ -643,64 +687,4 @@ static int DEFENBS[] = {0}; #define CONFIG_STRING_MACRLC_CONFIG "macrlc_config" -/* MACRLC configuration parameters names */ -#define CONFIG_STRING_MACRLC_CC "num_cc" -#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference" -#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name" -#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address" -#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address" -#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc" -#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc" -#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD "local_n_portd" -#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD "remote_n_portd" -#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE "tr_s_preference" -#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME "local_s_if_name" -#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS "local_s_address" -#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS "remote_s_address" -#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC "local_s_portc" -#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC "remote_s_portc" -#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD "local_s_portd" -#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD "remote_s_portd" - - -/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* MacRLC configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ -#define MACRLCPARAMS_DESC { \ -{CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_L1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_PORTC, NULL, 0, uptr:NULL, defintval:50010, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_N_PORTD, NULL, 0, uptr:NULL, defintval:50011, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"local_RRC", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS, NULL, 0, uptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defintval:50020, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -{CONFIG_STRING_MACRLC_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ -} -#define MACRLC_CC_IDX 0 -#define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 -#define MACRLC_LOCAL_N_IF_NAME_IDX 2 -#define MACRLC_LOCAL_N_ADDRESS_IDX 3 -#define MACRLC_REMOTE_N_ADDRESS_IDX 4 -#define MACRLC_LOCAL_N_PORTC_IDX 5 -#define MACRLC_REMOTE_N_PORTC_IDX 6 -#define MACRLC_LOCAL_N_PORTD_IDX 7 -#define MACRLC_REMOTE_N_PORTD_IDX 8 -#define MACRLC_TRANSPORT_S_PREFERENCE_IDX 9 -#define MACRLC_LOCAL_S_IF_NAME_IDX 10 -#define MACRLC_LOCAL_S_ADDRESS_IDX 11 -#define MACRLC_REMOTE_S_ADDRESS_IDX 12 -#define MACRLC_LOCAL_S_PORTC_IDX 13 -#define MACRLC_REMOTE_S_PORTC_IDX 14 -#define MACRLC_LOCAL_S_PORTD_IDX 15 -#define MACRLC_REMOTE_S_PORTD_IDX 16 -/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ + diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index c1743bf744f821df542c8029928dbf1c6d54b22f..3200f55f16fa1100e75140b87c98b6f257786701 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -131,8 +131,8 @@ int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) { - if (!phy_is_present(mod_id, 0)) return 0; - return RC.eNB[mod_id][0]->UE_stats[ue_id].DL_cqi[0]; + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].dl_cqi[0]; } rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) @@ -188,12 +188,145 @@ int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) } } +uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes; +} + +uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->eNB_stats[cc_id].total_ulsch_bytes_rx; +} + +uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].TBS; +} + +uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_TBS; +} + +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx; +} + +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx; +} + +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used; +} + +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].rbs_used_rx; +} + uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { if (!mac_is_present(mod_id)) return 0; return RC.mac[mod_id]->UE_list.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id]; } +uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1; +} + +uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2; +} + +uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1; +} + +uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2; +} + +uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used; +} + +uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx; +} + +uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus; +} + +uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx; +} + +uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes; +} + +uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS; +} + +int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].harq_round; +} + +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx; +} + +unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index]; +} + +uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid) +{ + if (!mac_is_present(mod_id)) return 0; + return RC.mac[mod_id]->UE_list.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid]; +} + + /* TODO needs to be revised */ void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index aafb82077e986f989e577149350dc1b4f8c0b8cc..4e5f214af00f133cc2d2485589b17650f7af0712 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * @@ -107,6 +107,81 @@ void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); */ /* this function is broken */ int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id); +/*Get number of mac SDU DL*/ +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Return the MAC sdu size got from logical channel lcid */ +uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid); + +/*Return number of MAC SDUs obtained in MAC layer*/ +uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get mac sdu lcid index*/ +unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index); + +/*Get MAC size sdus length dl*/ +uint32_t flexran_get_size_dl_mac_sdus(mid_t mod_id, int cc_id); + +/*Get MAC size sdus length ul */ +uint32_t flexran_get_size_ul_mac_sdus(mid_t mod_id, int cc_id); + +/*Get total size DL MAC SDUS*/ +uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total size of UL mac SDUS*/ +uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total number of PDU DL*/ +uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total number of PDU UL*/ +uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total PRB dl TODO Should be changed*/ +uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total PRB ul TODO Should be changed*/ +uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for tx per UE DL*/ +uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for rx per UE UL*/ +uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for retx per UE UL*/ +uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get number of prb for retx per UE*/ +uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS before rate adaptation DL*/ +uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS after rate adaptation DL*/ +uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS before rate adaptation UL*/ +uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*MCS after rate adaptation UL*/ +uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get downlink TBS*/ +uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get uplink TBS */ +uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total TBS DL*/ +uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id); + +/*Get total TBS DL*/ +uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id); + +/* Get the current HARQ round for UE ue_id */ +int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id); + /* Get the number of active component carriers for a specific UE */ int flexran_get_active_CC(mid_t mod_id, mid_t ue_id); diff --git a/openair2/ENB_APP/flexran_agent_timer.c b/openair2/ENB_APP/flexran_agent_timer.c index f5436e4d01dcf192744dac2506978986ad5bc02e..dda302735388ce56f5ce57d9e39de10a5cd712b8 100644 --- a/openair2/ENB_APP/flexran_agent_timer.c +++ b/openair2/ENB_APP/flexran_agent_timer.c @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/ENB_APP/flexran_agent_timer.h b/openair2/ENB_APP/flexran_agent_timer.h index 86e0d07825c094ed2fc2efa80f929414931db02d..98d83c78a950d7db533316f297e3f3e4ac4c9704 100644 --- a/openair2/ENB_APP/flexran_agent_timer.h +++ b/openair2/ENB_APP/flexran_agent_timer.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/LAYER2/MAC/config_NB_IoT.h b/openair2/LAYER2/MAC/config_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..0e497e3b0f407b9c3da8fd7d357375a5596f8422 --- /dev/null +++ b/openair2/LAYER2/MAC/config_NB_IoT.h @@ -0,0 +1,301 @@ + +/*! \file config_NB_IoT.h + * \brief configured structures used by scheduler + * \author NTUST BMW Lab./ + * \date 2017 + * \email: + * \version 1.0 + * + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +//#include "NB_IoT_Message_definitions.h" + +#define NUMBER_OF_SIBS_MAX_NB_IoT 6 + +///MIB +typedef enum operationModeInf{ + iNB_IoTand_SamePCI_r13 = 1, + iNB_IoTand_DifferentPCI_r13 = 2, + guardband_r13 = 3, + standalone_r13 = 4 +}operationModeInf_t; + +///SIB1_SchedulingInfo_NB_IoT_r13 +typedef enum si_Periodicity{ + si_Periodicity_rf64=640, + si_Periodicity_rf128=1280, + si_Periodicity_rf256=2560, + si_Periodicity_rf512=5120, + si_Periodicity_rf1024=10240, + si_Periodicity_rf2048=20480, + si_Periodicity_rf4096=40960 +}si_Periodicity_NB_IoT; + +typedef enum si_RepetitionPattern{ + si_RepetitionPattern_every2ndRF=0, + si_RepetitionPattern_every4thRF, + si_RepetitionPattern_every8thRF, + si_RepetitionPattern_every16thRF +}si_RepetitionPattern_NB_IoT; + +typedef enum sib_MappingInfo{ + sib2_v=0x1, + sib3_v=0x2, + sib4_v=0x4, + sib5_v=0x8, + sib14_v=0x10, + sib16_v=0x20 +}sib_MappingInfo_NB_IoT; + +typedef enum si_TB{ + si_TB_56=2, + si_TB_120=2, + si_TB_208=8, + si_TB_256=8, + si_TB_328=8, + si_TB_440=8, + si_TB_552=8, + si_TB_680=8 +}si_TB_NB_IoT; + +///RACH_ConfigCommon configuration + +typedef enum ra_ResponseWindowSize{ + ra_ResponseWindowSize_pp2=2, + ra_ResponseWindowSize_pp3=3, + ra_ResponseWindowSize_pp4=4, + ra_ResponseWindowSize_pp5=5, + ra_ResponseWindowSize_pp6=6, + ra_ResponseWindowSize_pp7=7, + ra_ResponseWindowSize_pp8=8, + ra_ResponseWindowSize_pp10=10 +}ra_ResponseWindowSize_NB_IoT; + +typedef enum mac_ContentionResolutionTimer{ + mac_ContentionResolutionTimer_pp1=1, + mac_ContentionResolutionTimer_pp2=2, + mac_ContentionResolutionTimer_pp3=3, + mac_ContentionResolutionTimer_pp4=4, + mac_ContentionResolutionTimer_pp8=8, + mac_ContentionResolutionTimer_pp16=16, + mac_ContentionResolutionTimer_pp32=32, + mac_ContentionResolutionTimer_pp64=64 +}mac_ContentionResolutionTimer_NB_IoT; + +///NPRACH_ConfigSIB configuration + +typedef enum nprach_Periodicity{ + nprach_Periodicity_ms40=40, + nprach_Periodicity_ms80=80, + nprach_Periodicity_ms160=160, + nprach_Periodicity_ms240=240, + nprach_Periodicity_ms320=320, + nprach_Periodicity_ms640=640, + nprach_Periodicity_ms1280=1280, + nprach_Periodicity_ms2560=2560 +}nprach_Periodicity_NB_IoT; + +typedef enum nprach_StartTime{ + nprach_StartTime_ms8=8, + nprach_StartTime_ms16=16, + nprach_StartTime_ms32=32, + nprach_StartTime_ms64=64, + nprach_StartTime_ms128=128, + nprach_StartTime_ms256=256, + nprach_StartTime_ms512=512, + nprach_StartTime_ms1024=1024 +}nprach_StartTime_NB_IoT; + +typedef enum nprach_SubcarrierOffset{ + nprach_SubcarrierOffset_n0=0, + nprach_SubcarrierOffset_n12=12, + nprach_SubcarrierOffset_n24=24, + nprach_SubcarrierOffset_n36=36, + nprach_SubcarrierOffset_n2=2, + nprach_SubcarrierOffset_n18=18, + nprach_SubcarrierOffset_n34=34 +}nprach_SubcarrierOffset_NB_IoT; + +typedef enum nprach_NumSubcarriers{ + nprach_NumSubcarriers_n12=12, + nprach_NumSubcarriers_n24=24, + nprach_NumSubcarriers_n36=36, + nprach_NumSubcarriers_n48=48 +}nprach_NumSubcarriers_NB_IoT; + +typedef enum nprach_SubcarrierMSG3_RangeStart{ + nprach_SubcarrierMSG3_RangeStart_zero=0, + nprach_SubcarrierMSG3_RangeStart_oneThird=1/3, + nprach_SubcarrierMSG3_RangeStart_twoThird=2/3, + nprach_SubcarrierMSG3_RangeStart_one=1 +}nprach_SubcarrierMSG3_RangeStart_NB_IoT; + +typedef enum maxNumPreambleAttemptCE{ + maxNumPreambleAttemptCE_n3=3, + maxNumPreambleAttemptCE_n4=4, + maxNumPreambleAttemptCE_n5=5, + maxNumPreambleAttemptCE_n6=6, + maxNumPreambleAttemptCE_n7=7, + maxNumPreambleAttemptCE_n8=8, + maxNumPreambleAttemptCE_n10=10 +}maxNumPreambleAttemptCE_NB_IoT; + +typedef enum numRepetitionsPerPreambleAttempt{ + numRepetitionsPerPreambleAttempt_n1=1, + numRepetitionsPerPreambleAttempt_n2=2, + numRepetitionsPerPreambleAttempt_n4=4, + numRepetitionsPerPreambleAttempt_n8=8, + numRepetitionsPerPreambleAttempt_n16=16, + numRepetitionsPerPreambleAttempt_n32=32, + numRepetitionsPerPreambleAttempt_n64=64, + numRepetitionsPerPreambleAttempt_n128=128 +}numRepetitionsPerPreambleAttempt_NB_IoT; + +typedef enum npdcch_NumRepetitions_RA{ + npdcch_NumRepetitions_RA_r1=1, + npdcch_NumRepetitions_RA_r2=2, + npdcch_NumRepetitions_RA_r4=4, + npdcch_NumRepetitions_RA_r8=8, + npdcch_NumRepetitions_RA_r16=16, + npdcch_NumRepetitions_RA_r32=32, + npdcch_NumRepetitions_RA_r64=64, + npdcch_NumRepetitions_RA_r128=128, + npdcch_NumRepetitions_RA_r256=256, + npdcch_NumRepetitions_RA_r512=512, + npdcch_NumRepetitions_RA_r1024=1024, + npdcch_NumRepetitions_RA_r2048=2048 +}npdcch_NumRepetitions_RA_NB_IoT; + +typedef enum npdcch_StartSF_CSS_RA{ + npdcch_StartSF_CSS_RA_v1dot5=3/2, + npdcch_StartSF_CSS_RA_v2=2, + npdcch_StartSF_CSS_RA_v4=4, + npdcch_StartSF_CSS_RA_v8=8, + npdcch_StartSF_CSS_RA_v16=16, + npdcch_StartSF_CSS_RA_v32=32, + npdcch_StartSF_CSS_RA_v48=48, + npdcch_StartSF_CSS_RA_v64=64 +}npdcch_StartSF_CSS_RA_NB_IoT; + +typedef enum npdcch_Offset_RA{ + zero=0, + oneEighth=1/8, + oneFourth=1/4, + threeEighth=3/8 +}npdcch_Offset_RA_NB_IoT; + +typedef enum si_window_length_e{ + ms160=160, + ms320=320, + ms480=480, + ms640=640, + ms960=960, + ms1280=1280, + ms1600=1600 +}si_window_length_t; + +typedef enum si_periodicity_e{ + rf64=640, + rf128=1280, + rf256=2560, + rf512=5120, + rf1024=10240, + rf2048=20480, + rf4096=40960 +}si_periodicity_t; + +typedef enum si_repetition_pattern_e{ + every2ndRF=20, + every4thRF=40, + every8thRF=80, + every16thRF=160 +}si_repetition_pattern_t; + +typedef enum si_tb_e{ + b56=2, + b120=2, + b208=8, + b256=8, + b328=8, + b440=8, + b552=8, + b680=8 +}si_tb_t; + + +typedef struct sibs_NB_IoT_sched_s{ + si_periodicity_t si_periodicity; + si_repetition_pattern_t si_repetition_pattern; + sib_MappingInfo_NB_IoT sib_mapping_info; //bit vector + si_tb_t si_tb; + +}sibs_NB_IoT_sched_t; + + +///-------------------------------------------------------MAC--------------------------------------------------------------------/// +typedef struct sib1_NB_IoT_sched_s{ + int repetitions; // 4, 8, 16 + int starting_rf; +}sib1_NB_IoT_sched_t; + +typedef struct { + + uint32_t mac_ra_ResponseWindowSize_NB_IoT; + uint32_t mac_ContentionResolutionTimer_NB_IoT; + +}mac_RACH_ConfigCommon_NB_IoT; + +typedef struct { + + uint32_t mac_nprach_Periodicity_NB_IoT; + uint32_t mac_nprach_StartTime_NB_IoT; + uint32_t mac_nprach_SubcarrierOffset_NB_IoT; + uint32_t mac_nprach_NumSubcarriers_NB_IoT; + uint32_t mac_nprach_SubcarrierMSG3_RangeStart_NB_IoT; + uint32_t mac_maxNumPreambleAttemptCE_NB_IoT; + uint32_t mac_numRepetitionsPerPreambleAttempt_NB_IoT; + // css + uint32_t mac_npdcch_NumRepetitions_RA_NB_IoT; // rmax + uint32_t mac_npdcch_StartSF_CSS_RA_NB_IoT; // G + uint32_t mac_npdcch_Offset_RA_NB_IoT; // alpha offset + +}mac_NPRACH_ConfigSIB_NB_IoT; + +typedef struct{ + //npdcch-NumRepetitions-r13 + uint32_t R_max; + //npdcch-StartSF-USS-r13 + double G; + //npdcch-Offset-USS-r13 + double a_offset; +}npdcch_ConfigDedicated_NB_IoT; + +typedef struct rrc_config_NB_IoT_s{ + + ///MIB + uint16_t schedulingInfoSIB1_NB_IoT; + + ///SIB1 + uint32_t cellIdentity_NB_IoT; + + sib1_NB_IoT_sched_t sib1_NB_IoT_sched_config; + ///SIBS + sibs_NB_IoT_sched_t sibs_NB_IoT_sched[NUMBER_OF_SIBS_MAX_NB_IoT]; + si_window_length_t si_window_length; + uint32_t si_radio_frame_offset; + + ///SIB2 mac_RACH_ConfigCommon_NB_IoT + mac_RACH_ConfigCommon_NB_IoT mac_RACH_ConfigCommon[3]; + + ///SIB2 mac_NPRACH_ConfigSIB_NB_IoT + mac_NPRACH_ConfigSIB_NB_IoT mac_NPRACH_ConfigSIB[3]; + + ///NPDCCH Dedicated config + npdcch_ConfigDedicated_NB_IoT npdcch_ConfigDedicated[3]; + +}rrc_config_NB_IoT_t; + +#endif diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h index ef1d7101389d6fa96502c928eb029b9d3f4f7daf..e3f5d954f1aacd5d6b958a30c52e55f46092fe29 100644 --- a/openair2/LAYER2/MAC/defs.h +++ b/openair2/LAYER2/MAC/defs.h @@ -157,13 +157,13 @@ #define U_PLANE_INACTIVITY_VALUE 6000 -/* - * eNB part +/* + * eNB part */ -/* - * UE/ENB common part +/* + * UE/ENB common part */ /*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */ typedef struct { @@ -448,20 +448,20 @@ typedef struct { } eNB_DLSCH_INFO; /*! \brief eNB overall statistics */ typedef struct { - /// num BCCH PDU per CC + /// num BCCH PDU per CC uint32_t total_num_bcch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t bcch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_bcch_buffer; /// BCCH MCS uint32_t bcch_mcs; - /// num CCCH PDU per CC + /// num CCCH PDU per CC uint32_t total_num_ccch_pdu; - /// BCCH buffer size + /// BCCH buffer size uint32_t ccch_buffer; - /// total BCCH buffer size + /// total BCCH buffer size uint32_t total_ccch_buffer; /// BCCH MCS uint32_t ccch_mcs; @@ -562,6 +562,13 @@ typedef struct { uint32_t num_retransmission; /// instantaneous tx throughput for each TTI // uint32_t tti_throughput[NB_RB_MAX]; + // Number of received MAC SDU + uint32_t num_mac_sdu_tx; + // LCID related to SDU + unsigned char lcid_sdu[NB_RB_MAX]; + // Length of SDU Got from LC DL + uint32_t sdu_length_tx[NB_RB_MAX]; + /// overall // @@ -608,6 +615,8 @@ typedef struct { /// uplink transport block size uint32_t ulsch_TBS; + uint32_t total_ulsch_TBS; + /// total rb used for a new uplink transmission uint32_t num_retransmission_rx; /// total rb used for a new uplink transmission @@ -616,9 +625,9 @@ typedef struct { uint32_t rbs_used_retx_rx; /// total rb used for a new uplink transmission uint32_t total_rbs_used_rx; - /// normalized rx power + /// normalized rx power int32_t normalized_rx_power; - /// target rx power + /// target rx power int32_t target_rx_power; /// num rx pdu @@ -648,6 +657,10 @@ typedef struct { uint32_t total_num_pdus_rx; /// num of error pdus uint32_t total_num_errors_rx; + // Number of error PDUS + uint32_t num_mac_sdu_rx; + // Length of SDU Got from LC UL - Size array can be refined + uint32_t sdu_length_rx[NB_RB_MAX]; } eNB_UE_STATS; /*! \brief eNB template for UE context information */ @@ -741,7 +754,7 @@ typedef struct { uint32_t dl_buffer_head_sdu_creation_time[MAX_NUM_LCID]; /// maximum creation time of the downlink buffer head across all LCID uint32_t dl_buffer_head_sdu_creation_time_max; - /// a flag indicating that the downlink head SDU is segmented + /// a flag indicating that the downlink head SDU is segmented uint8_t dl_buffer_head_sdu_is_segmented[MAX_NUM_LCID]; /// size of remaining size to send for the downlink head SDU uint32_t dl_buffer_head_sdu_remaining_size_to_send[MAX_NUM_LCID]; @@ -936,21 +949,21 @@ typedef struct { /// Dedicated information for UEs struct PhysicalConfigDedicated *physicalConfigDedicated[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// DLSCH pdu + /// DLSCH pdu DLSCH_PDU DLSCH_pdu[MAX_NUM_CCs][2][NUMBER_OF_UE_MAX]; /// DCI template and MAC connection parameters for UEs UE_TEMPLATE UE_template[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; /// DCI template and MAC connection for RA processes int pCC_id[NUMBER_OF_UE_MAX]; - /// sorted downlink component carrier for the scheduler + /// sorted downlink component carrier for the scheduler int ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier + /// number of downlink active component carrier int numactiveCCs[NUMBER_OF_UE_MAX]; - /// sorted uplink component carrier for the scheduler + /// sorted uplink component carrier for the scheduler int ordered_ULCCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - /// number of uplink active component carrier + /// number of uplink active component carrier int numactiveULCCs[NUMBER_OF_UE_MAX]; - /// number of downlink active component carrier + /// number of downlink active component carrier uint8_t dl_CC_bitmap[NUMBER_OF_UE_MAX]; /// eNB to UE statistics eNB_UE_STATS eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -1076,7 +1089,7 @@ typedef struct eNB_MAC_INST_s { nfapi_ul_config_request_t UL_req[MAX_NUM_CCs]; /// NFAPI "Temporary" UL Config Request Structure, holds future UL_config requests nfapi_ul_config_request_t UL_req_tmp[MAX_NUM_CCs][10]; - /// Preallocated HI_DCI0 pdu list + /// Preallocated HI_DCI0 pdu list nfapi_hi_dci0_request_pdu_t hi_dci0_pdu_list[MAX_NUM_CCs][MAX_NUM_HI_DCI0_PDU]; /// NFAPI HI/DCI0 Config Request Structure @@ -1099,21 +1112,21 @@ typedef struct eNB_MAC_INST_s { /// eNB stats eNB_STATS eNB_stats[MAX_NUM_CCs]; // MAC function execution peformance profiler - /// processing time of eNB scheduler + /// processing time of eNB scheduler time_stats_t eNB_scheduler; - /// processing time of eNB scheduler for SI + /// processing time of eNB scheduler for SI time_stats_t schedule_si; /// processing time of eNB scheduler for Random access time_stats_t schedule_ra; - /// processing time of eNB ULSCH scheduler + /// processing time of eNB ULSCH scheduler time_stats_t schedule_ulsch; /// processing time of eNB DCI generation time_stats_t fill_DLSCH_dci; /// processing time of eNB MAC preprocessor time_stats_t schedule_dlsch_preprocessor; - /// processing time of eNB DLSCH scheduler + /// processing time of eNB DLSCH scheduler time_stats_t schedule_dlsch; // include rlc_data_req + MAC header + preprocessor - /// processing time of eNB MCH scheduler + /// processing time of eNB MCH scheduler time_stats_t schedule_mch; /// processing time of eNB ULSCH reception time_stats_t rx_ulsch_sdu; // include rlc_data_ind @@ -1121,8 +1134,8 @@ typedef struct eNB_MAC_INST_s { time_stats_t schedule_pch; } eNB_MAC_INST; -/* - * UE part +/* + * UE part */ typedef enum { @@ -1316,24 +1329,24 @@ typedef struct { uint8_t msi_status; // could be an array if there are >1 MCH in one MBSFN area #endif //#ifdef CBA - /// CBA RNTI for each group + /// CBA RNTI for each group uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; - /// last SFN for CBA channel access + /// last SFN for CBA channel access uint8_t cba_last_access[NUM_MAX_CBA_GROUP]; //#endif - /// total UE scheduler processing time + /// total UE scheduler processing time time_stats_t ue_scheduler; // total - /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation + /// UE ULSCH tx processing time inlcuding RLC interface (rlc_data_req) and mac header generation time_stats_t tx_ulsch_sdu; /// UE DLSCH rx processing time inlcuding RLC interface (mac_rrc_data_ind or mac_rlc_status_ind+mac_rlc_data_ind) and mac header parser time_stats_t rx_dlsch_sdu; - /// UE query for MCH subframe processing time + /// UE query for MCH subframe processing time time_stats_t ue_query_mch; - /// UE MCH rx processing time + /// UE MCH rx processing time time_stats_t rx_mch_sdu; - /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) + /// UE BCCH rx processing time including RLC interface (mac_rrc_data_ind) time_stats_t rx_si; - /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) + /// UE PCCH rx processing time including RLC interface (mac_rrc_data_ind) time_stats_t rx_p; } UE_MAC_INST; /*! \brief ID of the neighboring cells used for HO*/ diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..77c0828b283076bd4edce975379dfe99f4bbd321 --- /dev/null +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -0,0 +1,543 @@ + +/*! \file defs_NB_IoT.c + * \brief MAC layer structures + * \author NTUST BMW Lab./ + * \date 2017 + * \email: + * \version 1.0 + * + */ +#ifndef __LAYER2_MAC_DEFS_NB_IOT_H__ +#define __LAYER2_MAC_DEFS_NB_IOT_H__ +#ifdef USER_MODE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#endif +//#include "COMMON/openair_defs.h" +#include "COMMON/platform_constants.h" +#include "COMMON/mac_rrc_primitives.h" +#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h" +//#include "PHY/defs.h" +#include "PHY/defs_L1_NB_IoT.h" +#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "config_NB_IoT.h" +// MAC definition +#define MAX_FRAME 0xfffff +#define NUM_FRAME 0x100000 +#define MAX_SUBFRAME 10485760 + +#define MAX(a, b) (((a)>(b))?(a):(b)) + +// RA-RNTI: 1+SFN_id>>2 +#define RA_RNTI_LOW 0x0001 // SFN_id = 0 +#define RA_RNTI_HIGH 0x0100 // SFN_id = 1023 +#define C_RNTI_LOW 0x0101 +#define C_RNTI_HIGH + +// ULSCH LCHAN IDs +/*!\brief LCID of extended power headroom for ULSCH */ +#define EXTENDED_POWER_HEADROOM 25 +/*!\brief LCID of power headroom for ULSCH */ +#define POWER_HEADROOM 26 +/*!\brief LCID of CRNTI for ULSCH */ +#define CRNTI 27 +/*!\brief LCID of truncated BSR for ULSCH */ +#define TRUNCATED_BSR 28 +/*!\brief LCID of short BSR for ULSCH */ +#define SHORT_BSR 29 +/*!\brief LCID of long BSR for ULSCH */ +#define LONG_BSR 30 +/*! \brief Values of CCCH LCID for DLSCH */ +#define CCCH_LCHANID 0 +/*!\brief Values of BCCH logical channel */ +#define BCCH 3 // SI +/*!\brief Values of PCCH logical channel */ +#define PCCH 4 // Paging +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH 0 // srb0 +/*!\brief DCCH / SRB1 logical channel */ +#define DCCH 1 // srb1 +/*!\brief DCCH1 / SRB2 logical channel */ +#define DCCH1 2 // srb2 +/*!\brief DTCH DRB1 logical channel */ +#define DTCH 3 // LCID +/*!\brief MCCH logical channel */ +#define MCCH 4 +/*!\brief MTCH logical channel */ +#define MTCH 1 +// DLSCH LCHAN ID +/*!\brief LCID of UE contention resolution identity for DLSCH*/ +#define UE_CONT_RES 28 +/*!\brief LCID of timing advance for DLSCH */ +#define TIMING_ADV_CMD 29 +/*!\brief LCID of discontinous reception mode for DLSCH */ +#define DRX_CMD 30 +/*!\brief LCID of padding LCID for DLSCH */ +#define SHORT_PADDING 31 + + +typedef enum tone_type_e +{ + sixtone = 0, + threetone, + singletone1, + singletone2, + singletone3 +}tone_type_t; + +typedef enum channel_NB_IoT_e +{ + NPDCCH = 0, + NPUSCH, + NPDSCH +}channel_NB_IoT_t; + +typedef enum{ + UL = 0, + DL +}message_direction_t; + +#define MAX_NUMBER_OF_UE_MAX_NB_IoT 20 +#define SCH_PAYLOAD_SIZE_MAX_NB_IoT 320 +#define MAX_NUMBER_OF_SIBs_NB_IoT 16 + +/*!\brief Values of BCCH0 logical channel for MIB*/ +#define BCCH0_NB_IoT 11 // MIB-NB_IoT +/*!\brief Values of BCCH1 logical channel for SIBs */ +#define BCCH1_NB_IoT 12 // SI-SIB-NB_IoTs +/*!\brief Values of PCCH logical channel */ +#define PCCH_NB_IoT 13 // Paging XXX not used for the moment +#define MCCH_NB_IoT 14 +/*!\brief Value of CCCH / SRB0 logical channel */ +#define CCCH_NB_IoT 0 // srb0 ---> XXX exactly the same as in LTE (commented for compilation purposes) +/*!\brief DCCH0 / SRB1bis logical channel */ +#define DCCH0_NB_IoT 3 // srb1bis +/*!\brief DCCH1 / SRB1 logical channel */ +#define DCCH1_NB_IoT 1 // srb1 //XXX we redefine it for the SRB1 +/*!\brief DTCH0 DRB0 logical channel */ +#define DTCH0_NB_IoT 4 // DRB0 +/*!\brief DTCH1 DRB1 logical channel */ +#define DTCH1_NB_IoT 5 // DRB1 +/*Index of UE contention resoulution logical channel*/ +#define UE_CONTENTION_RESOLUTION 28 +/*Index of TIMING_ADVANCE logical channel*/ +#define TIMING_ADVANCE 29 +/*Index of DRX_COMMAND logical channel*/ +#define DRX_COMMAND 30 +/*Index of PADDING logical channel*/ +#define PADDING 31 + + +/// NPRACH-ParametersList-NB_IoT-r13 from 36.331 RRC spec defined in PHY +/*typedef struct NPRACH_Parameters_NB_IoT{ + + /// the period time for nprach + int nprach_Periodicity; + /// for the start time for the NPRACH resource from 40ms-2560ms + int nprach_StartTime; + /// for the subcarrier of set to the NPRACH preamble from n0 - n34 + int nprach_SubcarrierOffset; + ///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48) + int nprach_NumSubcarriers; + /// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1 + int nprach_SubcarrierMSG3_RangeStart; + /// The max preamble transmission attempt for the CE level from 1 - 128 + int maxNumPreambleAttemptCE; + /// Number of NPRACH repetitions per attempt for each NPRACH resource + int numRepetitionsPerPreambleAttempt; + /// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax) + int npdcch_NumRepetitions_RA; + /// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4) + int npdcch_StartSF_CSS_RA; + /// Fractional period offset of starting subframe for NPDCCH common search space + int npdcch_Offset_RA; + +} nprach_parameters_NB_IoT_t;*/ + +/*! \brief Downlink SCH PDU Structure */ +typedef struct { + uint8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; + uint32_t pdu_size; +} __attribute__ ((__packed__)) DLSCH_PDU_NB_IoT; + +/*! \brief eNB template for UE context information */ +typedef struct { + // C-RNTI of UE + rnti_t rnti; + // UE CE level + int CE_level; + // Direction of transmission(DL:0\UL:1\NONE:-1) + int32_t direction; + // DCI Reptition + uint32_t R_dci; + // MAX repetition + uint32_t R_max; + + // HARQ round + uint32_t HARQ_round; + /*Downlink information*/ + + /// DLSCH pdu + DLSCH_PDU_NB_IoT DLSCH_pdu; + // PDU size + uint32_t DLSCH_pdu_size; + // Data Reptition + uint32_t R_dl; + // MCS index + uint32_t I_mcs_dl; + // total downlink buffer DCCH0_NB_IoT + uint32_t dl_buffer_DCCH0_NB_IoT; + // NDI + int oldNDI_DL; + //HARQ ACK/NACK repetition + uint32_t R_harq; + + /*Uplink information*/ + int oldNDI_UL; + // Uplink data repeat, now just follow the rach repeat number + uint32_t R_ul; + // PHR value (0-3) + uint32_t PHR; + // The uplink data size from BSR or DVI + uint32_t ul_total_buffer; + // Determine if this UE support multi-tone transmission or not + int multi_tone; + // Next UE_template ID + int next; + // Previous UE_template ID + int prev; + // MSG4 complete + int RRC_connected; + // UE active flag + int active; + +} UE_TEMPLATE_NB_IoT; + +/*36331 NPDCCH-ConfigDedicated-NB_IoT*/ +typedef struct{ + //npdcch-NumRepetitions-r13 + uint32_t R_max; + //npdcch-StartSF-USS-r13 + double G; + //npdcch-Offset-USS-r13 + double a_offset; + //NPDCCH period + uint32_t T; + //Starting subfrane of Search Space which is mod T + uint32_t ss_start_uss; +}NPDCCH_config_dedicated_NB_IoT_t; + + +/*! \brief UE list used by eNB to order UEs/CC for scheduling*/ +typedef struct { + + /// DCI template and MAC connection parameters for UEs + UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + + /// NPDCCH Period and searching space info + NPDCCH_config_dedicated_NB_IoT_t NPDCCH_config_dedicated; + //int next[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + // -1:No UE in list + int head; + // -1:No UE in list + int tail; + int num_UEs; + //boolean_t active[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + +} UE_list_NB_IoT_t; + + +typedef struct{ + + // flag to indicate scheduing MIB-NB_IoT + uint8_t flag_MIB; + // flag to indicate scheduling SIB1-NB_IoT + uint8_t flag_SIB1; + // flag to indicate scheduling SIBs-NB_IoT + uint8_t flag_SIBs[MAX_NUMBER_OF_SIBs_NB_IoT]; + // flag to indicate scheduling type2 NPDCCH CSS with different CE level + uint8_t flag_type2_css[3]; + // flag to indicate scheduling type1 NPDCCH CSS with different CE level + uint8_t flag_type1_css[3]; + // flag to indicate scheduling NPDCCH USS with UE list + uint8_t flag_uss[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + // flag to indicate scheduling sib1/MIB + uint8_t flag_fix_scheduling; + // number of the type2 css to schedule in this period + uint8_t num_type2_css_run; + // number of the type1 css to schedule in this period + uint8_t num_type1_css_run; + // number of the uss to schedule in this period + uint8_t num_uss_run; + +}scheduling_flag_t; + +typedef struct available_resource_UL_s{ + + ///Resource start subframe + uint32_t start_subframe; + ///Resource end subframe + uint32_t end_subframe; + // pointer to next node + struct available_resource_UL_s *next, *prev; + +}available_resource_UL_t; + +typedef struct available_resource_DL_s{ + uint32_t start_subframe; + uint32_t end_subframe; + + struct available_resource_DL_s *next, *prev; +}available_resource_DL_t; + +/*Structure used for scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end,sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + uint32_t start_h, end_h; + uint32_t start_f, end_f; + uint32_t start_sf, end_sf; + //whcih available resource node is used + available_resource_DL_t *node; +}sched_temp_DL_NB_IoT_t; + +/*!\brief MAC subheader short with 7bit Length field */ +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L:7; // octet 2 LSB + uint8_t F:1; // octet 2 MSB +} __attribute__((__packed__))SCH_SUBHEADER_SHORT_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:7; + uint8_t F:1; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_NB_IoT; +typedef struct { + uint8_t LCID:5; // octet 1 LSB + uint8_t E:1; + uint8_t F2:1; + uint8_t R:1; // octet 1 MSB + uint8_t L_MSB:8; // octet 2 MSB + uint8_t L_LSB:8; +} __attribute__((__packed__))SCH_SUBHEADER_LONG_EXTEND_NB_IoT; +/*!\brief MAC subheader short without length field */ +typedef struct { + uint8_t LCID:5; + uint8_t F2:1; + uint8_t E:1; + uint8_t R:1; +} __attribute__((__packed__))SCH_SUBHEADER_FIXED_NB_IoT; + + +/*! \brief Uplink SCH PDU Structure */ +typedef struct { + int8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT]; /*!< \brief SACH payload */ + uint16_t Pdu_size; +} __attribute__ ((__packed__)) ULSCH_PDU_NB_IoT; + +typedef struct { + uint8_t PH:6; + uint8_t R:2; +} __attribute__((__packed__))POWER_HEADROOM_CMD_NB_IoT; + +typedef struct { + uint8_t RAPID:6; + uint8_t T:1; + uint8_t E:1; +} __attribute__((__packed__))RA_HEADER_RAPID_NB_IoT; + +/*Structure used for UL scheduling*/ +typedef struct{ + //resource position info. + uint32_t sf_end, sf_start; + //resource position info. separate by HyperSF, Frame, Subframe + //uint32_t start_h, end_h; + //uint32_t start_f, end_f; + //uint32_t start_sf, end_sf; + // information for allocating the resource + int tone; + int scheduling_delay; + int subcarrier_indication; + int ACK_NACK_resource_field; + available_resource_UL_t *node; +}sched_temp_UL_NB_IoT_t; + +typedef struct Available_available_resource_DL{ + + ///Available Resoruce for sixtone + available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame; + uint32_t sixtone_end_subframe; + ///Available Resoruce for threetone + available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame; + uint32_t threetone_end_subframe; + ///Available Resoruce for singletone1 + available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame; + uint32_t singletone1_end_subframe; + ///Available Resoruce for singletone2 + available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame; + uint32_t singletone2_end_subframe; + ///Available Resoruce for singletone3 + available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame; + uint32_t singletone3_end_subframe; + +}available_resource_tones_UL_t; + +typedef struct schedule_result{ + // The subframe read by output handler + uint32_t output_subframe; + // SDU length + uint32_t sdu_length; + // MAC PDU + uint8_t *DLSCH_pdu; + // The data direction indicated by this DCI + uint8_t direction; + // pointer to DCI + void *DCI_pdu; + // when all the procedure related to this DCI, enable this flag + boolean_t DCI_release; + // Indicate the channel which to transmit + channel_NB_IoT_t channel; + // rnti + rnti_t rnti; + // 0 = TC-RNTI , 1 = RA-RNTI, 2 = P-RNTI, 3 = others + uint8_t rnti_type; + // 0 = data, 1 = ACK/NACK + uint8_t npusch_format; + //HARQ ACK/NACK repetition + uint32_t R_harq; + // pointer to next node + struct schedule_result *next; + + uint32_t end_subframe; + + uint8_t *rar_buffer; + +}schedule_result_t; + +/*Flag structure used for trigger each scheduler*/ +typedef struct{ + scheduling_flag_t scheduling_flag; + //sched_temp_DL_NB_IoT_t sched_result_DL; + //resource grid for Uplink + available_resource_tones_UL_t *UL_resource; + //scheduling result read by output handler + schedule_result_t *schedule_result_list_UL; + schedule_result_t *schedule_result_list_DL; +}SCHEDULE_NB_IoT_t; + +typedef struct{ + uint32_t num_dlsf_per_period; + uint16_t *sf_to_dlsf_table; + uint16_t *dlsf_to_sf_table; +}DLSF_INFO_t; + +typedef enum ce_level_e{ + ce0=0, + ce1, + ce2, + ce_level_total +}ce_level_t; + + + +/*! \brief eNB template for the Random access information */ +typedef struct RA_TEMPLATE_NB_IoT_s{ + + boolean_t active; + uint32_t msg3_retransmit_count; + uint32_t msg4_retransmit_count; + uint16_t ta; + uint8_t preamble_index; + ce_level_t ce_level; + rnti_t ue_rnti; + rnti_t ra_rnti; + struct RA_TEMPLATE_NB_IoT_s *next, *prev; + boolean_t wait_msg4_ack; + boolean_t wait_msg3_ack; + uint8_t rar_buffer[7]; + +} RA_TEMPLATE_NB_IoT; + +typedef struct RA_template_list_s{ + RA_TEMPLATE_NB_IoT *head; + RA_TEMPLATE_NB_IoT *tail; +}RA_template_list_t; + + +/*! \brief top level eNB MAC structure */ +typedef struct eNB_MAC_INST_NB_IoT_s { + /// Ethernet parameters for northbound midhaul interface + eth_params_t eth_params_n; + /// Ethernet parameters for fronthaul interface + eth_params_t eth_params_s; + + uint8_t Mod_id; + // System + uint32_t hyper_system_frame; + uint32_t system_frame; + uint32_t sub_frame; + + uint32_t current_subframe; + /// Pointer to IF module instance for PHY + IF_Module_t *if_inst; + // RA + RA_template_list_t RA_msg2_list; + RA_template_list_t RA_msg3_list; + RA_template_list_t RA_msg4_list; + + RA_TEMPLATE_NB_IoT RA_template[MAX_NUMBER_OF_UE_MAX_NB_IoT]; + + //int32_t last_tx_subframe; + + // for tool + int32_t sib1_flag[64]; + int32_t sib1_count[64]; + int32_t sib1_period; + uint16_t dlsf_table[64]; + int32_t sibs_table[256]; + + // channel config + + //USS list + //Number of USS period is used + int num_uss_list; + UE_list_NB_IoT_t *UE_list_spec; + + scheduling_flag_t scheduling_flag; + + uint32_t schedule_subframe_DL; + uint32_t schedule_subframe_UL; + + rrc_config_NB_IoT_t rrc_config; + + nfapi_config_request_t config; + + IF_Module_NB_IoT_t *if_inst_NB_IoT; +} eNB_MAC_INST_NB_IoT; + +// actually not here, but for now put it here +typedef struct { + uint32_t bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */ + uint32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ + uint32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ + uint32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ + boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ +} mac_rlc_status_resp_NB_IoT_t; + +// global variables + +nprach_parameters_NB_IoT_t nprach_list[3]; + +//DLSF Table +DLSF_INFO_t DLSF_information; + +#endif /*__LAYER2_MAC_DEFS_NB_IoT_H__ */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 48b19b091942ac19dd02f1ac102190781792023f..0729073eba3cc5e6ca1351603329d83c095497bc 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -154,7 +154,7 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, } //------------------------------------------------------------------------------ -unsigned char +int generate_dlsch_header(unsigned char *mac_header, unsigned char num_sdus, unsigned short *sdu_lengths, @@ -344,7 +344,6 @@ generate_dlsch_header(unsigned char *mac_header, //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); return ((unsigned char *) mac_header_ptr - mac_header); - } //------------------------------------------------------------------------------ @@ -563,33 +562,28 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { - - - uint8_t CC_id; + int CC_id; int UE_id; - unsigned char aggregation; + int aggregation; mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = - 0, header_len_dtch_last = 0; - unsigned char ta_len = 0; - unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; - uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = - 0, post_padding = 0; + int ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX]; + int lcid, offset, num_sdus = 0; + int nb_rb, nb_rb_temp, nb_available_rb; + uint16_t sdu_lengths[NB_RB_MAX]; + int TBS, j, rnti, padding = 0, post_padding = 0; unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - unsigned char round = 0; - unsigned char harq_pid = 0; + int round = 0; + int harq_pid = 0; eNB_UE_STATS *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; + int sdu_length_total = 0; eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &eNB->UE_list; int continue_flag = 0; int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; + int tpc = 1; UE_sched_ctrl *ue_sched_ctl; int mcs; int i; @@ -601,6 +595,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, nfapi_dl_config_request_pdu_t *dl_config_pdu; int tdd_sfa; int ta_update; + int header_length_last; + int header_length_total; #if 0 if (UE_list->head == -1) { @@ -744,7 +740,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } } /* if (continue_flag != 1 */ - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, aggregation, rnti)) { LOG_D(MAC, @@ -792,6 +788,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue; + header_length_total = 0; sdu_length_total = 0; num_sdus = 0; @@ -838,8 +835,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (cc[CC_id].tdd_Config != NULL) { UE_list->UE_template[CC_id][UE_id].DAI++; update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI); + UE_list->UE_template[CC_id][UE_id].DAI); LOG_D(MAC, "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", CC_id, subframeP, UE_id, @@ -929,7 +925,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, dl_req->number_dci++; dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; @@ -988,13 +984,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, module_idP, frameP, CC_id, UE_id); } } else { /* This is a potentially new SDU opportunity */ - rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - // check first for RLC data on DCCH + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + // add the length for all the control elements (timing adv, drx, etc) : header + payload if (ue_sched_ctl->ta_timer == 0) { @@ -1009,36 +1004,42 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, ta_len = (ta_update != 31) ? 2 : 0; - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - - if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)); // transport block set size + // RLC data on DCCH + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + TBS - ta_len - header_length_total - sdu_length_total - 3); sdu_lengths[0] = 0; - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC, - "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", module_idP, frameP, subframeP, CC_id, - TBS - header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used - (char *) - &dlsch_buffer - [0]); + TBS - ta_len - header_length_total - sdu_length_total - 3); + + sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + TBS, //not used + (char *)&dlsch_buffer[0]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); - LOG_D(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", + LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", module_idP, CC_id, sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0]; UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; + + header_length_last = 1 + 1 + (sdu_lengths[0] >= 128); + header_length_total += header_length_last; + num_sdus = 1; + #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes :", @@ -1050,26 +1051,25 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, LOG_T(MAC, "\n"); #endif - } else { - header_len_dcch = 0; - sdu_length_total = 0; } } - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)); // transport block set size less allocations for timing advance and + + // RLC data on DCCH1 + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + TBS - ta_len - header_length_total - sdu_length_total - 3); + // DCCH SDU sdu_lengths[num_sdus] = 0; if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", module_idP, frameP, CC_id, - TBS - header_len_dcch - sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used - (char *) - &dlsch_buffer - [sdu_length_total]); + TBS - ta_len - header_length_total - sdu_length_total - 3); + + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total]); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), @@ -1078,11 +1078,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, sdu_lcids[num_sdus] = DCCH1; sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = DCCH1; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; + + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + num_sdus++; + #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d][DCCH1] CC_id %d Got %d bytes :", @@ -1094,25 +1099,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, LOG_T(MAC, "\n"); #endif - } } - // assume the max dtch header size, and adjust it later - header_len_dtch = 0; - header_len_dtch_last = 0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). + + // TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list). for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active + // TODO: check if the lcid is active - header_len_dtch += 3; - header_len_dtch_last = 3; - LOG_D(MAC, - "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", module_idP, frameP, lcid, TBS, - TBS - ta_len - header_len_dcch - - sdu_length_total - header_len_dtch); + TBS - ta_len - header_length_total - sdu_length_total - 3); - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, @@ -1121,25 +1119,22 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS - ta_len - - header_len_dcch - - sdu_length_total - - header_len_dtch); + TBS - ta_len - header_length_total - sdu_length_total - 3); - if (rlc_status.bytes_in_buffer > 0) { + if (rlc_status.bytes_in_buffer > 0) { LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", module_idP, frameP, - TBS - header_len_dcch - - sdu_length_total - header_len_dtch, lcid, - header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used - (char - *) - &dlsch_buffer - [sdu_length_total]); + TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, + header_length_total); + + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total]); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), @@ -1148,48 +1143,39 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); + sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] - += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx - [lcid] += sdu_lengths[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + num_sdus++; + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } // no data for this LCID - else { - header_len_dtch -= 3; } - } // no TBS left - else { - header_len_dtch -= 3; + } else { + // no TBS left break; } } - if (header_len_dtch == 0) - header_len_dtch_last = 0; - // there is at least one SDU + + /* last header does not have length field */ + if (header_length_total) { + header_length_total -= header_length_last; + header_length_total++; + } + + // there is at least one SDU or TA command // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + - header_len_dtch) > 0) { + if (ta_len + sdu_length_total + header_length_total > 0) { // Now compute number of required RBs for total sdu length // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field - } else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU - } mcs = eNB_UE_stats->dlsch_mcs1; @@ -1201,16 +1187,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, TBS = get_TBS_DL(mcs, nb_rb); - while (TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) { + while (TBS < sdu_length_total + header_length_total + ta_len) { nb_rb += min_rb_unit[CC_id]; // if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs // (can happen if N_RB_DL is odd) - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_available_rb); + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); nb_rb = nb_available_rb; break; } @@ -1244,13 +1226,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, } // decrease mcs until TBS falls below required length - while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs > 0)) { + while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { mcs--; TBS = get_TBS_DL(mcs, nb_rb); } // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) + while ((TBS < sdu_length_total + header_length_total + ta_len) && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) && (mcs < 28)) || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) @@ -1271,23 +1253,14 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif - if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) { - padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len); + if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { + padding = TBS - header_length_total - sdu_length_total - ta_len; post_padding = 0; } else { padding = 0; - - // adjust the header len - if (header_len_dtch == 0) { - header_len_dcch = header_len_dcch_tmp; - } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - } - - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header + post_padding = 1; } - offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus sdu_lengths, // sdu_lcids, 255, // no drx @@ -1298,12 +1271,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, //#ifdef DEBUG_eNB_SCHEDULER if (ta_update != 31) { LOG_D(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n", module_idP, frameP, UE_id, CC_id, sdu_length_total, num_sdus, sdu_lengths[0], sdu_lcids[0], offset, ta_update, padding, post_padding, mcs, TBS, nb_rb, - header_len_dcch, header_len_dtch); + header_length_total); } //#endif #ifdef DEBUG_eNB_SCHEDULER @@ -1321,11 +1294,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, dlsch_buffer, sdu_length_total); // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); +#if 0 // fill remainder of DLSCH with random data for (j = 0; j < (TBS - sdu_length_total - offset); j++) { UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char) (taus() & 0xff); } - +#endif + // fill remainder of DLSCH with 0 + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; + } if (opt_enabled == 1) { trace_pdu(1, (uint8_t *) @@ -1342,8 +1320,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), - T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id]. - payload[0], TBS)); + T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; @@ -1355,6 +1332,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].num_mac_sdu_tx = num_sdus; UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; @@ -1371,6 +1349,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->UE_template[CC_id][UE_id]. DAI); } + // do PUCCH power control // this is the normalized RX power eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; @@ -1392,24 +1371,21 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, if (normalized_rx_power > (target_rx_power + 4)) { tpc = 0; //-1 - tpc_accumulated--; } else if (normalized_rx_power < (target_rx_power - 4)) { tpc = 2; //+1 - tpc_accumulated++; } else { tpc = 1; //0 } LOG_D(MAC, - "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, - tpc, tpc_accumulated, + "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, normalized_rx_power, target_rx_power); - } // Po_PUCCH has been updated + } // Po_PUCCH has been updated else { tpc = 1; //0 - } // time to do TPC update + } // time to do TPC update else { tpc = 1; //0 } @@ -1449,13 +1425,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, module_idP, CC_id, harq_pid, mcs); } + LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", dl_req->number_pdu); + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, dl_config_pdu->dci_dl_pdu. dci_dl_pdu_rel8.aggregation_level, rnti)) { - - ue_sched_ctl->round[CC_id][harq_pid] = 0; dl_req->number_dci++; dl_req->number_pdu++; @@ -1475,8 +1451,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != - NULL, + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is NULL\n"); AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); @@ -1499,16 +1474,11 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, 0, //number of PRBs treated as one subband, not used here 0 // number of beamforming vectors, not used here ); - eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB-> - TX_req - [CC_id].tx_request_body, + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, (frameP * 10) + subframeP, TBS, eNB->pdu_index[CC_id], - eNB-> - UE_list.DLSCH_pdu[CC_id][0][(unsigned char) - UE_id].payload - [0]); - + eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]); + LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", eNB->pdu_index[CC_id]); @@ -1516,10 +1486,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, eNB->pdu_index[CC_id]++; program_dlsch_acknak(module_idP, CC_id, UE_id, frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); } else { LOG_W(MAC, "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", @@ -1543,7 +1510,6 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP, stop_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); - } //------------------------------------------------------------------------------ @@ -1688,9 +1654,9 @@ update_ul_dci(module_id_t module_idP, int i; - if (cc->tdd_Config != NULL) { // TDD + if (cc->tdd_Config != NULL) { // TDD for (i = 0; - i <HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; + i <HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; i++) { if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index ac87498560f9ca258460e7b9d7d5fd56ea57b3e3..b4fb025ea479c5b5b42291af6f88509daa8be6c5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1315,6 +1315,7 @@ schedule_ulsch_rnti(module_id_t module_idP, rb_table[rb_table_index]); UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template->TBS_UL[harq_pid]; // buffer_occupancy -= TBS; T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 759bc591dd5133cdbcc302ebf7b61f48b03a86a1..e7458c347f40932ef248d991bd51b1e3a554e002 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -593,588 +593,591 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t #endif } +void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int N_RBG[MAX_NUM_CCs], + int min_rb_unit[MAX_NUM_CCs], + uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], + uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX], + uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]) { + + + int UE_id, CC_id; + int ii, r1; + + rnti_t rnti; + uint8_t harq_pid, round, transmission_mode; + uint8_t total_rbs_used[MAX_NUM_CCs]; + uint8_t total_ue_count[MAX_NUM_CCs]; + uint16_t average_rbs_per_user[MAX_NUM_CCs]; + uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + + int N_RB_DL; + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; + COMMON_channels_t *cc; + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + total_ue_count[CC_id] = 0; + total_rbs_used[CC_id] = 0; + average_rbs_per_user[CC_id] = 0; + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; ++UE_id) { + nb_rbs_required_remaining[CC_id][UE_id] = 0; + } + } + // loop over all active UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; -// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done -void -dlsch_scheduler_pre_processor(module_id_t Mod_id, - slice_id_t slice_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], int *mbsfn_flag) -{ - - unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX], harq_pid = - 0, round = 0, total_ue_count[MAX_NUM_CCs], total_rbs_used[MAX_NUM_CCs]; - unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; - int UE_id, i; - uint16_t ii, j; - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t average_rbs_per_user[MAX_NUM_CCs] = { 0 }; - rnti_t rnti; - int min_rb_unit[MAX_NUM_CCs]; - uint16_t r1 = 0; - uint8_t CC_id; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - - int N_RB_DL; - int transmission_mode = 0; - UE_sched_ctrl *ue_sched_ctl; - // int rrc_status = RRC_IDLE; - COMMON_channels_t *cc; - -#ifdef TM5 - int harq_pid1 = 0; - int round1 = 0, round2 = 0; - int UE_id2; - uint16_t i1, i2, i3; - rnti_t rnti1, rnti2; - LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; - LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; - UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; -#endif - - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + // TODO Can we use subframe2harqpid() here? + if (cc->tdd_Config) + harq_pid = ((frameP * 10) + subframeP) % 10; + else + harq_pid = ((frameP * 10) + subframeP) & 7; + round = ue_sched_ctl->round[CC_id][harq_pid]; + average_rbs_per_user[CC_id] = 0; + if (round != 8) { + nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + total_rbs_used[CC_id] += nb_rbs_required[CC_id][UE_id]; + } - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); + //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; + if (nb_rbs_required[CC_id][UE_id] > 0) { + total_ue_count[CC_id] = total_ue_count[CC_id] + 1; + } + } + } - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; + // loop over all active UEs and calculate avg rb per user based on total active UEs + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); - if (!ue_slice_membership(i, slice_id)) - continue; + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; - UE_id = i; - // Initialize scheduling information for all active UEs + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + // hypothetical assignment + /* + * If schedule is enabled and if the priority of the UEs is modified + * The average rbs per logical channel per user will depend on the level of + * priority. Concerning the hypothetical assignement, we should assign more + * rbs to prioritized users. Maybe, we can do a mapping between the + * average rbs per user and the level of priority or multiply the average rbs + * per user by a coefficient which represents the degree of priority. + */ + N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - total_rbs_used[CC_id]; - dlsch_scheduler_pre_processor_reset(Mod_id, - UE_id, - CC_id, - frameP, - subframeP, - N_RBG[CC_id], - nb_rbs_required, - nb_rbs_required_remaining, - total_ue_count, - total_rbs_used, - rballoc_sub, - MIMO_mode_indicator); + // recalculate based on the what is left after retransmission + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] = + flexran_nb_rbs_allowed_slice(slice_percentage[slice_id], N_RB_DL); - } + if (total_ue_count[CC_id] == 0) { + average_rbs_per_user[CC_id] = 0; + } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= + (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { + average_rbs_per_user[CC_id] = + (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); + } else { + // consider the total number of use that can be scheduled UE + average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; + } } + } + // note: nb_rbs_required is assigned according to total_buffer_dl + // extend nb_rbs_required to capture per LCID RB required + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + rnti = UE_RNTI(Mod_id, UE_id); - // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id, slice_id,frameP, subframeP); - - + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, - min_rb_unit); + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + cc = &RC.mac[Mod_id]->common_channels[CC_id]; + // TODO Can we use subframe2harqpid() here? + if (cc->tdd_Config) + harq_pid = ((frameP * 10) + subframeP) % 10; + else + harq_pid = ((frameP * 10) + subframeP) & 7; + round = ue_sched_ctl->round[CC_id][harq_pid]; + + // control channel or retransmission + /* TODO: do we have to check for retransmission? */ + if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round > 0) { + nb_rbs_required_remaining_1[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id]; + } else { + nb_rbs_required_remaining_1[CC_id][UE_id] = + cmin(average_rbs_per_user[CC_id], nb_rbs_required[CC_id][UE_id]); + } + } + } + //Allocation to UEs is done in 2 rounds, + // 1st stage: average number of RBs allocated to each UE + // 2nd stage: remaining RBs are allocated to high priority UEs + for (r1 = 0; r1 < 2; r1++) { + + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + CC_id = UE_list->ordered_CCids[ii][UE_id]; + + if (r1 == 0) { + nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_required_remaining_1[CC_id][UE_id]; + } else { // rb required based only on the buffer - rb allocated in the 1st round + extra reaming rb form the 1st round + nb_rbs_required_remaining[CC_id][UE_id] = + nb_rbs_required[CC_id][UE_id] - + nb_rbs_required_remaining_1[CC_id][UE_id] + + nb_rbs_required_remaining[CC_id][UE_id]; + if (nb_rbs_required_remaining[CC_id][UE_id] < 0) + abort(); + } + if (nb_rbs_required[CC_id][UE_id] > 0) + LOG_D(MAC, + "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", + r1, CC_id, UE_id, + nb_rbs_required_remaining[CC_id][UE_id], + nb_rbs_required_remaining_1[CC_id][UE_id], + nb_rbs_required[CC_id][UE_id], + UE_list->UE_sched_ctrl[UE_id].pre_nb_available_rbs[CC_id], + N_RBG[CC_id], + min_rb_unit[CC_id]); - // Sorts the user on the basis of dlsch logical channel buffer and CQI - sort_UEs(Mod_id, slice_id, frameP, subframeP); + } + } + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + + for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + + CC_id = UE_list->ordered_CCids[ii][UE_id]; + // if there are UEs with traffic + if (total_ue_count[CC_id] > 0) { + // ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + // round = ue_sched_ctl->round[CC_id][harq_pid]; + + rnti = UE_RNTI(Mod_id, UE_id); + + // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); + if (rnti == NOT_A_RNTI) + continue; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; + + transmission_mode = get_tmode(Mod_id, CC_id, UE_id); + // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); + // rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); + /* 1st allocate for the retx */ + + // retransmission in data channels + // control channel in the 1st transmission + // data channel for all TM + LOG_T(MAC, + "calling dlsch_scheduler_pre_processor_allocate .. \n "); + dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, + CC_id, + N_RBG[CC_id], + transmission_mode, + min_rb_unit + [CC_id], + to_prb(RC.mac + [Mod_id]->common_channels + [CC_id].mib->message.dl_Bandwidth), + nb_rbs_required, + nb_rbs_required_remaining, + rballoc_sub, + MIMO_mode_indicator); - // loop over all active UEs - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); +#ifdef TM5 + // data chanel TM5: to be revisited + if ((round == 0) && + (transmission_mode == 5) && + (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { + + for (j = 0; j < N_RBG[CC_id]; j += 2) { + + if ((((j == (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j] == 0) + && (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && (rballoc_sub[CC_id][j + 1] == 0) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j + 1] == 0))) + && (nb_rbs_required_remaining[CC_id][UE_id] + > 0)) { + + for (ii = UE_list->next[UE_id + 1]; ii >= 0; + ii = UE_list->next[ii]) { + + UE_id2 = ii; + rnti2 = UE_RNTI(Mod_id, UE_id2); + ue_sched_ctl2 = + &UE_list->UE_sched_ctrl[UE_id2]; + round2 = ue_sched_ctl2->round[CC_id]; + if (rnti2 == NOT_A_RNTI) + continue; + if (UE_list-> + UE_sched_ctrl + [UE_id2].ul_out_of_sync == 1) + continue; + + eNB_UE_stats2 = + UE_list-> + eNB_UE_stats[CC_id][UE_id2]; + //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); + + if ((mac_eNB_get_rrc_status + (Mod_id, + rnti2) >= RRC_RECONFIGURED) + && (round2 == 0) + && + (get_tmode(Mod_id, CC_id, UE_id2) + == 5) + && (ue_sched_ctl-> + dl_pow_off[CC_id] != 1)) { + + if ((((j == (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl->rballoc_sub_UE + [CC_id][j] == 0)) + || ((j < (N_RBG[CC_id] - 1)) + && + (ue_sched_ctl-> + rballoc_sub_UE[CC_id][j + + 1] + == 0))) + && + (nb_rbs_required_remaining + [CC_id] + [UE_id2] > 0)) { + + if ((((eNB_UE_stats2-> + DL_pmi_single ^ + eNB_UE_stats1-> + DL_pmi_single) + << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration + + rballoc_sub[CC_id][j] = 1; + ue_sched_ctl-> + rballoc_sub_UE[CC_id] + [j] = 1; + ue_sched_ctl2-> + rballoc_sub_UE[CC_id] + [j] = 1; + MIMO_mode_indicator[CC_id] + [j] = 0; + + if (j < N_RBG[CC_id] - 1) { + rballoc_sub[CC_id][j + + 1] = + 1; + ue_sched_ctl-> + rballoc_sub_UE + [CC_id][j + 1] = 1; + ue_sched_ctl2->rballoc_sub_UE + [CC_id][j + 1] = 1; + MIMO_mode_indicator + [CC_id][j + 1] + = 0; + } + + ue_sched_ctl-> + dl_pow_off[CC_id] + = 0; + ue_sched_ctl2-> + dl_pow_off[CC_id] + = 0; + + + if ((j == N_RBG[CC_id] - 1) + && ((N_RB_DL == 25) + || (N_RB_DL == + 50))) { + + nb_rbs_required_remaining + [CC_id][UE_id] = + nb_rbs_required_remaining + [CC_id][UE_id] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + nb_rbs_required_remaining + [CC_id][UE_id2] = + nb_rbs_required_remaining + [CC_id][UE_id2] - + min_rb_unit[CC_id] + + 1; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + + min_rb_unit[CC_id] + - 1; + } else { + + nb_rbs_required_remaining + [CC_id][UE_id] = + nb_rbs_required_remaining + [CC_id][UE_id] - 4; + ue_sched_ctl->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl->pre_nb_available_rbs + [CC_id] + 4; + nb_rbs_required_remaining + [CC_id][UE_id2] = + nb_rbs_required_remaining + [CC_id][UE_id2] - + 4; + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] = + ue_sched_ctl2->pre_nb_available_rbs + [CC_id] + 4; + } + + break; + } + } + } + } + } + } + } +#endif + } // total_ue_count + } // CC + } // UE + } // end of for for r1 and r2 +} - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - UE_id = i; - if (!ue_slice_membership(UE_id, slice_id)) - continue; +// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done +void +dlsch_scheduler_pre_processor(module_id_t Mod_id, + slice_id_t slice_id, + frame_t frameP, + sub_frame_t subframeP, + int N_RBG[MAX_NUM_CCs], + int *mbsfn_flag) { - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - cc = &RC.mac[Mod_id]->common_channels[ii]; - if (cc->tdd_Config) - harq_pid = ((frameP * 10) + subframeP) % 10; - else - harq_pid = ((frameP * 10) + subframeP) & 7; - round = ue_sched_ctl->round[CC_id][harq_pid]; + int UE_id; + uint8_t CC_id; + uint16_t i, j; - average_rbs_per_user[CC_id] = 0; + uint8_t rballoc_sub[MAX_NUM_CCs][N_RBG_MAX]; + uint8_t MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; // If TM5 is revisited, we can move this inside accounting + int min_rb_unit[MAX_NUM_CCs]; + uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - if (round != 8) { - nb_rbs_required[CC_id][UE_id] = - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - total_rbs_used[CC_id]+=nb_rbs_required[CC_id][UE_id]; - } + UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; + UE_sched_ctrl *ue_sched_ctl; +// int rrc_status = RRC_IDLE; - //nb_rbs_required_remaining[UE_id] = nb_rbs_required[UE_id]; - if (nb_rbs_required[CC_id][UE_id] > 0) { - total_ue_count[CC_id] = total_ue_count[CC_id] + 1; - } +#ifdef TM5 + int harq_pid1 = 0; + int round1 = 0, round2 = 0; + int UE_id2; + uint16_t i1, i2, i3; + rnti_t rnti1, rnti2; + LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; + LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; + UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; +#endif - } - } + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - // loop over all active UEs and calculate avg rb per user based on total active UEs - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); + if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here + continue; - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - UE_id = i; - if (!ue_slice_membership(UE_id, slice_id)) - continue; + min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - - // hypothetical assignment - /* - * If schedule is enabled and if the priority of the UEs is modified - * The average rbs per logical channel per user will depend on the level of - * priority. Concerning the hypothetical assignement, we should assign more - * rbs to prioritized users. Maybe, we can do a mapping between the - * average rbs per user and the level of priority or multiply the average rbs - * per user by a coefficient which represents the degree of priority. - */ - - - N_RB_DL = - to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib-> - message.dl_Bandwidth) - total_rbs_used[CC_id]; - - //recalcualte based on the what is left after retransmission - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id]= flexran_nb_rbs_allowed_slice(slice_percentage[slice_id],N_RB_DL); - - if (total_ue_count[CC_id] == 0) { - average_rbs_per_user[CC_id] = 0; - } else if ((min_rb_unit[CC_id] * total_ue_count[CC_id]) <= (ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id])) { - average_rbs_per_user[CC_id] = - (uint16_t) floor(ue_sched_ctl->max_rbs_allowed_slice[CC_id][slice_id] / total_ue_count[CC_id]); - } else { - average_rbs_per_user[CC_id] = min_rb_unit[CC_id]; // consider the total number of use that can be scheduled UE - } - } - } - - // note: nb_rbs_required is assigned according to total_buffer_dl - // extend nb_rbs_required to capture per LCID RB required - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - rnti = UE_RNTI(Mod_id, i); + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; ++UE_id) { + if (UE_list->active[UE_id] != TRUE) + continue; - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1) - continue; - if (!ue_slice_membership(i, slice_id)) - continue; + if (!ue_slice_membership(UE_id, slice_id)) + continue; - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[i]; - round = ue_sched_ctl->round[CC_id][harq_pid]; - - // control channel or retransmission - /* TODO: do we have to check for retransmission? */ - if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED - || round > 0) { - nb_rbs_required_remaining_1[CC_id][i] = - nb_rbs_required[CC_id][i]; - } else { - nb_rbs_required_remaining_1[CC_id][i] = - cmin(average_rbs_per_user[CC_id], - nb_rbs_required[CC_id][i]); + // Initialize scheduling information for all active UEs + dlsch_scheduler_pre_processor_reset(Mod_id, + UE_id, + CC_id, + frameP, + subframeP, + N_RBG[CC_id], + nb_rbs_required, + rballoc_sub, + MIMO_mode_indicator); - } - } } + } - //Allocation to UEs is done in 2 rounds, - // 1st stage: average number of RBs allocated to each UE - // 2nd stage: remaining RBs are allocated to high priority UEs - for (r1 = 0; r1 < 2; r1++) { - - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, i); ii++) { - CC_id = UE_list->ordered_CCids[ii][i]; - - if (r1 == 0) { - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required_remaining_1[CC_id][i]; - } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round - nb_rbs_required_remaining[CC_id][i] = - nb_rbs_required[CC_id][i] - - nb_rbs_required_remaining_1[CC_id][i] + - nb_rbs_required_remaining[CC_id][i]; - if (nb_rbs_required_remaining[CC_id][i] < 0) - abort(); - } - - if (nb_rbs_required[CC_id][i] > 0) - LOG_D(MAC, - "round %d : nb_rbs_required_remaining[%d][%d]= %d (remaining_1 %d, required %d, pre_nb_available_rbs %d, N_RBG %d, rb_unit %d)\n", - r1, CC_id, i, - nb_rbs_required_remaining[CC_id][i], - nb_rbs_required_remaining_1[CC_id][i], - nb_rbs_required[CC_id][i], - UE_list->UE_sched_ctrl[i]. - pre_nb_available_rbs[CC_id], N_RBG[CC_id], - min_rb_unit[CC_id]); - - } - } - + // Store the DLSCH buffer for each logical channel + store_dlsch_buffer(Mod_id, slice_id, frameP, subframeP); - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; + // Calculate the number of RBs required by each UE on the basis of logical channel's buffer + assign_rbs_required(Mod_id, slice_id, frameP, subframeP, nb_rbs_required, min_rb_unit); - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { + // Sorts the user on the basis of dlsch logical channel buffer and CQI + sort_UEs(Mod_id, slice_id, frameP, subframeP); - // if there are UEs with traffic - if (total_ue_count [CC_id] > 0) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - round = ue_sched_ctl->round[CC_id][harq_pid]; + // This function does the main allocation of the number of RBs + dlsch_scheduler_pre_processor_accounting(Mod_id, + slice_id, + frameP, + subframeP, + N_RBG, + min_rb_unit, + rballoc_sub, + MIMO_mode_indicator, + nb_rbs_required); - rnti = UE_RNTI(Mod_id, UE_id); - - // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti ); - if (rnti == NOT_A_RNTI) - continue; - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; - if (!ue_slice_membership(i, slice_id)) - continue; - - transmission_mode = get_tmode(Mod_id, CC_id, UE_id); - // mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0); - //rrc_status = mac_eNB_get_rrc_status(Mod_id,rnti); - /* 1st allocate for the retx */ - - // retransmission in data channels - // control channel in the 1st transmission - // data channel for all TM - LOG_T(MAC, - "calling dlsch_scheduler_pre_processor_allocate .. \n "); - dlsch_scheduler_pre_processor_allocate(Mod_id, UE_id, - CC_id, - N_RBG[CC_id], - transmission_mode, - min_rb_unit - [CC_id], - to_prb(RC.mac - [Mod_id]->common_channels - [CC_id].mib->message.dl_Bandwidth), - nb_rbs_required, - nb_rbs_required_remaining, - rballoc_sub, - MIMO_mode_indicator); #ifdef TM5 + // This has to be revisited!!!! + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + i1 = 0; + i2 = 0; + i3 = 0; + + for (j = 0; j < N_RBG[CC_id]; j++) { + if (MIMO_mode_indicator[CC_id][j] == 2) { + i1 = i1 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 1) { + i2 = i2 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 0) { + i3 = i3 + 1; + } + } - // data chanel TM5: to be revisted - if ((round == 0) && - (transmission_mode == 5) && - (ue_sched_ctl->dl_pow_off[CC_id] != 1)) { - - for (j = 0; j < N_RBG[CC_id]; j += 2) { - - if ((((j == (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j] == 0) - && (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && (rballoc_sub[CC_id][j + 1] == 0) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j + 1] == 0))) - && (nb_rbs_required_remaining[CC_id][UE_id] - > 0)) { - - for (ii = UE_list->next[i + 1]; ii >= 0; - ii = UE_list->next[ii]) { - - UE_id2 = ii; - rnti2 = UE_RNTI(Mod_id, UE_id2); - ue_sched_ctl2 = - &UE_list->UE_sched_ctrl[UE_id2]; - round2 = ue_sched_ctl2->round[CC_id]; - if (rnti2 == NOT_A_RNTI) - continue; - if (UE_list-> - UE_sched_ctrl - [UE_id2].ul_out_of_sync == 1) - continue; - - eNB_UE_stats2 = - UE_list-> - eNB_UE_stats[CC_id][UE_id2]; - //mac_xface->get_ue_active_harq_pid(Mod_id,CC_id,rnti2,frameP,subframeP,&harq_pid2,&round2,0); - - if ((mac_eNB_get_rrc_status - (Mod_id, - rnti2) >= RRC_RECONFIGURED) - && (round2 == 0) - && - (get_tmode(Mod_id, CC_id, UE_id2) - == 5) - && (ue_sched_ctl-> - dl_pow_off[CC_id] != 1)) { - - if ((((j == (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl->rballoc_sub_UE - [CC_id][j] == 0)) - || ((j < (N_RBG[CC_id] - 1)) - && - (ue_sched_ctl-> - rballoc_sub_UE[CC_id][j + - 1] - == 0))) - && - (nb_rbs_required_remaining - [CC_id] - [UE_id2] > 0)) { - - if ((((eNB_UE_stats2-> - DL_pmi_single ^ - eNB_UE_stats1-> - DL_pmi_single) - << (14 - j)) & 0xc000) == 0x4000) { //MU-MIMO only for 25 RBs configuration - - rballoc_sub[CC_id][j] = 1; - ue_sched_ctl-> - rballoc_sub_UE[CC_id] - [j] = 1; - ue_sched_ctl2-> - rballoc_sub_UE[CC_id] - [j] = 1; - MIMO_mode_indicator[CC_id] - [j] = 0; - - if (j < N_RBG[CC_id] - 1) { - rballoc_sub[CC_id][j + - 1] = - 1; - ue_sched_ctl-> - rballoc_sub_UE - [CC_id][j + 1] = 1; - ue_sched_ctl2->rballoc_sub_UE - [CC_id][j + 1] = 1; - MIMO_mode_indicator - [CC_id][j + 1] - = 0; - } - - ue_sched_ctl-> - dl_pow_off[CC_id] - = 0; - ue_sched_ctl2-> - dl_pow_off[CC_id] - = 0; - - - if ((j == N_RBG[CC_id] - 1) - && ((N_RB_DL == 25) - || (N_RB_DL == - 50))) { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - min_rb_unit[CC_id] - + 1; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + - min_rb_unit[CC_id] - - 1; - } else { - - nb_rbs_required_remaining - [CC_id][UE_id] = - nb_rbs_required_remaining - [CC_id][UE_id] - 4; - ue_sched_ctl->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl->pre_nb_available_rbs - [CC_id] + 4; - nb_rbs_required_remaining - [CC_id][UE_id2] = - nb_rbs_required_remaining - [CC_id][UE_id2] - - 4; - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] = - ue_sched_ctl2->pre_nb_available_rbs - [CC_id] + 4; - } - - break; - } - } - } - } - } - } - } -#endif - } // total_ue_count - } - } - } // end of for for r1 and r2 - -#ifdef TM5 - - // This has to be revisited!!!! - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - i1 = 0; - i2 = 0; - i3 = 0; - - for (j = 0; j < N_RBG[CC_id]; j++) { - if (MIMO_mode_indicator[CC_id][j] == 2) { - i1 = i1 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 1) { - i2 = i2 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 0) { - i3 = i3 + 1; - } - } - - if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_SUMIMO_transmissions + 1; - } - - if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + - 1; - } + if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_SUMIMO_transmissions + 1; + } - if ((i1 < N_RBG[CC_id]) && (i3 > 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_MUMIMO_transmissions + 1; - } + if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + + 1; + } - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + - 1; + if ((i1 < N_RBG[CC_id]) && (i3 > 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_MUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_MUMIMO_transmissions + 1; + } - } + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + + 1; + } #endif - for (i = UE_list->head; i >= 0; i = UE_list->next[i]) { - UE_id = i; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { - for (ii = 0; ii < UE_num_active_CC(UE_list, UE_id); ii++) { - CC_id = UE_list->ordered_CCids[ii][UE_id]; - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + for (i = 0; i < UE_num_active_CC(UE_list, UE_id); i++) { + CC_id = UE_list->ordered_CCids[i][UE_id]; + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; - if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { - LOG_D(MAC, - "******************DL Scheduling Information for UE%d ************************\n", - UE_id); - LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, - ue_sched_ctl->dl_pow_off[CC_id]); - LOG_D(MAC, - "***********RB Alloc for every subband for UE%d ***********\n", - UE_id); - - for (j = 0; j < N_RBG[CC_id]; j++) { - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; - LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", - UE_id, j, - ue_sched_ctl->rballoc_sub_UE[CC_id][j]); - } + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { + LOG_D(MAC, "******************DL Scheduling Information for UE%d ************************\n", UE_id); + LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, ue_sched_ctl->dl_pow_off[CC_id]); + LOG_D(MAC, "***********RB Alloc for every subband for UE%d ***********\n", UE_id); - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; - LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", Mod_id, slice_id, UE_id, - ue_sched_ctl->pre_nb_available_rbs[CC_id]); - } - } + for (j = 0; j < N_RBG[CC_id]; j++) { + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[UE_id] = rballoc_sub_UE[CC_id][UE_id][UE_id]; + LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", UE_id, j, ue_sched_ctl->rballoc_sub_UE[CC_id][j]); + } + + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; + LOG_D(MAC, "[eNB %d][SLICE %d]Total RBs allocated for UE%d = %d\n", + Mod_id, slice_id, UE_id, ue_sched_ctl->pre_nb_available_rbs[CC_id]); + } } + } } #define SF0_LIMIT 1 void dlsch_scheduler_pre_processor_reset(int module_idP, - int UE_id, - uint8_t CC_id, - int frameP, - int subframeP, - int N_RBG, - uint16_t nb_rbs_required[MAX_NUM_CCs] - [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - unsigned char total_ue_count[MAX_NUM_CCs], - unsigned char total_rbs_used[MAX_NUM_CCs], - unsigned char - rballoc_sub[MAX_NUM_CCs] - [N_RBG_MAX], - unsigned char - MIMO_mode_indicator[MAX_NUM_CCs] - [N_RBG_MAX]) + int UE_id, + uint8_t CC_id, + int frameP, + int subframeP, + int N_RBG, + uint16_t nb_rbs_required[MAX_NUM_CCs] + [NUMBER_OF_UE_MAX], + unsigned char + rballoc_sub[MAX_NUM_CCs] + [N_RBG_MAX], + unsigned char + MIMO_mode_indicator[MAX_NUM_CCs] + [N_RBG_MAX]) { - int i, j; - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; - UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - rnti_t rnti = UE_RNTI(module_idP, UE_id); - - uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; - int N_RB_DL = - to_prb(RC.mac[module_idP]->common_channels[CC_id].mib-> - message.dl_Bandwidth); - int RBGsize = N_RB_DL / N_RBG, RBGsize_last; + int i, j; + UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + rnti_t rnti = UE_RNTI(module_idP, UE_id); + + uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map; + int N_RB_DL = + to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); + int RBGsize = N_RB_DL / N_RBG, RBGsize_last; #ifdef SF0_LIMIT - int sf0_upper = -1, sf0_lower = -1; + int sf0_upper = -1, sf0_lower = -1; #endif - LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); - // initialize harq_pid and round + LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); + // initialize harq_pid and round - if (ue_sched_ctl->ta_timer) - ue_sched_ctl->ta_timer--; + if (ue_sched_ctl->ta_timer) + ue_sched_ctl->ta_timer--; /* eNB_UE_stats *eNB_UE_stats; @@ -1234,95 +1237,96 @@ dlsch_scheduler_pre_processor_reset(int module_idP, } */ - nb_rbs_required[CC_id][UE_id] = 0; - ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; - ue_sched_ctl->dl_pow_off[CC_id] = 2; - nb_rbs_required_remaining[CC_id][UE_id] = 0; - total_ue_count[CC_id]=0; - total_rbs_used[CC_id]=0; - switch (N_RB_DL) { + nb_rbs_required[CC_id][UE_id] = 0; + ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0; + ue_sched_ctl->dl_pow_off[CC_id] = 2; + + switch (N_RB_DL) { case 6: - RBGsize = 1; - RBGsize_last = 1; - break; + RBGsize = 1; + RBGsize_last = 1; + break; case 15: - RBGsize = 2; - RBGsize_last = 1; - break; + RBGsize = 2; + RBGsize_last = 1; + break; case 25: - RBGsize = 2; - RBGsize_last = 1; - break; + RBGsize = 2; + RBGsize_last = 1; + break; case 50: - RBGsize = 3; - RBGsize_last = 2; - break; + RBGsize = 3; + RBGsize_last = 2; + break; case 75: - RBGsize = 4; - RBGsize_last = 3; - break; + RBGsize = 4; + RBGsize_last = 3; + break; case 100: - RBGsize = 4; - RBGsize_last = 4; - break; + RBGsize = 4; + RBGsize_last = 4; + break; default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #ifdef SF0_LIMIT - switch (N_RBG) { + switch (N_RBG) { case 6: - sf0_lower = 0; - sf0_upper = 5; - break; + sf0_lower = 0; + sf0_upper = 5; + break; case 8: - sf0_lower = 2; - sf0_upper = 5; - break; + sf0_lower = 2; + sf0_upper = 5; + break; case 13: - sf0_lower = 4; - sf0_upper = 7; - break; + sf0_lower = 4; + sf0_upper = 7; + break; case 17: - sf0_lower = 7; - sf0_upper = 9; - break; + sf0_lower = 7; + sf0_upper = 9; + break; case 25: - sf0_lower = 11; - sf0_upper = 13; - break; + sf0_lower = 11; + sf0_upper = 13; + break; default: - AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); - } + AssertFatal(1 == 0, "unsupported RBs (%d)\n", N_RB_DL); + } #endif - // Initialize Subbands according to VRB map - for (i = 0; i < N_RBG; i++) { - int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; - ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; - rballoc_sub[CC_id][i] = 0; + // Initialize Subbands according to VRB map + for (i = 0; i < N_RBG; i++) { + int rb_size = i == N_RBG - 1 ? RBGsize_last : RBGsize; + + ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0; + rballoc_sub[CC_id][i] = 0; + #ifdef SF0_LIMIT - // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) - /* TODO: make it proper - allocate those RBs, do not "protect" them, but - * compute number of available REs and limit MCS according to the - * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) - */ - if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) - rballoc_sub[CC_id][i] = 1; + // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors) + /* TODO: make it proper - allocate those RBs, do not "protect" them, but + * compute number of available REs and limit MCS according to the + * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor) + */ + if (subframeP == 0 && i >= sf0_lower && i <= sf0_upper) + rballoc_sub[CC_id][i] = 1; #endif - // for SI-RNTI,RA-RNTI and P-RNTI allocations - for (j = 0; j < rb_size; j++) { - if (vrb_map[j + (i * RBGsize)] != 0) { - rballoc_sub[CC_id][i] = 1; - LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", - frameP, subframeP, j + (i * RBGsize)); - break; - } - } - LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", - frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); - MIMO_mode_indicator[CC_id][i] = 2; + + // for SI-RNTI,RA-RNTI and P-RNTI allocations + for (j = 0; j < rb_size; j++) { + if (vrb_map[j + (i * RBGsize)] != 0) { + rballoc_sub[CC_id][i] = 1; + LOG_D(MAC, "Frame %d, subframe %d : vrb %d allocated\n", + frameP, subframeP, j + (i * RBGsize)); + break; + } } + LOG_D(MAC, "Frame %d Subframe %d CC_id %d RBG %i : rb_alloc %d\n", + frameP, subframeP, CC_id, i, rballoc_sub[CC_id][i]); + MIMO_mode_indicator[CC_id][i] = 2; + } } @@ -1605,6 +1609,10 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, } } +#if 0 + /* this logging is wrong, ue_sched_ctl may not be valid here + * TODO: fix + */ for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { if (total_allocated_rbs[CC_id] > 0) { @@ -1613,6 +1621,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP, ue_sched_ctl->max_rbs_allowed_slice_uplink[CC_id][slice_id] - first_rb[CC_id]); } } +#endif } diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h index 348b080d1e96eb20f0b0145fb68d268525953f07..2586c94f432887276f6359e5039b55770dae3bd9 100644 --- a/openair2/LAYER2/MAC/proto.h +++ b/openair2/LAYER2/MAC/proto.h @@ -209,11 +209,6 @@ void dlsch_scheduler_pre_processor_reset(int module_idP, int UE_id, uint16_t nb_rbs_required[MAX_NUM_CCs] [NUMBER_OF_UE_MAX], - uint16_t - nb_rbs_required_remaining - [MAX_NUM_CCs][NUMBER_OF_UE_MAX], - unsigned char total_ue_count[MAX_NUM_CCs], - unsigned char total_rbs_used[MAX_NUM_CCs], unsigned char rballoc_sub[MAX_NUM_CCs] [N_RBG_MAX], @@ -860,15 +855,15 @@ in the DLSCH buffer. @param post_padding number of bytes for padding at the end of MAC PDU @returns Number of bytes used for header */ -unsigned char generate_dlsch_header(unsigned char *mac_header, - unsigned char num_sdus, - unsigned short *sdu_lengths, - unsigned char *sdu_lcids, - unsigned char drx_cmd, - unsigned short timing_advance_cmd, - unsigned char *ue_cont_res_id, - unsigned char short_padding, - unsigned short post_padding); +int generate_dlsch_header(unsigned char *mac_header, + unsigned char num_sdus, + unsigned short *sdu_lengths, + unsigned char *sdu_lcids, + unsigned char drx_cmd, + unsigned short timing_advance_cmd, + unsigned char *ue_cont_res_id, + unsigned char short_padding, + unsigned short post_padding); /** \brief RRC eNB Configuration primitive for PHY/MAC. Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages. @param Mod_id Instance ID of eNB diff --git a/openair2/LAYER2/MAC/proto_NB_IoT.h b/openair2/LAYER2/MAC/proto_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..6e6d98eba1628abc8e20a6c46dae81de5722e4c7 --- /dev/null +++ b/openair2/LAYER2/MAC/proto_NB_IoT.h @@ -0,0 +1,198 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file LAYER2/MAC/proto_NB_IoT.h + * \brief MAC functions prototypes for eNB and UE + * \author Navid Nikaein and Raymond Knopp + * \date 2010 - 2014 + * \email navid.nikaein@eurecom.fr + * \version 1.0 + */ + +#ifndef __LAYER2_MAC_PROTO_NB_IoT_H__ +#define __LAYER2_MAC_PROTO_NB_IoT_H__ + +#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include "LAYER2/MAC/defs_NB_IoT.h" +#include "COMMON/platform_types.h" +#include "openair2/RRC/LITE/defs_NB_IoT.h" +/** \addtogroup _mac + * @{ + */ + +int l2_init_eNB_NB_IoT(void); + +///config +void rrc_mac_config_req_NB_IoT( + module_id_t Mod_idP, + int CC_idP, + int rntiP, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + SystemInformationBlockType1_NB_t *sib1_NB_IoT, + RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon, + PhysicalConfigDedicated_NB_r13_t *physicalConfigDedicated, + LogicalChannelConfig_NB_r13_t *logicalChannelConfig, //FIXME: decide how to use it + uint8_t ded_flag, + uint8_t ue_list_ded_num); + +///system +void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst); +//void init_rrc_NB_IoT(); +void release_mac_inst(uint8_t order); +eNB_MAC_INST_NB_IoT *get_mac_inst(uint8_t order); +uint8_t register_mac_inst(eNB_MAC_INST_NB_IoT *inst, uint8_t order); + +///tool +void init_tool(sib1_NB_IoT_sched_t *config); +void UE_info_setting(UE_TEMPLATE_NB_IoT *UE_info); +UE_TEMPLATE_NB_IoT *get_ue_from_rnti(eNB_MAC_INST_NB_IoT *inst, rnti_t rnti); + +///scheduler +void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe); +void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe); + +//Calvin temp define self-tools +int init_debug(eNB_MAC_INST_NB_IoT *inst); +void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst); +void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe); +available_resource_DL_t *check_sibs_resource(eNB_MAC_INST_NB_IoT *mac_inst, int check_start_subframe, int check_end_subframe, int num_subframe, int *residual_subframe, int *out_last_subframe, int *out_first_subframe); +uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe); +void init(eNB_MAC_INST_NB_IoT *mac_inst); +void init_dl_list(eNB_MAC_INST_NB_IoT *mac_inst); +int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void fill_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, available_resource_DL_t *node, int start_subframe, int end_subframe, schedule_result_t *new_node); +available_resource_DL_t *check_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int check_subframe, int num_subframes, int *out_last_subframe, int *out_first_subframe); +void print_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst); +void print_schedule_result_DL(void); +void print_schedule_result_UL(void); +void add_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce, uint32_t PHR, uint32_t ul_total_buffer); +void remove_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce); +// SIBs +void schedule_sibs(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t sibs_order, int start_subframe); + +//RA +void msg3_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti); +void msg4_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti); +void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst); +void init_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint8_t preamble_index, ce_level_t ce_level, uint32_t sfn_id, uint16_t ta); +void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void receive_msg3_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti, uint32_t phr, uint32_t ul_total_buffer); +void schedule_msg3_retransimission_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +void fill_rar_NB_IoT(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template, uint8_t msg3_schedule_delay, uint8_t msg3_rep, sched_temp_UL_NB_IoT_t *schedule_template); +void receive_msg4_ack_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t rnti); + +//USS +void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int index_ss); + +//DATA +uint8_t *parse_ulsch_header( uint8_t *mac_header, + uint8_t *num_ce, + uint8_t *num_sdu, + uint8_t *rx_ces, + uint8_t *rx_lcids, + uint16_t *rx_lengths, + uint16_t tb_length ); + +/*******UL Scheduler**********/ +void print_scheduling_result_UL(void); +void print_available_UL_resource(void); +/*set nprach configuration at intial time*/ +void setting_nprach(void); +/*Uplink main scheduler*/ +int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info, uint32_t subframe, uint32_t frame, uint32_t H_SFN); +/*Check available uplink resource list, if there is available uplink resource, return 0, otherwise, return 1*/ +int Check_UL_resource(uint32_t DL_end, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int multi_tone, int fmt2_flag); +/*Get I Repetition number in DCI*/ +int get_I_REP(int N_rep); +/*Get N REP from preamble repeat*/ +int get_N_REP(int CE_level); +/*Get TBS from mcs, multi-tone, Iru*/ +int get_TBS_UL_NB_IoT(uint32_t mcs,uint32_t multi_tone,int Iru); +/*get I tbs from mcs and multi-tone*/ +int get_I_TBS_NB_IoT(int x,int y); +/*Get DCI REP from R max and R*/ +int get_DCI_REP(uint32_t R,uint32_t R_max); +/*Check single tone resource list*/ +int single_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int fmt2_flag); +/*Check multi tone resource list*/ +int multi_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info); +/*Generate scheduling result of DCI N0 and Uplink config*/ +void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subframe, uint32_t UL_subframe, uint32_t UL_end_subframe, DCIFormatN0_t *DCI_inst, rnti_t rnti, uint8_t *ul_debug_str, uint8_t *dl_debug_str); +/*Adjust UL resource by removing the used resource*/ +void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info); +/*Initialize resource by nprach configuration*/ +void Initialize_Resource(void); +/*Function to extend uplink resource grid*/ +//void add_UL_Resource(eNB_MAC_INST_NB_IoT *mac_inst); +void add_UL_Resource(void); +/*Get ACK/NAK resource field*/ +int get_resource_field_value(int subcarrier, int k0); +/*Get DL Repetition index*/ +uint8_t get_index_Rep_dl(uint16_t R); + +/*******DL Scheduler********/ +void schedule_DL_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, UE_TEMPLATE_NB_IoT *UE_info, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start); +int check_resource_NPDCCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, sched_temp_DL_NB_IoT_t *NPDCCH_info, uint32_t cdd_num, uint32_t dci_rep); +int check_resource_NPDSCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDSCH_info, uint32_t sf_end, uint32_t I_delay, uint32_t R_max, uint32_t R_dl, uint32_t n_sf); +int check_resource_DL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, uint32_t dlsf_require, sched_temp_DL_NB_IoT_t *schedule_info); +uint32_t get_I_mcs(int CE_level); +uint32_t get_max_tbs(uint32_t I_tbs); +uint32_t get_tbs(uint32_t data_size, uint32_t I_tbs, uint32_t *I_sf); +uint32_t get_num_sf(uint32_t I_sf); +uint32_t get_scheduling_delay(uint32_t I_delay, uint32_t R_max); +uint32_t get_HARQ_delay(int subcarrier_spacing, uint32_t HARQ_delay_index); +//void generate_scheduling_result_DL(uint32_t DCI_subframe, uint32_t NPDSCH_subframe, uint32_t HARQ_subframe, DCIFormatN1_t *DCI, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu); +void generate_scheduling_result_DL(sched_temp_DL_NB_IoT_t* DCI_info, sched_temp_DL_NB_IoT_t* NPDSCH_info, sched_temp_UL_NB_IoT_t* HARQ_info, DCIFormatN1_t *DCI_inst, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu); +void fill_DCI_N1(DCIFormatN1_t *DCI_N1, UE_TEMPLATE_NB_IoT *UE_info, uint32_t scheddly, uint32_t I_sf, uint32_t I_harq); +//Transfrom source into hyperSF, Frame, Subframe format +void convert_system_number(uint32_t source_sf,uint32_t *hyperSF, uint32_t *frame, uint32_t *subframe); +//Trnasform hyperSF, Frame, Subframe format into subframe unit +uint32_t convert_system_number_sf(uint32_t hyperSF, uint32_t frame, uint32_t subframe); +/*input start position amd num_dlsf DL subframe, caculate the last subframe number*/ +uint32_t cal_num_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF, uint32_t frame, uint32_t subframe, uint32_t* hyperSF_result, uint32_t* frame_result, uint32_t* subframe_result, uint32_t num_dlsf_require); +void init_dlsf_info(eNB_MAC_INST_NB_IoT *mac_inst, DLSF_INFO_t *DLSF_info); +uint32_t generate_dlsch_header_NB_IoT(uint8_t *pdu, uint32_t num_sdu, logical_chan_id_t *logical_channel, uint32_t *sdu_length, uint8_t flag_drx, uint8_t flag_ta, uint32_t TBS); +void maintain_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDCCH_info, sched_temp_DL_NB_IoT_t *NPDSCH_info); +void init_tool_sib1(eNB_MAC_INST_NB_IoT *mac_inst); +//int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe); +/**DL test , delete**/ +available_resource_DL_t* new_dl_node(uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf); +void initialize_dl_resource(available_resource_DL_t *DL_Resource_node, uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf); +void insert_dl_resource(available_resource_DL_t *DL_Resource_node); +void insert_schedule_result(schedule_result_t **list, int subframe, schedule_result_t *node); +//interface with IF + +uint8_t *parse_ulsch_header_NB_IoT( uint8_t *mac_header, uint8_t *num_ce, uint8_t *num_sdu, uint8_t *rx_ces, uint8_t *rx_lcids, uint16_t *rx_lengths, uint16_t tb_length); + +void rx_sdu_NB_IoT(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t subframe, uint16_t rnti, uint8_t *sdu, uint16_t length); + +int output_handler(eNB_MAC_INST_NB_IoT *mac_inst, module_id_t module_id, int CC_id, uint32_t hypersfn, uint32_t frame, uint32_t subframe, uint8_t MIB_flag, uint8_t SIB1_flag, uint32_t current_time); +// main + +void mac_top_init_eNB_NB_IoT(void); + +uint32_t to_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_CarrierFreq, float m_dl); + +uint32_t from_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_earfcn, float m_dl); + +int32_t get_uldl_offset_NB_IoT(int eutra_band); +#endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index e9d2188bfb8577c8071b4a0748ef8151f57d679f..2de1b3fc743a4bd4ca41d9de64866fa0a8c79285 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -769,18 +769,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) { - unsigned char *otg_pkt=NULL; + module_id_t dst_id; // dst for otg - rb_id_t rb_id; - unsigned int pkt_size=0; protocol_ctxt_t ctxt; // we need to add conditions to avoid transmitting data when the UE is not RRC connected. if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic - unsigned int ctime=0; - ctime = ctxt_pP->frame * 100; - /*if ((mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 0 ) > 2) && - (mac_get_rrc_status(eNB_index, ctxt_pP->enb_flag, 1 ) > 2)) { */ + + + PROTOCOL_CTXT_SET_BY_MODULE_ID( &ctxt, ctxt_pP->module_id, @@ -792,36 +789,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) { ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id]; -/* - if (ctxt.rnti != NOT_A_RNTI) { - if (mac_eNB_get_rrc_status(ctxt.module_id, ctxt.rnti ) > 2 ) { - unsigned int temp = 0; - otg_pkt=packet_gen( - ENB_MODULE_ID_TO_INSTANCE(ctxt.module_id), - UE_MODULE_ID_TO_INSTANCE(dst_id), - 0, - ctime, - &temp); - pkt_size = temp; - - if (otg_pkt != NULL) { - rb_id = dst_id * maxDRB + DTCH; - pdcp_data_req(&ctxt, - SRB_FLAG_NO, - rb_id, - RLC_MUI_UNDEFINED, - RLC_SDU_CONFIRM_NO, - pkt_size, - otg_pkt, - PDCP_TRANSMISSION_MODE_DATA); - LOG_I(OTG, - "send packet from module %d on rab id %d (src %d, dst %d) pkt size %d\n", - ctxt_pP->module_id, rb_id, ctxt_pP->module_id, dst_id, pkt_size); - free(otg_pkt); - } - } - } -*/ + } } } diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c index f9af7c1cc2b167a3935615aca9b973784ef3cd40..98a44ceeeb0fccb77a78e4016410294eace7ab53 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c @@ -172,7 +172,7 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP test_pdu_remaining_size = 0; test_remaining_size_to_substract = 0; test_remaining_num_li_to_substract = 0; - pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3); + //pdu_remaining_size = pdu_remaining_size - (test_li_length_in_bytes ^ 3); } else if ((sdu_mngt_p->sdu_remaining_size + (test_li_length_in_bytes ^ 3)) < test_pdu_remaining_size ) { test_num_li += 1; num_fill_sdu += 1; @@ -365,9 +365,9 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP sdu_mngt_p->sdu_remaining_size, pdu_remaining_size - sdu_mngt_p->sdu_remaining_size); #endif -#if !EXMIMO - assert(1!=1); -#endif +//#if !EXMIMO +// assert(1!=1); +//#endif memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size); // reduce the size of the PDU continue_fill_pdu_with_sdu = 0; diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index d27d46ff4282b4ca3488a85ffb649f6f5d7d80ee..783441bd586928fb2dfe9dfc61dc1e926ca31ada 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -437,6 +437,15 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, break; case RLC_MODE_UM: + /* TODO: this is a hack, needs better solution. Let's not use too + * much memory and store at maximum 5 millions bytes. + */ + /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ + if (rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um) > 5000000) { + free_mem_block(sdu_pP, __func__); + return RLC_OP_STATUS_OUT_OF_RESSOURCES; + } + new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__); if (new_sdu_p != NULL) { diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c index 7cb6ce0d2c28c6b82fa7a06e1fcb5d791550dee6..f66d1142abf5c668f240de1fcda9bc2aa65337ff 100644 --- a/openair2/LAYER2/openair2_proc.c +++ b/openair2/LAYER2/openair2_proc.c @@ -228,9 +228,7 @@ int dump_eNB_l2_stats(char *buffer, int length) PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, eNB_id, ENB_FLAG_YES, - /* the following is suspicious, let's put back what was there before */ - /*UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, */ - UE_list->eNB_UE_stats[UE_PCCID(eNB_id,UE_id)][UE_id].crnti, + UE_list->eNB_UE_stats[0][UE_id].crnti,//UE_PCCID(eNB_id,UE_id)][UE_id].crnti, eNB->frame, eNB->subframe, eNB_id); diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index 086ec3909ca225376d36cf520dca88f44aaf55d4..f8a420697a95d043d2f5870d2c55ca8279567ed5 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -241,7 +241,7 @@ int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -306,7 +306,7 @@ void nas_tx_timeout(struct net_device *dev) printk("TX_TIMEOUT: begin\n"); // (struct nas_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE>=1796 netif_trans_update(dev); #else dev->trans_start = jiffies; diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 29db4ae07a172f26e49dd14811420084f88816a7..36c6afe914bb3f16f8ab5367733d879d7b65f4c3 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -236,7 +236,7 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) // End debug information netif_stop_queue(dev_pP); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE >= 1796 netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; @@ -312,7 +312,7 @@ void ue_ip_tx_timeout(struct net_device *dev_pP) printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; (priv_p->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || RHEL_RELEASE_CODE >= 1796 netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 7baae6c3b6f8e09c9eef43a77a207ac3989f99c5..3b1c88dda03b5857f99c40a3a724b1a072a469e5 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -3,7 +3,7 @@ * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.0 (the "License"); you may not use this file + * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * diff --git a/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..479bd47d947d0c2fd79c96b84c72badf21557712 --- /dev/null +++ b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h @@ -0,0 +1,215 @@ + +/*This is the interface module between PHY +*Provided the FAPI style interface structures for P7. +*Provide the semi-FAPI style interface for P5 (configuration) +* +*/ + +#ifndef __IF_MODULE_NB_IoT__H__ +#define __IF_MODULE_NB_IoT__H__ + +#include "nfapi_interface.h" +//#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h" +#include "PhysicalConfigDedicated-NB-r13.h" +//#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "openair2/COMMON/platform_types.h" +//#include "openair1/SCHED/IF_Module_L1_primitives_NB_IoT.h" + +//#define SCH_PAYLOAD_SIZE_MAX 4096 +#define BCCH_PAYLOAD_SIZE_MAX_NB_IoT 128 + + + +// P5 FAPI-like configuration structures------------------------------------------------------------------------------- + +/*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS + * some of them may not needed because are used only at UE side + * some of them are not needed because not necessary at PHY level + * other have to be clarified since seems to be needed at PHY layer + * there is no UE_Config. request message carrying NB-IoT parameters??? + * + * */ +typedef struct{ + //nprach_config + uint16_t nprach_config_0_subcarrier_MSG3_range_start; + uint16_t nprach_config_1_subcarrier_MSG3_range_start; + uint16_t nprach_config_2_subcarrier_MSG3_range_start; + uint16_t nprach_config_0_max_num_preamble_attempt_CE; + uint16_t nprach_config_1_max_num_preamble_attempt_CE; + uint16_t nprach_config_2_max_num_preamble_attempt_CE; + uint16_t nprach_config_0_npdcch_num_repetitions_RA; //Rmax (see TS 36.213 ch 16.6) -->only this is managed at PHY layer + uint16_t nprach_config_1_npdcch_num_repetitions_RA; + uint16_t nprach_config_2_npdcch_num_repetitions_RA; + uint16_t nprach_config_0_npdcch_startSF_CSS_RA; //G (see TS 36.213 ch 16.6) + uint16_t nprach_config_1_npdcch_startSF_CSS_RA; + uint16_t nprach_config_2_npdcch_startSF_CSS_RA; + uint16_t nprach_config_0_npdcch_offset_RA; //Alfa_offset (see TS 36.213 ch 16.6) + uint16_t nprach_config_1_npdcch_offset_RA; + uint16_t nprach_config_2_npdcch_offset_RA; + + //configured through the phy_config_dedicated + //Higher layer parameter for NPDCCH UE-spec search space + uint16_t npdcch_NumRepetitions;//Rmax (see TS 36.213 ch 16.6) -->only this is managed at PHY layer + uint16_t npdcch_StartSF_USS; //G (see TS 36.213 ch 16.6) + uint16_t npdcch_Offset_USS; //Alfa_offset (see TS 36.213 ch 16.6) + + + ACK_NACK_NumRepetitions_NB_r13_t *ack_nack_numRepetitions_MSG4; //pointer to the first cell of a list of ack_nack_num_repetitions + + //ulPowerControlCommon (UE side) + uint16_t p0_nominal_npusch; + uint16_t alpha; + uint16_t delta_preamle_MSG3; + + + /*Dedicated configuration -->not supported by FAPI (may not needed) + * In OAI at least are needed when we manage the phy_procedures_eNB_TX in which we call the phy_config_dedicated_eNB_step2 + * that use the physicalConfigDedicated info previously stored in the PHY_VARS_eNB_NB_IoT structure through the phy_config_dedicated procedure + */ + //PhysicalConfigDedicated_NB_r13_t *phy_config_dedicated; + + + + +}extra_phyConfig_t; + +typedef struct{ + + /*OAI config. parameters*/ + module_id_t mod_id; + int CC_id; + uint16_t rnti; + int get_MIB; //should be different from 0 only when the mib!= null (NB_rrc_mac_config_req_eNB_IoT) + int get_COMMON; + int get_DEDICATED; + + //ID of the Resource Block dedicated to NB-IoT + //For Nb-IoT only a restricted values of PRB indexes are allowed (see Rhode&Shwartz pag9) + //unsigned short NB_IoT_RB_ID; (should coincide with PRB index) + + + + + /*FAPI useful config. parameters used in the code + * + * -nfapi_uplink_reference_signal_config_t uplink_reference_signal_config + * -nfapi_subframe_config_t subframe_config; + * -nfapi_rf_config_t rf_config; + * -nfapi_sch_config_t sch_config; + * -nfapi_nb_iot_config_t config_NB_IoT; + * -nfapi_l23_config_t l23_config; + * -nfapi_config --> EARFCN (for the transport of the dl_CarrierFreq + * */ + + //XXX where allocate memory?? + nfapi_config_request_t* cfg; + + /*MP: MISSED COMMON CONFIG. of SIB2-NB in FAPI SPECS (may non needed)*/ + extra_phyConfig_t extra_phy_parms; + +}PHY_Config_NB_IoT_t; + + + +// uplink subframe P7--------------------------------------------------------------------------------- + + +/*UL_IND_t: +* A structure handles all the uplink information. +* Corresponding to the NRACH.indicaiton, UL_Config_indication, RX_ULSCH.indication, CRC.inidcation, NB_HARQ.indication in FAPI +*/ +typedef struct{ + + /*Start at the common part*/ + + int test; + + //Module ID + module_id_t module_id; + //CC ID + int CC_id; + //frame + frame_t frame; + //subframe + sub_frame_t subframe; + //Hyper frame for NB-IoT implementation + uint32_t hypersfn; + + /*preamble part*/ + + nfapi_nrach_indication_body_t NRACH; + + /*Uplink data part*/ + + /*indication of the harq feedback*/ + nfapi_nb_harq_indication_t nb_harq_ind; + /*indication of the uplink data PDU*/ + nfapi_rx_indication_body_t RX_NPUSCH; + /*crc_indication*/ + nfapi_crc_indication_body_t crc_ind; + + }UL_IND_NB_IoT_t; + + // Downlink subframe P7 + + +typedef struct{ + + /*Start at the common part*/ + + //Module ID + module_id_t module_id; + //CC ID + int CC_id; + // hyper subframe + uint32_t hypersfn; + //frame + frame_t frame; + //subframe + sub_frame_t subframe; + + /// nFAPI DL Config Request + nfapi_dl_config_request_t *DL_req; + /// nFAPI UL Config Request + nfapi_ul_config_request_t *UL_req; + /// nFAPI HI_DCI Request + nfapi_hi_dci0_request_t *HI_DCI0_req; + /// nFAPI TX Request + nfapi_tx_request_t *TX_req; + /// Pointers to DL SDUs + //uint8_t **sdu; + +}Sched_Rsp_NB_IoT_t; + + +/*IF_Module_t a group for gathering the Interface +It should be allocated at the main () in lte-softmodem.c*/ +typedef struct IF_Module_NB_IoT_s{ + //define the function pointer + void (*UL_indication)(UL_IND_NB_IoT_t *UL_INFO); + void (*schedule_response)(Sched_Rsp_NB_IoT_t *Sched_INFO); + void (*PHY_config_req)(PHY_Config_NB_IoT_t* config_INFO); +}IF_Module_NB_IoT_t; + +/*Initial */ + +/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ +void schedule_response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO); + +/*Interface for PHY Configuration + * Trigger the phy_config_xxx functions using parameters from the shared PHY_Config structure + * */ +void PHY_config_req_NB_IoT(PHY_Config_NB_IoT_t* config_INFO); + +//int IF_Module_init(IF_Module_t *if_inst); + +/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/ +//void Schedule_Response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO); + +/*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler) +*/ +void UL_indication_NB_IoT(UL_IND_NB_IoT_t *UL_INFO); + +IF_Module_NB_IoT_t *IF_Module_init_NB_IoT(int Mod_id); + +#endif diff --git a/openair2/RRC/LITE/L2_interface_ue.c b/openair2/RRC/LITE/L2_interface_ue.c index 7bdbe2523e818e9641b915e4cfea60f88e7165f4..244f0d2253bbd6cd78f5724650be5b3dcf7a29d3 100644 --- a/openair2/RRC/LITE/L2_interface_ue.c +++ b/openair2/RRC/LITE/L2_interface_ue.c @@ -65,26 +65,15 @@ mac_rrc_data_req_ue( ) //-------------------------------------------------------------------------- { - asn_enc_rval_t enc_rval; - SRB_INFO *Srb_info; - uint8_t Sdu_size = 0; - uint8_t sfn = (uint8_t)((frameP>>2)&0xff); - #ifdef DEBUG_RRC int i; LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); #endif - eNB_RRC_INST *rrc; - rrc_eNB_carrier_data_t *carrier; - BCCH_BCH_Message_t *mib; - - LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); - if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { #if defined(ENABLE_ITTI) @@ -139,7 +128,6 @@ mac_rrc_data_ind_ue( ) //-------------------------------------------------------------------------- { - SRB_INFO *Srb_info; protocol_ctxt_t ctxt; sdu_size_t sdu_size = 0; @@ -214,6 +202,7 @@ mac_rrc_data_ind_ue( itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p); } #else + SRB_INFO *Srb_info; Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP]; memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); Srb_info->Rx_buffer.payload_size = sdu_lenP; diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c new file mode 100644 index 0000000000000000000000000000000000000000..43721bbfd55f0ee6d03f2c90e618dcf92571e63d --- /dev/null +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.c @@ -0,0 +1,1417 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file asn1_msg.c +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr, navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#include <stdio.h> +#include <sys/types.h> +#include <stdlib.h> /* for atoi(3) */ +#include <unistd.h> /* for getopt(3) */ +#include <string.h> /* for strerror(3) */ +#include <sysexits.h> /* for EX_* exit codes */ +#include <errno.h> /* for errno */ +#include "UTIL/LOG/log.h" +#include <asn_application.h> +#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */ +#include <per_encoder.h> +#include "asn1_msg.h" + + + +//#include for NB-IoT------------------- +#include "RRCConnectionRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "UL-CCCH-Message-NB.h" +#include "UL-DCCH-Message-NB.h" +#include "DL-CCCH-Message-NB.h" +#include "DL-DCCH-Message-NB.h" +#include "EstablishmentCause-NB-r13.h" +#include "RRCConnectionSetup-NB.h" +#include "SRB-ToAddModList-NB-r13.h" +#include "DRB-ToAddModList-NB-r13.h" +#include "RRC/LITE/defs_NB_IoT.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "MasterInformationBlock-NB.h" +#include "SystemInformation-NB.h" +#include "SystemInformationBlockType1.h" +#include "SIB-Type-NB-r13.h" +#include "RRCConnectionResume-NB.h" +#include "RRCConnectionReestablishment-NB.h" +#include "../defs_NB_IoT.h" +//---------------------------------------- + +//#include "PHY/defs.h" +#include "enb_config.h" + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + + + + +/*do_MIB_NB_NB_IoT*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint16_t N_RB_DL,//may not needed--> for NB_IoT only 1 PRB is used + uint32_t frame, + uint32_t hyper_frame) +{ + asn_enc_rval_t enc_rval; + BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT); + + /* + * systemFrameNumber-MSB: (TS 36.331 pag 576) + * define the 4 MSB of the SFN (10 bits). The last significant 6 bits will be acquired implicitly by decoding the NPBCH + * NOTE: 6 LSB will be used for counting the 64 radio frames in the TTI period (640 ms) that is exactly the MIB period + * + * hyperSFN-LSB: + * indicates the 2 least significant bits of the HSFN. The remaining 8 bits are present in SIB1-NB + * NOTE: with the 2 bits we count the 4 HSFN (is 1 SIB1-Nb modification period) while the other 6 count the number of modification periods + * + * + * NOTE: in OAI never modify the SIB messages!!?? + */ + + //XXX check if correct the bit assignment + uint8_t sfn_MSB = (uint8_t)((frame>>6) & 0x0f); // all the 4 bits are set to 1 + uint8_t hsfn_LSB = (uint8_t)(hyper_frame & 0x03); //2 bits set to 1 (0x3 = 0011) + uint16_t spare=0; //11 bits --> use uint16 + + mib_NB_IoT->message.systemFrameNumber_MSB_r13.buf = &sfn_MSB; + mib_NB_IoT->message.systemFrameNumber_MSB_r13.size = 1; //if expressed in byte + mib_NB_IoT->message.systemFrameNumber_MSB_r13.bits_unused = 4; //is byte based (so how many bits you don't use of the 8 bits of a bite + + mib_NB_IoT->message.hyperSFN_LSB_r13.buf= &hsfn_LSB; + mib_NB_IoT->message.hyperSFN_LSB_r13.size= 1; + mib_NB_IoT->message.hyperSFN_LSB_r13.bits_unused = 6; + + //XXX to be set?? + mib_NB_IoT->message.spare.buf = (uint8_t *)&spare; + mib_NB_IoT->message.spare.size = 2; + mib_NB_IoT->message.spare.bits_unused = 5; + + //decide how to set it + mib_NB_IoT->message.schedulingInfoSIB1_r13 =11; //see TS 36.213-->tables 16.4.1.3-3 ecc... + mib_NB_IoT->message.systemInfoValueTag_r13= 0; + mib_NB_IoT->message.ab_Enabled_r13 = 0; + + //to be decided + mib_NB_IoT->message.operationModeInfo_r13.present = MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13; + mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 0; + + printf("[MIB] Initialization of frame information,sfn_MSB %x, hsfn_LSB %x\n", + (uint32_t)sfn_MSB, + (uint32_t)hsfn_LSB); + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message_NB, + (void*)mib_NB_IoT, + carrier->MIB_NB_IoT, + 100); + if(enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); + +} + +/*do_SIB1_NB*/ +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ) +{ + BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT); + SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT); + + + asn_enc_rval_t enc_rval; + + PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT; + MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; + SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT; + SIB_Type_NB_r13_t *sib_type_NB_IoT; + + + long* attachWithoutPDN_Connectivity = NULL; + attachWithoutPDN_Connectivity = CALLOC(1,sizeof(long)); + long *nrs_CRS_PowerOffset=NULL; + nrs_CRS_PowerOffset = CALLOC(1, sizeof(long)); + long *eutraControlRegionSize=NULL; //this parameter should be set only if we are considering in-band operating mode (samePCI or differentPCI) + eutraControlRegionSize = CALLOC(1,sizeof(long)); + long systemInfoValueTagSI = 0; + + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13; + + //allocation + *sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13; + + + /*TS 36.331 v14.2.0 pag 589 + * hyperSFN-MSB + * Indicates the 8 most significant bits of the hyper-SFN. Together with the hyper-LSB in MIB-NB the complete HSFN is build up + */ + //FIXME see if correct + uint8_t hyperSFN_MSB = (uint8_t) ((frame>>2)& 0xff); + + //XXX to be checked + (*sib1_NB_IoT)->hyperSFN_MSB_r13.buf = &hyperSFN_MSB; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1; + (*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0; + + memset(&PLMN_identity_info_NB_IoT,0,sizeof(PLMN_IdentityInfo_NB_r13_t)); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); + + asn_set_empty(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list);//.size=0; + + //left as it is??? +#if defined(ENABLE_ITTI) + dummy_mcc[0] = (configuration->mcc / 100) % 10; + dummy_mcc[1] = (configuration->mcc / 10) % 10; + dummy_mcc[2] = (configuration->mcc / 1) % 10; +#else + dummy_mcc[0] = 0; + dummy_mcc[1] = 0; + dummy_mcc[2] = 1; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[1]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc->list,&dummy_mcc[2]); + + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.size=0; + PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list.count=0; + + +#if defined(ENABLE_ITTI) + + if (configuration->mnc >= 100) { + dummy_mnc[0] = (configuration->mnc / 100) % 10; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } else { + if (configuration->mnc_digit_length == 2) { + dummy_mnc[0] = (configuration->mnc / 10) % 10; + dummy_mnc[1] = (configuration->mnc / 1) % 10; + dummy_mnc[2] = 0xf; + } else { + dummy_mnc[0] = (configuration->mnc / 100) % 100; + dummy_mnc[1] = (configuration->mnc / 10) % 10; + dummy_mnc[2] = (configuration->mnc / 1) % 10; + } + } + +#else + dummy_mnc[0] = 0; + dummy_mnc[1] = 1; + dummy_mnc[2] = 0xf; +#endif + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[0]); + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[1]); + + if (dummy_mnc[2] != 0xf) { + ASN_SEQUENCE_ADD(&PLMN_identity_info_NB_IoT.plmn_Identity_r13.mnc.list,&dummy_mnc[2]); + } + + //still set to "notReserved" as in the previous case + PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved; + + *attachWithoutPDN_Connectivity = 0; + PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity; + + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->cellAccessRelatedInfo_r13.plmn_IdentityList_r13.list,&PLMN_identity_info_NB_IoT); + + // 16 bits = 2 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf = MALLOC(2); //MALLOC works in byte + + //lefts as it is? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = (configuration->tac >> 8) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = (configuration->tac >> 0) & 0xff; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.buf[1] = 0x01; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.size=2; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.trackingAreaCode_r13.bits_unused=0; + + // 28 bits --> i have to use 32 bits = 4 byte + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf = MALLOC(8); // why allocate 8 byte? +#if defined(ENABLE_ITTI) + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = (configuration->cell_identity >> 20) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = (configuration->cell_identity >> 12) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = (configuration->cell_identity >> 4) & 0xff; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = (configuration->cell_identity << 4) & 0xf0; +#else + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[0] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[1] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[2] = 0x00; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.buf[3] = 0x10; +#endif + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.size=4; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4; + + //Still set to "notBarred" as in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred; + + //Still Set to "notAllowed" like in the previous case + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed; + + + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589 + (*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 = 0; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value) + + (*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(P_Max_t)); + *((*sib1_NB_IoT)->p_Max_r13) = 23; + + //FIXME + (*sib1_NB_IoT)->freqBandIndicator_r13 = +#if defined(ENABLE_ITTI) + configuration->eutra_band; +#else + 5; //if not configured we use band 5 (UL: 824 MHz - 849MHz / DL: 869 MHz - 894 MHz FDD mode) +#endif + + //OPTIONAL new parameters, to be used? + /* + * freqBandInfo_r13 + * multiBandInfoList_r13 + * nrs_CRS_PowerOffset_r13 + * sib1_NB_IoT->downlinkBitmap_r13.choice.subframePattern10_r13 =(is a BIT_STRING) + */ + + + (*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13)); + ((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING; + + *eutraControlRegionSize = 1; + (*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize; + + + *nrs_CRS_PowerOffset= 0; + (*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset; + + schedulingInfo_NB_IoT = (SchedulingInfo_NB_r13_t*) malloc (3*sizeof(SchedulingInfo_NB_r13_t)); + sib_type_NB_IoT = (SIB_Type_NB_r13_t *) malloc (3*sizeof(SIB_Type_NB_r13_t)); + + memset(&schedulingInfo_NB_IoT[0],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[1],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[2],0,sizeof(SchedulingInfo_NB_r13_t)); + memset(&sib_type_NB_IoT[0],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[1],0,sizeof(SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[2],0,sizeof(SIB_Type_NB_r13_t)); + + + // Now, follow the scheduler SIB configuration + // There is only one sib2+sib3 common setting + schedulingInfo_NB_IoT[0].si_Periodicity_r13=SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; + schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission. + schedulingInfo_NB_IoT[0].si_TB_r13= SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits + + + // This is for SIB2/3 + /*SIB3 --> There is no mapping information of SIB2 since it is always present + * in the first SystemInformation message + * listed in the schedulingInfoList list. + * */ + sib_type_NB_IoT[0]=SIB_Type_NB_r13_sibType3_NB_r13; + + ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]); + + //printf("[ASN Debug] SI P: %ld\n",(*sib1_NB_IoT)->schedulingInfoList_r13.list.array[0]->si_Periodicity_r13); + +#if defined(ENABLE_ITTI) + + if (configuration->frame_type == TDD) +#endif + { + //FIXME in NB-IoT mandatory to be FDD --> so must give an error + LOG_E(RRC,"[NB-IoT %d] Frame Type is TDD --> not supported by NB-IoT, exiting\n", Mod_id); //correct? + exit(-1); + } + + //FIXME which value chose for the following parameter + (*sib1_NB_IoT)->si_WindowLength_r13=SystemInformationBlockType1_NB__si_WindowLength_r13_ms160; + (*sib1_NB_IoT)->si_RadioFrameOffset_r13= 0; + + /*In Nb-IoT change/update of specific SI message can additionally be indicated by a SI message specific value tag + * systemInfoValueTagSI (there is no SystemInfoValueTag in SIB1-NB but only in MIB-NB) + *contained in systemInfoValueTagList_r13 + **/ + //FIXME correct? + (*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13)); + asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list); + ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI); + + +#ifdef XER_PRINT //generate xml files + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + + + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB1_NB_IoT, + 100); + + if (enc_rval.encoded > 0){ + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformationBlockType1-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*SIB23_NB_IoT*/ +//to be clarified is it is possible to carry SIB2 and SIB3 in the same SI message for NB-IoT? +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier,//MP: this is already a carrier[CC_id] + NbIoTRrcConfigurationReq *configuration ) //openair2/COMMON/rrc_messages_types.h +{ + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part; + struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part; + + BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + + asn_enc_rval_t enc_rval; + RACH_Info_NB_r13_t rach_Info_NB_IoT; + NPRACH_Parameters_NB_r13_t *nprach_parameters; + + //optional + long *connEstFailOffset = NULL; + connEstFailOffset = CALLOC(1, sizeof(long)); + +// RSRP_ThresholdsNPRACH_InfoList_NB_r13_t *rsrp_ThresholdsPrachInfoList; +// RSRP_Range_t rsrp_range; + + ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition; + struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config; + struct DL_GapConfig_NB_r13 *dl_Gap; + + long *srs_SubframeConfig; + srs_SubframeConfig= CALLOC(1, sizeof(long)); + + + if (bcch_message) { + memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + } else { + LOG_E(RRC,"[NB-IoT %d] BCCH_MESSAGE_NB is null, exiting\n", Mod_id); + exit(-1); + } + + //before schould be allocated memory somewhere? +// if (!carrier->sib2_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib2_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } +// +// if (!carrier->sib3_NB_IoT) { +// LOG_E(RRC,"[NB-IoT %d] sib3_NB_IoT is null, exiting\n", Mod_id); +// exit(-1); +// } + + + LOG_I(RRC,"[NB-IoT %d] Configuration SIB2/3\n", Mod_id); + + sib2_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + sib3_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib2_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib3_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + + sib2_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13; + sib3_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13; + + //may bug if not correct allocation of memory + carrier->sib2_NB_IoT = &sib2_NB_part->choice.sib2_r13; + carrier->sib3_NB_IoT = &sib3_NB_part->choice.sib3_r13; + sib2_NB_IoT = carrier->sib2_NB_IoT; + sib3_NB_IoT = carrier->sib3_NB_IoT; + + nprach_parameters = (NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(NPRACH_Parameters_NB_r13_t)); + + memset(&nprach_parameters[0],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[1],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[2],0,sizeof(NPRACH_Parameters_NB_r13_t)); + +/// SIB2-NB----------------------------------------- + + //Barring is manage by ab-Enabled in MIB-NB (but is not a struct as ac-BarringInfo in LTE legacy) + + //RACH Config. Common-------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.preambleTransMax_CE_r13 = + configuration->rach_preambleTransMax_CE_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.powerRampingStep = + configuration->rach_powerRampingStep_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.powerRampingParameters_r13.preambleInitialReceivedTargetPower = + configuration->rach_preambleInitialReceivedTargetPower_NB; + + rach_Info_NB_IoT.ra_ResponseWindowSize_r13 = configuration->rach_raResponseWindowSize_NB; + rach_Info_NB_IoT.mac_ContentionResolutionTimer_r13 = configuration-> rach_macContentionResolutionTimer_NB; + //rach_infoList max size = maxNPRACH-Resources-NB-r13 = 3 + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.rach_InfoList_r13.list,&rach_Info_NB_IoT); + + //TS 36.331 pag 614 --> if not present the value to infinity sould be used + *connEstFailOffset = 0; + + sib2_NB_IoT->radioResourceConfigCommon_r13.rach_ConfigCommon_r13.connEstFailOffset_r13 = connEstFailOffset; /*OPTIONAL*/ + + + // BCCH-Config-NB-IoT---------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.bcch_Config_r13.modificationPeriodCoeff_r13 + = configuration->bcch_modificationPeriodCoeff_NB; + + // PCCH-Config-NB-IoT----------------------------------------------------------------- + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.defaultPagingCycle_r13 + = configuration->pcch_defaultPagingCycle_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.nB_r13 = configuration->pcch_nB_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.pcch_Config_r13.npdcch_NumRepetitionPaging_r13 = configuration-> pcch_npdcch_NumRepetitionPaging_NB; + + //NPRACH-Config-NB-IoT----------------------------------------------------------------- + + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13 = NULL; + sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_CP_Length_r13 = configuration->nprach_CP_Length; + /*OPTIONAL*/ +// =CALLOC(1, sizeof(struct RSRP_ThresholdsNPRACH_InfoList_NB_r13)); //fatto uguale dopo +// rsrp_ThresholdsPrachInfoList = sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.rsrp_ThresholdsPrachInfoList_r13; +// rsrp_range = configuration->nprach_rsrp_range_NB; +// ASN_SEQUENCE_ADD(&rsrp_ThresholdsPrachInfoList->list,rsrp_range); + + // According configuration to set the 3 CE level configuration setting + + nprach_parameters[0].nprach_Periodicity_r13 = configuration->nprach_Periodicity[0]; + nprach_parameters[0].nprach_StartTime_r13 = configuration->nprach_StartTime[0]; + nprach_parameters[0].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[0]; + nprach_parameters[0].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[0]; + nprach_parameters[0].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[0]; + nprach_parameters[0].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[0].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[0].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[0]; + nprach_parameters[0].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[0]; + nprach_parameters[0].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[0]; + + nprach_parameters[1].nprach_Periodicity_r13 = configuration->nprach_Periodicity[1]; + nprach_parameters[1].nprach_StartTime_r13 = configuration->nprach_StartTime[1]; + nprach_parameters[1].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[1]; + nprach_parameters[1].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[1]; + nprach_parameters[1].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[1]; + nprach_parameters[1].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[1].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[1].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[1]; + nprach_parameters[1].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[1]; + nprach_parameters[1].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[1]; + + nprach_parameters[2].nprach_Periodicity_r13 = configuration->nprach_Periodicity[2]; + nprach_parameters[2].nprach_StartTime_r13 = configuration->nprach_StartTime[2]; + nprach_parameters[2].nprach_SubcarrierOffset_r13 = configuration->nprach_SubcarrierOffset[2]; + nprach_parameters[2].nprach_NumSubcarriers_r13 = configuration->nprach_NumSubcarriers[2]; + nprach_parameters[2].numRepetitionsPerPreambleAttempt_r13 = configuration->numRepetitionsPerPreambleAttempt_NB[2]; + nprach_parameters[2].nprach_SubcarrierMSG3_RangeStart_r13 = configuration->nprach_SubcarrierMSG3_RangeStart; + nprach_parameters[2].maxNumPreambleAttemptCE_r13 = configuration->maxNumPreambleAttemptCE_NB; + nprach_parameters[2].npdcch_NumRepetitions_RA_r13 = configuration->npdcch_NumRepetitions_RA[2]; + nprach_parameters[2].npdcch_StartSF_CSS_RA_r13 = configuration->npdcch_StartSF_CSS_RA[2]; + nprach_parameters[2].npdcch_Offset_RA_r13 = configuration->npdcch_Offset_RA[2]; + + + //nprach_parameterList have a max size of 3 possible nprach configuration (see maxNPRACH_Resources_NB_r13) + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[0]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[1]); + ASN_SEQUENCE_ADD(&sib2_NB_IoT->radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list,&nprach_parameters[2]); + + // NPDSCH-Config NB-IOT + sib2_NB_IoT->radioResourceConfigCommon_r13.npdsch_ConfigCommon_r13.nrs_Power_r13= configuration->npdsch_nrs_Power; + + + //NPUSCH-Config NB-IoT---------------------------------------------------------------- + //list of size 3 (see maxNPRACH_Resources_NB_r13) + ack_nack_repetition = configuration-> npusch_ack_nack_numRepetitions_NB; //is an enumerative + ASN_SEQUENCE_ADD(&(sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ack_NACK_NumRepetitions_Msg4_r13.list) ,&ack_nack_repetition); + + *srs_SubframeConfig = configuration->npusch_srs_SubframeConfig_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.srs_SubframeConfig_r13= srs_SubframeConfig; /*OPTIONAL*/ + + + /*OPTIONAL*/ + dmrs_config = CALLOC(1,sizeof(struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13)); + dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13; + dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13; + + /*OPTIONAL + * -define the base sequence for a DMRS sequence in a cell with multi tone transmission (3,6,12) see TS 36.331 NPUSCH-Config-NB + * -if not defined will be calculated based on the cellID once we configure the phy layer (rrc_mac_config_req) through the config_sib2 */ + dmrs_config->threeTone_BaseSequence_r13 = NULL; + dmrs_config->sixTone_BaseSequence_r13 = NULL; + dmrs_config->twelveTone_BaseSequence_r13 = NULL; + + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.dmrs_Config_r13 = dmrs_config; + + //ulReferenceSignalsNPUSCH + /*Reference Signal (RS) for UL in NB-IoT is called DRS (Demodulation Reference Signal) + * sequence-group hopping can be enabled or disabled by means of the cell-specific parameter groupHoppingEnabled_r13 + * sequence-group hopping can be disabled for certain specific UE through the parameter groupHoppingDisabled (physicalConfigDedicated) + * groupAssignmentNPUSCH--> is used for generate the sequence-shift pattern + */ + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupHoppingEnabled_r13= configuration->npusch_groupHoppingEnabled; + sib2_NB_IoT->radioResourceConfigCommon_r13.npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13 =configuration->npusch_groupAssignmentNPUSCH_r13; + + + //dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/ + dl_Gap = CALLOC(1,sizeof(struct DL_GapConfig_NB_r13)); + dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB; + dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB; + dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB; + sib2_NB_IoT->radioResourceConfigCommon_r13.dl_Gap_r13 = dl_Gap; + + + // uplinkPowerControlCommon - NB-IoT------------------------------------------------------ + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.p0_NominalNPUSCH_r13 = configuration->npusch_p0_NominalNPUSCH; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.deltaPreambleMsg3_r13 = configuration->deltaPreambleMsg3; + sib2_NB_IoT->radioResourceConfigCommon_r13.uplinkPowerControlCommon_r13.alpha_r13 = configuration->npusch_alpha; + //no deltaFlist_PUCCH and no UL cyclic prefix + + // UE Timers and Constants -NB-IoT-------------------------------------------------------- + sib2_NB_IoT->ue_TimersAndConstants_r13.t300_r13 = configuration-> ue_TimersAndConstants_t300_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t301_r13 = configuration-> ue_TimersAndConstants_t301_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t310_r13 = configuration-> ue_TimersAndConstants_t310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.t311_r13 = configuration-> ue_TimersAndConstants_t311_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n310_r13 = configuration-> ue_TimersAndConstants_n310_NB; + sib2_NB_IoT->ue_TimersAndConstants_r13.n311_r13 = configuration-> ue_TimersAndConstants_n311_NB; + + //other SIB2-NB Parameters-------------------------------------------------------------------------------- + sib2_NB_IoT->freqInfo_r13.additionalSpectrumEmission_r13 = 1; + sib2_NB_IoT->freqInfo_r13.ul_CarrierFreq_r13 = NULL; /*OPTIONAL*/ + + sib2_NB_IoT->timeAlignmentTimerCommon_r13=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; + + /*OPTIONAL*/ + sib2_NB_IoT->multiBandInfoList_r13 = NULL; + +/// SIB3-NB------------------------------------------------------- + + sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4; + sib3_NB_IoT->cellReselectionServingFreqInfo_r13.s_NonIntraSearch_r13=0; //or define in configuration? + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_RxLevMin_r13 = -70; + //new + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13 = CALLOC(1,sizeof(*sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)); + *(sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_QualMin_r13)= 10; //a caso + + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.p_Max_r13 = NULL; + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.s_IntraSearchP_r13 = 31; // s_intraSearch --> s_intraSearchP!!! (they call in a different way) + sib3_NB_IoT->intraFreqCellReselectionInfo_r13.t_Reselection_r13=1; + + //how to manage? + sib3_NB_IoT->freqBandInfo_r13 = NULL; + sib3_NB_IoT->multiBandInfoList_r13 = NULL; + + +///BCCH message (generate the SI message) + bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13; + + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = SystemInformation_NB__criticalExtensions_PR_systemInformation_r13; + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list.count=0; + + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib2_NB_part); + ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, + sib3_NB_part); + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + (void*)bcch_message, + carrier->SIB23_NB_IoT, + 900); +// AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", +// enc_rval.failed_type->name, enc_rval.encoded); + +//#if defined(ENABLE_ITTI)..... + + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT] SystemInformation-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + msg("[RRC] ASN1 : SI-NB encoding failed for SIB23_NB_IoT\n"); + return(-1); + } + + carrier->sib2_NB_IoT = sib2_NB_IoT; + carrier->sib3_NB_IoT = sib3_NB_IoT; + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionSetup_NB_IoT--> the aim is to establish SRB1 and SRB1bis(implicitly)*/ +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, // maybe not used + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1 + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT +) + +{ + + asn_enc_rval_t enc_rval; + + + //MP:logical channel group not defined for Nb-IoT + + //MP: logical channel priority pag 605 (is 1 for SRB1 and for SRB1bis should be the same) + //long* prioritySRB1 = NULL; + long* prioritySRB1bis = NULL; + BOOLEAN_t* logicalChannelSR_Prohibit =NULL; //pag 605 + BOOLEAN_t* npusch_AllSymbols= NULL; + +// struct SRB_ToAddMod_NB_r13* SRB1_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB = NULL; +// struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB = NULL; + + struct SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL; + struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL; + + //No UL_specific parameters for NB-IoT in LogicalChanelConfig-NB + + PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13; + rrcConnectionSetup_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionSetup_r13; + + + if (*SRB_configList_NB_IoT) { + free(*SRB_configList_NB_IoT); + } + *SRB_configList_NB_IoT = CALLOC(1,sizeof(SRB_ToAddModList_NB_r13_t)); + +/// SRB1-------------------- + { +// SRB1_config_NB = CALLOC(1,sizeof(*SRB1_config_NB)); +// +// //no srb_Identity in SRB_ToAddMod_NB +// +// SRB1_rlc_config_NB = CALLOC(1,sizeof(*SRB1_rlc_config_NB)); +// SRB1_config_NB->rlc_Config_r13 = SRB1_rlc_config_NB; +// +// SRB1_rlc_config_NB->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; +// SRB1_rlc_config_NB->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//the only possible in NB_IoT +// +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_timer_poll_retransmit_r13; +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = enb_properties.properties[ctxt_pP->module_id]->srb1_max_retx_threshold_r13; +//// //(musT be disabled--> SRB1 config pag 640 specs ) +//// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; +// +// +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; +// //(musT be disabled--> SRB1 config pag 640 specs ) +// SRB1_rlc_config_NB->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 = NULL; +// +// SRB1_lchan_config_NB = CALLOC(1,sizeof(*SRB1_lchan_config_NB)); +// SRB1_config_NB->logicalChannelConfig_r13 = SRB1_lchan_config_NB; +// +// SRB1_lchan_config_NB->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; +// +// +// prioritySRB1 = CALLOC(1, sizeof(long)); +// *prioritySRB1 = 1; +// SRB1_lchan_config_NB->choice.explicitValue.priority_r13 = prioritySRB1; +// +// logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); +// *logicalChannelSR_Prohibit = 1; +// //schould be set to TRUE (specs pag 641) +// SRB1_lchan_config_NB->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; +// +// //ADD SRB1 +// ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1_config_NB); + } + +///SRB1bis (The configuration for SRB1 and SRB1bis is the same) the only difference is the logical channel identity = 3 but not set here + + SRB1bis_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_config_NB_IoT)); + + //no srb_Identity in SRB_ToAddMod_NB + SRB1bis_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_rlc_config_NB_IoT)); + SRB1bis_config_NB_IoT->rlc_Config_r13 = SRB1bis_rlc_config_NB_IoT; + + SRB1bis_rlc_config_NB_IoT->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT + + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; + //(musT be disabled--> SRB1 config pag 640 specs ) + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; + + SRB1bis_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_lchan_config_NB_IoT)); + SRB1bis_config_NB_IoT->logicalChannelConfig_r13 = SRB1bis_lchan_config_NB_IoT; + + SRB1bis_lchan_config_NB_IoT->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; + + prioritySRB1bis = CALLOC(1, sizeof(long)); + *prioritySRB1bis = 1; //same as SRB1? + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.priority_r13 = prioritySRB1bis; + + logicalChannelSR_Prohibit = CALLOC(1, sizeof(BOOLEAN_t)); + *logicalChannelSR_Prohibit = 1; //schould be set to TRUE (specs pag 641) + SRB1bis_lchan_config_NB_IoT->choice.explicitValue.logicalChannelSR_Prohibit_r13 = logicalChannelSR_Prohibit; + + //ADD SRB1bis + //MP: Actually there is no way to distinguish SRB1 and SRB1bis once put in the list + //MP: SRB_ToAddModList_NB_r13_t size = 1 + ASN_SEQUENCE_ADD(&(*SRB_configList_NB_IoT)->list,SRB1bis_config_NB_IoT); + + + // PhysicalConfigDedicated (NPDCCH, NPUSCH, CarrierConfig, UplinkPowerControl) + + physicalConfigDedicated2_NB_IoT = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT)); + *physicalConfigDedicated_NB_IoT = physicalConfigDedicated2_NB_IoT; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13= CALLOC(1, sizeof(*physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13)); + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13 = CALLOC(1,sizeof(*physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13)); + + //no tpc, no cqi and no pucch, no pdsch, no soundingRS, no AntennaInfo, no scheduling request config + + /* + * NB-IoT supports the operation with either one or two antenna ports, AP0 and AP1. + * For the latter case, Space Frequency Block Coding (SFBC) is applied. + * Once selected, the same transmission scheme applies to NPBCH, NPDCCH, and NPDSCH. + * */ + + //FIXME: MP: CarrierConfigDedicated check the set values ---------------------------------------------- + + //DL + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_CarrierFreq_r13.carrierFreq_r13=0;//random value set + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13->present= + DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13->present = + DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13; + + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.inbandCarrierInfo_r13= NULL; + + //UL + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->ul_CarrierConfig_r13.ul_CarrierFreq_r13= NULL; + + // NPDCCH + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_NumRepetitions_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_Offset_USS_r13 =0; + physicalConfigDedicated2_NB_IoT->npdcch_ConfigDedicated_r13->npdcch_StartSF_USS_r13=0; + + // NPUSCH //(specs TS 36.331 v14.2.1 pag 643) /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->ack_NACK_NumRepetitions_r13= NULL; + npusch_AllSymbols= CALLOC(1, sizeof(BOOLEAN_t)); + *npusch_AllSymbols= 1; //TRUE + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->npusch_AllSymbols_r13= npusch_AllSymbols; /* OPTIONAL */ + physicalConfigDedicated2_NB_IoT->npusch_ConfigDedicated_r13->groupHoppingDisabled_r13=NULL; /* OPTIONAL */ + + // UplinkPowerControlDedicated + physicalConfigDedicated2_NB_IoT->uplinkPowerControlDedicated_r13->p0_UE_NPUSCH_r13 = 0; // 0 dB (specs TS36.331 v14.2.1 pag 643) + + + //Fill the rrcConnectionSetup-NB message + rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value + rrcConnectionSetup_NB_IoT->criticalExtensions.present = RRCConnectionSetup_NB__criticalExtensions_PR_c1; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ; + //MP: carry only SRB1bis at the moment and phyConfigDedicated + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = *SRB_configList_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13 = NULL; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = physicalConfigDedicated2_NB_IoT; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = NULL; + +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionSetup-NB Encoded %zd bits (%zd bytes), ecause %d\n", + enc_rval.encoded,(enc_rval.encoded+7)/8,ecause); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_SecurityModeCommand - exactly the same as previous implementation*/ +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm) +{ + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.rrc_TransactionIdentifier = Transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present = + SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; + + // the two following information could be based on the mod_id + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm + = (CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm + = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] securityModeCommand-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : securityModeCommand-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_UECapabilityEnquiry_NB_IoT - very similar to legacy lte*/ +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +) + +{ + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + //no RAT type in NB-IoT + asn_enc_rval_t enc_rval; + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.rrc_TransactionIdentifier = Transaction_id; + + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = UECapabilityEnquiry_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present = + UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13; + + //no ue_CapabilityRequest (list of RAT_Type) + +//only changed "asn_DEF_DL_DCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT).... + +#ifdef USER_MODE + LOG_D(RRC,"[NB-IoT %d] UECapabilityEnquiry-NB for UE %x Encoded %zd bits (%zd bytes)\n", + ctxt_pP->module_id, + ctxt_pP->rnti, + enc_rval.encoded, + (enc_rval.encoded+7)/8); +#endif + + if (enc_rval.encoded==-1) { + LOG_E(RRC,"[NB-IoT %d] ASN1 : UECapabilityEnquiry-NB encoding failed for UE %x\n", + ctxt_pP->module_id, + ctxt_pP->rnti); + return(-1); + } + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReconfiguration_NB_IoT-->may convey information for resource configuration + * (including RBs, MAC main configuration and physical channel configuration) + * including any associated dedicated NAS information.*/ +uint16_t do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT, + MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT) + +{ + + //check on DRB_list if contains more than 2 DRB? + + asn_enc_rval_t enc_rval; + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13; + rrcConnectionReconfiguration_NB = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReconfiguration_r13; + + // RRCConnectionReconfiguration + rrcConnectionReconfiguration_NB->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReconfiguration_NB->criticalExtensions.present = RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ; + + //RAdioResourceconfigDedicated + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13 = + CALLOC(1,sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->srb_ToAddModList_r13 = SRB1_list_NB; //only SRB1 + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToAddModList_r13 = DRB_list_NB_IoT; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->drb_ToReleaseList_r13 = DRB_list2_NB_IoT; //NULL + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->physicalConfigDedicated_r13 = physicalConfigDedicated_NB_IoT; + //FIXME may not used now + //rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->rlf_TimersAndConstants_r13 + + if (mac_MainConfig_NB_IoT!=NULL) { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13 = + CALLOC(1, sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13)); + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->present + =RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13; + //why memcopy only this one? + memcpy(&rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->choice.explicitValue_r13, + mac_MainConfig_NB_IoT, sizeof(*mac_MainConfig_NB_IoT)); + + } else { + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13=NULL; + } + + //no measConfig, measIDlist + //no mobilityControlInfo + + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.dedicatedInfoNASList_r13 = dedicatedInfoNASList_NB_IoT; + //mainly used for cell-reselection/handover purposes?? + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.fullConfig_r13 = NULL; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed %s, %li\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //changed only asn_DEF_DL_DCCH_Message_NB +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); +#endif + +//#if defined(ENABLE_ITTI) +//# if !defined(DISABLE_XER_SPRINT)... + + + LOG_I(RRC,"RRCConnectionReconfiguration-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReestablishmentReject - exactly the same as legacy LTE*/ +uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13; + rrcConnectionReestablishmentReject = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishmentReject_r13; + + // RRCConnectionReestablishmentReject //exactly the same as LTE + rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC,"ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + + //Only change in "asn_DEF_DL_CCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + +/*do_RRCConnectionReject_NB_IoT*/ +uint8_t do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer) + +{ + + asn_enc_rval_t enc_rval; + + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT; + + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13; + rrcConnectionReject_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReject_r13; + + // RRCConnectionReject-NB_IoT + rrcConnectionReject_NB_IoT->criticalExtensions.present = RRCConnectionReject_NB__criticalExtensions_PR_c1; + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13; + /* let's put an extended wait time of 1s for the moment */ + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.extendedWaitTime_r13 = 1; + //new-use of suspend indication + //If present, this field indicates that the UE should remain suspended and not release its stored context. + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13= + CALLOC(1, sizeof(long)); + *(rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13)= + RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; + + //Only Modified "asn_DEF_DL_CCCH_Message_NB" +#ifdef XER_PRINT + xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg); +#endif + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + 100); + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %ld)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[20000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + +#ifdef USER_MODE + LOG_D(RRC,"RRCConnectionReject-NB Encoded %zd bits (%zd bytes)\n", + enc_rval.encoded,(enc_rval.encoded+7)/8); +#endif + + return((enc_rval.encoded+7)/8); +} + + +//no do_MBSFNAreaConfig(..) in NB-IoT +//no do_MeasurementReport(..) in NB-IoT + +/*do_DLInformationTransfer_NB*/ +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer) + +{ + ssize_t encoded; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + + memset(&dl_dcch_msg_NB_IoT, 0, sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.rrc_TransactionIdentifier = transaction_id; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = DLInformationTransfer_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.size = pdu_length; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.buf = pdu_buffer; + + encoded = uper_encode_to_new_buffer (&asn_DEF_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer); + + //only change in "asn_DEF_DL_DCCH_Message_NB" +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[10000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + return encoded; +} + +/*do_ULInformationTransfer*/ +//for the moment is not needed (UE-SIDE) + +/*OAI_UECapability_t *fill_ue_capability*/ + +/*do_RRCConnectionReestablishment_NB-->used to re-establish SRB1*/ //which parameter to use? +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured? +{ + + asn_enc_rval_t enc_rval; + DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT; + + memset(&dl_ccch_msg_NB_IoT, 0, sizeof(DL_CCCH_Message_NB_t)); + + dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13; + rrcConnectionReestablishment_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishment_r13; + + //rrcConnectionReestablishment_NB + rrcConnectionReestablishment_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = RRCConnectionReestablishment_NB__criticalExtensions_PR_c1; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = SRB_list_NB_IoT; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToReleaseList_r13 = NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.rlf_TimersAndConstants_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13= NULL; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.physicalConfigDedicated_r13 = NULL; + + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.nextHopChainingCount_r13=0; + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + (void*)&dl_ccch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE); + + if (enc_rval.encoded <= 0) { + LOG_F(RRC, "ASN1 message encoding failed (%s, %li)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + } + +#ifdef XER_PRINT + xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); +#endif + +#if defined(ENABLE_ITTI) +# if !defined(DISABLE_XER_SPRINT) + { + char message_string[30000]; + size_t message_string_size; + + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + MessageDef *msg_p; + + msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); + + itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); + } + } +# endif +#endif + + LOG_I(RRC,"RRCConnectionReestablishment-NB Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + return 0; +} + +/*do_RRCConnectionRelease_NB--> is used to command the release of an RRC connection*/ +uint8_t do_RRCConnectionRelease_NB_IoT( + uint8_t Mod_id, + uint8_t *buffer, + const uint8_t Transaction_id) +{ + + asn_enc_rval_t enc_rval; + + DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT; + + + memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + + dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13; + rrcConnectionRelease_NB_IoT = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionRelease_r13; + + // RRCConnectionRelease + rrcConnectionRelease_NB_IoT->rrc_TransactionIdentifier = Transaction_id; + rrcConnectionRelease_NB_IoT->criticalExtensions.present = RRCConnectionRelease_NB__criticalExtensions_PR_c1; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ; + + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = ReleaseCause_NB_r13_other; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.redirectedCarrierInfo_r13 = NULL; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.extendedWaitTime_r13 = NULL; + + //Why allocate memory for non critical extension? + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension=CALLOC(1, + sizeof(*rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension)); + + enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + (void*)&dl_dcch_msg_NB_IoT, + buffer, + RRC_BUF_SIZE);//check + + return((enc_rval.encoded+7)/8); +} + + + + diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..6fb073f80de30638aad1208c52a0af79edc42250 --- /dev/null +++ b/openair2/RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h @@ -0,0 +1,293 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file asn1_msg.h +* \brief primitives to build the asn1 messages +* \author Raymond Knopp, Navid Nikaein and Michele Paffetti +* \date 2011, 2017 +* \version 1.0 +* \company Eurecom +* \email: raymond.knopp@eurecom.fr ,navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifdef USER_MODE +#include <stdio.h> +#include <sys/types.h> +#include <stdlib.h> /* for atoi(3) */ +#include <unistd.h> /* for getopt(3) */ +#include <string.h> /* for strerror(3) */ +#include <sysexits.h> /* for EX_* exit codes */ +#include <errno.h> /* for errno */ +#else +#include <linux/module.h> /* Needed by all modules */ +#endif + +#include <asn_application.h> +#include <asn_internal.h> /* for _ASN_DEFAULT_STACK_MAX */ + + +#include "RRC/LITE/defs_NB_IoT.h" + +/* + * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) + * output into the chosen string buffer. + * RETURN VALUES: + * 0: The structure is printed. + * -1: Problem printing the structure. + * WARNING: No sensible error value is returned. + */ + + +/** +\brief Generate configuration for SIB1 (eNB). +@param carrier pointer to Carrier information +@param N_RB_DL Number of downlink PRBs +@param frame radio frame number +@return size of encoded bit stream in bytes*/ +uint8_t do_MIB_NB_IoT( + rrc_eNB_carrier_data_NB_IoT_t *carrier, + uint32_t N_RB_DL, + uint32_t frame, + uint32_t hyper_frame); + + +/** +\brief Generate a default configuration for SIB1-NB (eNB). +@param Mod_id Instance of eNB +@param CC_id Component carrier to configure +@param carrier pointer to Carrier information +@param configuration Pointer Configuration Request structure +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration, + uint32_t frame + ); + +/** +\brief Generate a default configuration for SIB2/SIB3-NB in one System Information PDU (eNB). +@param Mod_id Index of eNB (used to derive some parameters) +@param buffer Pointer to PER-encoded ASN.1 description of SI-NB PDU +@param systemInformation_NB_IoT Pointer to asn1c C representation of SI-NB PDU +@param sib2_NB Pointer (returned) to sib2_NB component withing SI-NB PDU +@param sib3_NB Pointer (returned) to sib3_NB component withing SI-NB PDU +@return size of encoded bit stream in bytes*/ + +uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, + int CC_id, + rrc_eNB_carrier_data_NB_IoT_t *carrier, + NbIoTRrcConfigurationReq *configuration + ); + +/**(UE-SIDE) +\brief Generate an RRCConnectionRequest-NB UL-CCCH-Message (UE) based on random string or S-TMSI. This +routine only generates an mo-data establishment cause. +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param rv 5 byte random string or S-TMSI +@param Mod_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRequest_NB_IoT(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); + + +/**(UE -SIDE) +\brief Generate an RRCConnectionSetupComplete-NB UL-DCCH-Message (UE) +@param Mod_id +@param Transaction_id +@param dedicatedInfoNASLength +@param dedicatedInfoNAS +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetupComplete_NB_IoT(uint8_t Mod_id, uint8_t* buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, + const char* dedicatedInfoNAS); + +/** (UE-SIDE) +\brief Generate an RRCConnectionReconfigurationComplete-NB UL-DCCH-Message (UE) +@param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU +@param ctxt_pP +@param Transaction_id +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* buffer, + const uint8_t Transaction_id +); + +/** +\brief Generate an RRCConnectionSetup-NB DL-CCCH-Message (eNB). This routine configures SRB_ToAddMod (SRB1/SRB1bis-NB) and +PhysicalConfigDedicated-NB IEs. +@param ctxt_pP Running context +@param ue_context_pP UE context +@param CC_id Component Carrier ID +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param transmission_mode Transmission mode for UE (1-9) +@param UE_id UE index for this message +@param Transaction_id Transaction_ID for this message +@param SRB_configList Pointer (returned) to SRB1_config/SRB1bis_config(later) IEs for this UE +@param physicalConfigDedicated_NB Pointer (returned) to PhysicalConfigDedicated-NB IE for this UE +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, //carrier[CC_id].Srb0.Tx_buffer.Payload + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed but not deleted + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //in order to be configured--> stanno puntando alla SRB_configlist dell ue_context + struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT //in order to be configured--> stanno puntando alla physicalConfigDedicated dell ue_context +); + + +/** + * For which SRB is used in NB-IoT?? +\brief Generate an RRCConnectionReconfiguration-NB DL-DCCH-Message (eNB). This routine configures SRBToAddMod-NB (SRB1) and one DRBToAddMod-NB +(DRB3). PhysicalConfigDedicated-NB is not updated. +@param ctxt_pP Running context +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@param Transaction_id Transaction_ID for this message +@param SRB_list_NB Pointer to SRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list_NB Pointer to DRB List to be added/modified (NULL if no additions/modifications) +@param DRB_list2_NB Pointer to DRB List to be released (NULL if none to be released) +//sps not supported by NB-IoT +@param physicalConfigDedicated_NB Pointer to PhysicalConfigDedicated-NB to be modified (NULL if no modifications) +//measurement not supported by NB-IoT +@param mac_MainConfig Pointer to Mac_MainConfig(NULL if no modifications) +//no CBA functionalities +@returns Size of encoded bit stream in bytes*/ + +uint16_t +do_RRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + SRB_ToAddModList_NB_r13_t *SRB_list_NB_IoT, + DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, + DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, + struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated, + MAC_MainConfig_t *mac_MainConfig, + struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + @param cipheringAlgorithm + @param integrityProtAlgorithm + */ + +uint8_t do_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id, + const uint8_t cipheringAlgorithm, + const uint8_t integrityProtAlgorithm); + +/** + * E-UTRAN applies the procedure as follows: when only for NB-IoT SRB1 and SRB1bis is established + \brief Generate a SecurityModeCommand + @param ctxt_pP Running context + @param buffer Pointer to PER-encoded ASN.1 description + @param Transaction_id Transaction_ID for this message + */ + +uint8_t do_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + uint8_t* const buffer, + const uint8_t Transaction_id +); + + +/** + * There is nothing new in this type of message for NB-IoT (only change in some nomenclature) +\brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ + +uint8_t +do_RRCConnectionReestablishmentReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionReject-NB DL-CCCH-Message (eNB). +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU +@returns Size of encoded bit stream in bytes*/ +uint8_t +do_RRCConnectionReject_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer); + + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); + + +uint8_t do_DLInformationTransfer_NB_IoT( + uint8_t Mod_id, + uint8_t **buffer, + uint8_t transaction_id, + uint32_t pdu_length, + uint8_t *pdu_buffer); + +//for now not implemented since UE side +//uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); + +//for now not implemented since UE side??? +//OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) + +/** +\brief Generate an RRCConnectionReestablishment-NB DL-CCCH Message + *@param + * + */ + +uint8_t do_RRCConnectionReestablishment_NB_IoT( + uint8_t Mod_id, + uint8_t* const buffer, + const uint8_t Transaction_id, + const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed + SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT + ); + +/** +\brief Generate an RRCConnectionRelease-NB DL-DCCH-Message (eNB) +@param Mod_id Module ID of eNB +@param buffer Pointer to PER-encoded ASN.1 description of DL-DCCH-Message PDU +@param transaction_id Transaction index +@returns Size of encoded bit stream in bytes*/ + +//uint8_t do_RRCConnectionRelease_NB_IoT(uint8_t Mod_id, uint8_t *buffer,int Transaction_id); diff --git a/openair2/RRC/LITE/defs_NB_IoT.h b/openair2/RRC/LITE/defs_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..376b66c79a1e5c61ccedad1aca00806137da49bc --- /dev/null +++ b/openair2/RRC/LITE/defs_NB_IoT.h @@ -0,0 +1,570 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file RRC/LITE/defs_NB_IoT.h +* \brief NB-IoT RRC struct definitions and function prototypes +* \author Navid Nikaein, Raymond Knopp and Michele Paffetti +* \date 2010 - 2014, 2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_DEFS_NB_IOT_H__ +#define __OPENAIR_RRC_DEFS_NB_IOT_H__ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "collection/tree.h" +#include "rrc_types_NB_IoT.h" +#include "COMMON/platform_constants.h" +#include "COMMON/platform_types.h" +#include "targets/COMMON/openairinterface5g_limits.h" + +#include "COMMON/mac_rrc_primitives.h" + +//-----NB-IoT #include files------- + +//#include "SystemInformationBlockType1-NB.h" +//#include "SystemInformation-NB.h" +#include "RRCConnectionReconfiguration-NB.h" +#include "RRCConnectionReconfigurationComplete-NB.h" +#include "RRCConnectionSetup-NB.h" +#include "RRCConnectionSetupComplete-NB.h" +#include "RRCConnectionRequest-NB.h" +#include "RRCConnectionReestablishmentRequest-NB.h" +#include "BCCH-DL-SCH-Message-NB.h" +#include "BCCH-BCH-Message-NB.h" +#include "AS-Config-NB.h" +#include "AS-Context-NB.h" +#include "UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h +//------------------- + +#if defined(ENABLE_ITTI) +# include "intertask_interface.h" +#endif + +/* TODO: be sure this include is correct. + * It solves a problem of compilation of the RRH GW, + * issue #186. + */ +#if !defined(ENABLE_ITTI) +# include "as_message.h" +#endif + +#if defined(ENABLE_USE_MME) +# include "commonDef.h" +#endif + +#if ENABLE_RAL +# include "collection/hashtable/obj_hashtable.h" +#endif + + + +/*I will change the name of the structure for compile purposes--> hope not to undo this process*/ + +typedef unsigned int uid_NB_IoT_t; +#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT (((NUMBER_OF_UE_MAX_NB_IoT/8)/sizeof(unsigned int)) + 1) + +typedef struct uid_linear_allocator_NB_IoT_s { + unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE_NB_IoT]; +} uid_allocator_NB_IoT_t; + + +#define PROTOCOL_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + +#define PROTOCOL_RRC_CTXT_FMT PROTOCOL_CTXT_FMT +#define PROTOCOL_RRC_CTXT_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) + + +//left as they are --> used in LAYER2/epenair2_proc.c and UE side +typedef enum UE_STATE_NB_IoT_e { + RRC_INACTIVE_NB_IoT=0, + RRC_IDLE_NB_IoT, + RRC_SI_RECEIVED_NB_IoT, + RRC_CONNECTED_NB_IoT, + RRC_RECONFIGURED_NB_IoT, + RRC_HO_EXECUTION_NB_IoT //maybe not needed? +} UE_STATE_NB_IoT_t; + + +/** @defgroup _rrc RRC + * @ingroup _oai2 + * @{ + */ +typedef struct UE_RRC_INFO_NB_IoT_s { + UE_STATE_NB_IoT_t State; + uint8_t SIB1systemInfoValueTag; + uint32_t SIStatus; + uint32_t SIcnt; +#if defined(Rel10) || defined(Rel14) + uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA +#endif + uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 + uint8_t handoverTarget; + //HO_STATE_t ho_state; + uint16_t SIperiod; //!< Corresponds to the SIB1 si-Periodicity parameter (multiplied by 10). Possible values are (final): 80,160,320,640,1280,2560,5120 + unsigned short UE_index; + uint32_t T300_active; + uint32_t T300_cnt; + uint32_t T304_active; + uint32_t T304_cnt; + uint32_t T310_active; + uint32_t T310_cnt; + uint32_t N310_cnt; + uint32_t N311_cnt; + rnti_t rnti; +} __attribute__ ((__packed__)) UE_RRC_INFO_NB_IoT; + +//#define NUM_PRECONFIGURED_LCHAN (NB_CH_CX*2) //BCCH, CCCH + +#define UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! +#define UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 + + + +// HO_STATE is not supported by NB-IoT + +//#define NUMBER_OF_UE_MAX MAX_MOBILES_PER_RG +#define RRM_FREE(p) if ( (p) != NULL) { free(p) ; p=NULL ; } +#define RRM_MALLOC(t,n) (t *) malloc16( sizeof(t) * n ) +#define RRM_CALLOC(t,n) (t *) malloc16( sizeof(t) * n) +#define RRM_CALLOC2(t,s) (t *) malloc16( s ) + +//Measurement Report not supported in NB-IoT + +#define PAYLOAD_SIZE_MAX 1024 +#define RRC_BUF_SIZE 255 +#define UNDEF_SECURITY_MODE 0xff +#define NO_SECURITY_MODE 0x20 + +/* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */ +#define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 + +typedef struct UE_S_TMSI_NB_IoT_s { + boolean_t presence; + mme_code_t mme_code; + m_tmsi_t m_tmsi; +} __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT; + + +typedef enum e_rab_satus_NB_IoT_e { + E_RAB_STATUS_NEW_NB_IoT, + E_RAB_STATUS_DONE_NB_IoT, // from the eNB perspective + E_RAB_STATUS_ESTABLISHED_NB_IoT, // get the reconfigurationcomplete form UE + E_RAB_STATUS_FAILED_NB_IoT, +} e_rab_status_NB_IoT_t; + +typedef struct e_rab_param_NB_IoT_s { + e_rab_t param; + uint8_t status; + uint8_t xid; // transaction_id +} __attribute__ ((__packed__)) e_rab_param_NB_IoT_t; + + +//HANDOVER_INFO not implemented in NB-IoT delete + + +#define RRC_HEADER_SIZE_MAX 64 +#define RRC_BUFFER_SIZE_MAX 1024 + +typedef struct { + char Payload[RRC_BUFFER_SIZE_MAX]; + char Header[RRC_HEADER_SIZE_MAX]; + char payload_size; +} RRC_BUFFER_NB_IoT; + +#define RRC_BUFFER_SIZE_NB_IoT sizeof(RRC_BUFFER_NB_IoT) + + +typedef struct RB_INFO_NB_IoT_s { + uint16_t Rb_id; //=Lchan_id + //LCHAN_DESC Lchan_desc[2]; no more used + //MAC_MEAS_REQ_ENTRY *Meas_entry; //may not needed for NB-IoT +} RB_INFO_NB_IoT; + +typedef struct SRB_INFO_NB_IoT_s { + uint16_t Srb_id; //=Lchan_id---> useful for distinguish between SRB1 and SRB1bis? + RRC_BUFFER_NB_IoT Rx_buffer; + RRC_BUFFER_NB_IoT Tx_buffer; + //LCHAN_DESC Lchan_desc[2]; no more used + unsigned int Trans_id; + uint8_t Active; +} SRB_INFO_NB_IoT; + + +typedef struct RB_INFO_TABLE_ENTRY_NB_IoT_s { + RB_INFO_NB_IoT Rb_info; + uint8_t Active; + uint32_t Next_check_frame; + uint8_t Status; +} RB_INFO_TABLE_ENTRY_NB_IoT; + +typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s { + SRB_INFO_NB_IoT Srb_info; + uint8_t Active; + uint8_t Status; + uint32_t Next_check_frame; +} SRB_INFO_TABLE_ENTRY_NB_IoT; + +//MEAS_REPORT_LIST_s not implemented in NB-IoT but is used at UE side +//HANDOVER_INFO_UE not implemented in NB-IoT +typedef struct HANDOVER_INFO_UE_NB_IoT_s { + PhysCellId_t targetCellId; + uint8_t measFlag; +} HANDOVER_INFO_UE_NB_IoT; + +//NB-IoT eNB_RRC_UE_NB_IoT_s--(used as a context in eNB --> ue_context in rrc_eNB_ue_context)------ +typedef struct eNB_RRC_UE_NB_IoT_s { + + EstablishmentCause_t establishment_cause; + uint8_t primaryCC_id; + //in NB-IoT only SRB0, SRB1 and SRB1bis (until AS security activation) exist + + /*MP: Concept behind List and List2 + * + * SRB_configList --> is used for the actual list of SRBs that is managed/that should be send over the RRC message + * SRB_configList2--> refers to all the SRBs configured for that specific transaction identifier + * this because in a single transaction one or more SRBs could be established + * and you want to keep memory on what happen for every transaction + * Transaction ID (xid): is used to associate the proper RRC....Complete message received by the UE to the corresponding + * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) + * this because it could happen that more messages are transmitted at the same time + */ + SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis + SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs + DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid + uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT + + struct PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; + MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; + + //No SPS(semi-persistent scheduling) in NB-IoT + //No Measurement report in NB-IoT + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1bis; + +#if defined(ENABLE_SECURITY) + /* KeNB as derived from KASME received from EPC */ + uint8_t kenb[32]; +#endif + + /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */ + e_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + + uint8_t Status; + rnti_t rnti; + uint64_t random_ue_identity; + + + + /* Information from UE RRC ConnectionRequest-NB-r13_IE--> NB-IoT */ + UE_S_TMSI_NB_IoT Initialue_identity_s_TMSI; + EstablishmentCause_NB_r13_t establishment_cause_NB_IoT; //different set for NB-IoT + + /* Information from UE RRC ConnectionReestablishmentRequest-NB--> NB-IoT */ + ReestablishmentCause_NB_r13_t reestablishment_cause_NB_IoT; //different set for NB_IoT + + /* UE id for initial connection to S1AP */ + uint16_t ue_initial_id; + + /* Information from S1AP initial_context_setup_req */ + uint32_t eNB_ue_s1ap_id :24; + + security_capabilities_t security_capabilities; + + /* Total number of e_rab already setup in the list */ //NAS list? + uint8_t setup_e_rabs; + /* Number of e_rab to be setup in the list */ //NAS list? + uint8_t nb_of_e_rabs; + /* list of e_rab to be setup by RRC layers */ + e_rab_param_NB_IoT_t e_rab[NB_RB_MAX_NB_IOT];//[S1AP_MAX_E_RAB]; + + // LG: For GTPV1 TUNNELS + uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; + rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + + //Which timers are referring to? + uint32_t ul_failure_timer; + uint32_t ue_release_timer; + //threshold of the release timer--> set in RRCConnectionRelease + uint32_t ue_release_timer_thres; +} eNB_RRC_UE_NB_IoT_t; +//-------------------------------------------------------------------------------- + +typedef uid_NB_IoT_t ue_uid_t; + + +//generally variable called: ue_context_pP +typedef struct rrc_eNB_ue_context_NB_IoT_s { + + /* Tree related data */ + RB_ENTRY(rrc_eNB_ue_context_NB_IoT_s) entries; + + /* Uniquely identifies the UE between MME and eNB within the eNB. + * This id is encoded on 24bits. + */ + rnti_t ue_id_rnti; + + // another key for protocol layers but should not be used as a key for RB tree + ue_uid_t local_uid; + + /* UE id for initial connection to S1AP */ + struct eNB_RRC_UE_NB_IoT_s ue_context; //context of ue in the e-nB + +} rrc_eNB_ue_context_NB_IoT_t; + + + +//---NB-IoT (completely changed)------------------------------- +//called "carrier"--> data from PHY layer +typedef struct { + + // buffer that contains the encoded messages + uint8_t *MIB_NB_IoT; + uint8_t sizeof_MIB_NB_IoT; + + uint8_t *SIB1_NB_IoT; + uint8_t sizeof_SIB1_NB_IoT; + uint8_t *SIB23_NB_IoT; + uint8_t sizeof_SIB23_NB_IoT; + + + //not actually implemented in OAI + uint8_t *SIB4_NB_IoT; + uint8_t sizeof_SIB4_NB_IoT; + uint8_t *SIB5_NB_IoT; + uint8_t sizeof_SIB5_NB_IoT; + uint8_t *SIB14_NB_IoT; + uint8_t sizeof_SIB14_NB_IoT; + uint8_t *SIB16_NB_IoT; + uint8_t sizeof_SIB16_NB_IoT; + + //TS 36.331 V14.2.1 +// uint8_t *SIB15_NB; +// uint8_t sizeof_SIB15_NB; +// uint8_t *SIB20_NB; +// uint8_t sizeof_SIB20_NB; +// uint8_t *SIB22_NB; +// uint8_t sizeof_SIB22_NB; + + //implicit parameters needed + int Ncp; //cyclic prefix for DL + int Ncp_UL; //cyclic prefix for UL + int p_eNB; //number of tx antenna port + int p_rx_eNB; //number of receiving antenna ports + uint32_t dl_CarrierFreq; //detected by the UE + uint32_t ul_CarrierFreq; //detected by the UE + uint16_t physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS + + //are the only static one (memory has been already allocated) + BCCH_BCH_Message_NB_t mib_NB_IoT; + BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB + BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI + + SystemInformationBlockType1_NB_t *sib1_NB_IoT; + SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + //not implemented yet + SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; + SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; + SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; + SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; + + + SRB_INFO_NB_IoT SI; + SRB_INFO_NB_IoT Srb0; + + uint8_t **MCCH_MESSAGE; // probably not needed , but added to remove errors + uint8_t sizeof_MCCH_MESSAGE[8];// but added to remove errors + SRB_INFO_NB_IoT MCCH_MESS[8];// MAX_MBSFN_AREA + /*future implementation TS 36.331 V14.2.1 + SystemInformationBlockType15_NB_r14_t *sib15; + SystemInformationBlockType20_NB_r14_t *sib20; + SystemInformationBlockType22_NB_r14_t *sib22; + + uint8_t SCPTM_flag; + uint8_t sizeof_SC_MCHH_MESS[]; + SC_MCCH_Message_NB_t scptm;*/ + + +} rrc_eNB_carrier_data_NB_IoT_t; +//--------------------------------------------------- + + + +//---NB-IoT---(completely change)--------------------- +typedef struct eNB_RRC_INST_NB_IoT_s { + + rrc_eNB_carrier_data_NB_IoT_t carrier[MAX_NUM_CCs]; + + uid_allocator_NB_IoT_t uid_allocator; // for rrc_ue_head + RB_HEAD(rrc_ue_tree_NB_IoT_s, rrc_eNB_ue_context_NB_IoT_s) rrc_ue_head; // ue_context tree key search by rnti + + uint8_t Nb_ue; + + hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t + hash_table_t *s1ap_id2_s1ap_ids ; // key is content is rrc_ue_s1ap_ids_t + + //RRC configuration + RrcConfigurationReq configuration; //rrc_messages_types.h + + // other PLMN parameters + /// Mobile country code + int mcc; + /// Mobile network code + int mnc; + /// number of mnc digits + int mnc_digit_length; + + // other RAN parameters //FIXME: to be checked--> depends on APP layer + int srb1_timer_poll_retransmit; + int srb1_max_retx_threshold; + int srb1_timer_reordering; + int srb1_timer_status_prohibit; + int srs_enable[MAX_NUM_CCs]; + + +} eNB_RRC_INST_NB_IoT; + +#define RRC_HEADER_SIZE_MAX_NB_IoT 64 +#define MAX_UE_CAPABILITY_SIZE_NB_IoT 255 + +//not needed for the moment +typedef struct OAI_UECapability_NB_IoT_s { + uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; + uint8_t sdu_size; +////NB-IoT------ + UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE +} OAI_UECapability_NB_IoT_t; + +#define RRC_BUFFER_SIZE_MAX_NB_IoT 1024 + + + +typedef struct UE_RRC_INST_NB_IoT_s { + Rrc_State_NB_IoT_t RrcState; + Rrc_Sub_State_NB_IoT_t RrcSubState; +# if defined(ENABLE_USE_MME) + plmn_t plmnID; + Byte_t rat; + as_nas_info_t initialNasMsg; +# endif + OAI_UECapability_NB_IoT_t *UECap; + uint8_t *UECapability; + uint8_t UECapability_size; + + UE_RRC_INFO_NB_IoT Info[NB_SIG_CNX_UE]; + + SRB_INFO_NB_IoT Srb0[NB_SIG_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb1[NB_CNX_UE]; + SRB_INFO_TABLE_ENTRY_NB_IoT Srb2[NB_CNX_UE]; + HANDOVER_INFO_UE_NB_IoT HandoverInfoUe; + /* + uint8_t *SIB1[NB_CNX_UE]; + uint8_t sizeof_SIB1[NB_CNX_UE]; + uint8_t *SI[NB_CNX_UE]; + uint8_t sizeof_SI[NB_CNX_UE]; + uint8_t SIB1Status[NB_CNX_UE]; + uint8_t SIStatus[NB_CNX_UE]; + SystemInformationBlockType1_t *sib1[NB_CNX_UE]; + SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). + */ + SystemInformationBlockType2_t *sib2[NB_CNX_UE]; + /* + SystemInformationBlockType3_t *sib3[NB_CNX_UE]; + SystemInformationBlockType4_t *sib4[NB_CNX_UE]; + SystemInformationBlockType5_t *sib5[NB_CNX_UE]; + SystemInformationBlockType6_t *sib6[NB_CNX_UE]; + SystemInformationBlockType7_t *sib7[NB_CNX_UE]; + SystemInformationBlockType8_t *sib8[NB_CNX_UE]; + SystemInformationBlockType9_t *sib9[NB_CNX_UE]; + SystemInformationBlockType10_t *sib10[NB_CNX_UE]; + SystemInformationBlockType11_t *sib11[NB_CNX_UE]; + +#if defined(Rel10) || defined(Rel14) + uint8_t MBMS_flag; + uint8_t *MCCH_MESSAGE[NB_CNX_UE]; + uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; + uint8_t MCCH_MESSAGEStatus[NB_CNX_UE]; + MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; + SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; + SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; +#endif +#ifdef CBA + uint8_t num_active_cba_groups; + uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; +#endif + uint8_t num_srb; + struct SRB_ToAddMod *SRB1_config[NB_CNX_UE]; + struct SRB_ToAddMod *SRB2_config[NB_CNX_UE]; + struct DRB_ToAddMod *DRB_config[NB_CNX_UE][8]; + rb_id_t *defaultDRB; // remember the ID of the default DRB + MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; + struct ReportConfigToAddMod *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; + */ + struct QuantityConfig *QuantityConfig[NB_CNX_UE]; + /* + struct MeasIdToAddMod *MeasId[NB_CNX_UE][MAX_MEAS_ID]; + MEAS_REPORT_LIST *measReportList[NB_CNX_UE][MAX_MEAS_ID]; + uint32_t measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells + RSRP_Range_t s_measure; + struct MeasConfig__speedStatePars *speedStatePars; + struct PhysicalConfigDedicated *physicalConfigDedicated[NB_CNX_UE]; + struct SPS_Config *sps_Config[NB_CNX_UE]; + MAC_MainConfig_t *mac_MainConfig[NB_CNX_UE]; + MeasGapConfig_t *measGapConfig[NB_CNX_UE]; + double filter_coeff_rsrp; // [7] ??? + double filter_coeff_rsrq; // [7] ??? + float rsrp_db[7]; + float rsrq_db[7]; + float rsrp_db_filtered[7]; + float rsrq_db_filtered[7]; +#if ENABLE_RAL + obj_hash_table_t *ral_meas_thresholds; + ral_transaction_id_t scan_transaction_id; +#endif +#if defined(ENABLE_SECURITY) + // KeNB as computed from parameters within USIM card // + uint8_t kenb[32]; +#endif + + // Used integrity/ciphering algorithms // + CipheringAlgorithm_r12_t ciphering_algorithm; + e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + */ +} UE_RRC_INST_NB_IoT; + + +#include "proto_NB_IoT.h" //should be put here otherwise compilation error + +#endif +/** @} */ diff --git a/openair2/RRC/LITE/extern_NB_IoT.h b/openair2/RRC/LITE/extern_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..f5e2f325756006d2841bb81f674d778ea68515f8 --- /dev/null +++ b/openair2/RRC/LITE/extern_NB_IoT.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file vars.h +* \brief rrc external vars +* \author Navid Nikaein and Raymond Knopp, Michele Paffetti +* \date 2011-2017 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it +*/ + +#ifndef __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#define __OPENAIR_RRC_EXTERN_NB_IOT_H__ +#include "RRC/LITE/defs_NB_IoT.h" +#include "PHY_INTERFACE/IF_Module_NB_IoT.h" +#include "LAYER2/RLC/rlc.h" +#include "LogicalChannelConfig-NB-r13.h" +#include "LAYER2/MAC/defs_NB_IoT.h" + +#include "common/ran_context.h" + + +//MP: NOTE:XXX some of the parameters defined in vars_nb_iot are called by the extern.h file so not replicated here + +extern UE_RRC_INST_NB_IoT *UE_rrc_inst_NB_IoT; + +extern eNB_RRC_INST_NB_IoT *eNB_rrc_inst_NB_IoT; +extern PHY_Config_NB_IoT_t *config_INFO; + +extern rlc_info_t Rlc_info_am_NB_IoT,Rlc_info_am_config_NB_IoT; +extern uint8_t DRB2LCHAN_NB_IoT[2]; +extern LogicalChannelConfig_NB_r13_t SRB1bis_logicalChannelConfig_defaultValue_NB_IoT; +extern LogicalChannelConfig_NB_r13_t SRB1_logicalChannelConfig_defaultValue_NB_IoT; + +extern uint16_t T300_NB_IoT[8]; +extern uint16_t T301_NB_IoT[8]; +extern uint16_t T310_NB_IoT[8]; +extern uint16_t T311_NB_IoT[8]; +extern uint16_t N310_NB_IoT[8]; +extern uint16_t N311_NB_IoT[8]; +extern uint8_t *get_NB_IoT_MIB(struct eNB_RRC_INST_NB_IoT_s *nb_iot_rrc); +#endif + + diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h index 9ece5bcfdd7b2a2415cab98c544b13f3da0addab..b92058741940a5aa8ee91b18b664f2cbd5bb0d46 100644 --- a/openair2/RRC/LITE/proto.h +++ b/openair2/RRC/LITE/proto.h @@ -409,6 +409,19 @@ rrc_data_req( const pdcp_transmission_mode_t modeP ); +uint8_t + +rrc_data_req_ue( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP +); + + void rrc_data_ind( const protocol_ctxt_t* const ctxt_pP, diff --git a/openair2/RRC/LITE/proto_NB_IoT.h b/openair2/RRC/LITE/proto_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..b2218517fc8761da2f7311554e25821f02f9f06a --- /dev/null +++ b/openair2/RRC/LITE/proto_NB_IoT.h @@ -0,0 +1,260 @@ +/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file proto_NB_IoT.h + * \brief RRC functions prototypes for eNB and UE for NB-IoT + * \author Navid Nikaein, Raymond Knopp and Michele Paffetti + * \date 2010 - 2014 + * \email navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it + * \version 1.0 + + */ +/** \addtogroup _rrc + * @{ + */ + +#include "RRC/LITE/defs_NB_IoT.h" +#include "pdcp.h" +#include "rlc.h" +#include "extern_NB_IoT.h" +#include "LAYER2/MAC/defs_NB_IoT.h" +/*NOTE: no static function should be declared in this header file (e.g. init_SI_NB)*/ + +/*------------------------common_nb_iot.c----------------------------------------*/ + +/** \brief configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs + */ +void openair_rrc_on_NB_IoT(const protocol_ctxt_t* const ctxt_pP); + +void rrc_config_buffer_NB_IoT(SRB_INFO_NB_IoT *srb_info, uint8_t Lchan_type, uint8_t Role); + +int L3_xface_init_NB_IoT(void); + +void openair_rrc_top_init_eNB_NB_IoT(void); + +//void rrc_top_cleanup(void); -->seems not to be used + +//rrc_t310_expiration-->seems not to be used + +/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310. +@param ctxt_pP running context +@param enb_index +@param CC_id +*/ +RRC_status_t rrc_rx_tx_NB_IoT(protocol_ctxt_t* const ctxt_pP, const uint8_t enb_index, const int CC_id); + +//long binary_search_int(int elements[], long numElem, int value);--> seems not to be used +//long binary_search_float(float elements[], long numElem, float value);--> used only at UE side + + + +//--------------------------------------- + + +//defined in L2_interface +//called by rx_sdu only in case of CCCH message (e.g RRCConnectionRequest-NB) +int8_t mac_rrc_data_ind_eNB_NB_IoT( + const module_id_t module_idP, + const int CC_id, + const frame_t frameP, + const sub_frame_t sub_frameP, + const rnti_t rntiP, + const rb_id_t srb_idP,//could be skipped since always go through the CCCH channel + const uint8_t* sduP, + const sdu_size_t sdu_lenP +); +//------------------------------------------- + +//defined in L2_interface +void dump_ue_list_NB_IoT(UE_list_NB_IoT_t *listP, int ul_flag); +//------------------------------------------- + + +//defined in L2_interface +void mac_eNB_rrc_ul_failure_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ + +//defined in eNB_scheduler_primitives.c +int rrc_mac_remove_ue_NB_IoT( + module_id_t mod_idP, + rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +void mac_eNB_rrc_ul_in_sync_NB_IoT( + const module_id_t mod_idP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP); +//------------------------------------------ +//defined in L2_interface +int mac_eNB_get_rrc_status_NB_IoT( + const module_id_t Mod_idP, + const rnti_t rntiP +); +//--------------------------- + + +/*-----------eNB procedures (rrc_eNB_nb_iot.c)---------------*/ + +//---Initialization-------------- +void openair_eNB_rrc_on_NB_IoT( + const protocol_ctxt_t* const ctxt_pP +); + +void rrc_config_buffer_NB_IoT( + SRB_INFO_NB_IoT* Srb_info, + uint8_t Lchan_type, + uint8_t Role +); + +char openair_rrc_eNB_configuration_NB_IoT( + const module_id_t enb_mod_idP, + NbIoTRrcConfigurationReq* configuration +); + +//----------------------------- +/**\brief RRC eNB task. (starting of the RRC state machine) + \param void *args_p Pointer on arguments to start the task. */ +void *rrc_enb_task_NB_IoT(void *args_p); + +/**\brief Entry routine to decode a UL-CCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Running context + \param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/ +int rrc_eNB_decode_ccch_NB_IoT( + protocol_ctxt_t* const ctxt_pP, + const SRB_INFO_NB_IoT* const Srb_info, + const int CC_id +); + +/**\brief Entry routine to decode a UL-DCCH-Message-NB. Invokes PER decoder and parses message. + \param ctxt_pP Context + \param Rx_sdu Pointer Received Message + \param sdu_size Size of incoming SDU*/ +int rrc_eNB_decode_dcch_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + const rb_id_t Srb_id, + const uint8_t* const Rx_sdu, + const sdu_size_t sdu_sizeP +); + +/**\brief Generate RRCConnectionReestablishmentReject-NB + \param ctxt_pP Running context + \param ue_context_pP UE context + \param CC_id Component Carrier ID*/ +void rrc_eNB_generate_RRCConnectionReestablishmentReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionReject_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_generate_RRCConnectionSetup_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP, + const int CC_id +); + +void rrc_eNB_process_RRCConnectionReconfigurationComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + const uint8_t xid //transaction identifier +); + + +void //was under ITTI +rrc_eNB_reconfigure_DRBs_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP); + +void //was under ITTI +rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +// const uint8_t ho_state + ); + +void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, + RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB +); + +void rrc_eNB_generate_SecurityModeCommand_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_UECapabilityEnquiry_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP +); + +void rrc_eNB_generate_defaultRRCConnectionReconfiguration_NB_IoT(const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP + //no HO flag + ); + + +/// Utilities------------------------------------------------ + +void rrc_eNB_free_UE_NB_IoT( + const module_id_t enb_mod_idP, + const struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP + ); + +void rrc_eNB_free_mem_UE_context_NB_IoT( + const protocol_ctxt_t* const ctxt_pP, + struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP +); + + + +/**\brief Function to get the next transaction identifier. + \param module_idP Instance ID for CH/eNB + \return a transaction identifier*/ +uint8_t rrc_eNB_get_next_transaction_identifier_NB_IoT(module_id_t module_idP); + + +int rrc_init_global_param_NB_IoT(void); + +//L2_interface.c +int8_t mac_rrc_data_req_eNB_NB_IoT( + const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const frame_t h_frameP, + const sub_frame_t subframeP, //need for the case in which both SIB1-NB_IoT and SIB23-NB_IoT will be scheduled in the same frame + const rb_id_t Srb_id, + uint8_t* const buffer_pP, + uint8_t flag +); + + + diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c index 8d1f47daf5b61fc9ebd9792864b5ce9a897fac02..3edf230ac2817ca736956c7affd80342980629f4 100644 --- a/openair2/RRC/LITE/rrc_UE.c +++ b/openair2/RRC/LITE/rrc_UE.c @@ -241,7 +241,7 @@ openair_rrc_on_ue( //----------------------------------------------------------------------------- { unsigned short i; - int CC_id; + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" UE?:OPENAIR RRC IN....\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); @@ -4842,10 +4842,6 @@ rrc_rx_tx_ue( ) //----------------------------------------------------------------------------- { - //uint8_t UE_id; - int32_t current_timestamp_ms, ref_timestamp_ms; - struct timeval ts; - struct rrc_eNB_ue_context_s *ue_context_p = NULL,*ue_to_be_removed = NULL; #ifdef LOCALIZATION double estimated_distance; diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c index 2a8967a531573b187e677c400c8ac6621b9e49d8..9faa686ef6532afafa413a9c5f4ae633940dcff7 100644 --- a/openair2/RRC/LITE/rrc_eNB.c +++ b/openair2/RRC/LITE/rrc_eNB.c @@ -118,7 +118,6 @@ openair_rrc_on( ) //----------------------------------------------------------------------------- { - unsigned short i; int CC_id; LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", @@ -1232,7 +1231,7 @@ rrc_eNB_generate_RRCConnectionReestablishment( void rrc_eNB_process_RRCConnectionReestablishmentComplete( const protocol_ctxt_t* const ctxt_pP, - const rnti_t const reestablish_rnti, + const rnti_t reestablish_rnti, rrc_eNB_ue_context_t* ue_context_pP, const uint8_t xid, RRCConnectionReestablishmentComplete_r8_IEs_t * rrcConnectionReestablishmentComplete diff --git a/openair2/RRC/LITE/rrc_types_NB_IoT.h b/openair2/RRC/LITE/rrc_types_NB_IoT.h new file mode 100644 index 0000000000000000000000000000000000000000..0266572cd01dd91fc327eadcd579c7b069e63592 --- /dev/null +++ b/openair2/RRC/LITE/rrc_types_NB_IoT.h @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file rrc_types.h +* \brief rrc types and subtypes +* \author Navid Nikaein and Raymond Knopp +* \date 2011 - 2014 +* \version 1.0 +* \company Eurecom +* \email: navid.nikaein@eurecom.fr, raymond.knopp@eurecom.fr +*/ + +#ifndef RRC_TYPES_NB_IOT_H_ +#define RRC_TYPES_NB_IOT_H_ + +typedef enum Rrc_State_NB_IoT_e { + RRC_STATE_INACTIVE_NB_IoT=0, + RRC_STATE_IDLE_NB_IoT, + RRC_STATE_CONNECTED_NB_IoT, + + RRC_STATE_FIRST_NB_IoT = RRC_STATE_INACTIVE_NB_IoT, + RRC_STATE_LAST_NB_IoT = RRC_STATE_CONNECTED_NB_IoT, +} Rrc_State_NB_IoT_t; + +typedef enum Rrc_Sub_State_NB_IoT_e { + RRC_SUB_STATE_INACTIVE_NB_IoT=0, + + RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT, + RRC_SUB_STATE_IDLE_RECEIVING_SIB_NB_IoT, + RRC_SUB_STATE_IDLE_SIB_COMPLETE_NB_IoT, + RRC_SUB_STATE_IDLE_CONNECTING_NB_IoT, + RRC_SUB_STATE_IDLE_NB_IoT, + + RRC_SUB_STATE_CONNECTED_NB_IoT, + + RRC_SUB_STATE_INACTIVE_FIRST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT, + RRC_SUB_STATE_INACTIVE_LAST_NB_IoT = RRC_SUB_STATE_INACTIVE_NB_IoT, + + RRC_SUB_STATE_IDLE_FIRST_NB_IoT = RRC_SUB_STATE_IDLE_SEARCHING_NB_IoT, + RRC_SUB_STATE_IDLE_LAST_NB_IoT = RRC_SUB_STATE_IDLE_NB_IoT, + + RRC_SUB_STATE_CONNECTED_FIRST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT, + RRC_SUB_STATE_CONNECTED_LAST_NB_IoT = RRC_SUB_STATE_CONNECTED_NB_IoT, +} Rrc_Sub_State_NB_IoT_t; + +#endif /* RRC_TYPES_H_ */ diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c index 948425e8daa27b45643b2bca6587953ea9b0beab..ff6a5cd5739a85b1694324b88cb4785941805c33 100644 --- a/openair2/UTIL/LOG/log.c +++ b/openair2/UTIL/LOG/log.c @@ -34,6 +34,7 @@ #define COMPONENT_LOG #define COMPONENT_LOG_IF #include <ctype.h> +#define LOG_MAIN #include "log.h" #include "vcd_signal_dumper.h" #include "assertions.h" @@ -46,7 +47,7 @@ # include <string.h> #include "common/config/config_userapi.h" // main log variables -log_t *g_log; + mapping log_level_names[] = { {"emerg", LOG_EMERG}, @@ -1562,7 +1563,7 @@ int set_log(int component, int level, int interval) component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, LOG_EMERG); - DevCheck((interval > 0) && (interval <= 0xFF), interval, 0, 0xFF); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); g_log->log_component[component].level = level; @@ -1596,7 +1597,7 @@ int set_comp_log(int component, int level, int verbosity, int interval) component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); DevCheck((level <= LOG_TRACE) && (level >= LOG_EMERG), level, LOG_TRACE, LOG_EMERG); - DevCheck((interval > 0) && (interval <= 0xFF), interval, 0, 0xFF); + DevCheck((interval >= 0) && (interval <= 0xFF), interval, 0, 0xFF); #if 0 if ((verbosity == LOG_NONE) || (verbosity == LOG_LOW) || diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h index c21407f6eb51854c2eb7bb0ab432dffd9ab057f2..00bc334de5b3a25e8a00ead69f68889c18179a9b 100644 --- a/openair2/UTIL/LOG/log.h +++ b/openair2/UTIL/LOG/log.h @@ -253,7 +253,17 @@ typedef enum log_instance_type_e { void log_set_instance_type (log_instance_type_t instance); #endif - +#ifdef LOG_MAIN +log_t *g_log; +#else +#ifdef __cplusplus + extern "C" { +#endif +extern log_t *g_log; +#ifdef __cplusplus +} +#endif +#endif /*--- INCLUDES ---------------------------------------------------------------*/ # include "log_if.h" /*----------------------------------------------------------------------------*/ @@ -279,9 +289,9 @@ void *log_thread_function(void * list); * @brief Macro used to call tr_log_full_ex with file, function and line information * @{*/ #ifdef LOG_NO_THREAD -#define logIt(component, level, format, args...) logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) +#define logIt(component, level, format, args...) (g_log->log_component[component].interval?logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0) #else //default -#define logIt(component, level, format, args...) logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args) +#define logIt(component, level, format, args...) (g_log->log_component[component].interval?logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args):(void)0) #endif /* @}*/ diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index a2517e07b84b162dd4fbfe55a02669f1fb7505f4..7f63e8c1ce6fdd179aa6a565bd61ef0dfbdc4ee1 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -53,6 +53,7 @@ #undef GTP_DUMP_SOCKET +/* extern boolean_t pdcp_data_req( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, @@ -62,7 +63,7 @@ extern boolean_t pdcp_data_req( const sdu_size_t sdu_buffer_sizeP, unsigned char *const sdu_buffer_pP, const pdcp_transmission_mode_t modeP); - +*/ extern unsigned char NB_eNB_INST; extern RAN_CONTEXT_t RC; diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c index 527715eb7a2470c3577bb1a3b5a4fa40303af74b..4d6bd6e033a45417a2044e2cfb39ffff3ac8d1c8 100644 --- a/openair3/UDP/udp_eNB_task.c +++ b/openair3/UDP/udp_eNB_task.c @@ -270,10 +270,21 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP) n, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); #endif - if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { + /* TODO: this is a hack. Let's accept failures and do nothing when + * it happens. Since itti_send_msg_to_task crashes when the message + * queue is full we wrote itti_try_send_msg_to_task that returns -1 + * if the queue is full. + */ + /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */ + //if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { + if (itti_try_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) { +#if 0 LOG_I(UDP_, "Failed to send message %d to task %d\n", UDP_DATA_IND, udp_sock_pP->task_id); +#endif + itti_free(TASK_UDP, message_p); + itti_free(TASK_UDP, forwarded_buffer); return; } } diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index eb9f80872e0093ec237ff34a3064cc8c332e8d95..d74b1c6d4fed2d65640c1d5989e2ec846c642dcf 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -36,6 +36,7 @@ #include <string.h> #include "common_lib.h" +#include "common/utils/load_module_shlib.h" int set_device(openair0_device *device) { @@ -85,52 +86,26 @@ int set_transport(openair0_device *device) { } } - +typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *); /* look for the interface library and load it */ int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) { - void *lib_handle; - oai_device_initfunc_t dp ; - oai_transport_initfunc_t tp ; + loader_shlibfunc_t shlib_fdesc[1]; int ret=0; - + char *libname; if (flag == RAU_LOCAL_RADIO_HEAD) { - lib_handle = dlopen(OAI_RF_LIBNAME, RTLD_LAZY); - if (!lib_handle) { - fprintf(stderr,"Unable to locate %s: HW device set to NONE_DEV.\n", OAI_RF_LIBNAME); - fprintf(stderr,"%s\n",dlerror()); - return -1; - } - - dp = dlsym(lib_handle,"device_init"); - - if (dp != NULL ) { - ret = dp(device,openair0_cfg); - if (ret<0) { - fprintf(stderr, "%s %d:oai device intialization failed %s\n", __FILE__, __LINE__, dlerror()); - } - } else { - fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); - return -1; - } + libname=OAI_RF_LIBNAME; + shlib_fdesc[0].fname="device_init"; } 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); - printf( "%s\n",dlerror()); - return -1; - } - - tp = dlsym(lib_handle,"transport_init"); - - if (tp != NULL ) { - tp(device,openair0_cfg,cfg); - } else { - fprintf(stderr, "%s %d:oai device intializing function not found %s\n", __FILE__, __LINE__, dlerror()); - return -1; - } + libname=OAI_TP_LIBNAME; + shlib_fdesc[0].fname="transport_init"; } - + ret=load_module_shlib(libname,shlib_fdesc,1); + if (ret < 0) { + fprintf(stderr,"Library %s couldn't be loaded\n",libname); + } else { + ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg); + } return ret; } diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 2dc1650bfd719208ef5e182b0b79f76e5f12ff55..433e29e97db7b15322b51d8f3282daa91b922c09 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -36,9 +36,9 @@ #include <sys/types.h> /* name of shared library implementing the radio front end */ -#define OAI_RF_LIBNAME "liboai_device.so" +#define OAI_RF_LIBNAME "oai_device" /* name of shared library implementing the transport */ -#define OAI_TP_LIBNAME "liboai_transpro.so" +#define OAI_TP_LIBNAME "oai_transpro" /* flags for BBU to determine whether the attached radio head is local or remote */ #define RAU_LOCAL_RADIO_HEAD 0 diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 63f5b96c330357d670606d49d13e9e2ed587fc1d..98de4a024f5225e7d061dc3d1ba09c2ec8802bad 100644 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -11,7 +11,6 @@ # define NUMBER_OF_RU_MAX 32 # define NUMBER_OF_UE_MAX 20 # define NUMBER_OF_CONNECTED_eNB_MAX 3 - # if defined(STANDALONE) && STANDALONE==1 # undef NUMBER_OF_eNB_MAX # undef NUMBER_OF_UE_MAX diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 01a2c68bf3b5147e45945fff430a1dad2acdf2fb..e1c5d10de561435bae4171bbf1714f6730b63470 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -163,13 +163,6 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) { - - static double cpu_freq_GHz = 0.0; - - if (cpu_freq_GHz == 0.0) - cpu_freq_GHz = get_cpu_freq_GHz(); - - start_meas(&softmodem_stats_rxtx_sf); // ******************************************************************* diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 06aad94d3099630f17484b8ebc0ee91428d00dd4..d9bda6a037993a4771c58eb4d9791f1ed9df40ee 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -95,6 +95,10 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "enb_config.h" //#include "PHY/TOOLS/time_meas.h" +/* these variables have to be defined before including ENB_APP/enb_paramdef.h */ +static int DEFBANDS[] = {7}; +static int DEFENBS[] = {0}; + #include "ENB_APP/enb_paramdef.h" #include "common/config/config_userapi.h" @@ -1519,7 +1523,13 @@ static void* ru_thread( void* param ) { printf( "Exiting ru_thread \n"); - + + if (ru->stop_rf != NULL) { + if (ru->stop_rf(ru) != 0) + LOG_E(HW,"Could not stop the RF device\n"); + else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx); + } + ru_thread_status = 0; return &ru_thread_status; @@ -1613,6 +1623,12 @@ int start_rf(RU_t *ru) { return(ru->rfdevice.trx_start_func(&ru->rfdevice)); } +int stop_rf(RU_t *ru) +{ + ru->rfdevice.trx_end_func(&ru->rfdevice); + return 0; +} + extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); extern void feptx_ofdm(RU_t *ru); @@ -1883,7 +1899,6 @@ void configure_ru(int idx, RRU_config_t *config = (RRU_config_t *)arg; RRU_capabilities_t *capabilities = (RRU_capabilities_t*)arg; int ret; - int i; LOG_I(PHY, "Received capabilities from RRU %d\n",idx); @@ -1918,6 +1933,7 @@ void configure_ru(int idx, config->prach_FreqOffset[0],config->prach_ConfigIndex[0]); #ifdef Rel14 + int i; for (i=0;i<4;i++) { config->emtc_prach_CElevel_enable[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i]; config->emtc_prach_FreqOffset[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i]; @@ -2078,6 +2094,7 @@ void set_function_spec_param(RU_t *ru) ru->fh_south_in = rx_rf; // local synchronous RF RX ru->fh_south_out = tx_rf; // local synchronous RF TX ru->start_rf = start_rf; // need to start the local RF interface + ru->stop_rf = stop_rf; printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf); /* if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise @@ -2109,6 +2126,7 @@ void set_function_spec_param(RU_t *ru) ru->fh_south_asynch_in = NULL; // no asynchronous UL } ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; ru->start_if = start_if; // need to start if interface for IF5 ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; @@ -2133,6 +2151,7 @@ void set_function_spec_param(RU_t *ru) ru->fh_north_out = NULL; ru->fh_north_asynch_in = NULL; ru->start_rf = NULL; // no local RF + ru->stop_rf = NULL; ru->start_if = start_if; // need to start if interface for IF4p5 ru->ifdevice.host_type = RAU_HOST; ru->ifdevice.eth_params = &ru->eth_params; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index f6789086b4ebc3fa4bc594de44f84b04a7269a82..03313146df30ab2dc486fc10ab494f48e7650226 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -100,7 +100,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "stats.h" #endif #include "lte-softmodem.h" - +#include "NB_IoT_interface.h" #ifdef XFORMS // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) // at eNB 0, an UL scope for every UE @@ -135,11 +135,10 @@ volatile int oai_exit = 0; static clock_source_t clock_source = internal; static int wait_for_sync = 0; -static char UE_flag=0; unsigned int mmapped_dma=0; int single_thread_flag=1; -static char threequarter_fs=0; +static int8_t threequarter_fs=0; uint32_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -322,7 +321,7 @@ void signal_handler(int sig) { void exit_fun(const char* s) { - int CC_id; + int ru_id; if (s != NULL) { @@ -331,33 +330,22 @@ void exit_fun(const char* s) oai_exit = 1; - if (UE_flag==0) { + + if (RC.ru == NULL) + exit(-1); // likely init not completed, prevent crash or hang, exit now... for (ru_id=0; ru_id<RC.nb_RU;ru_id++) { - if (RC.ru[ru_id]->rfdevice.trx_end_func) + if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - if (RC.ru[ru_id]->ifdevice.trx_end_func) + if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); } - } - - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - oai_exit = 1; - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - if (UE_flag == 0) { - } else { - if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func) - PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); - } - } #if defined(ENABLE_ITTI) sleep(1); //allow lte-softmodem threads to exit first itti_terminate_tasks (TASK_UNKNOWN); #endif - } } @@ -390,9 +378,9 @@ void reset_stats(FL_OBJECT *button, long arg) } static void *scope_thread(void *arg) { - char stats_buffer[16384]; + # ifdef ENABLE_XFORMS_WRITE_STATS - FILE *UE_stats, *eNB_stats; + FILE *eNB_stats; # endif struct sched_param sched_param; int UE_id, CC_id; @@ -405,47 +393,15 @@ static void *scope_thread(void *arg) { # ifdef ENABLE_XFORMS_WRITE_STATS - if (UE_flag==1) - UE_stats = fopen("UE_stats.txt", "w"); - else - eNB_stats = fopen("eNB_stats.txt", "w"); + eNB_stats = fopen("eNB_stats.txt", "w"); #endif while (!oai_exit) { - if (UE_flag==1) { - dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); - - phy_scope_UE(form_ue[0], - PHY_vars_UE_g[0][0], - 0, - 0,7); - - - } else { - /* - if (RC.eNB[0][0]->mac_enabled==1) { - len = dump_eNB_l2_stats (stats_buffer, 0); - //fl_set_object_label(form_stats_l2->stats_text, stats_buffer); - fl_clear_browser(form_stats_l2->stats_text); - fl_add_browser_line(form_stats_l2->stats_text, stats_buffer); - } - len = dump_eNB_stats (RC.eNB[0][0], stats_buffer, 0); - - if (MAX_NUM_CCs>1) - len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0); - //fl_set_object_label(form_stats->stats_text, stats_buffer); - fl_clear_browser(form_stats->stats_text); - fl_add_browser_line(form_stats->stats_text, stats_buffer); - */ ue_cnt=0; for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) { for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - // if ((RC.eNB[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) { if ((ue_cnt<scope_enb_num_ue)) { phy_scope_eNB(form_enb[CC_id][ue_cnt], RC.eNB[0][CC_id], @@ -453,12 +409,7 @@ static void *scope_thread(void *arg) { ue_cnt++; } } - } - - } - - //printf("doing forms\n"); - //usleep(100000); // 100 ms + } sleep(1); } @@ -466,19 +417,11 @@ static void *scope_thread(void *arg) { # ifdef ENABLE_XFORMS_WRITE_STATS - if (UE_flag==1) { - if (UE_stats) { - rewind (UE_stats); - fwrite (stats_buffer, 1, len, UE_stats); - fclose (UE_stats); - } - } else { if (eNB_stats) { rewind (eNB_stats); fwrite (stats_buffer, 1, len, eNB_stats); fclose (eNB_stats); } - } # endif @@ -497,7 +440,6 @@ void *l2l1_task(void *arg) { itti_set_task_real_time(TASK_L2L1); itti_mark_task_ready(TASK_L2L1); - if (UE_flag == 0) { /* Wait for the initialize message */ printf("Wait for the ITTI initialize message\n"); do { @@ -530,8 +472,7 @@ void *l2l1_task(void *arg) { result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - } - +/* ???? no else but seems to be UE only ??? do { // Wait for a message itti_receive_msg (TASK_L2L1, &message_p); @@ -562,17 +503,17 @@ void *l2l1_task(void *arg) { result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } while(!oai_exit); - +*/ return NULL; } #endif static void get_options(void) { - int CC_id; - int tddflag; - char *loopfile=NULL; - int dumpframe; + + int tddflag, nonbiotflag; + + uint32_t online_log_messages; uint32_t glog_level, glog_verbosity; uint32_t start_telnetsrv; @@ -607,97 +548,27 @@ static void get_options(void) { load_module_shlib("telnetsrv",NULL,0); } - - if (UE_flag > 0) { - uint8_t n_rb_dl; - paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; - paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; - - set_default_frame_parms(frame_parms); - - config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); - config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); - if (loopfile != NULL) { - printf("Input file for hardware emulation: %s",loopfile); - mode=loop_through_memory; - input_fd = fopen(loopfile,"r"); - AssertFatal(input_fd != NULL,"Please provide a valid input file\n"); - } - - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; - if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; - if ( (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = debug_prach; - if ( (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = no_L2_connect; - if ( (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = calib_prach_tx; - if ( (cmdline_uemodeparams[CMDLINE_DUMPMEMORY_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_dump_frame; - - if ( downlink_frequency[0][0] > 0) { - printf("Downlink frequency set to %u\n", downlink_frequency[0][0]); - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; - } - UE_scan=0; - } - - if (tddflag > 0) { - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) - frame_parms[CC_id]->frame_type = TDD; - } - - if (n_rb_dl !=0) { - printf("NB_RB set to %d\n",n_rb_dl); - if ( n_rb_dl < 6 ) { - n_rb_dl = 6; - printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",n_rb_dl); - } - if ( n_rb_dl > 100 ) { - n_rb_dl = 100; - printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",n_rb_dl); - } - if ( n_rb_dl > 50 && n_rb_dl < 100 ) { - n_rb_dl = 50; - printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",n_rb_dl); - } - if ( n_rb_dl > 25 && n_rb_dl < 50 ) { - n_rb_dl = 25; - printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",n_rb_dl); - } - UE_scan = 0; - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - frame_parms[CC_id]->N_RB_DL=n_rb_dl; - frame_parms[CC_id]->N_RB_UL=n_rb_dl; - } - } - - for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { - tx_max_power[CC_id]=tx_max_power[0]; - rx_gain[0][CC_id] = rx_gain[0][0]; - tx_gain[0][CC_id] = tx_gain[0][0]; - } - } /* UE_flag > 0 */ - #if T_TRACER paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); #endif if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - if (UE_flag == 0) { memset((void*)&RC,0,sizeof(RC)); /* Read RC configuration file */ RCConfig(); NB_eNB_INST = RC.nb_inst; NB_RU = RC.nb_RU; printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU); - } - } else if (UE_flag == 1 && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) { - // Here the configuration file is the XER encoded UE capabilities - // Read it in and store in asn1c data structures - sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME")); - printf("%s\n",uecap_xer); - uecap_xer_in=1; - } /* UE with config file */ + if (nonbiotflag <= 0) { + load_NB_IoT(); + printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n", + RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst); + } else { + printf("All Nb-IoT instances disabled\n"); + RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0; + } + } } @@ -756,9 +627,8 @@ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { } -void init_openair0(void); -void init_openair0() { +void init_openair0(void) { int card; int i; @@ -798,16 +668,14 @@ void init_openair0() { } - - if (frame_parms[0]->frame_type==TDD) openair0_cfg[card].duplex_mode = duplex_mode_TDD; else //FDD openair0_cfg[card].duplex_mode = duplex_mode_FDD; printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, - ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx), - ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); + RC.eNB[0][0]->frame_parms.nb_antennas_tx , + RC.eNB[0][0]->frame_parms.nb_antennas_rx ); openair0_cfg[card].Mod_id = 0; openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; @@ -815,29 +683,25 @@ void init_openair0() { openair0_cfg[card].clock_source = clock_source; - openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx)); - openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx)); + openair0_cfg[card].tx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_tx ); + openair0_cfg[card].rx_num_channels=min(2,RC.eNB[0][0]->frame_parms.nb_antennas_rx ); for (i=0; i<4; i++) { if (i<openair0_cfg[card].tx_num_channels) - openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i]; + openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i] ; else openair0_cfg[card].tx_freq[i]=0.0; if (i<openair0_cfg[card].rx_num_channels) - openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i]; + openair0_cfg[card].rx_freq[i] =downlink_frequency[0][i] + uplink_frequency_offset[0][i] ; else openair0_cfg[card].rx_freq[i]=0.0; openair0_cfg[card].autocal[i] = 1; openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; - if (UE_flag == 0) { - openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB; - } - else { - openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; - } + openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB; + openair0_cfg[card].configFilename = rf_config_file; printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", @@ -846,7 +710,7 @@ void init_openair0() { openair0_cfg[card].tx_freq[i], openair0_cfg[card].rx_freq[i]); } - } + } /* for loop on cards */ } @@ -994,7 +858,6 @@ int restart_L1L2(module_id_t enb_id) msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ); RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration; itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p); - /* TODO XForms might need to be restarted, but it is currently (09/02/18) * broken, so we cannot test it */ @@ -1015,7 +878,7 @@ int restart_L1L2(module_id_t enb_id) } #endif -static inline void wait_nfapi_init(char *thread_name) { +static void wait_nfapi_init(char *thread_name) { printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); pthread_mutex_lock( &nfapi_sync_mutex ); @@ -1037,9 +900,6 @@ int main( int argc, char **argv ) int CC_id; int ru_id; - uint8_t abstraction_flag=0; - uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; - #if defined (XFORMS) int ret; #endif @@ -1054,8 +914,6 @@ int main( int argc, char **argv ) setvbuf(stderr, NULL, _IONBF, 0); #endif - PHY_VARS_UE *UE[MAX_NUM_CCs]; - mode = normal_txrx; memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); @@ -1063,16 +921,12 @@ int main( int argc, char **argv ) set_latency_target(); - - // set default parameters - //if (UE_flag == 1) set_default_frame_parms(frame_parms); - logInit(); printf("Reading in command-line options\n"); get_options (); - if (CONFIG_ISFLAGSET(CONFIG_ABORT) && UE_flag == 0) { + if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); } @@ -1087,32 +941,10 @@ int main( int argc, char **argv ) //randominit (0); set_taus_seed (0); - if (UE_flag==1) { - printf("configuring for UE\n"); + printf("configuring for RAU/RRU\n"); - set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); - set_comp_log(PHY, LOG_INFO, LOG_HIGH, 1); - set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RLC, LOG_INFO, LOG_HIGH | FLAG_THREAD, 1); - set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); - set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); - set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); -#if defined(ENABLE_ITTI) - set_comp_log(EMU, LOG_INFO, LOG_MED, 1); -# if defined(ENABLE_USE_MME) - set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); -# endif -#endif - - } else { - printf("configuring for RAU/RRU\n"); - - } if (ouput_vcd) { - if (UE_flag==1) - VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); - else VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd"); } @@ -1122,12 +954,7 @@ int main( int argc, char **argv ) cpuf=get_cpu_freq_GHz(); #if defined(ENABLE_ITTI) - - if (UE_flag == 1) { - log_set_instance_type (LOG_INSTANCE_UE); - } else { - log_set_instance_type (LOG_INSTANCE_ENB); - } + log_set_instance_type (LOG_INSTANCE_ENB); printf("ITTI init\n"); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); @@ -1171,88 +998,15 @@ int main( int argc, char **argv ) LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - // init the parameters - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - if (UE_flag==1) { - frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; - frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; - frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later - } - } printf("Before CC \n"); - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - if (UE_flag==1) { - NB_UE_INST=1; - NB_INST=1; - PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)); - PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); - - - - PHY_vars_UE_g[0][CC_id] = init_ue_vars(frame_parms[CC_id], 0,abstraction_flag); - UE[CC_id] = PHY_vars_UE_g[0][CC_id]; - printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]); - - if (phy_test==1) - UE[CC_id]->mac_enabled = 0; - else - UE[CC_id]->mac_enabled = 1; - - if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode - for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { - UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; - UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; - - UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; - UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); - UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; - } - } - - UE[CC_id]->UE_scan = UE_scan; - UE[CC_id]->UE_scan_carrier = UE_scan_carrier; - UE[CC_id]->mode = mode; - printf("UE[%d]->mode = %d\n",CC_id,mode); - - if (UE[CC_id]->mac_enabled == 1) { - UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234; - UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234; - }else { - UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235; - UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235; - } - UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; - UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; - - if (frame_parms[CC_id]->frame_type==FDD) { - UE[CC_id]->N_TA_offset = 0; - } - else { - if (frame_parms[CC_id]->N_RB_DL == 100) - UE[CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - UE[CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - UE[CC_id]->N_TA_offset = 624/4; - } - init_openair0(); - } - - } - printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); - cpuf=get_cpu_freq_GHz(); - - - + + #ifndef DEADLINE_SCHEDULER printf("NO deadline scheduler\n"); @@ -1295,22 +1049,13 @@ int main( int argc, char **argv ) #if defined(ENABLE_ITTI) - if ((UE_flag == 1)|| - (RC.nb_inst > 0)) { + if (RC.nb_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP - if (UE_flag == 0) { if (create_tasks(1) < 0) { printf("cannot create ITTI tasks\n"); exit(-1); // need a softer mode } - } - else { - if (create_tasks_ue(1) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - } printf("ITTI tasks created\n"); } else { @@ -1342,7 +1087,6 @@ int main( int argc, char **argv ) if (do_forms==1) { fl_initialize (&argc, argv, NULL, 0, 0); - if (UE_flag==0) { form_stats_l2 = create_form_stats_form(); fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats"); form_stats = create_form_stats_form(); @@ -1363,25 +1107,6 @@ int main( int argc, char **argv ) } } // CC_id } // UE_id - } else { - form_stats = create_form_stats_form(); - fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); - UE_id = 0; - form_ue[UE_id] = create_lte_phy_scope_ue(); - sprintf (title, "LTE DL SCOPE UE"); - fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); - - /* - if (openair_daq_vars.use_ia_receiver) { - fl_set_button(form_ue[UE_id]->button_0,1); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); - } else { - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - }*/ - fl_set_button(form_ue[UE_id]->button_0,0); - fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); - } ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); @@ -1426,23 +1151,7 @@ int main( int argc, char **argv ) printf("START MAIN THREADS\n"); // start the main threads - if (UE_flag == 1) { - int eMBMS_active = 0; - init_UE(1,eMBMS_active,uecap_xer_in,0); - - if (phy_test==0) { - printf("Filling UE band info\n"); - fill_ue_band_info(); - dl_phy_sync_success (0, 0, 0, 1); - } - number_of_cards = 1; - for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - PHY_vars_UE_g[0][CC_id]->rf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; - } - } - else { number_of_cards = 1; printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); if (RC.nb_L1_inst > 0) { @@ -1489,42 +1198,10 @@ int main( int argc, char **argv ) } printf("ALL RUs ready - ALL eNBs ready\n"); - } // connect the TX/RX buffers - if (UE_flag==1) { - - for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - - -#ifdef OAI_USRP - UE[CC_id]->hw_timing_advance = timing_advance; -#else - UE[CC_id]->hw_timing_advance = 160; -#endif - } - if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { - printf("Error setting up eNB buffer\n"); - exit(-1); - } - - - - if (input_fd) { - printf("Reading in from file to antenna buffer %d\n",0); - if (fread(UE[0]->common_vars.rxdata[0], - sizeof(int32_t), - frame_parms[0]->samples_per_tti*10, - input_fd) != frame_parms[0]->samples_per_tti*10) - printf("error reading from file\n"); - } - //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; - } else { - - printf("eNB mode\n"); - - } + printf("Sending sync to all threads\n"); @@ -1563,10 +1240,6 @@ int main( int argc, char **argv ) fl_hide_form(form_stats->stats_form); fl_free_form(form_stats->stats_form); - if (UE_flag==1) { - fl_hide_form(form_ue[0]->lte_phy_scope_ue); - fl_free_form(form_ue[0]->lte_phy_scope_ue); - } else { fl_hide_form(form_stats_l2->stats_form); fl_free_form(form_stats_l2->stats_form); @@ -1576,7 +1249,6 @@ int main( int argc, char **argv ) fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb); } } - } } #endif @@ -1584,8 +1256,6 @@ int main( int argc, char **argv ) printf("stopping MODEM threads\n"); // cleanup - if (UE_flag == 1) { - } else { stop_eNB(NB_eNB_INST); stop_RU(NB_RU); /* release memory used by the RU/eNB threads (incomplete), after all @@ -1600,7 +1270,6 @@ int main( int argc, char **argv ) phy_free_RU(RC.ru[inst]); } free_lte_top(); - } pthread_cond_destroy(&sync_cond); @@ -1612,11 +1281,7 @@ int main( int argc, char **argv ) pthread_mutex_destroy(&ue_pf_po_mutex); // *** Handle per CC_id openair0 - if (UE_flag==1) { - if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) - PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); - } - else { + for(ru_id=0; ru_id<NB_RU; ru_id++) { if (RC.ru[ru_id]->rfdevice.trx_end_func) RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); @@ -1624,7 +1289,6 @@ int main( int argc, char **argv ) RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); } - } if (ouput_vcd) VCD_SIGNAL_DUMPER_CLOSE(); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 5cc4d5fea2d70208ba76151f08240671628f137c..e8b9d9249023d13a4d2047668b2de8eb12b28d0c 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -85,7 +85,7 @@ #define CONFIG_HLP_TPORT "tracer port\n" #define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n" #define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n" - +#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument @@ -129,10 +129,10 @@ {"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ {"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:90, TYPE_INT, 0}, \ -{"r" , CONFIG_HLP_PRB, 0, u8ptr:&n_rb_dl, defintval:0, TYPE_UINT8, 0}, \ +{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ } - +#define DEFAULT_DLF 2680000000 extern int16_t dlsch_demod_shift; /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -155,12 +155,11 @@ extern int16_t dlsch_demod_shift; {"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ -{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ +{"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT, 0}, \ {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ -{"U" , CONFIG_HLP_UE, PARAMFLAG_BOOL, i8ptr:&UE_flag, defintval:0, TYPE_INT8, 0}, \ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ {"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ @@ -168,7 +167,8 @@ extern int16_t dlsch_demod_shift; {"V" , CONFIG_HLP_VCD, PARAMFLAG_BOOL, iptr:&ouput_vcd, defintval:0, TYPE_INT, 0}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ -{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0} \ +{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ +{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ } #define CONFIG_HLP_FLOG "Enable online log \n" diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c new file mode 100644 index 0000000000000000000000000000000000000000..ae4798f399231040178b47a6b11f5b1a0aec8ae5 --- /dev/null +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -0,0 +1,1139 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file lte-enb.c + * \brief Top-level threads for eNodeB + * \author R. Knopp, F. Kaltenberger, Navid Nikaein + * \date 2012 + * \version 0.1 + * \company Eurecom + * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr + * \note + * \warning + */ + + +#define _GNU_SOURCE /* See feature_test_macros(7) */ +#include <sched.h> + + +#include "T.h" + +#include "rt_wrapper.h" + + +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "assertions.h" +#include "msc.h" + +#include "PHY/types.h" + +#include "PHY/defs.h" +#include "common/ran_context.h" +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" +#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "../../ARCH/COMMON/common_lib.h" +#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h" + +//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all + +#include "PHY/vars.h" +#include "SCHED/vars.h" +#include "LAYER2/MAC/vars.h" + +#include "../../SIMU/USER/init_lte.h" + +#include "LAYER2/MAC/defs.h" +#include "LAYER2/MAC/vars.h" +#include "LAYER2/MAC/proto.h" +#include "RRC/LITE/vars.h" +#include "PHY_INTERFACE/vars.h" + +#ifdef SMBV +#include "PHY/TOOLS/smbv.h" +unsigned short config_frames[4] = {2,9,11,13}; +#endif +#include "UTIL/LOG/log_extern.h" +#include "UTIL/OTG/otg_tx.h" +#include "UTIL/OTG/otg_externs.h" +#include "UTIL/MATH/oml.h" +#include "UTIL/LOG/vcd_signal_dumper.h" +#include "UTIL/OPT/opt.h" +#include "enb_config.h" +//#include "PHY/TOOLS/time_meas.h" + +#ifndef OPENAIR2 +#include "UTIL/OTG/otg_vars.h" +#endif + +#if defined(ENABLE_ITTI) +#include "intertask_interface_init.h" +#include "create_tasks.h" +#endif + +#include "system.h" + +#ifdef XFORMS +#include "PHY/TOOLS/lte_phy_scope.h" +#include "stats.h" +#endif +#include "lte-softmodem.h" + +/* temporary compilation wokaround (UE/eNB split */ +uint16_t sf_ahead; +#ifdef XFORMS +// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) +// at eNB 0, an UL scope for every UE +FD_lte_phy_scope_ue *form_ue[NUMBER_OF_UE_MAX]; +FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; +char title[255]; +unsigned char scope_enb_num_ue = 2; +static pthread_t forms_thread; //xforms +#endif //XFORMS + +pthread_cond_t sync_cond; +pthread_mutex_t sync_mutex; +int sync_var=-1; //!< protected by mutex \ref sync_mutex. +int config_sync_var=-1; + +uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] +uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100] + +#if defined(ENABLE_ITTI) +volatile int start_eNB = 0; +volatile int start_UE = 0; +#endif +volatile int oai_exit = 0; + +static clock_source_t clock_source = internal; +static int wait_for_sync = 0; + +unsigned int mmapped_dma=0; +int single_thread_flag=1; + +static int8_t threequarter_fs=0; + +uint32_t downlink_frequency[MAX_NUM_CCs][4]; +int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; + + + +#if defined(ENABLE_ITTI) +static char *itti_dump_file = NULL; +#endif + +int UE_scan = 1; +int UE_scan_carrier = 0; +runmode_t mode = normal_txrx; + +FILE *input_fd=NULL; + + +#if MAX_NUM_CCs == 1 +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}}; +#else +rx_gain_t rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}}; +double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}}; +double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}}; +#endif + +double rx_gain_off = 0.0; + +double sample_rate=30.72e6; +double bw = 10.0e6; + +static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; + +char rf_config_file[1024]; + +int chain_offset=0; +int phy_test = 0; +uint8_t usim_test = 0; + +uint8_t dci_Format = 0; +uint8_t agregation_Level =0xFF; + +uint8_t nb_antenna_tx = 1; +uint8_t nb_antenna_rx = 1; + +char ref[128] = "internal"; +char channels[128] = "0"; + +int rx_input_level_dBm; + +#ifdef XFORMS +extern int otg_enabled; +static char do_forms=0; +#else +int otg_enabled; +#endif +//int number_of_cards = 1; + + +static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; +uint32_t target_dl_mcs = 28; //maximum allowed mcs +uint32_t target_ul_mcs = 20; +uint32_t timing_advance = 0; +uint8_t exit_missed_slots=1; +uint64_t num_missed_slots=0; // counter for the number of missed slots + + +extern void reset_opp_meas(void); +extern void print_opp_meas(void); + +extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, + uint8_t UE_id, + uint8_t abstraction_flag); + + +int transmission_mode=1; + + + +/* struct for ethernet specific parameters given in eNB conf file */ +eth_params_t *eth_params; + +openair0_config_t openair0_cfg[MAX_CARDS]; + +double cpuf; + +extern char uecap_xer[1024]; +char uecap_xer_in=0; + +int oaisim_flag=0; +threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; + +/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed + * this is very hackish - find a proper solution + */ +uint8_t abstraction_flag=0; + +/* forward declarations */ +void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); + +/*---------------------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(void) { +#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) { + return (txi + (txq<<6) + (rxi<<12) + (rxq<<18)); +} +unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { + return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); +} + +#if !defined(ENABLE_ITTI) +void signal_handler(int sig) { + void *array[10]; + size_t size; + + if (sig==SIGSEGV) { + // get void*'s for all entries on the stack + size = backtrace(array, 10); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", sig); + backtrace_symbols_fd(array, size, 2); + exit(-1); + } else { + printf("trying to exit gracefully...\n"); + oai_exit = 1; + } +} +#endif +#define KNRM "\x1B[0m" +#define KRED "\x1B[31m" +#define KGRN "\x1B[32m" +#define KBLU "\x1B[34m" +#define RESET "\033[0m" + + + +void exit_fun(const char* s) +{ + int CC_id; + + if (s != NULL) { + printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s); + } + + oai_exit = 1; + + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice); + } + +#if defined(ENABLE_ITTI) + sleep(1); //allow lte-softmodem threads to exit first + itti_terminate_tasks (TASK_UNKNOWN); +#endif +} + +#ifdef XFORMS + + +void reset_stats(FL_OBJECT *button, long arg) +{ + int i,j,k; + PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0]; + + for (i=0; i<NUMBER_OF_UE_MAX; i++) { + for (k=0; k<8; k++) { //harq_processes + for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) { + phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0; + phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0; + } + + phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0; + phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0; + + + phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0; + phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0; + phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0; + } + } +} + +static void *scope_thread(void *arg) { + char stats_buffer[16384]; +# ifdef ENABLE_XFORMS_WRITE_STATS + FILE *UE_stats, *eNB_stats; +# endif + struct sched_param sched_param; + + + sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1; + sched_setscheduler(0, SCHED_FIFO,&sched_param); + + printf("Scope thread has priority %d\n",sched_param.sched_priority); + +# ifdef ENABLE_XFORMS_WRITE_STATS + + UE_stats = fopen("UE_stats.txt", "w"); + +#endif + + while (!oai_exit) { + dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm); + //fl_set_object_label(form_stats->stats_text, stats_buffer); + fl_clear_browser(form_stats->stats_text); + fl_add_browser_line(form_stats->stats_text, stats_buffer); + + phy_scope_UE(form_ue[0], + PHY_vars_UE_g[0][0], + 0, + 0,7); + + // printf("%s",stats_buffer); + } +# ifdef ENABLE_XFORMS_WRITE_STATS + + if (UE_stats) { + rewind (UE_stats); + fwrite (stats_buffer, 1, len, UE_stats); + fclose (UE_stats); + } + +# endif + + pthread_exit((void*)arg); +} +#endif + + + +#if defined(ENABLE_ITTI) +void *l2l1_task(void *arg) { + MessageDef *message_p = NULL; + int result; + + itti_set_task_real_time(TASK_L2L1); + itti_mark_task_ready(TASK_L2L1); + + + do { + // Wait for a message + itti_receive_msg (TASK_L2L1, &message_p); + + switch (ITTI_MSG_ID(message_p)) { + case TERMINATE_MESSAGE: + oai_exit=1; + itti_exit_task (); + break; + + case ACTIVATE_MESSAGE: + start_UE = 1; + break; + + case DEACTIVATE_MESSAGE: + start_UE = 0; + break; + + case MESSAGE_TEST: + LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p)); + break; + + default: + LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p)); + break; + } + + result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + } while(!oai_exit); + + return NULL; +} +#endif + + +static void get_options(void) { + int CC_id; + int tddflag, nonbiotflag; + char *loopfile=NULL; + int dumpframe; + uint32_t online_log_messages; + uint32_t glog_level, glog_verbosity; + uint32_t start_telnetsrv; + + paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; + paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; + + set_default_frame_parms(frame_parms); + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + + if (strlen(in_path) > 0) { + opt_type = OPT_PCAP; + opt_enabled=1; + printf("Enabling OPT for PCAP with the following file %s \n",in_path); + } + if (strlen(in_ip) > 0) { + opt_enabled=1; + opt_type = OPT_WIRESHARK; + printf("Enabling OPT for wireshark for local interface"); + } + + config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); + if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { + set_glog_onlinelog(online_log_messages); + } + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { + set_glog(glog_level, -1); + } + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGVERBO_IDX)) { + set_glog(-1, glog_verbosity); + } + if (start_telnetsrv) { + load_module_shlib("telnetsrv",NULL,0); + } + + paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; + paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; + + + config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); + config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); + if (loopfile != NULL) { + printf("Input file for hardware emulation: %s",loopfile); + mode=loop_through_memory; + input_fd = fopen(loopfile,"r"); + AssertFatal(input_fd != NULL,"Please provide a valid input file\n"); + } + + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; + if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; + if (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach; + if (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0) mode = no_L2_connect; + if (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) + if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; + if (dumpframe > 0) mode = rx_dump_frame; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0]; + } + UE_scan=0; + + + if (tddflag > 0) { + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) + frame_parms[CC_id]->frame_type = TDD; + } + + if (frame_parms[0]->N_RB_DL !=0) { + if ( frame_parms[0]->N_RB_DL < 6 ) { + frame_parms[0]->N_RB_DL = 6; + printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 100 ) { + frame_parms[0]->N_RB_DL = 100; + printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) { + frame_parms[0]->N_RB_DL = 50; + printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL); + } + if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) { + frame_parms[0]->N_RB_DL = 25; + printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL); + } + UE_scan = 0; + frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL; + for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL; + frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL; + } + } + + + for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++) { + tx_max_power[CC_id]=tx_max_power[0]; + rx_gain[0][CC_id] = rx_gain[0][0]; + tx_gain[0][CC_id] = tx_gain[0][0]; + } + +#if T_TRACER + paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ; + config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL); +#endif + + if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) { + // Here the configuration file is the XER encoded UE capabilities + // Read it in and store in asn1c data structures + sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME")); + printf("%s\n",uecap_xer); + uecap_xer_in=1; + } /* UE with config file */ +} + + +#if T_TRACER +int T_nowait = 0; /* by default we wait for the tracer */ +int T_port = 2021; /* default port to listen to to wait for the tracer */ +int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ +#endif + + + +void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { + + int CC_id; + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS)); + /* Set some default values that may be overwritten while reading options */ + frame_parms[CC_id]->frame_type = FDD; + frame_parms[CC_id]->tdd_config = 3; + frame_parms[CC_id]->tdd_config_S = 0; + frame_parms[CC_id]->N_RB_DL = 100; + frame_parms[CC_id]->N_RB_UL = 100; + frame_parms[CC_id]->Ncp = NORMAL; + frame_parms[CC_id]->Ncp_UL = NORMAL; + frame_parms[CC_id]->Nid_cell = 0; + frame_parms[CC_id]->num_MBSFN_config = 0; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; + frame_parms[CC_id]->nb_antennas_tx = 1; + frame_parms[CC_id]->nb_antennas_rx = 1; + + frame_parms[CC_id]->nushift = 0; + + frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth; + frame_parms[CC_id]->phich_config_common.phich_duration = normal; + // UL RS Config + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0 + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0; + frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; + + frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0; + frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0; + + downlink_frequency[CC_id][0] = DEFAULT_DLF; // Use float to avoid issue with frequency over 2^31. + downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0]; + downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0]; + + frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0]; + + } + +} + +void init_openair0(void) { + + int card; + int i; + + for (card=0; card<MAX_CARDS; card++) { + + openair0_cfg[card].mmapped_dma=mmapped_dma; + openair0_cfg[card].configFilename = NULL; + + if(frame_parms[0]->N_RB_DL == 100) { + if (frame_parms[0]->threequarter_fs) { + openair0_cfg[card].sample_rate=23.04e6; + openair0_cfg[card].samples_per_frame = 230400; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } else { + openair0_cfg[card].sample_rate=30.72e6; + openair0_cfg[card].samples_per_frame = 307200; + openair0_cfg[card].tx_bw = 10e6; + openair0_cfg[card].rx_bw = 10e6; + } + } else if(frame_parms[0]->N_RB_DL == 50) { + openair0_cfg[card].sample_rate=15.36e6; + openair0_cfg[card].samples_per_frame = 153600; + openair0_cfg[card].tx_bw = 5e6; + openair0_cfg[card].rx_bw = 5e6; + } else if (frame_parms[0]->N_RB_DL == 25) { + openair0_cfg[card].sample_rate=7.68e6; + openair0_cfg[card].samples_per_frame = 76800; + openair0_cfg[card].tx_bw = 2.5e6; + openair0_cfg[card].rx_bw = 2.5e6; + } else if (frame_parms[0]->N_RB_DL == 6) { + openair0_cfg[card].sample_rate=1.92e6; + openair0_cfg[card].samples_per_frame = 19200; + openair0_cfg[card].tx_bw = 1.5e6; + openair0_cfg[card].rx_bw = 1.5e6; + } + + + + + if (frame_parms[0]->frame_type==TDD) + openair0_cfg[card].duplex_mode = duplex_mode_TDD; + else //FDD + openair0_cfg[card].duplex_mode = duplex_mode_FDD; + + printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx, + PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + openair0_cfg[card].Mod_id = 0; + + openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL; + + openair0_cfg[card].clock_source = clock_source; + + + openair0_cfg[card].tx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx); + openair0_cfg[card].rx_num_channels=min(2,PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx); + + for (i=0; i<4; i++) { + + if (i<openair0_cfg[card].tx_num_channels) + openair0_cfg[card].tx_freq[i] = downlink_frequency[0][i]+uplink_frequency_offset[0][i]; + else + openair0_cfg[card].tx_freq[i]=0.0; + + if (i<openair0_cfg[card].rx_num_channels) + openair0_cfg[card].rx_freq[i] = downlink_frequency[0][i]; + else + openair0_cfg[card].rx_freq[i]=0.0; + + openair0_cfg[card].autocal[i] = 1; + openair0_cfg[card].tx_gain[i] = tx_gain[0][i]; + openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off; + + + openair0_cfg[card].configFilename = rf_config_file; + printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", + card,i, openair0_cfg[card].tx_gain[i], + openair0_cfg[card].rx_gain[i], + openair0_cfg[card].tx_freq[i], + openair0_cfg[card].rx_freq[i]); + } + } +} + + + + +#if defined(ENABLE_ITTI) +/* + * helper function to terminate a certain ITTI task + */ +void terminate_task(task_id_t task_id, module_id_t mod_id) +{ + LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); + MessageDef *msg; + msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE); + itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); +} + + + +#endif + +int main( int argc, char **argv ) +{ + int i; +#if defined (XFORMS) + void *status; +#endif + + int CC_id; + uint8_t abstraction_flag=0; + uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2; + +#if defined (XFORMS) + int ret; +#endif + + start_background_system(); + if ( load_configmodule(argc,argv) == NULL) { + exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); + } + +#ifdef DEBUG_CONSOLE + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); +#endif + + PHY_VARS_UE *UE[MAX_NUM_CCs]; + + mode = normal_txrx; + memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS); + + memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs); + + set_latency_target(); + + logInit(); + + printf("Reading in command-line options\n"); + + get_options (); + + +#if T_TRACER + T_init(T_port, 1-T_nowait, T_dont_fork); +#endif + + + + //randominit (0); + set_taus_seed (0); + + + set_comp_log(HW, LOG_DEBUG, LOG_HIGH, 1); + set_comp_log(PHY, LOG_INFO, LOG_HIGH, 1); + set_comp_log(MAC, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RLC, LOG_INFO, LOG_HIGH | FLAG_THREAD, 1); + set_comp_log(PDCP, LOG_INFO, LOG_HIGH, 1); + set_comp_log(OTG, LOG_INFO, LOG_HIGH, 1); + set_comp_log(RRC, LOG_INFO, LOG_HIGH, 1); +#if defined(ENABLE_ITTI) + set_comp_log(EMU, LOG_INFO, LOG_MED, 1); +# if defined(ENABLE_USE_MME) + set_comp_log(NAS, LOG_INFO, LOG_HIGH, 1); +# endif +#endif + + + if (ouput_vcd) { + VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd"); + } + + cpuf=get_cpu_freq_GHz(); + +#if defined(ENABLE_ITTI) + + log_set_instance_type (LOG_INSTANCE_UE); + + + printf("ITTI init\n"); + itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file); + + // initialize mscgen log after ITTI + MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); +#endif + + if (opt_type != OPT_NONE) { + radio_type_t radio_type; + + if (frame_parms[0]->frame_type == FDD) + radio_type = RADIO_TYPE_FDD; + else + radio_type = RADIO_TYPE_TDD; + + if (init_opt(in_path, in_ip, NULL, radio_type) == -1) + LOG_E(OPT,"failed to run OPT \n"); + } + +#ifdef PDCP_USE_NETLINK + printf("PDCP netlink\n"); + netlink_init(); +#if defined(PDCP_USE_NETLINK_QUEUES) + pdcp_netlink_init(); +#endif +#endif + +#if !defined(ENABLE_ITTI) + // to make a graceful exit when ctrl-c is pressed + signal(SIGSEGV, signal_handler); + signal(SIGINT, signal_handler); +#endif + + + check_clock(); + +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" +#endif + + LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + + // init the parameters + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; + frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; + frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later + } + + + + printf("Before CC \n"); + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + NB_UE_INST=1; + NB_INST=1; + PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**)); + PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs); + PHY_vars_UE_g[0][CC_id] = init_ue_vars(frame_parms[CC_id], 0,abstraction_flag); + UE[CC_id] = PHY_vars_UE_g[0][CC_id]; + printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]); + + if (phy_test==1) + UE[CC_id]->mac_enabled = 0; + else + UE[CC_id]->mac_enabled = 1; + + if (UE[CC_id]->mac_enabled == 0) { //set default UL parameters for testing mode + for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) { + UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index = beta_RI; + UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI; + + UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0; + UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3); + UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4; + } + } + + UE[CC_id]->UE_scan = UE_scan; + UE[CC_id]->UE_scan_carrier = UE_scan_carrier; + UE[CC_id]->mode = mode; + printf("UE[%d]->mode = %d\n",CC_id,mode); + + if (UE[CC_id]->mac_enabled == 1) { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234; + }else { + UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235; + UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235; + } + UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; + UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; + + if (frame_parms[CC_id]->frame_type==FDD) { + UE[CC_id]->N_TA_offset = 0; + } + else { + if (frame_parms[CC_id]->N_RB_DL == 100) + UE[CC_id]->N_TA_offset = 624; + else if (frame_parms[CC_id]->N_RB_DL == 50) + UE[CC_id]->N_TA_offset = 624/2; + else if (frame_parms[CC_id]->N_RB_DL == 25) + UE[CC_id]->N_TA_offset = 624/4; + + } + init_openair0(); + } + + printf("Runtime table\n"); + fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); + cpuf=get_cpu_freq_GHz(); + + + +#ifndef DEADLINE_SCHEDULER + + printf("NO deadline scheduler\n"); + /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */ + + cpu_set_t cpuset; + int s; + char cpu_affinity[1024]; + CPU_ZERO(&cpuset); +#ifdef CPU_AFFINITY + if (get_nprocs() > 2) { + CPU_SET(0, &cpuset); + s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_setaffinity_np"); + exit_fun("Error setting processor affinity"); + } + LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n"); + } +#endif + + /* Check the actual affinity mask assigned to the thread */ + s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); + if (s != 0) { + perror( "pthread_getaffinity_np"); + exit_fun("Error getting processor affinity "); + } + memset(cpu_affinity, 0 , sizeof(cpu_affinity)); + for (int j = 0; j < CPU_SETSIZE; j++) { + if (CPU_ISSET(j, &cpuset)) { + char temp[1024]; + sprintf(temp, " CPU_%d ", j); + strcat(cpu_affinity, temp); + } + } + LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity); +#endif + + + + +#if defined(ENABLE_ITTI) + if (create_tasks_ue(1) < 0) { + printf("cannot create ITTI tasks\n"); + exit(-1); // need a softer mode + } + printf("ITTI tasks created\n"); +#endif + + // init UE_PF_PO and mutex lock + pthread_mutex_init(&ue_pf_po_mutex, NULL); + memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); + + mlockall(MCL_CURRENT | MCL_FUTURE); + + pthread_cond_init(&sync_cond,NULL); + pthread_mutex_init(&sync_mutex, NULL); + +#ifdef XFORMS + int UE_id; + + printf("XFORMS\n"); + + if (do_forms==1) { + fl_initialize (&argc, argv, NULL, 0, 0); + + form_stats = create_form_stats_form(); + fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats"); + UE_id = 0; + form_ue[UE_id] = create_lte_phy_scope_ue(); + sprintf (title, "LTE DL SCOPE UE"); + fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title); + + /* + if (openair_daq_vars.use_ia_receiver) { + fl_set_button(form_ue[UE_id]->button_0,1); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON"); + } else { + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + }*/ + fl_set_button(form_ue[UE_id]->button_0,0); + fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF"); + ret = pthread_create(&forms_thread, NULL, scope_thread, NULL); + + if (ret == 0) + pthread_setname_np( forms_thread, "xforms" ); + + printf("Scope thread created, ret=%d\n",ret); + } + +#endif + + rt_sleep_ns(10*100000000ULL); + + // start the main threads + int eMBMS_active = 0; + init_UE(1,eMBMS_active,uecap_xer_in,0); + + if (phy_test==0) { + printf("Filling UE band info\n"); + fill_ue_band_info(); + dl_phy_sync_success (0, 0, 0, 1); + } + + number_of_cards = 1; + for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + PHY_vars_UE_g[0][CC_id]->rf_map.card=0; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + } + + + + // connect the TX/RX buffers + + for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { + + +#ifdef OAI_USRP + UE[CC_id]->hw_timing_advance = timing_advance; +#else + UE[CC_id]->hw_timing_advance = 160; +#endif + } + if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) { + printf("Error setting up eNB buffer\n"); + exit(-1); + } + + + + if (input_fd) { + printf("Reading in from file to antenna buffer %d\n",0); + if (fread(UE[0]->common_vars.rxdata[0], + sizeof(int32_t), + frame_parms[0]->samples_per_tti*10, + input_fd) != frame_parms[0]->samples_per_tti*10) + printf("error reading from file\n"); + } + //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX; + + printf("Sending sync to all threads\n"); + + pthread_mutex_lock(&sync_mutex); + sync_var=0; + pthread_cond_broadcast(&sync_cond); + pthread_mutex_unlock(&sync_mutex); + printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); + end_configmodule(); + printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__); + + // wait for end of program + printf("TYPE <CTRL-C> TO TERMINATE\n"); + //getchar(); + +#if defined(ENABLE_ITTI) + printf("Entering ITTI signals handler\n"); + itti_wait_tasks_end(); + printf("Returned from ITTI signal handler\n"); + oai_exit=1; + printf("oai_exit=%d\n",oai_exit); +#else + + while (oai_exit==0) + rt_sleep_ns(100000000ULL); + printf("Terminating application - oai_exit=%d\n",oai_exit); + +#endif + + // stop threads +#ifdef XFORMS + printf("waiting for XFORMS thread\n"); + + if (do_forms==1) { + pthread_join(forms_thread,&status); + fl_hide_form(form_stats->stats_form); + fl_free_form(form_stats->stats_form); + fl_hide_form(form_ue[0]->lte_phy_scope_ue); + fl_free_form(form_ue[0]->lte_phy_scope_ue); + } + +#endif + + printf("stopping MODEM threads\n"); + + pthread_cond_destroy(&sync_cond); + pthread_mutex_destroy(&sync_mutex); + + pthread_mutex_destroy(&ue_pf_po_mutex); + + // *** Handle per CC_id openair0 + if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func) + PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice); + + if (ouput_vcd) + VCD_SIGNAL_DUMPER_CLOSE(); + + if (opt_enabled == 1) + terminate_opt(); + + logClean(); + + printf("Bye.\n"); + + return 0; +} diff --git a/targets/SIMU/USER/channel_sim.c b/targets/SIMU/USER/channel_sim.c index e2420a1c77e21ff051c5acfdd1342bc77de4b145..94bd1bbe43d2f3ee8bb02dc1ab18a246dfad9710 100644 --- a/targets/SIMU/USER/channel_sim.c +++ b/targets/SIMU/USER/channel_sim.c @@ -140,6 +140,7 @@ void do_DL_sig(channel_desc_t *RU2UE[NUMBER_OF_RU_MAX][NUMBER_OF_UE_MAX][MAX_NUM if (!hold_channel) { // calculate the random channel from each RU for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { + frame_parms = &RC.ru[ru_id]->frame_parms; random_channel(RU2UE[ru_id][UE_id][CC_id],abstraction_flag); /* diff --git a/targets/SIMU/USER/event_handler.c b/targets/SIMU/USER/event_handler.c index dbdce23df2ab4e568822a64476bb6d2396f7ac06..e840bde57b05bac5af860933c89291013cec4e4b 100644 --- a/targets/SIMU/USER/event_handler.c +++ b/targets/SIMU/USER/event_handler.c @@ -685,8 +685,8 @@ void update_mac(Event_t event) LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_sched_ctrl[event.ue].priority[event.lcid]); } } else if(!strcmp((char *) event.key, "DCI_aggregation_min") && event.value!=NULL && validate_mac(event)) { - Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); - mac_config = (Mac_config *) event.value; + //Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); + //mac_config = (Mac_config *) event.value; LOG_I(EMU,"DCI_aggregation_min update \n"); @@ -706,8 +706,8 @@ void update_mac(Event_t event) LOG_I(EMU,"%" PRIu8 "\n",UE_list->UE_template[0][event.ue].DCI_aggregation_min);*/ } } else if(!strcmp((char *) event.key, "DLSCH_dci_size_bits") && event.value!=NULL && validate_mac(event)) { - Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); - mac_config = (Mac_config *) event.value; + //Mac_config* mac_config;// = malloc(sizeof(Mac_config)*16); + //mac_config = (Mac_config *) event.value; LOG_I(EMU,"DLSCH_dci_size_bits update \n"); diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c index 3a282e1d44ecaf3158d57b03889780f2eafa417e..0008ba3bbde128740f20be36289ad2b419d018e9 100644 --- a/targets/SIMU/USER/oaisim.c +++ b/targets/SIMU/USER/oaisim.c @@ -216,7 +216,8 @@ oai_shutdown (void); void reset_opp_meas_oaisim (void); -void wait_eNBs() { +void wait_eNBs(void) +{ return; } @@ -364,7 +365,7 @@ static void set_cli_start(module_id_t module_idP, uint8_t start) #ifdef OPENAIR2 int omv_write(int pfd, node_list* enb_node_list, node_list* ue_node_list, Data_Flow_Unit omv_data) { - module_id_t i, j; + module_id_t i; omv_data.end = 0; //omv_data.total_num_nodes = NB_UE_INST + NB_eNB_INST; @@ -495,7 +496,7 @@ l2l1_task (void *args_p) #undef PRINT_STATS /* this undef is to avoid gcc warnings */ #define PRINT_STATS #ifdef PRINT_STATS - int len; + //int len; FILE *UE_stats[NUMBER_OF_UE_MAX]; FILE *UE_stats_th[NUMBER_OF_UE_MAX]; FILE *eNB_stats[NUMBER_OF_eNB_MAX]; @@ -621,7 +622,6 @@ l2l1_task (void *args_p) } #endif - module_id_t enb_id; module_id_t UE_id; if (abstraction_flag == 1) { @@ -769,11 +769,11 @@ l2l1_task (void *args_p) */ for (ru_id=0;ru_id<NB_RU;ru_id++) { current_ru_rx_timestamp[ru_id][CC_id] += RC.ru[ru_id]->frame_parms.samples_per_tti; - LOG_D(EMU,"RU %d/%d: TS %llu\n",ru_id,CC_id,current_ru_rx_timestamp[ru_id][CC_id]); + LOG_D(EMU,"RU %d/%d: TS %"PRIi64"\n",ru_id,CC_id,current_ru_rx_timestamp[ru_id][CC_id]); } for (UE_inst = 0; UE_inst<NB_UE_INST;UE_inst++) { current_UE_rx_timestamp[UE_inst][CC_id] += PHY_vars_UE_g[UE_inst][CC_id]->frame_parms.samples_per_tti; - LOG_D(EMU,"UE %d/%d: TS %llu\n",UE_id,CC_id,current_UE_rx_timestamp[UE_inst][CC_id]); + LOG_D(EMU,"UE %d/%d: TS %"PRIi64"\n",UE_inst,CC_id,current_UE_rx_timestamp[UE_inst][CC_id]); } for (eNB_inst = oai_emulation.info.first_enb_local; @@ -818,13 +818,14 @@ l2l1_task (void *args_p) } */ #ifdef OPENAIR2 - +/* if (eNB_l2_stats) { len = dump_eNB_l2_stats (stats_buffer, 0); rewind (eNB_l2_stats); fwrite (stats_buffer, 1, len, eNB_l2_stats); fflush(eNB_l2_stats); } +*/ #endif #endif @@ -1012,8 +1013,8 @@ int T_dont_fork = 0; /* default is to fork, see 'T_init' to understand */ #endif -void wait_RUs() { - +void wait_RUs(void) +{ int i; // wait for all RUs to be configured over fronthaul @@ -1083,9 +1084,9 @@ static void print_current_directory(void) printf("working directory: %s\n", dir); } -/*------------------------------------------------------------------------------*/ -int -main (int argc, char **argv) +void init_devices(void); + +int main (int argc, char **argv) { clock_t t; @@ -1103,7 +1104,6 @@ main (int argc, char **argv) int node_id; int port,Process_Flag=0,wgt,Channel_Flag=0,temp; #endif - int i; //default parameters oai_emulation.info.n_frames = MAX_FRAME_NUMBER; //1024; //10; @@ -1471,8 +1471,10 @@ print_opp_meas_oaisim (void) &oaisim_stats, &oaisim_stats_f); - print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx, - "[UE][total_phy_proc_rx]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0], + "[UE][total_phy_proc_rx[0]]", &oaisim_stats, &oaisim_stats_f); + print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[1], + "[UE][total_phy_proc_rx[1]]", &oaisim_stats, &oaisim_stats_f); // print_meas (&PHY_vars_UE_g[UE_id][0]->ofdm_demod_stats, // "[UE][ofdm_demod]", &oaisim_stats, &oaisim_stats_f); print_meas (&PHY_vars_UE_g[UE_id][0]->rx_dft_stats, "[UE][rx_dft]", @@ -1843,8 +1845,8 @@ get_OAI_emulation () // dummy function declarations -void *rrc_enb_task(void *args_p) { - - +void *rrc_enb_task(void *args_p) +{ + return NULL; } diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c index be8f66fb9336873e3b5bb311af3987cf4881e1f6..ceaae1958b9c08df2b57028dd7f54c4fa7fe79b5 100644 --- a/targets/SIMU/USER/oaisim_functions.c +++ b/targets/SIMU/USER/oaisim_functions.c @@ -868,7 +868,7 @@ void check_and_adjust_params(void) { int32_t ret; - int i,j; + //int i,j; if (oai_emulation.info.nb_ue_local + oai_emulation.info.nb_rn_local > NUMBER_OF_UE_MAX) { LOG_E(EMU,"Enter fewer than %d UEs/RNs for the moment or change the NUMBER_OF_UE_MAX\n", NUMBER_OF_UE_MAX); @@ -1081,7 +1081,7 @@ int ru_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** while (sample_count<nsamps) { while (current_ru_rx_timestamp[ru_id][CC_id]< (nsamps+last_ru_rx_timestamp[ru_id][CC_id])) { - LOG_D(EMU,"RU: current TS %llu, last TS %llu, sleeping\n",current_ru_rx_timestamp[ru_id][CC_id],last_ru_rx_timestamp[ru_id][CC_id]); + LOG_D(EMU,"RU: current TS %"PRIi64", last TS %"PRIi64", sleeping\n",current_ru_rx_timestamp[ru_id][CC_id],last_ru_rx_timestamp[ru_id][CC_id]); usleep(500); } @@ -1136,13 +1136,13 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** read_size = sptti; while (sample_count<nsamps) { - LOG_D(EMU,"UE %d: DL simulation 1: UE_trx_read : current TS now %llu, last TS %llu\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); + LOG_D(EMU,"UE %d: DL simulation 1: UE_trx_read : current TS now %"PRIi64", last TS %"PRIi64"\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); while (current_UE_rx_timestamp[UE_id][CC_id] < (last_UE_rx_timestamp[UE_id][CC_id]+read_size)) { - LOG_D(EMU,"UE %d: DL simulation 2: UE_trx_read : current TS %llu, last TS %llu, sleeping\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); + LOG_D(EMU,"UE %d: DL simulation 2: UE_trx_read : current TS %"PRIi64", last TS %"PRIi64", sleeping\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); usleep(500); } - LOG_D(EMU,"UE %d: DL simulation 3: UE_trx_read : current TS now %llu, last TS %llu\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); + LOG_D(EMU,"UE %d: DL simulation 3: UE_trx_read : current TS now %"PRIi64", last TS %"PRIi64"\n",UE_id,current_UE_rx_timestamp[UE_id][CC_id],last_UE_rx_timestamp[UE_id][CC_id]); // if we cross a subframe-boundary subframe = (last_UE_rx_timestamp[UE_id][CC_id]/sptti)%10; @@ -1174,10 +1174,10 @@ int UE_trx_read(openair0_device *device, openair0_timestamp *ptimestamp, void ** &PHY_vars_UE_g[UE_id][CC_id]->frame_parms, UE_id, CC_id); - LOG_D(EMU,"UE %d: DL simulation 6: UE_trx_read @ TS %llu (%llu)=> frame %d, subframe %d\n", - UE_id,(unsigned long long)current_UE_rx_timestamp[UE_id][CC_id], - (unsigned long long)last_UE_rx_timestamp[UE_id][CC_id], - ((unsigned long long)last_UE_rx_timestamp[UE_id][CC_id]/(sptti*10))&1023, + LOG_D(EMU,"UE %d: DL simulation 6: UE_trx_read @ TS %"PRIi64" (%"PRIi64")=> frame %d, subframe %d\n", + UE_id, current_UE_rx_timestamp[UE_id][CC_id], + last_UE_rx_timestamp[UE_id][CC_id], + (int)((last_UE_rx_timestamp[UE_id][CC_id]/(sptti*10))&1023), subframe); last_UE_rx_timestamp[UE_id][CC_id] += read_size; @@ -1367,9 +1367,11 @@ void init_ocm(void) /* Added for PHY abstraction */ - char* frame_type = "unknown"; + /* TODO: frame_type is unused, is it intended? */ + //char* frame_type = "unknown"; LTE_DL_FRAME_PARMS *fp = &RC.ru[0]->frame_parms; +#if 0 switch (fp->frame_type) { case FDD: frame_type = "FDD"; @@ -1379,6 +1381,7 @@ void init_ocm(void) frame_type = "TDD"; break; } +#endif if (abstraction_flag) {