diff --git a/CMakeLists.txt b/CMakeLists.txt index 631de36ea60cf85fe542bbf9ede87d0619f6ccf7..69c8eeaa242c2d563cfae91275b88b1fb4f3dad4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1774,6 +1774,7 @@ add_library (GTPV1U ${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp ) target_link_libraries(GTPV1U PRIVATE asn1_nr_rrc asn1_lte_rrc) +target_link_libraries(GTPV1U PRIVATE SIMU) include_directories(${OPENAIR3_DIR}/ocp-gtp) set (MME_APP_SRC @@ -2120,13 +2121,6 @@ add_library(LIB_5GNAS_GNB target_link_libraries(LIB_5GNAS_GNB PRIVATE SECU_CN ${CRYPTO_LIBRARIES}) target_link_libraries(LIB_5GNAS_GNB PRIVATE asn1_nr_rrc asn1_lte_rrc) -add_library(SIMU_COMMON - ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/phase_noise.c - ) -target_link_libraries(SIMU_COMMON PRIVATE asn1_nr_rrc asn1_lte_rrc) - # Simulation library ########################## set (SIMUSRC @@ -2135,15 +2129,15 @@ set (SIMUSRC ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_tv_channel.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/abstraction.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c + ${OPENAIR1_DIR}/SIMULATION/TOOLS/phase_noise.c ${OPENAIR1_DIR}/SIMULATION/RF/rf.c ${OPENAIR1_DIR}/SIMULATION/RF/dac.c ${OPENAIR1_DIR}/SIMULATION/RF/adc.c - #${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ) - -# Simulation library -########################## -add_library(SIMU SHARED ${SIMUSRC} ) +) +add_library(SIMU STATIC ${SIMUSRC} ) +target_include_directories(SIMU PUBLIC ${OPENAIR1_DIR}/SIMULATION/TOOLS ${OPENAIR1_DIR}/SIMULATION/RF) target_link_libraries(SIMU PRIVATE asn1_nr_rrc asn1_lte_rrc) add_library(SIMU_ETH @@ -2201,7 +2195,7 @@ add_library(rfsimulator MODULE ${OPENAIR_DIR}/radio/rfsimulator/apply_channelmod.c ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c ) -target_link_libraries(rfsimulator PRIVATE SIMU_COMMON ${ATLAS_LIBRARIES}) +target_link_libraries(rfsimulator PRIVATE SIMU ${ATLAS_LIBRARIES}) target_link_libraries(rfsimulator PRIVATE asn1_nr_rrc asn1_lte_rrc) add_library(oai_iqplayer MODULE @@ -2290,7 +2284,6 @@ add_executable(lte-softmodem ${OPENAIR_DIR}/executables/lte-softmodem.c ${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_DIR}/executables/create_tasks.c ${OPENAIR_DIR}/executables/create_tasks_mbms.c ${OPENAIR_DIR}/radio/COMMON/common_lib.c @@ -2315,7 +2308,7 @@ target_link_libraries(lte-softmodem PRIVATE -Wl,--start-group lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U f1ap SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB - ${RAL_LIB} ${NAS_UE_LIB} ITTI + ${RAL_LIB} ${NAS_UE_LIB} ITTI SIMU -Wl,--end-group z dl) target_link_libraries(lte-softmodem PRIVATE ${LIBXML2_LIBRARIES}) @@ -2331,7 +2324,6 @@ add_executable(ocp-enb ${OPENAIR_DIR}/executables/main-fs6.c ${OPENAIR_DIR}/executables/transport_split.c ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_DIR}/executables/create_tasks.c ${OPENAIR_DIR}/executables/create_tasks_mbms.c ${OPENAIR_DIR}/radio/COMMON/common_lib.c @@ -2354,7 +2346,7 @@ add_dependencies(ocp-enb oai_iqplayer coding params_libconfig rfsimulator) target_link_libraries (ocp-enb -Wl,--start-group lte_rrc nr_rrc s1ap f1ap m2ap x2ap m3ap GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB - PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU_COMMON + PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU ${RAL_LIB} ${NAS_UE_LIB} ITTI -Wl,--end-group z dl) target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${CMAKE_DL_LIBS} ${LIB_LMS_LIBRARIES} ${T_LIB}) @@ -2415,7 +2407,7 @@ target_link_libraries(lte-uesoftmodem PRIVATE -Wl,--start-group lte_rrc nr_rrc s1ap x2ap m2ap m3ap SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON - PHY_UE PHY_RU L2_UE L2_LTE SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB + PHY_UE PHY_RU L2_UE L2_LTE SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB ${RAL_LIB} ${NAS_UE_LIB} ITTI ${ATLAS_LIBRARIES} -Wl,--end-group z dl) @@ -2441,7 +2433,6 @@ add_executable(nr-softmodem ${OPENAIR_DIR}/executables/nr-ru.c ${OPENAIR_DIR}/executables/nr-softmodem.c ${OPENAIR_DIR}/executables/softmodem-common.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_DIR}/radio/COMMON/common_lib.c ${OPENAIR_DIR}/radio/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c @@ -2460,12 +2451,12 @@ target_link_libraries(nr-softmodem PRIVATE -Wl,--start-group UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA ITTI ${RAL_LIB} ${NAS_UE_LIB} lte_rrc nr_rrc - ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB + ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU x2ap f1ap m2ap m3ap -Wl,--end-group z dl) target_link_libraries(nr-softmodem PRIVATE ${LIBXML2_LIBRARIES}) -target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES}) +target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES}) target_link_libraries(nr-softmodem PRIVATE ${LIB_LMS_LIBRARIES}) target_link_libraries(nr-softmodem PRIVATE ${T_LIB}) target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2490,7 +2481,6 @@ add_executable(nr-uesoftmodem ${OPENAIR_DIR}/executables/nr-uesoftmodem.c ${OPENAIR_DIR}/executables/nr-ue.c ${OPENAIR_DIR}/executables/softmodem-common.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_DIR}/radio/COMMON/common_lib.c ${OPENAIR_DIR}/radio/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c @@ -2509,7 +2499,7 @@ target_link_libraries(nr-uesoftmodem PRIVATE nr_rrc SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB PHY_COMMON PHY_NR_COMMON PHY_NR_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_NR_LIB - ${RAL_LIB} ITTI ${ATLAS_LIBRARIES} LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB} + ${RAL_LIB} ITTI ${ATLAS_LIBRARIES} LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB} SIMU -Wl,--end-group z dl) target_link_libraries(nr-uesoftmodem PRIVATE ${LIBXML2_LIBRARIES}) @@ -2543,7 +2533,7 @@ add_executable(dlsim_tm4 ${T_SOURCE} ) target_link_libraries (dlsim_tm4 - -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY ITTI -Wl,--end-group + -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY ITTI -Wl,--end-group pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES} ${T_LIB} ) @@ -2563,7 +2553,7 @@ add_executable(polartest ${SHLIB_LOADER_SOURCES} ) target_link_libraries(polartest PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl ) target_link_libraries(polartest PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2576,7 +2566,7 @@ add_executable(smallblocktest ) target_link_libraries(smallblocktest PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl ) target_link_libraries(smallblocktest PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2594,7 +2584,7 @@ if (CUDA_FOUND) add_dependencies( ldpctest ldpc_cuda) endif (CUDA_FOUND) target_link_libraries(ldpctest PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} dl ) target_link_libraries(ldpctest PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2607,7 +2597,7 @@ add_executable(nr_dlschsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlschsim PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl ) target_link_libraries(nr_dlschsim PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2619,7 +2609,7 @@ add_executable(nr_pbchsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_pbchsim PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl ) target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2634,7 +2624,7 @@ add_executable(nr_pucchsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_pucchsim PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl ) target_link_libraries(nr_pucchsim PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2652,7 +2642,7 @@ add_executable(nr_dlsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_dlsim PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2670,7 +2660,7 @@ add_executable(nr_prachsim ${T_SOURCE} ${SHLIB_LOADER_SOURCES}) target_link_libraries(nr_prachsim PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl) target_link_libraries(nr_prachsim PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2683,7 +2673,7 @@ add_executable(nr_ulschsim ${SHLIB_LOADER_SOURCES} ) target_link_libraries(nr_ulschsim PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl ) target_link_libraries(nr_ulschsim PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2706,7 +2696,7 @@ add_dependencies( nr_ulsim ldpc_offload) endif () target_link_libraries(nr_ulsim PRIVATE - -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl ) target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR) @@ -2725,7 +2715,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr ${NFAPI_USER_DIR}/nfapi.c ) target_link_libraries (${myExe} PRIVATE - -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU ITTI -Wl,--end-group + -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU ITTI -Wl,--end-group pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl ) target_link_libraries(${myExe} PRIVATE asn1_nr_rrc asn1_lte_rrc) @@ -2773,7 +2763,7 @@ if (${T_TRACER}) NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR ngap - CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB + CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU SIMU_ETH OPENAIR0_LIB ldpc_orig ldpc_optim ldpc_optim8seg ldpc dfts) if (TARGET ${i}) add_dependencies(${i} generate_T) diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml index 468005f54f677f8208ded94f278a67a7088e746e..8a6c67fa34b8aeaf4dd5adfeab7443f123641537 100644 --- a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml +++ b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml @@ -54,7 +54,7 @@ <testCase id="040000"> <class>Initialize_eNB</class> <desc>Initialize gNB</desc> - <Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf --sa --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args> + <Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf --sa --usrp-tx-thread-config 1 --tune-offset 30000000 --thread-pool 1,3,5,7,9,11,13,15 --gNBs.[0].min_rxtxtime 5 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args> <eNB_instance>0</eNB_instance> <eNB_serverId>0</eNB_serverId> <air_interface>nr</air_interface> diff --git a/cmake_targets/autotests/run_exec_autotests.bash b/cmake_targets/autotests/run_exec_autotests.bash index 2bb42f3d4dda3749e2a86a3e2a36d4392f90ab8c..0b8c86795e0449dbff7d55c6f5ee334ba43418b4 100755 --- a/cmake_targets/autotests/run_exec_autotests.bash +++ b/cmake_targets/autotests/run_exec_autotests.bash @@ -114,6 +114,7 @@ function test_run() { for (( run_index=1; run_index <= $nruns; run_index++ )) do + temp_exec_log="$log_dir/test.$test_case_name.${tags_array[$tags_array_index]}.run_$run_index" echo "</EXECUTION LOG Test Case = $test_case_name.${tags_array[$tags_array_index]}, Run = $run_index >" >> $temp_exec_log 2>&1 cat "$temp_exec_log" >> "$log_file" 2>&1 diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index bce610b560129176653a6c306e05fb31d5e03258..48770b752621d095dfc72a0309cd7fb43c58152c 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -440,30 +440,30 @@ (Test23: 3GPP G-FR1-A5-14, PUSCH Type B, 100 MHz BW, 30 kHz SCS, 4 RX Antennas Requirements Test), (Test24: 3GPP G-FR1-A5-14, PUSCH Type B, 100 MHz BW, 30 kHz SCS, 8 RX Antennas Requirements Test)</desc> <main_exec>nr_ulsim</main_exec> - <main_exec_args>-n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z2 -s12.4 -S12.4 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z4 -s8.5 -S8.5 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z8 -s5.4 -S5.4 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z2 -s12.5 -S12.5 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z4 -s8.9 -S8.9 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z8 -s5.7 -S5.7 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z2 -s12.6 -S12.6 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z4 -s8.9 -S8.9 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z8 -s5.8 -S5.8 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.3 -S12.3 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.8 -S8.8 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.7 -S5.7 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z2 -s12.5 -S12.5 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z4 -s8.6 -S8.6 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z8 -s5.6 -S5.6 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z2 -s12.5 -S12.5 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z4 -s8.6 -S8.6 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z8 -s5.6 -S5.6 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.5 -S12.5 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.7 -S8.7 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.5 -S5.5 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z2 -s13.1 -S13.1 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z4 -s9.2 -S9.2 - -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z8 -s5.9 -S5.9</main_exec_args> + <main_exec_args>-n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z2 -s12.4 -S12.4 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z4 -s8.5 -S8.5 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z8 -s5.4 -S5.4 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z2 -s12.5 -S12.5 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z4 -s8.9 -S8.9 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z8 -s5.7 -S5.7 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z2 -s12.6 -S12.6 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z4 -s8.9 -S8.9 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z8 -s5.8 -S5.8 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.3 -S12.3 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.8 -S8.8 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.7 -S5.7 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z2 -s12.5 -S12.5 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z4 -s8.6 -S8.6 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z8 -s5.6 -S5.6 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z2 -s12.5 -S12.5 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z4 -s8.6 -S8.6 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z8 -s5.6 -S5.6 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.5 -S12.5 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.7 -S8.7 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.5 -S5.5 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z2 -s13.1 -S13.1 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z4 -s9.2 -S9.2 + -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z8 -s5.9 -S5.9</main_exec_args> <tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 test22 test23 test24</tags> <search_expr_true>PUSCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> diff --git a/common/openairinterface5g_limits.h b/common/openairinterface5g_limits.h index f420722350f8163fd2bce6a23e696e04ce258c2e..2349941cf232324aaf7cdc951038d1dca167261a 100644 --- a/common/openairinterface5g_limits.h +++ b/common/openairinterface5g_limits.h @@ -27,7 +27,6 @@ # ifndef PHYSIM # ifndef UE_EXPANSION # define NUMBER_OF_UE_MAX 40 -# define NUMBER_OF_NR_UE_MAX 4 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 # else @@ -37,7 +36,6 @@ # endif # else # define NUMBER_OF_UE_MAX 4 -# define NUMBER_OF_NR_UE_MAX 4 # define NUMBER_OF_CONNECTED_eNB_MAX 1 # define NUMBER_OF_CONNECTED_gNB_MAX 1 # endif diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index d8398def67b745a2131f4cdb48bed6d3a7172499..1dcafd47517e23629d552221da0849205cb3181b 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -227,7 +227,8 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) { *n_rb = 6*count; } -int get_nb_periods_per_frame(uint8_t tdd_period) { +int get_nb_periods_per_frame(uint8_t tdd_period) +{ int nb_periods_per_frame; switch(tdd_period) { @@ -270,7 +271,13 @@ int get_nb_periods_per_frame(uint8_t tdd_period) { } -int get_dmrs_port(int nl, uint16_t dmrs_ports) { +int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols) +{ + return (nrofDownlinkSlots + (nrofDownlinkSymbols != 0 && nrofUplinkSymbols == 0)); +} + +int get_dmrs_port(int nl, uint16_t dmrs_ports) +{ if (dmrs_ports == 0) return 0; // dci 1_0 int p = -1; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 893dcba7015c9e9494d9cade913ea0aa7ac03c49..8cd210dec8acdf36d6863e42b59e1280e1fbd500 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -63,6 +63,7 @@ static inline int get_num_dmrs(uint16_t dmrs_mask ) { return(num_dmrs); } +int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols); int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs); int get_SLIV(uint8_t S, uint8_t L); void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset); diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index e69c8328bc11a629e93be003b772f358a028b442..3f7ffc9fdb24bba9dd800ab9876d4e7b4349b3a6 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -357,7 +357,8 @@ The following features are valid for the gNB and the 5G-NR UE. - RRCSetupRequest/RRCSetup/RRCSetupComplete - RRC Uplink/Downlink Information transfer carrying NAS messages transparently - RRC Reconfiguration/Reconfiguration complete - - Support for master cell group configuration + - Paging + - Support for master cell group configuration - Interface with NGAP for the interactions with the AMF - Interface with F1AP for CU/DU split deployment option - Periodic RRC measurements of serving cell (no A/B events) diff --git a/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md index fccab23cf829463ec5a71b9ff85405f7ebd8d834..8d82b1964f464fc39eea5dd2ec66e2af4008db1c 100644 --- a/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md +++ b/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md @@ -17,7 +17,7 @@ [[_TOC_]] # 1. Scenario -In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB, OAI UE and COTS UE. +In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB, OAI nrUE and COTS UE. Minimum hardware requirements: - Laptop/Desktop/Server for OAI CN5G and OAI gNB @@ -233,13 +233,14 @@ iperf -s -u -i 1 -B 12.1.1.2 docker exec -it oai-ext-dn iperf -u -t 86400 -i 1 -fk -B 192.168.70.135 -b 100M -c 12.1.1.2 ``` -## 5.2 Testing with OAI UE -### 5.2.1 Testing with OAI UE with USRP B210 +## 5.2 Testing with OAI nrUE +### 5.2.1 Testing with OAI nrUE with USRP B210 Important notes: - This should be run in a second Ubuntu 20.04 host, other than gNB - It only applies when running OAI gNB with USRP B210 +- OAI gNB must run with the following flag: `--gNBs.[0].min_rxtxtime 6` -Run OAI UE +Run OAI nrUE ```bash cd ~/openairinterface5g source oaienv @@ -247,12 +248,12 @@ cd cmake_targets/ran_build/build sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --nokrnmod --ue-fo-compensation --sa -E --uicc0.imsi 001010000000001 --uicc0.nssai_sd 1 ``` -### 5.2.2 Testing with OAI UE with RFsimulator +### 5.2.2 Testing with OAI nrUE with RFsimulator Important notes: - This should be run on the same host as the OAI gNB - It only applies when running OAI gNB with RFsimulator -Run OAI UE with RFsimulator +Run OAI nrUE with RFsimulator ```bash cd ~/openairinterface5g source oaienv @@ -291,6 +292,8 @@ sudo ethtool -G enp1s0f0 tx 4096 rx 4096 ``` ## 6.2 Real-time performance workarounds +- Enable Performance Mode in Ubuntu 22: + - Settings/Power/Power Mode: Performance - If you get real-time problems on heavy UL traffic, reduce the maximum UL MCS using an additional command-line switch: `--MACRLCs.[0].ul_max_mcs 14`. ## 6.3 Uplink issues related with noise on the DC carriers diff --git a/doc/nr-ue-design.md b/doc/nr-ue-design.md new file mode 100644 index 0000000000000000000000000000000000000000..32abe6bd80f1b908c78f88d89d247653798cbab7 --- /dev/null +++ b/doc/nr-ue-design.md @@ -0,0 +1,34 @@ +# PHY and MAC Interface +The PHY sends scheduling requests and data indication to MAC via `nr_ue_dl_indication` for DL path and `nr_ue_ul_indication()` for UL path and the MAC sends scheduling configuration to PHY via `nr_ue_scheduled_response()`. The following diagram shows the interaction for PDCCH and PDSCH reception. +```mermaid +sequenceDiagram + PHY->>+MAC: Requests for PDCCH config (via nr_ue_dl_indication) + MAC->>+PHY: Schedules PDCCH reception (via nr_ue_scheduled_response) + PHY->>+MAC: Indicates decoded DCI(s) (via nr_ue_dl_indication) + MAC->>+PHY: Schedules PDSCH reception (via nr_ue_scheduled_response) +``` + +# Multi-threading Design +The `UE_thread` function in `nr-ue.c` is the main top level thread that interacts with the radio unit. Once the thread spawns, it starts the 'Initial Synchronization'. Once its complete, the regular processing of slots commences. + +The UE exits when at any point in operation it gets out of synchronization. When the command line option `--non-stop` is used, the UE goes to 'Initial Synchronization' mode when it loses synchronization with gNB. However, this feature is not fully implemented and it is a work in progress at the time of writing this documentation. This will be the default behavior (not a command line option) when the feature is fully implemented. + +## Initial Synchronization Block +```mermaid +graph TD + A(Start) -->|UE_thread| B["readFrame<br/>--Reads samples worth 2 frames"] + B --> |Tpool thread| C["UE_synch<br/>--PSS & SSS detection<br/>--PBCH decode"] + B --> |UE_thread| D["readFrame<br/>--trash samples to unblock radio"] + C --> |Tpool thread| E[syncInFrame<br/>--shift first sample to start of frame] + D --> |UE_thread| E +``` +## Regular Slot Processing +```mermaid +graph TD + E[syncInFrame<br/>--shift first sample to start of frame] -->|UE_thread| F["trx_read_func (slot n)"] + F --> |Tpool thread| G["processSlotTX (slot n+4)<br/>--PUSCH encode<br/>--PUCCH encode<br/>--trx_write_func"] + F --> |UE_thread| H["UE_processing (slot n)<br/>--PDCCH decode<br/>--PDSCH decode"] + G --> |Tpool thread| I(Merge) + H --> |UE_thread| I(Merge) + I --> |Go to next slot<br/>UE_thread| F +``` diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2 index 701e65c8caf6df6164f66761266598a31f1e9d7d..de4a315ce4b934c37dcc1375ec59698fdc130413 100644 --- a/docker/Dockerfile.lteUE.rhel8.2 +++ b/docker/Dockerfile.lteUE.rhel8.2 @@ -70,7 +70,6 @@ COPY --from=lte-ue-build \ /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ - /oai-ran/cmake_targets/ran_build/build/libSIMU.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18 index e070ba20aff222337519aa77f53478a353bce3bb..7f1b30c2c73c60de6951763d14e06a4d22666bee 100644 --- a/docker/Dockerfile.lteUE.ubuntu18 +++ b/docker/Dockerfile.lteUE.ubuntu18 @@ -76,7 +76,6 @@ COPY --from=lte-ue-build \ /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \ /oai-ran/cmake_targets/ran_build/build/libcoding.so \ /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \ - /oai-ran/cmake_targets/ran_build/build/libSIMU.so \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \ /usr/local/lib/ diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2 index ba044d6203d305e63f79c30322496ba847e51662..c3f6d258b3df398a4753b2eb1af341f6294253e8 100644 --- a/docker/Dockerfile.phySim.rhel8.2 +++ b/docker/Dockerfile.phySim.rhel8.2 @@ -89,7 +89,6 @@ COPY --from=phy-sim-build \ /lib64/libxslt.so.1 \ /usr/lib64/libasan.so.5 \ /oai-ran/cmake_targets/ran_build/build/libdfts.so \ - /oai-ran/cmake_targets/ran_build/build/libSIMU.so \ /oai-ran/cmake_targets/ran_build/build/libldpc.so \ /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \ /usr/local/lib/ diff --git a/executables/docs/nr-ue-design.md b/executables/docs/nr-ue-design.md deleted file mode 100644 index 0b0b940d5fa2d4cca79e5204287a43a94df84150..0000000000000000000000000000000000000000 --- a/executables/docs/nr-ue-design.md +++ /dev/null @@ -1,22 +0,0 @@ -# Multi-threading Design -The `UE_thread` function in `nr-ue.c` is the main top level thread that interacts with the radio unit. Once the thread spawns, it starts the 'Initial Syncronization'. Once its complete, the regular processing of slots commences. - -## Initial Syncronization Block -```mermaid -graph TD - A(Start) -->|UE_thread| B["readFrame<br/>--Reads samples worth 2 frames"] - B --> |Tpool thread| C["UE_synch<br/>--PSS & SSS detection<br/>--PBCH decode"] - B --> |UE_thread| D["readFrame<br/>--trash samples to unblock radio"] - C --> |Tpool thread| E[syncInFrame<br/>--shift first sample to start of frame] - D --> |UE_thread| E -``` -## Regular Slot Processing -```mermaid -graph TD - E[syncInFrame<br/>--shift first sample to start of frame] -->|UE_thread| F["trx_read_func (slot n)"] - F --> |Tpool thread| G["processSlotTX (slot n+4)<br/>--PUSCH encode<br/>--PUCCH encode<br/>--trx_write_func"] - F --> |UE_thread| H["UE_processing (slot n)<br/>--PDCCH decode<br/>--PDSCH decode"] - G --> |Tpool thread| I(Merge) - H --> |UE_thread| I(Merge) - I --> |Go to next slot<br/>UE_thread| F -``` diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 2e0dde6c675c2035a0a83d7fc5ad41d272a2dd39..cd64a6628734814888d98d3a6653869d8e2a667a 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -31,8 +31,6 @@ #include "SCHED_NR_UE/defs.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "executables/softmodem-common.h" -#include "LAYER2/nr_pdcp/nr_pdcp_entity.h" -#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h" #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "radio/COMMON/common_lib.h" @@ -103,8 +101,6 @@ typedef enum { si = 2 } sync_mode_t; -queue_t nr_rach_ind_queue; - static void *NRUE_phy_stub_standalone_pnf_task(void *arg); static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len) @@ -154,17 +150,13 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t abstraction_flag) { - int nb_connected_gNB = 1, gNB_id; + int nb_connected_gNB = 1; ue->Mod_id = UE_id; ue->mac_enabled = 1; ue->if_inst = nr_ue_if_module_init(0); ue->dci_thres = 0; - // Setting UE mode to NOT_SYNCHED by default - for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++) - ue->UE_mode[gNB_id] = NOT_SYNCHED; - // initialize all signal buffers init_nr_ue_signal(ue, nb_connected_gNB); @@ -196,47 +188,6 @@ void init_nrUE_standalone_thread(int ue_idx) pthread_setname_np(phy_thread, "oai:nrue-stand-phy"); } -static void L1_nsa_prach_procedures(frame_t frame, int slot, fapi_nr_ul_config_prach_pdu *prach_pdu) -{ - NR_UE_MAC_INST_t *mac = get_mac_inst(0); - nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind)); - rach_ind->sfn = frame; - rach_ind->slot = slot; - rach_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION; - - uint8_t pdu_index = 0; - rach_ind->pdu_list = CALLOC(1, sizeof(*rach_ind->pdu_list)); - rach_ind->number_of_pdus = 1; - rach_ind->pdu_list[pdu_index].phy_cell_id = prach_pdu->phys_cell_id; - rach_ind->pdu_list[pdu_index].symbol_index = prach_pdu->prach_start_symbol; - rach_ind->pdu_list[pdu_index].slot_index = prach_pdu->prach_slot; - rach_ind->pdu_list[pdu_index].freq_index = prach_pdu->num_ra; - rach_ind->pdu_list[pdu_index].avg_rssi = 128; - rach_ind->pdu_list[pdu_index].avg_snr = 0xff; // invalid for now - - rach_ind->pdu_list[pdu_index].num_preamble = 1; - const int num_p = rach_ind->pdu_list[pdu_index].num_preamble; - rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t)); - uint8_t preamble_index = get_softmodem_params()->nsa ? - mac->ra.rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[0]->ra_PreambleIndex : - mac->ra.ra_PreambleIndex; - rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index = preamble_index; - - rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance = 0; - rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; - - if (!put_queue(&nr_rach_ind_queue, rach_ind)) - { - for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++) - { - free(rach_ind->pdu_list[pdu_index].preamble_list); - } - free(rach_ind->pdu_list); - free(rach_ind); - } - LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n"); -} - static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) { nfapi_nr_rach_indication_t *rach_ind = unqueue_matching(&nr_rach_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot); @@ -248,14 +199,12 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot), NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot), nr_ul_tti_req_queue.num_items); nfapi_nr_ul_tti_request_t *ul_tti_request_crc = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot); - if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0) - { + if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0) { check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc); } } - if (rach_ind && rach_ind->number_of_pdus > 0) - { + if (rach_ind && rach_ind->number_of_pdus > 0) { NR_UL_IND_t UL_INFO = { .rach_ind = *rach_ind, }; @@ -266,74 +215,32 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) } free_and_zero(rach_ind->pdu_list); free_and_zero(rach_ind); - nr_Msg1_transmitted(0); } - if (dl_tti_request) - { + if (dl_tti_request) { int dl_tti_sfn_slot = NFAPI_SFNSLOT2HEX(dl_tti_request->SFN, dl_tti_request->Slot); nfapi_nr_tx_data_request_t *tx_data_request = unqueue_matching(&nr_tx_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &dl_tti_sfn_slot); - if (!tx_data_request) - { + if (!tx_data_request) { LOG_E(NR_MAC, "[%d %d] No corresponding tx_data_request for given dl_tti_request sfn/slot\n", NFAPI_SFNSLOT2SFN(dl_tti_sfn_slot), NFAPI_SFNSLOT2SLOT(dl_tti_sfn_slot)); if (get_softmodem_params()->nsa) save_nr_measurement_info(dl_tti_request); free_and_zero(dl_tti_request); } - else if (dl_tti_request->dl_tti_request_body.nPDUs > 0 && tx_data_request->Number_of_PDUs > 0) - { + else if (dl_tti_request->dl_tti_request_body.nPDUs > 0 && tx_data_request->Number_of_PDUs > 0) { if (get_softmodem_params()->nsa) save_nr_measurement_info(dl_tti_request); check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL); } - else - { + else { AssertFatal(false, "We dont have PDUs in either dl_tti %d or tx_req %d\n", dl_tti_request->dl_tti_request_body.nPDUs, tx_data_request->Number_of_PDUs); } } - if (ul_dci_request && ul_dci_request->numPdus > 0) - { + if (ul_dci_request && ul_dci_request->numPdus > 0) { check_and_process_dci(NULL, NULL, ul_dci_request, NULL); } } -static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) -{ - fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx); - if (!ul_config) - { - LOG_E(NR_MAC, "mac->ul_config is null! \n"); - return; - } - if (mac->ra.ra_state != RA_SUCCEEDED) - { - AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), - "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); - fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; - uint8_t nr_prach = nr_ue_get_rach(prach_pdu, - ul_info->module_id, - ul_info->cc_id, - ul_info->frame_tx, - ul_info->gNB_index, - ul_info->slot_tx); - if (nr_prach == 1) - { - L1_nsa_prach_procedures(ul_info->frame_tx, ul_info->slot_tx, prach_pdu); - ul_config->number_pdus = 0; - ul_info->ue_sched_mode = SCHED_PUSCH; - } - else if (nr_prach == 2) - { - LOG_I(NR_PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, ul_info->module_id); - } - else if(nr_prach == 3) - { - LOG_I(NR_PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, ul_info->module_id); - } - } -} - static void *NRUE_phy_stub_standalone_pnf_task(void *arg) { LOG_I(MAC, "Clearing Queues\n"); @@ -358,17 +265,14 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot = -1; } - while (!oai_exit) - { - if (sem_wait(&sfn_slot_semaphore) != 0) - { + while (!oai_exit) { + if (sem_wait(&sfn_slot_semaphore) != 0) { LOG_E(NR_MAC, "sem_wait() error\n"); abort(); } uint16_t *slot_ind = get_queue(&nr_sfn_slot_queue); nr_phy_channel_params_t *ch_info = get_queue(&nr_chan_param_queue); - if (!slot_ind && !ch_info) - { + if (!slot_ind && !ch_info) { LOG_D(MAC, "get nr_sfn_slot_queue and nr_chan_param_queue == NULL!\n"); continue; } @@ -383,8 +287,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) frame_t frame = NFAPI_SFNSLOT2SFN(sfn_slot); int slot = NFAPI_SFNSLOT2SLOT(sfn_slot); - if (sfn_slot == last_sfn_slot) - { + if (sfn_slot == last_sfn_slot) { LOG_D(NR_MAC, "repeated sfn_sf = %d.%d\n", frame, slot); continue; @@ -394,19 +297,16 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) LOG_D(NR_MAC, "The received sfn/slot [%d %d] from proxy\n", frame, slot); - if (get_softmodem_params()->sa && mac->mib == NULL) - { + if (get_softmodem_params()->sa && mac->mib == NULL) { LOG_D(NR_MAC, "We haven't gotten MIB. Lets see if we received it\n"); nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); process_queued_nr_nfapi_msgs(mac, sfn_slot); } - if (mac->scc == NULL && mac->scc_SIB == NULL) - { + if (mac->scc == NULL && mac->scc_SIB == NULL) { LOG_D(MAC, "[NSA] mac->scc == NULL and [SA] mac->scc_SIB == NULL!\n"); continue; } - mac->ra.generate_nr_prach = 0; int CC_id = 0; uint8_t gNB_id = 0; nr_uplink_indication_t ul_info; @@ -419,7 +319,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) ul_info.slot_rx = slot; ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame; ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx; - ul_info.ue_sched_mode = SCHED_PUSCH; if (pthread_mutex_lock(&mac->mutex_dl_info)) abort(); @@ -441,8 +340,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) if (is_nr_DL_slot(get_softmodem_params()->nsa ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, - ul_info.slot_rx)) - { + ul_info.slot_rx)) { nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment); } @@ -451,13 +349,11 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) if (is_nr_UL_slot(get_softmodem_params()->nsa ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, - ul_info.slot_tx, mac->frame_type)) - { + ul_info.slot_tx, mac->frame_type)) { LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() and nr_ue_pucch_scheduler() from %s\n", ul_info.slot_tx, __FUNCTION__); nr_ue_scheduler(NULL, &ul_info); nr_ue_prach_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx); nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, NULL); - check_nr_prach(mac, &ul_info); } if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) { NR_UE_MAC_INST_t *mac = get_mac_inst(0); @@ -682,14 +578,13 @@ void processSlotTX(void *arg) { ul_indication.slot_rx = proc->nr_slot_rx; ul_indication.frame_tx = proc->frame_tx; ul_indication.slot_tx = proc->nr_slot_tx; - ul_indication.ue_sched_mode = rxtxD->ue_sched_mode; ul_indication.phy_data = &phy_data; UE->if_inst->ul_indication(&ul_indication); stop_meas(&UE->ue_ul_indication_stats); } - phy_procedures_nrUE_TX(UE, proc, proc->gNB_id, &phy_data); + phy_procedures_nrUE_TX(UE, proc, &phy_data); } RU_write(rxtxD); @@ -699,7 +594,6 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) { UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; - uint8_t gNB_id = 0; nr_phy_data_t phy_data = {0}; if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) { @@ -716,7 +610,7 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) { if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) { nr_downlink_indication_t dl_indication; - nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id, &phy_data); + nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, &phy_data); UE->if_inst->dl_indication(&dl_indication, NULL); } @@ -725,7 +619,7 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) { phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL ); #else uint64_t a=rdtsc_oai(); - phy_procedures_nrUE_RX(UE, proc, gNB_id, &phy_data); + phy_procedures_nrUE_RX(UE, proc, &phy_data); LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500); #endif diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 091fc813e912ed5c699c7fc72473f73289edb3c1..21710940d6c9cce797cbc9a03d32e0361258ccd8 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -189,8 +189,6 @@ typedef struct { uint8_t restricted_set; /// see TS 38.211 (6.3.3.2). uint16_t freq_msg1; - // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble - uint8_t ssb_nb_in_ro; /// Preamble index for PRACH (0-63) uint8_t ra_PreambleIndex; /// PRACH TX power (TODO possibly modify to uint) diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 08d47bad0bf32d7c637efc5fd35c0dd33fe97893..ac7d1ceed926585822dfe55a3615d0ce94d3d9ee 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -39,104 +39,6 @@ extern uint16_t beta_cqi[16]; -/*! \brief Helper function to allocate memory for DLSCH data structures. - * \param[out] pdsch Pointer to the LTE_UE_PDSCH structure to initialize. - * \param[in] frame_parms LTE_DL_FRAME_PARMS structure. - * \note This function is optimistic in that it expects malloc() to succeed. - */ -void phy_init_nr_ue_PDSCH(NR_UE_PDSCH *const pdsch, - const NR_DL_FRAME_PARMS *const fp) { - - AssertFatal( pdsch, "pdsch==0" ); - - pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) ); - // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV - // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there - pdsch->rxdataF_ext = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->rxdataF_uespec_pilots = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->rxdataF_comp0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->rho = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t **) ); - pdsch->dl_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_mag0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_magb0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->dl_ch_magr0 = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->ptrs_phase_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - pdsch->ptrs_re_per_slot = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) ); - // the allocated memory size is fixed: - AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4 - - const size_t num = 7*2*fp->N_RB_DL*12; - for (int i=0; i<fp->nb_antennas_rx; i++) { - pdsch->rxdataF_ext[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->rxdataF_uespec_pilots[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12); - pdsch->ptrs_phase_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 ); - pdsch->ptrs_re_per_slot[i] = (int32_t *)malloc16_clear( sizeof(int32_t) * 14); - pdsch->rho[i] = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t *) ); - - for (int j=0; j<NR_MAX_NB_LAYERS; j++) { - const int idx = (j*fp->nb_antennas_rx)+i; - for (int k=0; k<NR_MAX_NB_LAYERS; k++) { - pdsch->rho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - } - pdsch->rxdataF_comp0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); - pdsch->dl_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_bf_ch_estimates[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2); - pdsch->dl_bf_ch_estimates_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_mag0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_magb0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - pdsch->dl_ch_magr0[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num ); - } - } -} - -void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp) -{ - for (int i = 0; i < fp->nb_antennas_rx; i++) { - for (int j = 0; j < NR_MAX_NB_LAYERS; j++) { - const int idx = j * fp->nb_antennas_rx + i; - for (int k = 0; k < NR_MAX_NB_LAYERS; k++) - free_and_zero(pdsch->rho[i][j*NR_MAX_NB_LAYERS+k]); - free_and_zero(pdsch->rxdataF_comp0[idx]); - free_and_zero(pdsch->dl_ch_estimates[idx]); - free_and_zero(pdsch->dl_ch_estimates_ext[idx]); - free_and_zero(pdsch->dl_bf_ch_estimates[idx]); - free_and_zero(pdsch->dl_bf_ch_estimates_ext[idx]); - free_and_zero(pdsch->dl_ch_mag0[idx]); - free_and_zero(pdsch->dl_ch_magb0[idx]); - free_and_zero(pdsch->dl_ch_magr0[idx]); - } - free_and_zero(pdsch->rxdataF_ext[i]); - free_and_zero(pdsch->rxdataF_uespec_pilots[i]); - free_and_zero(pdsch->ptrs_phase_per_slot[i]); - free_and_zero(pdsch->ptrs_re_per_slot[i]); - free_and_zero(pdsch->rho[i]); - } - free_and_zero(pdsch->pmi_ext); - int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1; - for (int i=0; i<nb_codewords; i++) - free_and_zero(pdsch->llr[i]); - for (int i=0; i<NR_MAX_NB_LAYERS; i++) - free_and_zero(pdsch->layer_llr[i]); - free_and_zero(pdsch->llr128); - free_and_zero(pdsch->rxdataF_ext); - free_and_zero(pdsch->rxdataF_uespec_pilots); - free_and_zero(pdsch->rxdataF_comp0); - free_and_zero(pdsch->rho); - free_and_zero(pdsch->dl_ch_estimates); - free_and_zero(pdsch->dl_ch_estimates_ext); - free_and_zero(pdsch->dl_bf_ch_estimates); - free_and_zero(pdsch->dl_bf_ch_estimates_ext); - free_and_zero(pdsch->dl_ch_mag0); - free_and_zero(pdsch->dl_ch_magb0); - free_and_zero(pdsch->dl_ch_magr0); - free_and_zero(pdsch->ptrs_phase_per_slot); - free_and_zero(pdsch->ptrs_re_per_slot); -} - void RCconfig_nrUE_prs(void *cfg) { int j = 0, k = 0, gNB_id = 0; @@ -406,11 +308,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // init RX buffers common_vars->rxdata = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - common_vars->rxdataF = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); for (i=0; i<fp->nb_antennas_rx; i++) { common_vars->rxdata[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+fp->ofdm_symbol_size)*sizeof(int32_t) ); - common_vars->rxdataF[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->samples_per_slot_wCP) ); } // ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK) @@ -453,19 +353,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) } // DLSCH - for (gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) { - ue->pdsch_vars[gNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH)); - phy_init_nr_ue_PDSCH( ue->pdsch_vars[gNB_id], fp ); - - int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1; - for (i=0; i<nb_codewords; i++) { - ue->pdsch_vars[gNB_id]->llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448 - } - for (i=0; i<NR_MAX_NB_LAYERS; i++) { - ue->pdsch_vars[gNB_id]->layer_llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448 - } - } - for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH)); pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH)); @@ -539,9 +426,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) for (int i = 0; i < fp->nb_antennas_rx; i++) { free_and_zero(common_vars->rxdata[i]); - free_and_zero(common_vars->rxdataF[i]); } - free_and_zero(common_vars->rxdataF); free_and_zero(common_vars->rxdata); for (int slot = 0; slot < fp->slots_per_frame; slot++) { @@ -564,10 +449,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) for (int gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) { // PDSCH - free_and_zero(ue->pdsch_vars[gNB_id]->llr_shifts); - free_and_zero(ue->pdsch_vars[gNB_id]->llr128_2ndstream); - phy_term_nr_ue__PDSCH(ue->pdsch_vars[gNB_id], fp); - free_and_zero(ue->pdsch_vars[gNB_id]); } for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { @@ -628,7 +509,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) } } -void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb) { +void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb) { uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; if (num_rb != 273) { @@ -636,19 +517,21 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int a_segments = (a_segments/273)+1; } - for (int i=0; i<number_of_processes; i++) { - free_and_zero(harq_list[i].b); + for (int j=0; j < 2; j++) { + for (int i=0; i<number_of_processes; i++) { + free_and_zero(harq_list[j][i].b); - for (int r=0; r<a_segments; r++) { - free_and_zero(harq_list[i].c[r]); - free_and_zero(harq_list[i].d[r]); + for (int r=0; r<a_segments; r++) { + free_and_zero(harq_list[j][i].c[r]); + free_and_zero(harq_list[j][i].d[r]); + } + free_and_zero(harq_list[j][i].c); + free_and_zero(harq_list[j][i].d); } - free_and_zero(harq_list[i].c); - free_and_zero(harq_list[i].d); } } -void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx) { +void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx) { int max_layers = (num_ant_tx < NR_MAX_NB_LAYERS) ? num_ant_tx : NR_MAX_NB_LAYERS; uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*max_layers; //number of segments to be allocated @@ -676,14 +559,11 @@ void term_nr_ue_transport(PHY_VARS_NR_UE *ue) { const int N_RB_DL = ue->frame_parms.N_RB_DL; const int N_RB_UL = ue->frame_parms.N_RB_UL; - int num_cw = NR_MAX_NB_LAYERS > 4? 2:1; - for (int j = 0; j < num_cw; j++) { - free_nr_ue_dl_harq(ue->dl_harq_processes[j], NR_MAX_DLSCH_HARQ_PROCESSES, N_RB_DL); - } + free_nr_ue_dl_harq(ue->dl_harq_processes, NR_MAX_DLSCH_HARQ_PROCESSES, N_RB_DL); free_nr_ue_ul_harq(ue->ul_harq_processes, NR_MAX_ULSCH_HARQ_PROCESSES, N_RB_UL, ue->frame_parms.nb_antennas_tx); } -void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb) { +void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb) { int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS; //number of segments to be allocated if (num_rb != 273) { @@ -693,35 +573,39 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_process uint32_t dlsch_bytes = a_segments*1056; // allocated bytes per segment - for (int i=0; i<number_of_processes; i++) { - memset(harq_list + i, 0, sizeof(NR_DL_UE_HARQ_t)); - init_downlink_harq_status(harq_list + i); - harq_list[i].b = malloc16(dlsch_bytes); + for (int j=0; j<2; j++) { + for (int i=0; i<number_of_processes; i++) { + memset(harq_list[j] + i, 0, sizeof(NR_DL_UE_HARQ_t)); + init_downlink_harq_status(harq_list[j] + i); + harq_list[j][i].b = malloc16(dlsch_bytes); - if (harq_list[i].b) - memset(harq_list[i].b, 0, dlsch_bytes); - else - AssertFatal(true, "Unable to reset harq memory \"b\"\n"); - - harq_list[i].c = malloc16(a_segments*sizeof(uint8_t *)); - harq_list[i].d = malloc16(a_segments*sizeof(int16_t *)); - for (int r=0; r<a_segments; r++) { - harq_list[i].c[r] = malloc16(1056); - harq_list[i].d[r] = malloc16(5*8448*sizeof(int16_t)); - if (harq_list[i].c[r]) - memset(harq_list[i].c[r],0,1056); - else - AssertFatal(true, "Unable to reset harq memory \"c\"\n"); - - if (harq_list[i].d[r]) - memset(harq_list[i].d[r],0,5*8448); + if (harq_list[j][i].b) + memset(harq_list[j][i].b, 0, dlsch_bytes); else - AssertFatal(true, "Unable to reset harq memory \"d\"\n"); + AssertFatal(true, "Unable to reset harq memory \"b\"\n"); + + harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *)); + harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *)); + for (int r=0; r<a_segments; r++) { + harq_list[j][i].c[r] = malloc16(1056); + harq_list[j][i].d[r] = malloc16(5*8448*sizeof(int16_t)); + if (harq_list[j][i].c[r]) + memset(harq_list[j][i].c[r],0,1056); + else + AssertFatal(true, "Unable to reset harq memory \"c\"\n"); + + if (harq_list[j][i].d[r]) + memset(harq_list[j][i].d[r],0,5*8448); + else + AssertFatal(true, "Unable to reset harq memory \"d\"\n"); + } + harq_list[j][i].status = 0; + harq_list[j][i].DLround = 0; } } } -void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx) { +void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx) { int max_layers = (num_ant_tx < NR_MAX_NB_LAYERS) ? num_ant_tx : NR_MAX_NB_LAYERS; uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*max_layers; //number of segments to be allocated @@ -772,11 +656,7 @@ void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t *harq_list, int number_of_process void init_nr_ue_transport(PHY_VARS_NR_UE *ue) { - int num_codeword = NR_MAX_NB_LAYERS > 4? 2:1; - - for (int j=0; j<num_codeword; j++) { - nr_init_dl_harq_processes(ue->dl_harq_processes[j], NR_MAX_DLSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_DL); - } + nr_init_dl_harq_processes(ue->dl_harq_processes, NR_MAX_DLSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_DL); nr_init_ul_harq_processes(ue->ul_harq_processes, NR_MAX_ULSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_UL, ue->frame_parms.nb_antennas_tx); for(int i=0; i<5; i++) diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index ed4b83fa5db7bcea81001e6384639208ca908685..5ec47c1dae48f3d849bca1122ad10863a51aa0ff 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -418,10 +418,10 @@ void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg); void RCconfig_nrUE_prs(void *cfg); void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue); -void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb); -void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx); -void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb); -void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx); +void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb); +void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx); +void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb); +void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx); /** @} */ #endif diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h index 6ed10a8c77c3cf355235500d93ed10a175646f9b..031b444323b7f5699f1f3a0f827e749a625a9169 100644 --- a/openair1/PHY/MODULATION/modulation_UE.h +++ b/openair1/PHY/MODULATION/modulation_UE.h @@ -51,14 +51,14 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue, int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, unsigned char l, - unsigned char Ns); + c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP]); int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, unsigned char symbol, - unsigned char Ns, int sample_offset, - bool pbch_decoded); + bool pbch_decoded, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue, unsigned char l, diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index a8bbe343551a3c9949b58c564a5495eed2363492..d902c2af479d8e92dda6a62592070725bbe0690a 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -37,10 +37,11 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, unsigned char symbol, - unsigned char Ns) + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; + int Ns = proc->nr_slot_rx; AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1); @@ -75,8 +76,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, //#endif for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - memset(&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t)); - int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset]; // if input to dft is not 256-bit aligned @@ -92,7 +91,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, dft(dftsize, rxdata_ptr, - (int16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], 1); stop_meas(&ue->rx_dft_stats); @@ -108,7 +107,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, #endif c16_t *shift_rot = frame_parms->timeshift_symbol_rotation; - c16_t *this_symbol = (c16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol]; + c16_t *this_symbol = &rxdataF[aa][frame_parms->ofdm_symbol_size*symbol]; if (frame_parms->N_RB_DL & 1) { rotate_cpx_vector(this_symbol, &rot2, this_symbol, @@ -149,12 +148,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, unsigned char symbol, - unsigned char Ns, int sample_offset, - bool pbch_decoded) + bool pbch_decoded, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; + int Ns = proc->nr_slot_rx; AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1); AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1); @@ -189,7 +189,6 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, #endif for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) { - memset(&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t)); int16_t *rxdata_ptr; rx_offset%=frame_length_samples*2; @@ -225,7 +224,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, dft(dftsize, rxdata_ptr, - (int16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + (int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], 1); stop_meas(&ue->rx_dft_stats); @@ -240,7 +239,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, symbol+symb_offset,rot2.r,rot2.i); #endif - c16_t *this_symbol = (c16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol]; + c16_t *this_symbol = &rxdataF[aa][frame_parms->ofdm_symbol_size*symbol]; rotate_cpx_vector(this_symbol, &rot2, this_symbol, frame_parms->ofdm_symbol_size, 15); } diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index 1fd502a93e1369526ac012dd7905a24b6a94e3a8..179c5d9cbd320375480eca104814194cef7c9759 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -341,7 +341,7 @@ int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t count /* perform averaging of channel estimates and store result in first symbol buffer */ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms, - int **ch_est, + int32_t **ch_estimates, uint8_t num_symbols, uint8_t start_symbol, uint16_t dmrs_bitmap, @@ -356,9 +356,9 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms, AssertFatal(first_dmrs_symb > -1, "No DMRS symbol present in this slot\n"); for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { for (int symb = first_dmrs_symb+1; symb < total_symbols; symb++) { - ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; + ul_ch128_0 = (__m128i *)&ch_estimates[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; if ((dmrs_bitmap >> symb) & 0x01) { - ul_ch128_1 = (__m128i *)&ch_est[aarx][symb*frame_parms->ofdm_symbol_size]; + ul_ch128_1 = (__m128i *)&ch_estimates[aarx][symb*frame_parms->ofdm_symbol_size]; for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) { ul_ch128_0[0] = _mm_adds_epi16(ul_ch128_0[0], ul_ch128_1[0]); ul_ch128_0[1] = _mm_adds_epi16(ul_ch128_0[1], ul_ch128_1[1]); @@ -368,7 +368,7 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms, } } } - ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; + ul_ch128_0 = (__m128i *)&ch_estimates[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; if (num_dmrs_symb == 2) { for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) { ul_ch128_0[0] = _mm_srai_epi16(ul_ch128_0[0], 1); @@ -384,7 +384,7 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms, ul_ch128_0 += 3; } } else if (num_dmrs_symb == 3) { - ul_ch16_0 = (int16_t *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; + ul_ch16_0 = (int16_t *)&ch_estimates[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size]; for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) { ul_ch16_0[0] /= 3; ul_ch16_0[1] /= 3; diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h index 1297a0cc2ff7b2f95c65ccb2259fc77681094ed9..4611e363e57304b723db81e37138c6cc58a0a768 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.h +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h @@ -66,7 +66,7 @@ int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter, uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask, uint16_t nb_symb); int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter); void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms, - int **ch_est, + int32_t **ch_estimates, uint8_t num_symbols, uint8_t start_symbol, uint16_t dmrs_bitmap, diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h index 03610ae30fb5adc597906d7f39e8ab8a27ad4b3c..212ee59c1d13e05a8429a1c9868c7abbc07c779c 100644 --- a/openair1/PHY/NR_REFSIG/sss_nr.h +++ b/openair1/PHY/NR_REFSIG/sss_nr.h @@ -96,7 +96,7 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]); -int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss); +int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); #undef INIT_VARIABLES_SSS_NR_H #undef EXTERN diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index 983366e35e3eb13efc46a733bc4a33c4600c5d80..feed70b854c0a808c992f8d18eb7ff5b62299caf 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -101,18 +101,9 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, //printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok); - if(count_max_pos_ok > 10 && first_time == 1) - { + if(count_max_pos_ok > 10 && first_time == 1) { first_time = 0; ue->time_sync_cell = 1; - if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) { - LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); - //mac_resynch(); - //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); - ue->UE_mode[0] = PRACH; - } else { - ue->UE_mode[0] = PUSCH; - } } #ifdef DEBUG_PHY diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 927734e538be53f3f9ccd60f3abb9540a56a0f95..0a0d92743d42e84e4de25236a18e7c46013152b8 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -61,15 +61,15 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_idx = max_idx; } -int nr_prs_channel_estimation(uint8_t gNB_id, - uint8_t rsc_id, +int nr_prs_channel_estimation(uint8_t rsc_id, uint8_t rep_num, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - NR_DL_FRAME_PARMS *frame_params) + NR_DL_FRAME_PARMS *frame_params, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { + int gNB_id = proc->gNB_id; uint8_t rxAnt = 0, idx = 0; - int32_t **rxdataF = ue->common_vars.rxdataF; prs_config_t *prs_cfg = &ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg; prs_meas_t **prs_meas = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_meas; c16_t ch_tmp_buf[ ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32))); @@ -567,11 +567,10 @@ int nr_prs_channel_estimation(uint8_t gNB_id, int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, unsigned char symbol, int dmrss, - NR_UE_SSB *current_ssb) + NR_UE_SSB *current_ssb, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int pilot[200] __attribute__((aligned(16))); unsigned short k; @@ -583,7 +582,6 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, uint8_t nushift; uint8_t ssb_index=current_ssb->i_ssb; uint8_t n_hf=current_ssb->n_hf; - int **rxdataF=ue->common_vars.rxdataF; nushift = ue->frame_parms.Nid_cell%4; ue->frame_parms.nushift = nushift; @@ -600,7 +598,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_PBCH - printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); + printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); #endif // generate pilot @@ -730,13 +728,13 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, struct complex16 dl_ch_estimates [][estimateSz], struct complex16 dl_ch_estimates_time [][ue->frame_parms.ofdm_symbol_size], UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, unsigned char symbol, int dmrss, uint8_t ssb_index, - uint8_t n_hf) + uint8_t n_hf, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { + int Ns = proc->nr_slot_rx; int pilot[200] __attribute__((aligned(16))); unsigned short k; unsigned int pilot_cnt; @@ -745,8 +743,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, //int slot_pbch; uint8_t nushift; - int **rxdataF=ue->common_vars.rxdataF; - nushift = ue->frame_parms.Nid_cell%4; ue->frame_parms.nushift = nushift; unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; @@ -764,7 +760,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, k = nushift; #ifdef DEBUG_PBCH - printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); + printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol); #endif switch (k) { @@ -994,24 +990,23 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, unsigned char symbol, fapi_nr_coreset_t *coreset, uint16_t first_carrier_offset, uint16_t BWPStart, int32_t pdcch_est_size, - int32_t pdcch_dl_ch_estimates[][pdcch_est_size]) + int32_t pdcch_dl_ch_estimates[][pdcch_est_size], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { + int Ns = proc->nr_slot_rx; + int gNB_id = proc->gNB_id; unsigned char aarx; unsigned short k; unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch; int ch_offset,symbol_offset; - int **rxdataF=ue->common_vars.rxdataF; - ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; @@ -1239,9 +1234,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, bool is_SI, - unsigned char Ns, unsigned short p, unsigned char symbol, unsigned char nscid, @@ -1249,8 +1242,13 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short BWPStart, uint8_t config_type, unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch) + unsigned short nb_rb_pdsch, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { + int gNB_id = proc->gNB_id; + int Ns = proc->nr_slot_rx; int pilot[3280] __attribute__((aligned(16))); unsigned char aarx; unsigned short k; @@ -1260,9 +1258,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int ch_offset,symbol_offset; uint8_t nushift; - int **dl_ch_estimates = ue->pdsch_vars[gNB_id]->dl_ch_estimates; - int **rxdataF=ue->common_vars.rxdataF; - ch_offset = ue->frame_parms.ofdm_symbol_size*symbol; symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol; @@ -2030,7 +2025,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, * NAME : nr_pdsch_ptrs_processing * * PARAMETERS : PHY_VARS_NR_UE : ue data structure - * NR_UE_PDSCH : pdsch_vars pointer + * c16_t : ptrs_phase_per_slot array + * int32_t : ptrs_re_per_slot array + * uint32_t : rx_size, + * int32_t : rxdataF_comp, array * NR_DL_FRAME_PARMS : frame_parms pointer * NR_DL_UE_HARQ_t : dlsch0_harq pointer * NR_DL_UE_HARQ_t : dlsch1_harq pointer @@ -2049,7 +2047,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, * 3) Compensate signal with PTRS estimation for slot *********************************************************************/ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, - NR_UE_PDSCH **pdsch_vars, + c16_t ptrs_phase_per_slot[][14], + int32_t ptrs_re_per_slot[][14], + uint32_t rx_size, + int32_t rxdataF_comp[][rx_size], NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, @@ -2104,8 +2105,8 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, } /* loop over antennas */ for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - c16_t *phase_per_symbol = (c16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx]; - ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx]; + c16_t *phase_per_symbol = (c16_t*)ptrs_phase_per_slot[aarx]; + ptrs_re_symbol = (int32_t*)ptrs_re_per_slot[aarx]; ptrs_re_symbol[symbol] = 0; phase_per_symbol[symbol].i = 0; // Imag /* set DMRS estimates to 0 angle with magnitude 1 */ @@ -2141,7 +2142,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, rnti, nr_slot_rx, symbol,frame_parms->ofdm_symbol_size, - (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)], + (int16_t*)&rxdataF_comp[aarx][(symbol * nb_re_pdsch)], ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0], (int16_t*)&phase_per_symbol[symbol], &ptrs_re_symbol[symbol]); @@ -2161,9 +2162,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, } } #ifdef DEBUG_DL_PTRS - LOG_M("ptrsEst.m","est",pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); + LOG_M("ptrsEst.m","est",ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 ); LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp", - &pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ], + &rxdataF_comp[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ], (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1); #endif /*------------------------------------------------------------------------------------------------------- */ @@ -2176,9 +2177,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, #ifdef DEBUG_DL_PTRS printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector((c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + rotate_cpx_vector((c16_t*)&rxdataF_comp[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], &phase_per_symbol[i], - (c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + (c16_t*)&rxdataF_comp[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol }// symbol loop diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index c8ae045e1b1e313434795175f4662cea526f4ea8..cf4917369a1ebe8b0c26c56877d8a203401d95a5 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -33,12 +33,12 @@ #define SYNCH_HYST 2 /* A function to perform the channel estimation of DL PRS signal */ -int nr_prs_channel_estimation(uint8_t gNB_id, - uint8_t rsc_id, +int nr_prs_channel_estimation(uint8_t rsc_id, uint8_t rep_num, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - NR_DL_FRAME_PARMS *frame_params); + NR_DL_FRAME_PARMS *frame_params, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); /* Generic function to find the peak of channel estimation buffer */ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val); @@ -52,40 +52,35 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t */ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, unsigned char symbol, fapi_nr_coreset_t *coreset, uint16_t first_carrier_offset, uint16_t BWPStart, int32_t pdcch_est_size, - int32_t pdcch_dl_ch_estimates[][pdcch_est_size]); + int32_t pdcch_dl_ch_estimates[][pdcch_est_size], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, unsigned char symbol, int dmrss, - NR_UE_SSB *current_ssb); + NR_UE_SSB *current_ssb, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, int estimateSz, - struct complex16 dl_ch_estimates [][estimateSz], - struct complex16 dl_ch_estimates_time [][estimateSz], - UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - unsigned char Ns, + struct complex16 dl_ch_estimates [][estimateSz], + struct complex16 dl_ch_estimates_time [][estimateSz], + UE_nr_rxtx_proc_t *proc, unsigned char symbol, int dmrss, uint8_t ssb_index, - uint8_t n_hf); + uint8_t n_hf, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, bool is_SI, - unsigned char Ns, unsigned short p, unsigned char symbol, unsigned char nscid, @@ -93,7 +88,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned short BWPStart, uint8_t config_type, unsigned short bwp_start_subcarrier, - unsigned short nb_rb_pdsch); + unsigned short nb_rb_pdsch, + uint32_t pdsch_est_size, + int32_t pdsch_dl_ch_estimates[][pdsch_est_size], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, @@ -107,24 +105,28 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, void nr_ue_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t slot, - NR_UE_DLSCH_t *dlsch); + NR_UE_DLSCH_t *dlsch, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size]); void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, uint8_t gNB_index, UE_nr_rxtx_proc_t *proc, - uint8_t slot); + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t slot); + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t gNB_id); void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, - NR_UE_PDSCH **pdsch_vars, + c16_t ptrs_phase_per_slot[][14], + int32_t ptrs_re_per_slot[][14], + uint32_t rx_size, + int32_t rxdataF_comp[][rx_size], NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index 1b5689f33523ef0e7b3aa5e4224694d5aa166df8..5545f5c4bd4edf62af2e227cb840ecd21c27653b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -76,9 +76,11 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index) void nr_ue_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t slot, - NR_UE_DLSCH_t *dlsch) + NR_UE_DLSCH_t *dlsch, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size]) { + int slot = proc->nr_slot_rx; int aarx, aatx, gNB_id = 0; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int ch_offset = frame_parms->ofdm_symbol_size*2; @@ -97,7 +99,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){ - ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = (signal_energy_nodc(&ue->pdsch_vars[0]->dl_ch_estimates[gNB_id][ch_offset], N_RB_DL*NR_NB_SC_PER_RB)); + ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = (signal_energy_nodc(&dl_ch_estimates[gNB_id][ch_offset], N_RB_DL*NR_NB_SC_PER_RB)); if (ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]<0) ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = 0; @@ -170,10 +172,11 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue, void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, int ssb_index, UE_nr_rxtx_proc_t *proc, - uint8_t slot) { + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int k_start = 56; int k_end = 183; + int slot = proc->nr_slot_rx; unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier; int symbol_offset = nr_get_ssb_start_symbol(&ue->frame_parms,ssb_index); @@ -192,7 +195,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) { - int16_t *rxF_sss = (int16_t *)&ue->common_vars.rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset]; + int16_t *rxF_sss = (int16_t *)&rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset]; for(int k = k_start; k < k_end; k++){ @@ -225,9 +228,10 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue, // - psd_awgn (AWGN power spectral density): dBm/Hz void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t slot){ + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]){ uint8_t k; + int slot = proc->nr_slot_rx; int aarx, nb_nulls; int16_t *rxF_sss; uint8_t k_left = 48; @@ -246,7 +250,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue, nb_nulls = 0; ue->measurements.n0_power[aarx] = 0; - rxF_sss = (int16_t *)&ue->common_vars.rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset]; + rxF_sss = (int16_t *)&rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset]; //-ve spectrum from SSS for(k = k_left; k < k_left + k_length; k++){ diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 64222cab9a34dd7e71b473a7c7987f48a23e765e..6768c8bc37005d94573451fa2a45d27bb9348c11 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -190,9 +190,9 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue, const uint8_t *l_overline, int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP], uint32_t *rsrp, - int *rsrp_dBm) { + int *rsrp_dBm, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - int32_t **rxdataF = ue->common_vars.rxdataF; const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; uint16_t meas_count = 0; uint32_t rsrp_sum = 0; @@ -218,7 +218,7 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue, for (int lp = 0; lp <= l_prime; lp++) { uint16_t symb = lp + l_overline[cdm_id]; uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; - c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset]; + c16_t *rx_signal = &rxdataF[ant_rx][symbol_offset]; c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; rx_csi_rs_signal[k].r = rx_signal[k].r; rx_csi_rs_signal[k].i = rx_signal[k].i; @@ -729,9 +729,9 @@ int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr, int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, - uint32_t *interference_plus_noise_power) { + uint32_t *interference_plus_noise_power, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - int32_t **rxdataF = ue->common_vars.rxdataF; const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; const uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ? @@ -764,7 +764,7 @@ int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { - c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset]; + c16_t *rx_signal = &rxdataF[ant_rx][symbol_offset]; for (int rb = csiim_config_pdu->start_rb; rb < end_rb; rb++) { @@ -800,8 +800,9 @@ int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, return 0; } -int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { +int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { + int gNB_id = proc->gNB_id; if(!ue->csiim_vars[gNB_id]->active) { return -1; } @@ -818,14 +819,15 @@ int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]); #endif - nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power); + nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power, rxdataF); ue->nr_csi_info->csi_im_meas_computed = true; return 0; } -int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { +int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { + int gNB_id = proc->gNB_id; if(!ue->csirs_vars[gNB_id]->active) { return -1; } @@ -901,7 +903,8 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t l_overline, csi_rs_received_signal, &rsrp, - &rsrp_dBm); + &rsrp_dBm, + rxdataF); nr_csi_rs_channel_estimation(ue, proc, @@ -958,8 +961,8 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t csirs_measurements.cqi = cqi; nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind),1); - nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL); - nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, gNB_id, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, NULL); + nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements); if (ue->if_inst && ue->if_inst->dl_indication) { ue->if_inst->dl_indication(&dl_indication, NULL); } else { diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index 315519bf993960a6fd39d396238309a75516ad5a..423140fc7a3bddb7e02c428eb44e9cf83af03ea7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -340,7 +340,8 @@ void nr_pdcch_channel_level(int32_t rx_size, // This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources) -void nr_pdcch_extract_rbs_single(int32_t **rxdataF, +void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz, + c16_t rxdataF[][rxdataF_sz], int32_t est_size, int32_t dl_ch_estimates[][est_size], int32_t rx_size, @@ -415,7 +416,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start) if (((c_rb + n_BWP_start) < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case - rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; + rxF = (int32_t *)&rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12]; LOG_DDD("in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); } @@ -423,14 +424,14 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, if (((c_rb + n_BWP_start) >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC) // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF - rxF = &rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol + rxF = (int32_t *)&rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size = (%d)]\n", c_rb,aarx,(12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size)); } if (((c_rb + n_BWP_start) < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case - rxF = &rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size]; + rxF = (int32_t *)&rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size]; LOG_DDD("in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size)); } @@ -438,7 +439,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, if (((c_rb + n_BWP_start) > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // number of RBs is odd and c_rb is higher than half system bandwidth + 1 // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC - rxF = &rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol + rxF = (int32_t *)&rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol LOG_DDD("in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size = (%d)]\n", c_rb,aarx,(12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size)); } @@ -446,7 +447,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, if (((c_rb + n_BWP_start) == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // treatment of RB containing the DC // if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC) // we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table) - rxF = &rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size]; + rxF = (int32_t *)&rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size]; LOG_DDD("in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size)); j = 0; @@ -467,7 +468,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, } // then we point at the begining of the symbol part of rxdataF do process second part of RB - rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol + rxF = (int32_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol LOG_DDD("in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][symbol * frame_parms->ofdm_symbol_size = (%d)]\n", c_rb,aarx,(symbol * frame_parms->ofdm_symbol_size)); for (; i < 12; i++) { @@ -671,11 +672,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, int32_t pdcch_est_size, int32_t pdcch_dl_ch_estimates[][pdcch_est_size], int16_t *pdcch_e_rx, - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) { + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { uint32_t frame = proc->frame_rx; uint32_t slot = proc->nr_slot_rx; - NR_UE_COMMON *common_vars = &ue->common_vars; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; uint8_t log2_maxh, aarx; @@ -703,7 +704,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) { LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); - nr_pdcch_extract_rbs_single(common_vars->rxdataF, + nr_pdcch_extract_rbs_single(ue->frame_parms.samples_per_slot_wCP, + rxdataF, pdcch_est_size, pdcch_dl_ch_estimates, rx_size, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 2a3de5a9bc879ae796176acb0bfe8cee6123e995..39d45a82d85ca61298f9d75a402909a5ee146f33 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -81,38 +81,40 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{ #define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7]) /* compute H_h_H matrix inversion up to 4x4 matrices */ -uint8_t nr_zero_forcing_rx(int **rxdataF_comp, - int **dl_ch_mag, - int **dl_ch_magb, - int **dl_ch_magr, - int **dl_ch_estimates_ext, - unsigned short nb_rb, - unsigned char n_rx, - unsigned char n_tx,//number of layer - unsigned char mod_order, - int shift, - unsigned char symbol, - int length); +uint8_t nr_zero_forcing_rx(uint32_t rx_size, + int32_t rxdataF_comp[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], + int32_t dl_ch_estimates_ext[][rx_size], + unsigned short nb_rb, + unsigned char n_rx, + unsigned char n_tx,//number of layer + unsigned char mod_order, + int shift, + unsigned char symbol, + int length); /* Apply layer demapping */ -static void nr_dlsch_layer_demapping(int16_t **llr_cw, +static void nr_dlsch_layer_demapping(int16_t *llr_cw[2], uint8_t Nl, uint8_t mod_order, uint32_t length, int32_t codeword_TB0, int32_t codeword_TB1, - int16_t **llr_layers); + int16_t *llr_layers[NR_MAX_NB_LAYERS]); /* compute LLR */ -static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, +static int nr_dlsch_llr(uint32_t rx_size, + int16_t *layer_llr[NR_MAX_NB_LAYERS], NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp_ptr, - int32_t **dl_ch_mag_ptr, + int32_t rxdataF_comp[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, unsigned char harq_pid, - unsigned char gNB_id, - unsigned char gNB_id_i, unsigned char first_symbol_flag, unsigned char symbol, unsigned short nb_rb, @@ -120,26 +122,40 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, int32_t codeword_TB1, uint32_t len, uint8_t nr_slot_rx, - NR_UE_DLSCH_t *dlsch); - + NR_UE_DLSCH_t dlsch[2], + uint32_t llr_offset[NR_SYMBOLS_PER_SLOT]); /* Main Function */ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t *dlsch, - unsigned char gNB_id, - unsigned char gNB_id_i, - uint32_t frame, - uint8_t nr_slot_rx, + NR_UE_DLSCH_t dlsch[2], unsigned char symbol, unsigned char first_symbol_flag, - unsigned char harq_pid) + unsigned char harq_pid, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size], + int16_t *llr[2], + c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], + int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], + uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], + uint32_t rx_size, + int32_t dl_ch_estimates_ext[][rx_size], + int32_t rxdataF_ext[][rx_size], + int32_t rxdataF_comp[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], + uint32_t llr_offset[NR_SYMBOLS_PER_SLOT], + int32_t *log2_maxh) { NR_UE_COMMON *common_vars = &ue->common_vars; - NR_UE_PDSCH **pdsch_vars; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; PHY_NR_MEASUREMENTS *measurements = &ue->measurements; + int frame = proc->frame_rx; + int nr_slot_rx = proc->nr_slot_rx; + int gNB_id = proc->gNB_id; int avg[16]; // int avg_0[2]; @@ -152,8 +168,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int avgs = 0;// rb; NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL; - int32_t **rxdataF_comp_ptr; - int32_t **dl_ch_mag_ptr; int32_t codeword_TB0 = -1; int32_t codeword_TB1 = -1; @@ -169,7 +183,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, uint16_t nbSymb=0; uint16_t pduBitmap=0x0; - pdsch_vars = ue->pdsch_vars; dlsch0_harq = &ue->dl_harq_processes[0][harq_pid]; if (NR_MAX_NB_LAYERS>4) dlsch1_harq = &ue->dl_harq_processes[1][harq_pid]; @@ -251,11 +264,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return(-1); } - if (!pdsch_vars) { - LOG_W(PHY,"dlsch_demodulation.c: Null pdsch_vars pointer\n"); - return(-1); - } - if (!frame_parms) { LOG_W(PHY,"dlsch_demodulation.c: Null frame_parms\n"); return(-1); @@ -272,10 +280,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //--------------------- RBs extraction --------------------- //---------------------------------------------------------- start_meas(&ue->generic_stat_bis[slot]); - nr_dlsch_extract_rbs(common_vars->rxdataF, - pdsch_vars[gNB_id]->dl_ch_estimates, - pdsch_vars[gNB_id]->rxdataF_ext, - pdsch_vars[gNB_id]->dl_ch_estimates_ext, + nr_dlsch_extract_rbs(ue->frame_parms.samples_per_slot_wCP, + rxdataF, + rx_size, + dl_ch_estimates, + rxdataF_ext, + dl_ch_estimates_ext, symbol, pilots, config_type, @@ -298,7 +308,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //--------------------- Channel Scaling -------------------- //---------------------------------------------------------- start_meas(&ue->generic_stat_bis[slot]); - nr_dlsch_scale_channel(pdsch_vars[gNB_id]->dl_ch_estimates_ext, + nr_dlsch_scale_channel(rx_size, + dl_ch_estimates_ext, frame_parms, nl, n_rx, @@ -317,7 +328,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //---------------------------------------------------------- start_meas(&ue->generic_stat_bis[slot]); if (first_symbol_flag==1) { - nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext, + nr_dlsch_channel_level(rx_size, + dl_ch_estimates_ext, frame_parms, nl, avg, @@ -333,7 +345,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, median[(aatx*n_rx)+aarx] = avg[(aatx*n_rx)+aarx]; } if (dlsch[0].Nl > 1) { - nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext, + nr_dlsch_channel_level_median(rx_size, + dl_ch_estimates_ext, median, nl, n_rx, @@ -345,14 +358,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } } } - pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1; - //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, pdsch_vars[gNB_id]->log2_maxh); - LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n", + *log2_maxh = (log2_approx(avgs)/2) + 1; + //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs, log2_maxh); + LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d,%d)\n", frame%1024, nr_slot_rx, - pdsch_vars[gNB_id]->log2_maxh, - pdsch_vars[gNB_id]->log2_maxh0, - pdsch_vars[gNB_id]->log2_maxh1, + *log2_maxh, avg[0], avgs); } @@ -373,13 +384,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, //---------------------------------------------------------- // Disable correlation measurement for optimizing UE start_meas(&ue->generic_stat_bis[slot]); - nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext, - pdsch_vars[gNB_id]->dl_ch_estimates_ext, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->dl_ch_magr0, - pdsch_vars[gNB_id]->rxdataF_comp0, - NULL,//NULL:disable meas. pdsch_vars[gNB_id]->rho:enable meas. + nr_dlsch_channel_compensation(rx_size, + rxdataF_ext, + dl_ch_estimates_ext, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + rxdataF_comp, + NULL, frame_parms, nl, symbol, @@ -387,67 +399,63 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, first_symbol_flag, dlsch[0].dlsch_config.qamModOrder, nb_rb_pdsch, - pdsch_vars[gNB_id]->log2_maxh, + *log2_maxh, measurements); // log2_maxh+I0_shift stop_meas(&ue->generic_stat_bis[slot]); if (cpumeas(CPUMEAS_GETSTATE)) - LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[slot].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n", frame, nr_slot_rx, slot, symbol, *log2_maxh, proc->channel_level, ue->generic_stat_bis[slot].p_time/(cpuf*1000.0)); start_meas(&ue->generic_stat_bis[slot]); if (n_rx > 1) { - nr_dlsch_detection_mrc(pdsch_vars[gNB_id]->rxdataF_comp0, - (nl>1)? pdsch_vars[gNB_id]->rho : NULL, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->dl_ch_magr0, + nr_dlsch_detection_mrc(rx_size, + rxdataF_comp, + NULL, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, nl, n_rx, symbol, nb_rb_pdsch, nb_re_pdsch); if (nl >= 2)//Apply zero forcing for 2, 3, and 4 Tx layers - nr_zero_forcing_rx(pdsch_vars[gNB_id]->rxdataF_comp0, - pdsch_vars[gNB_id]->dl_ch_mag0, - pdsch_vars[gNB_id]->dl_ch_magb0, - pdsch_vars[gNB_id]->dl_ch_magr0, - pdsch_vars[gNB_id]->dl_ch_estimates_ext, - nb_rb_pdsch, - n_rx, - nl, - dlsch[0].dlsch_config.qamModOrder, - pdsch_vars[gNB_id]->log2_maxh, - symbol, - nb_re_pdsch); + nr_zero_forcing_rx(rx_size, + rxdataF_comp, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + dl_ch_estimates_ext, + nb_rb_pdsch, + n_rx, + nl, + dlsch[0].dlsch_config.qamModOrder, + *log2_maxh, + symbol, + nb_re_pdsch); } stop_meas(&ue->generic_stat_bis[slot]); - //printf("start compute LLR\n"); - rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0; - dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0; - if (cpumeas(CPUMEAS_GETSTATE)) LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0)); start_meas(&ue->generic_stat_bis[slot]); /* Store the valid DL RE's */ - pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch; + dl_valid_re[symbol-1] = nb_re_pdsch; if(dlsch0_harq->status == ACTIVE) { startSymbIdx = dlsch[0].dlsch_config.start_symbol; nbSymb = dlsch[0].dlsch_config.number_symbols; pduBitmap = dlsch[0].dlsch_config.pduBitmap; } - if(dlsch1_harq) { - startSymbIdx = dlsch[1].dlsch_config.start_symbol; - nbSymb = dlsch[1].dlsch_config.number_symbols; - pduBitmap = dlsch[1].dlsch_config.pduBitmap; - } - + /* Check for PTRS bitmap and process it respectively */ if((pduBitmap & 0x1) && (dlsch[0].rnti_type == _C_RNTI_)) { nr_pdsch_ptrs_processing(ue, - pdsch_vars, + ptrs_phase_per_slot, + ptrs_re_per_slot, + rx_size, + rxdataF_comp, frame_parms, dlsch0_harq, dlsch1_harq, @@ -456,11 +464,31 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, symbol, (nb_rb_pdsch*12), dlsch[0].rnti,dlsch); - pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol]; + dl_valid_re[symbol-1] -= ptrs_re_per_slot[0][symbol]; } /* at last symbol in a slot calculate LLR's for whole slot */ if(symbol == (startSymbIdx + nbSymb -1)) { + uint8_t nb_re_dmrs; + if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups; + } + else { + nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups; + } + uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); + + const uint32_t rx_llr_size = nr_get_G(dlsch[0].dlsch_config.number_rbs, + dlsch[0].dlsch_config.number_symbols, + nb_re_dmrs, + dmrs_len, + dlsch[0].dlsch_config.qamModOrder, + dlsch[0].Nl); + const uint32_t rx_llr_layer_size = (rx_llr_size + dlsch[0].Nl - 1) / dlsch[0].Nl; + + int16_t* layer_llr[NR_MAX_NB_LAYERS]; + for (int i=0; i<NR_MAX_NB_LAYERS; i++) + layer_llr[i] = (int16_t *)malloc16_clear(rx_llr_layer_size*sizeof(int16_t)); for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) { /* re evaluating the first symbol flag as LLR's are done in symbol loop */ if(i == startSymbIdx && i < 3) { @@ -470,27 +498,27 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, first_symbol_flag=0; } /* Calculate LLR's for each symbol */ - nr_dlsch_llr(pdsch_vars, frame_parms, - rxdataF_comp_ptr, dl_ch_mag_ptr, - dlsch0_harq, dlsch1_harq, + nr_dlsch_llr(rx_size, + layer_llr, + frame_parms, + rxdataF_comp, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + dlsch0_harq, + dlsch1_harq, harq_pid, - gNB_id, gNB_id_i, first_symbol_flag, - i, nb_rb_pdsch, - codeword_TB0, codeword_TB1, - pdsch_vars[gNB_id]->dl_valid_re[i-1], - nr_slot_rx, dlsch); + i, + nb_rb_pdsch, + codeword_TB0, + codeword_TB1, + dl_valid_re[i-1], + nr_slot_rx, + dlsch, + llr_offset); } - int dmrs_type = dlsch[0].dlsch_config.dmrsConfigType; - uint8_t nb_re_dmrs; - uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); - if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { - nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups; - } else { - nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups; - } - dlsch0_harq->G = nr_get_G(dlsch[0].dlsch_config.number_rbs, dlsch[0].dlsch_config.number_symbols, nb_re_dmrs, @@ -498,51 +526,53 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch[0].dlsch_config.qamModOrder, dlsch[0].Nl); - nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr, + nr_dlsch_layer_demapping(llr, dlsch[0].Nl, dlsch[0].dlsch_config.qamModOrder, dlsch0_harq->G, codeword_TB0, codeword_TB1, - pdsch_vars[gNB_id]->layer_llr); - } - - stop_meas(&ue->generic_stat_bis[slot]); - if (cpumeas(CPUMEAS_GETSTATE)) - LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0)); + layer_llr); + for (int i=0; i<NR_MAX_NB_LAYERS; i++) + free(layer_llr[i]); // Please keep it: useful for debugging #ifdef DEBUG_PDSCH_RX - char filename[50]; - uint8_t aa = 0; - - snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); - write_output(filename, "rxdataF0", &common_vars->rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); + char filename[50]; + uint8_t aa = 0; - snprintf(filename, 50, "dl_ch_estimates0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); - write_output(filename, "dl_ch_estimates", &pdsch_vars[gNB_id]->dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); + snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx); + write_output(filename, "rxdataF0", &rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); - snprintf(filename, 50, "rxdataF_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); - write_output(filename, "rxdataF_ext", &pdsch_vars[gNB_id]->rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); + snprintf(filename, 50, "dl_ch_estimates0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "dl_ch_estimates", &dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1); - snprintf(filename, 50, "dl_ch_estimates_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); - write_output(filename, "dl_ch_estimates_ext00", &pdsch_vars[gNB_id]->dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); + snprintf(filename, 50, "rxdataF_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "rxdataF_ext", &rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); - snprintf(filename, 50, "rxdataF_comp0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); - write_output(filename, "rxdataF_comp00", &pdsch_vars[gNB_id]->rxdataF_comp0[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); -/* - for (int i=0; i < 2; i++){ - snprintf(filename, 50, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx); - write_output(filename,"llr", &pdsch_vars[gNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0); - } -*/ + snprintf(filename, 50, "dl_ch_estimates_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "dl_ch_estimates_ext00", &dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); + + snprintf(filename, 50, "rxdataF_comp0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx); + write_output(filename, "rxdataF_comp00", &rxdataF_comp[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1); + /* + for (int i=0; i < 2; i++){ + snprintf(filename, 50, "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx); + write_output(filename,"llr", &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0); + } + */ #endif + } + + stop_meas(&ue->generic_stat_bis[slot]); + if (cpumeas(CPUMEAS_GETSTATE)) + LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0)); #if T_TRACER T(T_UE_PHY_PDSCH_IQ, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame%1024), T_INT(nr_slot_rx), T_INT(nb_rb_pdsch), T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_slot), - T_BUFFER(&pdsch_vars[gNB_id]->rxdataF_comp0[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2)); + T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2)); #endif return(0); @@ -599,12 +629,13 @@ void nr_dlsch_deinterleaving(uint8_t symbol, // Pre-processing for LLR computation //============================================================================================== -void nr_dlsch_channel_compensation(int **rxdataF_ext, - int **dl_ch_estimates_ext, - int **dl_ch_mag, - int **dl_ch_magb, - int **dl_ch_magr, - int **rxdataF_comp, +void nr_dlsch_channel_compensation(uint32_t rx_size, + int32_t rxdataF_ext[][rx_size], + int32_t dl_ch_estimates_ext[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], + int32_t rxdataF_comp[][rx_size], int ***rho, NR_DL_FRAME_PARMS *frame_parms, uint8_t nb_aatx, @@ -1304,14 +1335,15 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext, } -void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_tx, - uint8_t n_rx, - uint8_t symbol, - uint8_t pilots, - uint32_t len, - unsigned short nb_rb) +void nr_dlsch_scale_channel(uint32_t rx_size, + int32_t dl_ch_estimates_ext[][rx_size], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_tx, + uint8_t n_rx, + uint8_t symbol, + uint8_t pilots, + uint32_t len, + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) @@ -1359,13 +1391,14 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext, //compute average channel_level on each (TX,RX) antenna pair -void nr_dlsch_channel_level(int **dl_ch_estimates_ext, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_tx, - int32_t *avg, - uint8_t symbol, - uint32_t len, - unsigned short nb_rb) +void nr_dlsch_channel_level(uint32_t rx_size, + int32_t dl_ch_estimates_ext[][rx_size], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_tx, + int32_t *avg, + uint8_t symbol, + uint32_t len, + unsigned short nb_rb) { #if defined(__x86_64__)||defined(__i386__) @@ -1466,12 +1499,13 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext, #endif } -void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, - int32_t *median, - int n_tx, - int n_rx, - int length, - int start_point) +void nr_dlsch_channel_level_median(uint32_t rx_size, + int32_t dl_ch_estimates_ext[][rx_size], + int32_t *median, + int n_tx, + int n_rx, + int length, + int start_point) { #if defined(__x86_64__)||defined(__i386__) @@ -1563,10 +1597,12 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, // Extraction functions //============================================================================================== -void nr_dlsch_extract_rbs(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, +void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, + c16_t rxdataF[][rxdataF_sz], + uint32_t rx_size, + int32_t dl_ch_estimates[][rx_size], + int32_t rxdataF_ext[][rx_size], + int32_t dl_ch_estimates_ext[][rx_size], unsigned char symbol, uint8_t pilots, uint8_t config_type, @@ -1597,7 +1633,7 @@ void nr_dlsch_extract_rbs(int **rxdataF, for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { int32_t *rxF_ext = &rxdataF_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB]; - int32_t *rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; + int32_t *rxF = (int32_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; for (unsigned char aatx = 0; aatx < Nl; aatx++) { @@ -1682,11 +1718,12 @@ void nr_dlsch_extract_rbs(int **rxdataF, } } -void nr_dlsch_detection_mrc(int **rxdataF_comp, +void nr_dlsch_detection_mrc(uint32_t rx_size, + int32_t rxdataF_comp[][rx_size], int ***rho, - int **dl_ch_mag, - int **dl_ch_magb, - int **dl_ch_magr, + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], short n_tx, short n_rx, unsigned char symbol, @@ -2144,11 +2181,12 @@ void nr_conjch0_mult_ch1(int *ch0, * * * */ -uint8_t nr_zero_forcing_rx(int **rxdataF_comp, - int **dl_ch_mag, - int **dl_ch_magb, - int **dl_ch_magr, - int **dl_ch_estimates_ext, +uint8_t nr_zero_forcing_rx(uint32_t rx_size, + int32_t rxdataF_comp[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], + int32_t dl_ch_estimates_ext[][rx_size], unsigned short nb_rb, unsigned char n_rx, unsigned char n_tx,//number of layer @@ -2305,13 +2343,13 @@ uint8_t nr_zero_forcing_rx(int **rxdataF_comp, return(0); } -static void nr_dlsch_layer_demapping(int16_t **llr_cw, - uint8_t Nl, - uint8_t mod_order, - uint32_t length, - int32_t codeword_TB0, - int32_t codeword_TB1, - int16_t **llr_layers) { +static void nr_dlsch_layer_demapping(int16_t *llr_cw[2], + uint8_t Nl, + uint8_t mod_order, + uint32_t length, + int32_t codeword_TB0, + int32_t codeword_TB1, + int16_t *llr_layers[NR_MAX_NB_LAYERS]) { switch (Nl) { case 1: @@ -2343,15 +2381,16 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw, } } -static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, +static int nr_dlsch_llr(uint32_t rx_size, + int16_t *layer_llr[NR_MAX_NB_LAYERS], NR_DL_FRAME_PARMS *frame_parms, - int32_t **rxdataF_comp_ptr, - int32_t **dl_ch_mag_ptr, + int32_t rxdataF_comp[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, unsigned char harq_pid, - unsigned char gNB_id, - unsigned char gNB_id_i, unsigned char first_symbol_flag, unsigned char symbol, unsigned short nb_rb, @@ -2359,22 +2398,23 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, int32_t codeword_TB1, uint32_t len, uint8_t nr_slot_rx, - NR_UE_DLSCH_t *dlsch) + NR_UE_DLSCH_t dlsch[2], + uint32_t llr_offset[14]) { uint32_t llr_offset_symbol; if (first_symbol_flag==1) - pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0; - llr_offset_symbol = pdsch_vars[gNB_id]->llr_offset[symbol-1]; + llr_offset[symbol-1] = 0; + llr_offset_symbol = llr_offset[symbol-1]; - pdsch_vars[gNB_id]->llr_offset[symbol] = len*dlsch->dlsch_config.qamModOrder + llr_offset_symbol; + llr_offset[symbol] = len*dlsch[0].dlsch_config.qamModOrder + llr_offset_symbol; switch (dlsch[0].dlsch_config.qamModOrder) { case 2 : for(int l=0; l < dlsch[0].Nl; l++) nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], - pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, + rxdataF_comp[l*frame_parms->nb_antennas_rx], + layer_llr[l]+llr_offset_symbol, symbol, len, first_symbol_flag, @@ -2384,9 +2424,9 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, case 4 : for(int l=0; l < dlsch[0].Nl; l++) nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], - pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, - pdsch_vars[gNB_id]->dl_ch_mag0[0], + rxdataF_comp[l*frame_parms->nb_antennas_rx], + layer_llr[l]+llr_offset_symbol, + dl_ch_mag[0], symbol, len, first_symbol_flag, @@ -2396,10 +2436,10 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, case 6 : for(int l=0; l < dlsch[0].Nl; l++) nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], - pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, - pdsch_vars[gNB_id]->dl_ch_mag0[0], - pdsch_vars[gNB_id]->dl_ch_magb0[0], + rxdataF_comp[l*frame_parms->nb_antennas_rx], + layer_llr[l]+llr_offset_symbol, + dl_ch_mag[0], + dl_ch_magb[0], symbol, len, first_symbol_flag, @@ -2409,11 +2449,11 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, case 8: for(int l=0; l < dlsch[0].Nl; l++) nr_dlsch_256qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx], - pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol, - pdsch_vars[gNB_id]->dl_ch_mag0[0], - pdsch_vars[gNB_id]->dl_ch_magb0[0], - pdsch_vars[gNB_id]->dl_ch_magr0[0], + rxdataF_comp[l*frame_parms->nb_antennas_rx], + layer_llr[l]+llr_offset_symbol, + dl_ch_mag[0], + dl_ch_magb[0], + dl_ch_magr[0], symbol, len, first_symbol_flag, @@ -2426,12 +2466,13 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, break; } + //TODO: Revisited for Nl>4 if (dlsch1_harq) { switch (dlsch[1].dlsch_config.qamModOrder) { case 2 : nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[0], - pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, + rxdataF_comp[0], + layer_llr[0]+llr_offset_symbol, symbol, len, first_symbol_flag, @@ -2440,9 +2481,9 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, case 4: nr_dlsch_16qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[0], - pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, - pdsch_vars[gNB_id]->dl_ch_mag0[0], + rxdataF_comp[0], + layer_llr[0]+llr_offset_symbol, + dl_ch_mag[0], symbol, len, first_symbol_flag, @@ -2451,10 +2492,10 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, case 6 : nr_dlsch_64qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[0], - pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, - pdsch_vars[gNB_id]->dl_ch_mag0[0], - pdsch_vars[gNB_id]->dl_ch_magb0[0], + rxdataF_comp[0], + layer_llr[0]+llr_offset_symbol, + dl_ch_mag[0], + dl_ch_magb[0], symbol, len, first_symbol_flag, @@ -2463,11 +2504,11 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars, case 8 : nr_dlsch_256qam_llr(frame_parms, - pdsch_vars[gNB_id]->rxdataF_comp0[0], - pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol, - pdsch_vars[gNB_id]->dl_ch_mag0[0], - pdsch_vars[gNB_id]->dl_ch_magb0[0], - pdsch_vars[gNB_id]->dl_ch_magr0[0], + rxdataF_comp[0], + layer_llr[0]+llr_offset_symbol, + dl_ch_mag[0], + dl_ch_magb[0], + dl_ch_magr[0], symbol, len, first_symbol_flag, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index e87062de55d815bde44861d0b7de7aa16e8194b0..1904bed4570fb86b10e6f23abf6e13a95fae5934 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -101,7 +101,7 @@ void free_list(NR_UE_SSB *node) { } -int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, nr_phy_data_t *phy_data) +int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, nr_phy_data_t *phy_data, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; int ret =-1; @@ -127,7 +127,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini start_meas(&ue->dlsch_channel_estimation_stats); // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++) - nr_pbch_dmrs_correlation(ue,proc,0,0,i,i-pbch_initial_symbol,current_ssb); + nr_pbch_dmrs_correlation(ue,proc,i,i-pbch_initial_symbol,current_ssb,rxdataF); stop_meas(&ue->dlsch_channel_estimation_stats); current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im; @@ -152,7 +152,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++) nr_pbch_channel_estimation(ue,estimateSz, dl_ch_estimates, dl_ch_estimates_time, - proc,0,0,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf); + proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF); stop_meas(&ue->dlsch_channel_estimation_stats); fapiPbch_t result; @@ -162,11 +162,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini dl_ch_estimates, ue->pbch_vars[0], frame_parms, - 0, temp_ptr->i_ssb, SISO, phy_data, - &result); + &result, + rxdataF); if (DUMP_PBCH_CH_ESTIMATES && (ret == 0)) { write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1); @@ -242,6 +242,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, * sync_pos SS/PBCH block */ + const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP; + __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; cnt++; if (1){ // (cnt>100) cnt =0; @@ -302,16 +304,16 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, nr_slot_fep_init_sync(ue, proc, i, - 0, is*fp->samples_per_frame+ue->ssb_offset, - false); + false, + rxdataF); #ifdef DEBUG_INITIAL_SYNCH LOG_I(PHY,"Calling sss detection (normal CP)\n"); #endif int freq_offset_sss = 0; - ret = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss); + ret = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF); // digital compensation of FFO for SSB symbols if (ue->UE_fo_compensation){ @@ -341,7 +343,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, if (ret==0) { //we got sss channel nr_gold_pbch(ue); - ret = nr_pbch_detection(proc, ue, 1, &phy_data); // start pbch detection at first symbol after pss + ret = nr_pbch_detection(proc, ue, 1, &phy_data, rxdataF); // start pbch detection at first symbol after pss } if (ret == 0) { @@ -464,7 +466,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, frame_parms->Nid_cell,frame_parms->frame_type); #endif - ue->UE_mode[0] = NOT_SYNCHED; ue->pbch_vars[0]->pdu_errors_last=ue->pbch_vars[0]->pdu_errors; ue->pbch_vars[0]->pdu_errors++; ue->pbch_vars[0]->pdu_errors_conseq++; @@ -525,7 +526,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, if (sa==1 && ret==0) { nr_ue_dlsch_init(phy_data.dlsch, 1, ue->max_ldpc_iterations); bool dec = false; - int gnb_id = 0; //FIXME + proc->gNB_id = 0; //FIXME // Hold the channel estimates in frequency domain. int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16); @@ -539,23 +540,22 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, nr_slot_fep_init_sync(ue, proc, l, // the UE PHY has no notion of the symbols to be monitored in the search space - phy_pdcch_config->slot, is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset, - true); + true, + rxdataF); nr_pdcch_channel_estimation(ue, proc, - 0, - phy_pdcch_config->slot, l, &phy_pdcch_config->pdcch_config[n_ss].coreset, fp->first_carrier_offset, phy_pdcch_config->pdcch_config[n_ss].BWPStart, pdcch_est_size, - pdcch_dl_ch_estimates); + pdcch_dl_ch_estimates, + rxdataF); } - int dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_data, n_ss); + int dci_cnt = nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_data, n_ss, rxdataF); if (dci_cnt>0){ NR_UE_DLSCH_t *dlsch = phy_data.dlsch; if (dlsch[0].active == 1) { @@ -566,24 +566,46 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, nr_slot_fep_init_sync(ue, proc, m, - phy_pdcch_config->slot, // same slot and offset as pdcch is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset, - true); + true, + rxdataF); } + uint8_t nb_re_dmrs; + if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups; + } + else { + nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups; + } + uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); + + const uint32_t rx_llr_size = nr_get_G(dlsch[0].dlsch_config.number_rbs, + dlsch[0].dlsch_config.number_symbols, + nb_re_dmrs, + dmrs_len, + dlsch[0].dlsch_config.qamModOrder, + dlsch[0].Nl); + int16_t* llr[2]; + int16_t* layer_llr[NR_MAX_NB_LAYERS]; + llr[0] = (int16_t *)malloc16_clear(rx_llr_size*sizeof(int16_t)); + int ret = nr_ue_pdsch_procedures(ue, proc, - gnb_id, - dlsch); + phy_data.dlsch, + llr, + rxdataF); if (ret >= 0) dec = nr_ue_dlsch_procedures(ue, proc, - gnb_id, - dlsch, - NULL); + phy_data.dlsch, + llr); // deactivate dlsch once dlsch proc is done - dlsch->active = 0; + dlsch[0].active = 0; + free(llr[0]); + for (int i=0; i<NR_MAX_NB_LAYERS; i++) + free(layer_llr[i]); } } } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c index 2a037d1e70bab81162ace66835709fba28236e94..1d9d30ec33d151064936a3568217f8193481c49a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c @@ -49,7 +49,8 @@ #define PBCH_MAX_RE (PBCH_MAX_RE_PER_SYMBOL*4) #define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7]) -static uint16_t nr_pbch_extract(int **rxdataF, +static uint16_t nr_pbch_extract(uint32_t rxdataF_sz, + c16_t rxdataF[][rxdataF_sz], const int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL], @@ -67,7 +68,7 @@ static uint16_t nr_pbch_extract(int **rxdataF, for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier; rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size); - struct complex16 *rxF = (struct complex16 *)&rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; + struct complex16 *rxF = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size]; struct complex16 *rxF_ext = rxdataF_ext[aarx]; #ifdef DEBUG_PBCH printf("extract_rbs (nushift %d): rx_offset=%d, symbol %u\n",frame_parms->nushift, @@ -388,13 +389,12 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, int estimateSz, struct complex16 dl_ch_estimates [][estimateSz], NR_UE_PBCH *nr_ue_pbch_vars, NR_DL_FRAME_PARMS *frame_parms, - uint8_t gNB_id, uint8_t i_ssb, MIMO_mode_t mimo_mode, nr_phy_data_t *phy_data, - fapiPbch_t *result) { + fapiPbch_t *result, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { - NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars; int max_h=0; int symbol; //uint8_t pbch_a[64]; @@ -424,7 +424,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, #ifdef DEBUG_PBCH //printf("address dataf %p",nr_ue_common_vars->rxdataF); write_output("rxdataF0_pbch.m","rxF0pbch", - &nr_ue_common_vars->rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); + &rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1); #endif // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot double log2_maxh = 0; @@ -434,7 +434,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, __attribute__ ((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL]; memset(dl_ch_estimates_ext,0, sizeof dl_ch_estimates_ext); - nr_pbch_extract(nr_ue_common_vars->rxdataF, + nr_pbch_extract(ue->frame_parms.samples_per_slot_wCP, + rxdataF, estimateSz, dl_ch_estimates, rxdataF_ext, @@ -580,8 +581,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue, fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1); uint16_t number_pdus = 1; - nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, phy_data); - nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc,(void *)result); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, phy_data); + nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc,(void *)result); if (ue->if_inst && ue->if_inst->dl_indication) ue->if_inst->dl_indication(&dl_indication, NULL); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index efdcd51e64706bdd9be3852ca72f7e6bd1946fc6..921be8500245bac72024ca98b00696d33baed20c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -543,10 +543,12 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms, @param n_dmrs_cdm_groups @param frame_parms Pointer to frame descriptor */ -void nr_dlsch_extract_rbs(int **rxdataF, - int **dl_ch_estimates, - int **rxdataF_ext, - int **dl_ch_estimates_ext, +void nr_dlsch_extract_rbs(uint32_t rxdataF_sz, + c16_t rxdataF[][rxdataF_sz], + uint32_t rx_size, + int32_t dl_ch_estimates[][rx_size], + int32_t rxdataF_ext[][rx_size], + int32_t dl_ch_estimates_ext[][rx_size], unsigned char symbol, uint8_t pilots, uint8_t config_type, @@ -558,7 +560,6 @@ void nr_dlsch_extract_rbs(int **rxdataF, uint16_t dlDmrsSymbPos, int chest_time_type); - /** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation. In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation) @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated @param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated @@ -574,22 +575,23 @@ void nr_dlsch_extract_rbs(int **rxdataF, @param output_shift Rescaling for compensated output (should be energy-normalizing) @param phy_measurements Pointer to UE PHY measurements */ -void nr_dlsch_channel_compensation(int32_t **rxdataF_ext, - int32_t **dl_ch_estimates_ext, - int32_t **dl_ch_mag, - int32_t **dl_ch_magb, - int32_t **dl_ch_magr, - int32_t **rxdataF_comp, - int32_t ***rho, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t nb_aatx, - uint8_t symbol, - int length, - uint8_t first_symbol_flag, - uint8_t mod_order, - uint16_t nb_rb, - uint8_t output_shift, - PHY_NR_MEASUREMENTS *phy_measurements); +void nr_dlsch_channel_compensation(uint32_t rx_size, + int32_t rxdataF_ext[][rx_size], + int32_t dl_ch_estimates_ext[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], + int32_t rxdataF_comp[][rx_size], + int ***rho, + NR_DL_FRAME_PARMS *frame_parms, + uint8_t nb_aatx, + unsigned char symbol, + int length, + uint8_t first_symbol_flag, + unsigned char mod_order, + unsigned short nb_rb, + unsigned char output_shift, + PHY_NR_MEASUREMENTS *measurements); void nr_dlsch_channel_compensation_core(int **rxdataF_ext, int **dl_ch_estimates_ext, @@ -611,18 +613,20 @@ void nr_dlsch_deinterleaving(uint8_t symbol, uint16_t *llr_deint, uint16_t nb_rb_pdsch); -void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext, - int32_t *median, - int n_tx, - int n_rx, - int length, - int start_point); +void nr_dlsch_channel_level_median(uint32_t rx_size, + int32_t dl_ch_estimates[][rx_size], + int32_t *median, + int n_tx, + int n_rx, + int length, + int start_point); -void nr_dlsch_detection_mrc(int **rxdataF_comp, +void nr_dlsch_detection_mrc(uint32_t rx_size, + int32_t rxdataF_comp[][rx_size], int ***rho, - int **dl_ch_mag, - int **dl_ch_magb, - int **dl_ch_magr, + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], short n_tx, short n_rx, unsigned char symbol, @@ -647,23 +651,24 @@ void nr_a_sum_b(__m128i *input_x, @param pilots_flag Flag to indicate pilots in symbol @param nb_rb Number of allocated RBs */ -void nr_dlsch_channel_level(int **dl_ch_estimates_ext, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_tx, - int32_t *avg, - uint8_t symbol, - uint32_t len, - unsigned short nb_rb); - - -void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext, - NR_DL_FRAME_PARMS *frame_parms, - uint8_t n_tx, - uint8_t n_rx, - uint8_t symbol, - uint8_t start_symbol, - uint32_t len, - uint16_t nb_rb); +void nr_dlsch_channel_level(uint32_t rx_size, + int32_t dl_ch_estimates[][rx_size], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_tx, + int32_t *avg, + uint8_t symbol, + uint32_t len, + unsigned short nb_rb); + +void nr_dlsch_scale_channel(uint32_t rx_size, + int32_t dl_ch_estimates[][rx_size], + NR_DL_FRAME_PARMS *frame_parms, + uint8_t n_tx, + uint8_t n_rx, + uint8_t symbol, + uint8_t pilots, + uint32_t len, + unsigned short nb_rb); /** \brief This is the top-level entry point for DLSCH decoding in UE. It should be replicated on several threads (on multi-core machines) corresponding to different HARQ processes. The routine first @@ -751,7 +756,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, int32_t pdcch_est_size, int32_t pdcch_dl_ch_estimates[][pdcch_est_size], int16_t *pdcch_e_rx, - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15); + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); /*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix) @@ -773,16 +779,17 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, struct complex16 dl_ch_estimates[][estimateSz], NR_UE_PBCH *nr_ue_pbch_vars, NR_DL_FRAME_PARMS *frame_parms, - uint8_t eNB_id, uint8_t i_ssb, MIMO_mode_t mimo_mode, nr_phy_data_t *phy_data, - fapiPbch_t* result); + fapiPbch_t* result, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); int nr_pbch_detection(UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, - nr_phy_data_t *phy_data); + nr_phy_data_t *phy_data, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); #ifndef modOrder @@ -862,14 +869,26 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue, */ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - NR_UE_DLSCH_t *dlsch, - unsigned char gNB_id, - unsigned char gNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference - uint32_t frame, - uint8_t nr_slot_rx, + NR_UE_DLSCH_t dlsch[2], unsigned char symbol, unsigned char first_symbol_flag, - unsigned char harq_pid); + unsigned char harq_pid, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size], + int16_t *llr[2], + c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT], + int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT], + uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT], + uint32_t rx_size, + int32_t dl_ch_estimates_ext[][rx_size], + int32_t rxdataF_ext[][rx_size], + int32_t rxdataF_comp[][rx_size], + int32_t dl_ch_mag[][rx_size], + int32_t dl_ch_magb[][rx_size], + int32_t dl_ch_magr[][rx_size], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP], + uint32_t llr_offset[NR_SYMBOLS_PER_SLOT], + int32_t *log2_maxh); int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot); diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 55669ba3229e6c99372565870886ac4941e9aed3..5e60ae29407502b266dfcb8f7aff69f588e07642 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -432,9 +432,8 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, * send srs according to current configuration * *********************************************************************/ -int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) +int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc) { - if(!ue->srs_vars[0]->active) { return -1; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h index 2c3d6d266cf486366e09fe5e0c8f04ba1b2ac6ce..5feea8d9ce3ca072c8f54ddf8193f3ecd2414dc4 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h @@ -175,7 +175,7 @@ int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource, @param current gNB_id identifier @returns 0 if srs is transmitted -1 otherwise */ -int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id); +int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc); #undef EXTERN #undef INIT_VARIABLES_SRS_MODULATION_NR_H diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c index 53191f09462d46d5d411f09a0409e60516ab685c..41829b68f2dbc3e5e2b9fafa80e840d270a5d5c0 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c @@ -318,13 +318,13 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], uint8_t doPss, uint8_t doSss, - uint8_t subframe) // add flag to indicate extracting only PSS, only SSS, or both + uint8_t subframe, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both { uint8_t aarx; int32_t *pss_rxF,*pss_rxF_ext; int32_t *sss_rxF,*sss_rxF_ext; uint8_t pss_symbol, sss_symbol; - int32_t **rxdataF; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { @@ -332,12 +332,10 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue, pss_symbol = 0; sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB; - rxdataF = ue->common_vars.rxdataF; - unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size; - pss_rxF = &rxdataF[aarx][pss_symbol*ofdm_symbol_size]; - sss_rxF = &rxdataF[aarx][sss_symbol*ofdm_symbol_size]; + pss_rxF = (int32_t *)&rxdataF[aarx][pss_symbol*ofdm_symbol_size]; + sss_rxF = (int32_t *)&rxdataF[aarx][sss_symbol*ofdm_symbol_size]; pss_rxF_ext = &pss_ext[aarx][0]; sss_rxF_ext = &sss_ext[aarx][0]; @@ -402,9 +400,10 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, UE_nr_rxtx_proc_t *proc, int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR], int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR], - uint8_t subframe) + uint8_t subframe, + c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP]) { - return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe); + return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe, rxdataF); } /******************************************************************* @@ -420,7 +419,7 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue, * *********************************************************************/ -int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss) +int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { uint8_t i; int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR]; @@ -439,7 +438,8 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, proc, pss_ext, sss_ext, - 0); /* subframe */ + 0, + rxdataF); /* subframe */ #ifdef DEBUG_PLOT_SSS diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 8d963281c43d771c58e6d8293008540be6334f0e..23f6f761818690700f51111a350b5981e2d3dfea 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -788,13 +788,19 @@ static void ueChannelResponse (scopeGraphData_t **data, OAIgraph_t *graph, PHY_ } static void ueFreqWaterFall (scopeGraphData_t **data, OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) { - NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms; //use 1st antenna + if (!data[commonRxdataF]) + return; + + const int sz = data[commonRxdataF]->lineSz; + + scopeSample_t *rxdataF = (scopeSample_t *)(data[commonRxdataF]+1); + genericWaterFall(graph, - (scopeSample_t *)phy_vars_ue->common_vars.rxdataF[0], - frame_parms->samples_per_slot_wCP, - phy_vars_ue->frame_parms.slots_per_frame, - "X axis: one frame frequency" ); + rxdataF, + sz, + 1, + "X axis: one slot frequency" ); } /* static void uePbchFrequencyResp (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { @@ -925,70 +931,48 @@ static void uePcchIQ (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_U } static void uePdschLLR (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PDSCH LLRs - if (!phy_vars_ue->pdsch_vars[eNB_id]->llr[0]) + if (!data[pdschLlr]) return; - int num_re = 4500; - int Qm = 2; - int coded_bits_per_codeword = num_re*Qm; - int newsz = 0; + const int sz = data[pdschLlr]->lineSz; float *llr, *bit; + int nx = sz; + int16_t *pdsch_llr = (int16_t *)(data[pdschLlr]+1); -#ifndef WEBSRVSCOPE - oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0); -#endif - int base=0; - - for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) { - int16_t *pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[eNB_id]->llr[0]; // stream 0 #ifdef WEBSRVSCOPE - newsz += websrv_cpllrbuff_tomsg(graph, pdsch_llr, coded_bits_per_codeword, 0, thr, RX_NB_TH_MAX); + nx = websrv_cpllrbuff_tomsg(graph, pdsch_llr, sz, UE_id, 0, 0); #else - for (int i=0; i<coded_bits_per_codeword; i++) { - llr[base+i] = (float) pdsch_llr[i]; - bit[base+i] = (float) base+i; - } - newsz += coded_bits_per_codeword; -#endif - base+=coded_bits_per_codeword; + oai_xygraph_getbuff(graph, &bit, &llr, sz, 0); + + for (int i=0; i<sz; i++) { + llr[i] = (float) pdsch_llr[i]; } +#endif - AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, ""); //fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword); - oai_xygraph(graph, bit, llr, newsz, 0, 10); + oai_xygraph(graph, bit, llr, nx, 0, 10); } static void uePdschIQ (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { // PDSCH I/Q of MF Output - if (!phy_vars_ue->pdsch_vars[eNB_id]->rxdataF_comp0[0]) + if (!data[pdschRxdataF_comp]) return; - NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms; - int sz=7*2*frame_parms->N_RB_DL*12; // size of the malloced buffer - int newsz = 0; + const int sz=data[pdschRxdataF_comp]->lineSz; + int nz = sz; float *I, *Q; - int base=0; - -#ifndef WEBSRVSCOPE - oai_xygraph_getbuff(graph, &I, &Q, sz * RX_NB_TH_MAX, 0); - memset(I+base, 0, sz*RX_NB_TH_MAX * sizeof(*I)); - memset(Q+base, 0, sz*RX_NB_TH_MAX * sizeof(*Q)); -#endif - for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) { - scopeSample_t *pdsch_comp = (scopeSample_t *) phy_vars_ue->pdsch_vars[eNB_id]->rxdataF_comp0[0]; + scopeSample_t *pdsch_comp = (scopeSample_t *) (data[pdschRxdataF_comp]+1); #ifdef WEBSRVSCOPE - newsz += websrv_cpiqbuff_tomsg(graph, pdsch_comp, sz, 0, base); + nz += websrv_cpiqbuff_tomsg(graph, pdsch_comp, sz, 0, 0); #else - for (int s=0; s<sz; s++) { - I[s+base] += pdsch_comp[s].r; - Q[s+base] += pdsch_comp[s].i; - } - newsz += sz; -#endif - base+=sz; + oai_xygraph_getbuff(graph, &I, &Q, sz, 0); + + for (int s=0; s<sz; s++) { + I[s] = pdsch_comp[s].r; + Q[s] = pdsch_comp[s].i; } +#endif - AssertFatal(base <= sz*RX_NB_TH_MAX, ""); - oai_xygraph(graph, I, Q, newsz, 0, 10); + oai_xygraph(graph, I, Q, nz, 0, 10); } static void uePdschThroughput (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) { /* @@ -1153,19 +1137,23 @@ static void *nrUEscopeThread(void *arg) { } #endif +pthread_mutex_t UEcopyDataMutex; + void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) { // Local static copy of the scope data bufs // The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input) // Index of "2" could be set to the number of Rx threads + 1 - static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][2] = {0}; + static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][3] = {0}; static int copyDataBufsIdx[UEdataTypeNumberOfItems] = {0}; scopeData_t *tmp=(scopeData_t *)ue->scopeData; if (tmp) { - // Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex - int newCopyDataIdx = (copyDataBufsIdx[type]==0)?1:0; + // Begin of critical zone between UE Rx threads that might copy new data at the same time: + pthread_mutex_lock(&UEcopyDataMutex); + int newCopyDataIdx = (copyDataBufsIdx[type]<2)?copyDataBufsIdx[type]+1:0; copyDataBufsIdx[type] = newCopyDataIdx; + pthread_mutex_unlock(&UEcopyDataMutex); // End of critical zone between UE Rx threads // New data will be copied in a different buffer than the live one @@ -1204,6 +1192,7 @@ STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue) pthread_t forms_thread; threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW); #endif + pthread_mutex_init(&UEcopyDataMutex, NULL); } void nrscope_autoinit(void *dataptr) { diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h index 6162e1eee58023622c0aaccc5e2de962aa62bb67..00efbdff245c2958e15db6cf98cfb4c69e63d133 100644 --- a/openair1/PHY/TOOLS/phy_scope_interface.h +++ b/openair1/PHY/TOOLS/phy_scope_interface.h @@ -47,6 +47,9 @@ enum UEdataType { pbchRxdataF_comp, pdcchLlr, pdcchRxdataF_comp, + pdschLlr, + pdschRxdataF_comp, + commonRxdataF, UEdataTypeNumberOfItems }; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 2b96f1582cce8f20dd61b2d5374ac606b1419723..a75529b1d315c74eacc46fc713722b53e2b4ac4a 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -232,11 +232,6 @@ typedef struct { /// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+2048[ int32_t **rxdata; - /// \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; - /// holds output of the sync correlator int32_t *sync_corr; /// estimated frequency offset (in radians) for all subcarriers @@ -245,97 +240,6 @@ typedef struct { int32_t eNb_id; } NR_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 Hold the 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_ch_estimates; - /// \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 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 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, 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, first layer (256QAM level). - int32_t **dl_ch_magr0; - /// \brief Cross-correlation Matrix of the gNB Tx channel signals. - /// - first index: aatx*n_rx+aarx for all aatx=[0..n_tx[ and aarx=[0..nb_rx[ - /// - second index: symbol [0..] - int32_t ***rho; - /// \brief Pointers to llr vectors (2 TBs). - /// - first index: ? [0..1] (hard coded) - /// - second index: ? [0..1179743] (hard coded) - int16_t *llr[2]; - /// Pointers to layer llr vectors (4 layers). - int16_t *layer_llr[4]; - /// \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; - // llr offset per ofdm symbol - uint32_t llr_offset[14]; - // llr length per ofdm symbol - uint32_t llr_length[14]; - // llr offset per ofdm symbol - uint32_t dl_valid_re[14]; - /// \brief Estimated phase error based upon PTRS on each symbol . - /// - first index: ? [0..7] Number of Antenna - /// - second index: ? [0...14] smybol per slot - int32_t **ptrs_phase_per_slot; - /// \brief Estimated phase error based upon PTRS on each symbol . - /// - first index: ? [0..7] Number of Antenna - /// - second index: ? [0...14] smybol per slot - int32_t **ptrs_re_per_slot; -} NR_UE_PDSCH; - #define NR_PRS_IDFT_OVERSAMP_FACTOR 1 // IDFT oversampling factor for NR PRS channel estimates in time domain, ALLOWED value 16x, and 1x is default(ie. IDFT size is frame_params->ofdm_symbol_size) typedef struct { prs_config_t prs_cfg; @@ -421,6 +325,7 @@ typedef struct { typedef struct { int16_t amp; + bool active; fapi_nr_ul_config_prach_pdu prach_pdu; } NR_UE_PRACH; @@ -532,7 +437,6 @@ typedef struct { fapi_nr_config_request_t nrUE_config; - NR_UE_PDSCH *pdsch_vars[NUMBER_OF_CONNECTED_gNB_MAX+1]; NR_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_CSI_IM *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX]; @@ -540,7 +444,7 @@ typedef struct { NR_UE_SRS *srs_vars[NUMBER_OF_CONNECTED_gNB_MAX]; NR_UE_PRS *prs_vars[NR_MAX_PRS_COMB_SIZE]; uint8_t prs_active_gNBs; - NR_DL_UE_HARQ_t dl_harq_processes[NR_MAX_NB_LAYERS>4 ? 2:1][NR_MAX_DLSCH_HARQ_PROCESSES]; + NR_DL_UE_HARQ_t dl_harq_processes[2][NR_MAX_DLSCH_HARQ_PROCESSES]; NR_UL_UE_HARQ_t ul_harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; //Paging parameters @@ -548,10 +452,6 @@ typedef struct { uint32_t PF; uint32_t PO; - UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX]; - /// cell-specific reference symbols - //uint32_t lte_gold_table[7][20][2][14]; - #if defined(UPGRADE_RAT_NR) /// demodulation reference signal for NR PBCH @@ -750,6 +650,13 @@ typedef struct { int dl_errors; int dl_stats[8]; void* scopeData; + // Pointers to hold PDSCH data only for phy simulators + void *phy_sim_rxdataF; + void *phy_sim_pdsch_llr; + void *phy_sim_pdsch_rxdataF_ext; + void *phy_sim_pdsch_rxdataF_comp; + void *phy_sim_pdsch_dl_ch_estimates; + void *phy_sim_pdsch_dl_ch_estimates_ext; } PHY_VARS_NR_UE; typedef struct nr_phy_data_tx_s { @@ -759,7 +666,7 @@ typedef struct nr_phy_data_tx_s { typedef struct nr_phy_data_s { NR_UE_PDCCH_CONFIG phy_pdcch_config; - NR_UE_DLSCH_t dlsch[NR_MAX_NB_LAYERS>4 ? 2:1]; + NR_UE_DLSCH_t dlsch[2]; } nr_phy_data_t; /* this structure is used to pass both UE phy vars and * proc to the function UE_thread_rxn_txnp4 @@ -767,7 +674,6 @@ typedef struct nr_phy_data_s { typedef struct nr_rxtx_thread_data_s { UE_nr_rxtx_proc_t proc; PHY_VARS_NR_UE *UE; - NR_UE_SCHED_MODE_t ue_sched_mode; int writeBlockSize; } nr_rxtx_thread_data_t; diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 742f77186dd8a9987515a4423036645b2e6ad634..6db54684e65927e62ef05cd782491b157e89e154 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -518,102 +518,6 @@ typedef struct { } initial_pucch_resource_t; -/* structure with all possible fields for pucch format from 0 to 4 */ -typedef struct { - pucch_format_nr_t format; /* format 0 1 2 3 4 */ - uint8_t initialCyclicShift; /* x x */ - uint8_t nrofSymbols; /* x x x x x */ - uint8_t startingSymbolIndex; /* x x x x x */ - uint8_t timeDomainOCC; /* x */ - uint8_t nrofPRBs; /* x x */ - uint8_t occ_length; /* x */ - uint8_t occ_Index; /* x */ -} PUCCH_format_t; - -typedef struct { - uint8_t pucch_ResourceId; /* maxNrofPUCCH-Resources = 128 */ - uint16_t startingPRB; /* maxNrofPhysicalResourceBlocks = 275 */ - feature_status_t intraSlotFrequencyHopping; - uint16_t secondHopPRB; - PUCCH_format_t format_parameters; -} PUCCH_Resource_t; - -typedef struct { - uint8_t pucch_ResourceSetId; /* maxNrofPUCCH-ResourceSets = 4 */ -/* - -- PUCCH resources of format0 and format1 are only allowed in the first PUCCH reosurce set, - -- i.e., in a PUCCH-ResourceSet with pucch-ResourceSetId = 0. This set may contain between 8 and 32 resources. - -- PUCCH resources of format2, format3 and format4 are only allowed in a PUCCH-ReosurceSet with pucch-ResourceSetId > 0. If present, these sets must contain 8 resources each. - -- The UE chooses a PUCCH-Resource from this list based on the 3-bit PUCCH resource indicator field in DCI as - -- speciied in 38.213, FFS_section. - -- Note that this list contains only a list of resource IDs. The actual resources are configured in PUCCH-Config. -*/ - uint8_t pucch_resource_id[MAX_NB_OF_PUCCH_RESOURCES_PER_SET]; /* pucch resources belonging to current set is a 32 bit map to address maxNrofPUCCH-ResourcesPerSet = 32 resources */ - - uint8_t first_resources_set_R_PUCCH; /* size of first resource set which can be higher than 8 */ -/* - -- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE - -- chooses the first of its PUCCH-ResourceSet which supports the number of bits that the UE wants to transmit. - -- The field is not present in the first set (Set0) since the maximum Size of Set0 is specified to be 3 bit. - -- The field is not present in the last configured set since the UE derives its maximum payload size as specified in 38.213. - -- This field can take integer values that are multiples of 4. Corresponds to L1 parameter 'N_2' or 'N_3' (see 38.213, section 9.2) -*/ - uint16_t maxPayloadMinus1; /* INTEGER (4..256) */ -} PUCCH_ResourceSet_t; - -typedef struct { -/* - -- Enabling inter-slot frequency hopping when PUCCH Format 1, 3 or 4 is repeated over multiple slots. - -- The field is not applicable for format 2. - */ - feature_status_t interslotFrequencyHopping; -/* - -- Enabling 2 DMRS symbols per hop of a PUCCH Format 3 or 4 if both hops are more than X symbols when FH is enabled (X=4). - -- Enabling 4 DMRS sybmols for a PUCCH Format 3 or 4 with more than 2X+1 symbols when FH is disabled (X=4). - -- Corresponds to L1 parameter 'PUCCH-F3-F4-additional-DMRS' (see 38.213, section 9.2.1) - -- The field is not applicable for format 1 and 2. -*/ - enable_feature_t additionalDMRS; -/* - -- Max coding rate to determine how to feedback UCI on PUCCH for format 2, 3 or 4 - -- Corresponds to L1 parameter 'PUCCH-F2-maximum-coderate', 'PUCCH-F3-maximum-coderate' and 'PUCCH-F4-maximum-coderate' - -- (see 38.213, section 9.2.5) - -- The field is not applicable for format 1. -*/ - PUCCH_MaxCodeRate_t maxCodeRate; -/* - -- Number of slots with the same PUCCH F1, F3 or F4. When the field is absent the UE applies the value n1. - -- Corresponds to L1 parameter 'PUCCH-F1-number-of-slots', 'PUCCH-F3-number-of-slots' and 'PUCCH-F4-number-of-slots' - -- (see 38.213, section 9.2.6) - -- The field is not applicable for format 2. -*/ - uint8_t nrofSlots; -/* - -- Enabling pi/2 BPSK for UCI symbols instead of QPSK for PUCCH. - -- Corresponds to L1 parameter 'PUCCH-PF3-PF4-pi/2PBSK' (see 38.213, section 9.2.5) - -- The field is not applicable for format 1 and 2. -*/ - feature_status_t pi2PBSK; -/* - -- Enabling simultaneous transmission of CSI and HARQ-ACK feedback with or without SR with PUCCH Format 2, 3 or 4 - -- Corresponds to L1 parameter 'PUCCH-F2-Simultaneous-HARQ-ACK-CSI', 'PUCCH-F3-Simultaneous-HARQ-ACK-CSI' and - -- 'PUCCH-F4-Simultaneous-HARQ-ACK-CSI' (see 38.213, section 9.2.5) - -- When the field is absent the UE applies the value OFF - -- The field is not applicable for format 1. -*/ - enable_feature_t simultaneousHARQ_ACK_CSI; -} PUCCH_FormatConfig_t; - -typedef struct { - PUCCH_Resource_t *PUCCH_Resource[MAX_NB_OF_PUCCH_RESOURCES]; - PUCCH_ResourceSet_t *PUCCH_ResourceSet[MAX_NB_OF_PUCCH_RESOURCE_SETS]; - PUCCH_FormatConfig_t *formatConfig[NUMBER_PUCCH_FORMAT_NR-1]; /* format 0 is not there */ - uint8_t dl_DataToUL_ACK[NB_DL_DATA_TO_UL_ACK]; /* table TS 38.213 Table 9.2.3-1: Mapping of PSDCH-to-HARQ_feedback timing indicator field values to numbers of slots */ - void *spatial_Relation_Info[MAX_NR_OF_SPATIAL_RELATION_INFOS]; -} PUCCH_Config_t; - - - /*********************************************************************** * * FUNCTIONALITY : Scheduling Request Configuration (SR) diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 89e5d7501c9c2807d034b56a9a7623dfe5f1c6d5..1439c9fd010dcd98f631c95fa24ef4a886e8e48c 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -96,22 +96,20 @@ typedef struct { @param proc Pointer to RXn-TXnp4 proc information @param eNB_id Local id of eNB on which to act */ -void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, nr_phy_data_tx_t *phy_data); +void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data); /*! \brief Scheduling for UE RX procedures in normal subframes. @param ue Pointer to UE variables on which to act @param proc Pointer to proc information - @param gNB_id Local id of eNB on which to act @param dlsch_parallel use multithreaded dlsch processing @param phy_pdcch_config PDCCH Config for this slot @param txFifo Result fifo if PDSCH is run in parallel */ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, nr_phy_data_t *phy_data); -int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type); +int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type); void processSlotTX(void *arg); @@ -120,7 +118,7 @@ void processSlotTX(void *arg); @param @param */ -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id); +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc); int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); @@ -151,7 +149,6 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, fapi_nr_rx_indication_t *rx_ind, UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, - uint8_t gNB_id, void *phy_data); /*@}*/ @@ -164,7 +161,6 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, */ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, uint8_t pdu_type, - uint8_t gNB_id, PHY_VARS_NR_UE *ue, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, @@ -174,26 +170,26 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - int gNB_id, - NR_UE_DLSCH_t *dlsch0, - NR_UE_DLSCH_t *dlsch1); + NR_UE_DLSCH_t dlsch[2], + int16_t* llr[2]); int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - int gNB_id, - NR_UE_DLSCH_t *dlsch); + NR_UE_DLSCH_t dlsch[2], + int16_t *llr[2], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); -int nr_ue_pdcch_procedures(uint8_t gNB_id, - PHY_VARS_NR_UE *ue, +int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t pdcch_est_size, int32_t pdcch_dl_ch_estimates[][pdcch_est_size], nr_phy_data_t *phy_data, - int n_ss); + int n_ss, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); -int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id); +int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); -int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id); +int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]); #endif diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 9c9e7a249b5da6f776ba2f9199afbc75e17fa716..e7fc09e4a26ffde59339042e7fa8729aaa5fd538 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -49,6 +49,7 @@ const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"}; queue_t nr_rx_ind_queue; queue_t nr_crc_ind_queue; queue_t nr_uci_ind_queue; +queue_t nr_rach_ind_queue; static void fill_uci_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4, fapi_nr_ul_config_pucch_pdu *pucch_pdu) @@ -108,29 +109,56 @@ static void free_uci_inds(nfapi_nr_uci_indication_t *uci_ind) } int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response) { + NR_UE_MAC_INST_t *mac = get_mac_inst(0); - if(scheduled_response != NULL) - { - if (scheduled_response->ul_config != NULL) - { + + if(scheduled_response != NULL) { + if (scheduled_response->ul_config != NULL) { fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config; AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), "Too many ul_config pdus %d", ul_config->number_pdus); - for (int i = 0; i < ul_config->number_pdus; ++i) - { + for (int i = 0; i < ul_config->number_pdus; ++i) { LOG_D(NR_PHY, "In %s: processing type %d PDU of %d total UL PDUs (ul_config %p) \n", __FUNCTION__, ul_config->ul_config_list[i].pdu_type, ul_config->number_pdus, ul_config); uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type; - switch (pdu_type) - { - case (FAPI_NR_UL_CONFIG_TYPE_PUSCH): - { + switch (pdu_type) { + case FAPI_NR_UL_CONFIG_TYPE_PRACH: { + fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[i].prach_config_pdu; + nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind)); + rach_ind->sfn = scheduled_response->frame; + rach_ind->slot = scheduled_response->slot; + rach_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION; + uint8_t pdu_index = 0; + rach_ind->pdu_list = CALLOC(1, sizeof(*rach_ind->pdu_list)); + rach_ind->number_of_pdus = 1; + rach_ind->pdu_list[pdu_index].phy_cell_id = prach_pdu->phys_cell_id; + rach_ind->pdu_list[pdu_index].symbol_index = prach_pdu->prach_start_symbol; + rach_ind->pdu_list[pdu_index].slot_index = prach_pdu->prach_slot; + rach_ind->pdu_list[pdu_index].freq_index = prach_pdu->num_ra; + rach_ind->pdu_list[pdu_index].avg_rssi = 128; + rach_ind->pdu_list[pdu_index].avg_snr = 0xff; // invalid for now + rach_ind->pdu_list[pdu_index].num_preamble = 1; + const int num_p = rach_ind->pdu_list[pdu_index].num_preamble; + rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t)); + rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index = prach_pdu->ra_PreambleIndex; + rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance = 0; + rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff; + + if (!put_queue(&nr_rach_ind_queue, rach_ind)) { + for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++) + free(rach_ind->pdu_list[pdu_index].preamble_list); + free(rach_ind->pdu_list); + free(rach_ind); + } + LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n"); + break; + } + case (FAPI_NR_UL_CONFIG_TYPE_PUSCH): { nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind)); nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind)); nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu; - if (scheduled_response->tx_request) - { + if (scheduled_response->tx_request) { AssertFatal(scheduled_response->tx_request->number_of_pdus < sizeof(scheduled_response->tx_request->tx_request_body) / sizeof(scheduled_response->tx_request->tx_request_body[0]), "Too many tx_req pdus %d", scheduled_response->tx_request->number_of_pdus); @@ -139,8 +167,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response rx_ind->slot = scheduled_response->ul_config->slot; rx_ind->number_of_pdus = scheduled_response->tx_request->number_of_pdus; rx_ind->pdu_list = CALLOC(rx_ind->number_of_pdus, sizeof(*rx_ind->pdu_list)); - for (int j = 0; j < rx_ind->number_of_pdus; j++) - { + for (int j = 0; j < rx_ind->number_of_pdus; j++) { fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[j]; rx_ind->pdu_list[j].handle = pusch_config_pdu->handle; rx_ind->pdu_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; @@ -160,8 +187,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response crc_ind->sfn = scheduled_response->ul_config->sfn; crc_ind->slot = scheduled_response->ul_config->slot; crc_ind->crc_list = CALLOC(crc_ind->number_crcs, sizeof(*crc_ind->crc_list)); - for (int j = 0; j < crc_ind->number_crcs; j++) - { + for (int j = 0; j < crc_ind->number_crcs; j++) { crc_ind->crc_list[j].handle = pusch_config_pdu->handle; crc_ind->crc_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id; LOG_D(NR_MAC, "This is the harq pid %d for crc_list[%d]\n", crc_ind->crc_list[j].harq_id, j); @@ -179,11 +205,9 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response scheduled_response->frame, scheduled_response->slot, crc_ind->sfn, crc_ind->slot,pusch_config_pdu->mcs_index); } - if (!put_queue(&nr_rx_ind_queue, rx_ind)) - { + if (!put_queue(&nr_rx_ind_queue, rx_ind)) { LOG_E(NR_MAC, "Put_queue failed for rx_ind\n"); - for (int i = 0; i < rx_ind->number_of_pdus; i++) - { + for (int i = 0; i < rx_ind->number_of_pdus; i++) { free(rx_ind->pdu_list[i].pdu); rx_ind->pdu_list[i].pdu = NULL; } @@ -193,8 +217,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response free(rx_ind); rx_ind = NULL; } - if (!put_queue(&nr_crc_ind_queue, crc_ind)) - { + if (!put_queue(&nr_crc_ind_queue, crc_ind)) { LOG_E(NR_MAC, "Put_queue failed for crc_ind\n"); free(crc_ind->crc_list); crc_ind->crc_list = NULL; @@ -203,32 +226,26 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response } LOG_D(PHY, "In %s: Filled queue rx/crc_ind which was filled by ulconfig. \n", __FUNCTION__); - scheduled_response->tx_request->number_of_pdus = 0; } break; } - - case FAPI_NR_UL_CONFIG_TYPE_PUCCH: - { + case FAPI_NR_UL_CONFIG_TYPE_PUCCH: { nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind)); uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION; uci_ind->sfn = scheduled_response->frame; uci_ind->slot = scheduled_response->slot; uci_ind->num_ucis = 1; uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list)); - for (int j = 0; j < uci_ind->num_ucis; j++) - { + for (int j = 0; j < uci_ind->num_ucis; j++) { LOG_D(NR_MAC, "ul_config->ul_config_list[%d].pucch_config_pdu.n_bit = %d\n", i, ul_config->ul_config_list[i].pucch_config_pdu.n_bit); - if (ul_config->ul_config_list[i].pucch_config_pdu.n_bit > 3 && mac->nr_ue_emul_l1.num_csi_reports > 0) - { + if (ul_config->ul_config_list[i].pucch_config_pdu.n_bit > 3 && mac->nr_ue_emul_l1.num_csi_reports > 0) { uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE; uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t); nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[j].pucch_pdu_format_2_3_4; fill_uci_2_3_4(pdu_2_3_4, &ul_config->ul_config_list[i].pucch_config_pdu); } - else - { + else { nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1; uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); @@ -248,12 +265,10 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response pdu_0_1->harq->harq_confidence_level = 0; pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list)); int harq_pid = -1; - for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) - { + for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) { if (mac->nr_ue_emul_l1.harq[k].active && mac->nr_ue_emul_l1.harq[k].active_dl_harq_sfn == uci_ind->sfn && - mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot) - { + mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot) { mac->nr_ue_emul_l1.harq[k].active = false; harq_pid = k; AssertFatal(harq_index < pdu_0_1->harq->num_harq, "Invalid harq_index %d\n", harq_index); @@ -481,6 +496,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ // prach config pdu prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu; memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu)); + PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->active = true; ul_config->ul_config_list[i].pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more pdu_done++; LOG_D(PHY, "%d.%d ul A ul_config %p t %d pdu_done %d number_pdus %d\n", scheduled_response->frame, slot, ul_config, pdu_type, pdu_done, ul_config->number_pdus); @@ -533,11 +549,9 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){ fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; - if(phy_config != NULL) { - memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t)); - if (PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] == NOT_SYNCHED) - PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] = PRACH; - } + if(phy_config != NULL) + memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t)); + return 0; } diff --git a/openair1/SCHED_NR_UE/harq_nr.h b/openair1/SCHED_NR_UE/harq_nr.h index e511e6f1c651bd4b8ef6354a8b0baa531d34d9f2..f640d0f7be96e69c428ac0932030f3f202cb8842 100644 --- a/openair1/SCHED_NR_UE/harq_nr.h +++ b/openair1/SCHED_NR_UE/harq_nr.h @@ -65,6 +65,11 @@ /*************** FUNCTIONS ****************************************/ +/** \brief This function update uplink harq context and return transmission type (new transmission or retransmission) + @param ulsch uplink harq context + @param harq process identifier harq_pid + @returns retransmission or new transmission */ + harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, NR_UL_UE_HARQ_t harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES], int ndi, uint8_t rnti_type); /** \brief This function initialises downlink HARQ status diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 305cf3922501f18c4acac979b8be033e724dfd8a..5d624bfd63b03174e44124a322814c6d509352d2 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -52,7 +52,8 @@ #include "executables/softmodem-common.h" #include "executables/nr-uesoftmodem.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" -#include "openair1/SCHED_NR_UE/pucch_uci_ue_nr.h" +#include "SCHED_NR_UE/pucch_uci_ue_nr.h" +#include <openair1/PHY/TOOLS/phy_scope_interface.h> //#define DEBUG_PHY_PROC #define NR_PDCCH_SCHED @@ -76,8 +77,6 @@ fifo_dump_emos_UE emos_dump_UE; #include "intertask_interface.h" #include "T.h" -char nr_mode_string[NUM_UE_MODE][20] = {"NOT SYNCHED","PRACH","RAR","RA_WAIT_CR", "PUSCH", "RESYNCH"}; - #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) extern uint64_t downlink_frequency[MAX_NUM_CCs][4]; #endif @@ -89,12 +88,11 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, fapi_nr_rx_indication_t *rx_ind, UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, - uint8_t gNB_id, void *phy_data){ memset((void*)dl_ind, 0, sizeof(nr_downlink_indication_t)); - dl_ind->gNB_index = gNB_id; + dl_ind->gNB_index = proc->gNB_id; dl_ind->module_id = ue->Mod_id; dl_ind->cc_id = ue->CC_id; dl_ind->frame = proc->frame_rx; @@ -116,7 +114,6 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, uint8_t pdu_type, - uint8_t gNB_id, PHY_VARS_NR_UE *ue, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, @@ -270,11 +267,11 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, nr_phy_data_tx_t *phy_data) { int slot_tx = proc->nr_slot_tx; int frame_tx = proc->frame_tx; + int gNB_id = proc->gNB_id; AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); @@ -287,22 +284,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, start_meas(&ue->phy_proc_tx); - if (ue->UE_mode[gNB_id] <= PUSCH){ - - for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) { - if (ue->ul_harq_processes[harq_pid].status == ACTIVE) - nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data); - } + for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) { + if (ue->ul_harq_processes[harq_pid].status == ACTIVE) + nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data); } - ue_srs_procedures_nr(ue, proc, gNB_id); + ue_srs_procedures_nr(ue, proc); - if (ue->UE_mode[gNB_id] <= PUSCH) { - pucch_procedures_ue_nr(ue, - gNB_id, - proc, - phy_data); - } + pucch_procedures_ue_nr(ue, proc, phy_data); LOG_D(PHY, "Sending Uplink data \n"); nr_ue_pusch_common_procedures(ue, @@ -310,8 +299,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, &ue->frame_parms, ue->frame_parms.nb_antennas_tx); - if (ue->UE_mode[gNB_id] > NOT_SYNCHED && ue->UE_mode[gNB_id] < PUSCH) - nr_ue_prach_procedures(ue, proc, proc->gNB_id); + nr_ue_prach_procedures(ue, proc); LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx); @@ -322,13 +310,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, void nr_ue_measurement_procedures(uint16_t l, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, - uint16_t slot, - NR_UE_DLSCH_t *dlsch){ + NR_UE_DLSCH_t *dlsch, + uint32_t pdsch_est_size, + int32_t dl_ch_estimates[][pdsch_est_size]) { NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; + int gNB_id = proc->gNB_id; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN); if (l==2) { @@ -339,10 +328,10 @@ void nr_ue_measurement_procedures(uint16_t l, nr_slot_rx, ue->common_vars.rxdata); - nr_ue_measurements(ue, proc, nr_slot_rx, dlsch); + nr_ue_measurements(ue, proc, dlsch, pdsch_est_size, dl_ch_estimates); #if T_TRACER - if(slot == 0) + if(nr_slot_rx == 0) T(T_UE_PHY_MEAS, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx), T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)), T_INT((int)ue->measurements.rx_rssi_dBm[0]), @@ -355,7 +344,7 @@ void nr_ue_measurement_procedures(uint16_t l, } // accumulate and filter timing offset estimation every subframe (instead of every frame) - if (( slot == 2) && (l==(2-frame_parms->Ncp))) { + if (( nr_slot_rx == 2) && (l==(2-frame_parms->Ncp))) { // AGC @@ -372,46 +361,40 @@ void nr_ue_measurement_procedures(uint16_t l, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT); } -static void nr_ue_pbch_procedures(uint8_t gNB_id, - PHY_VARS_NR_UE *ue, +static void nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int estimateSz, struct complex16 dl_ch_estimates[][estimateSz], - nr_phy_data_t *phy_data) { + nr_phy_data_t *phy_data, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int ret = 0; DevAssert(ue); int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; + int gNB_id = proc->gNB_id; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); LOG_D(PHY,"[UE %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id); fapiPbch_t result; - ret = nr_rx_pbch(ue, proc, - estimateSz, dl_ch_estimates, + ret = nr_rx_pbch(ue, + proc, + estimateSz, + dl_ch_estimates, ue->pbch_vars[gNB_id], &ue->frame_parms, - gNB_id, (ue->frame_parms.ssb_index)&7, SISO, phy_data, - &result); + &result, + rxdataF); if (ret==0) { ue->pbch_vars[gNB_id]->pdu_errors_conseq = 0; - // Switch to PRACH state if it is first PBCH after initial synch and no timing correction is performed - if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){ - if (get_softmodem_params()->do_ra) { - ue->UE_mode[gNB_id] = PRACH; - } else { - ue->UE_mode[gNB_id] = PUSCH; - } - } - #ifdef DEBUG_PHY_PROC uint16_t frame_tx; LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n", @@ -498,13 +481,13 @@ unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb #ifdef NR_PDCCH_SCHED -int nr_ue_pdcch_procedures(uint8_t gNB_id, - PHY_VARS_NR_UE *ue, +int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t pdcch_est_size, int32_t pdcch_dl_ch_estimates[][pdcch_est_size], nr_phy_data_t *phy_data, - int n_ss) + int n_ss, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; @@ -522,7 +505,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, int16_t pdcch_e_rx[pdcch_e_rx_size]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN); - nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15); + nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15, rxdataF); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT); @@ -543,18 +526,18 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, //LOG_D(PHY,"[UE %d][PUSCH] Frame %d nr_slot_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_slot_rx); for (int i=0; i<dci_cnt; i++) { - LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI %i of %d total DCIs found --> rnti %x : format %d\n", - ue->Mod_id,frame_rx%1024,nr_slot_rx,nr_mode_string[ue->UE_mode[gNB_id]], - i + 1, - dci_cnt, - dci_ind.dci_list[i].rnti, - dci_ind.dci_list[i].dci_format); + LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n", + ue->Mod_id,frame_rx%1024,nr_slot_rx, + i + 1, + dci_cnt, + dci_ind.dci_list[i].rnti, + dci_ind.dci_list[i].dci_format); } dci_ind.number_of_dcis = dci_cnt; // fill dl_indication message - nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, gNB_id, phy_data); + nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data); // send to mac ue->if_inst->dl_indication(&dl_indication, NULL); @@ -566,23 +549,22 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id, } #endif // NR_PDCCH_SCHED -int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_id, NR_UE_DLSCH_t *dlsch) { +int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, + UE_nr_rxtx_proc_t *proc, + NR_UE_DLSCH_t dlsch[2], + int16_t *llr[2], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; int m; - int gNB_id_i; int first_symbol_flag=0; if (!dlsch[0].active) return 0; - NR_UE_DLSCH_t *dlsch1 = NULL; - - if (NR_MAX_NB_LAYERS > 4) - dlsch1 = &dlsch[1]; - - if (!dlsch1) { + // We handle only one CW now + if (!(NR_MAX_NB_LAYERS>4)) { NR_UE_DLSCH_t *dlsch0 = &dlsch[0]; int harq_pid = dlsch0->dlsch_config.harq_process_nbr; NR_DL_UE_HARQ_t *dlsch0_harq = ue->dl_harq_processes[harq_pid]; @@ -596,15 +578,17 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ LOG_D(PHY,"[UE %d] nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x, Nl %d\n", ue->Mod_id,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->dlsch_config.dlDmrsSymbPos, dlsch0->Nl); + const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot*ue->frame_parms.ofdm_symbol_size+15)/16)*16; + __attribute__ ((aligned(32))) int32_t pdsch_dl_ch_estimates[ue->frame_parms.nb_antennas_rx][pdsch_est_size]; + memset(pdsch_dl_ch_estimates, 0, sizeof(int32_t)*ue->frame_parms.nb_antennas_rx*pdsch_est_size); + for (m = s0; m < (s0 +s1); m++) { if (dlsch0->dlsch_config.dlDmrsSymbPos & (1 << m)) { for (uint8_t aatx=0; aatx<dlsch0->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m); nr_pdsch_channel_estimation(ue, proc, - gNB_id, is_SI, - nr_slot_rx, get_dmrs_port(aatx,dlsch0->dlsch_config.dmrs_ports), m, dlsch0->dlsch_config.nscid, @@ -612,7 +596,10 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ BWPStart, dlsch0->dlsch_config.dmrsConfigType, ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12, - pdsch_nb_rb); + pdsch_nb_rb, + pdsch_est_size, + pdsch_dl_ch_estimates, + rxdataF); #if 0 ///LOG_M: the channel estimation int nr_frame_rx = proc->frame_rx; @@ -626,10 +613,11 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ } } } + nr_ue_measurement_procedures(2, ue, proc, &dlsch[0], pdsch_est_size, pdsch_dl_ch_estimates); if (ue->chest_time == 1) { // averaging time domain channel estimates nr_chest_time_domain_avg(&ue->frame_parms, - ue->pdsch_vars[gNB_id]->dl_ch_estimates, + (int32_t **) pdsch_dl_ch_estimates, dlsch0->dlsch_config.number_symbols, dlsch0->dlsch_config.start_symbol, dlsch0->dlsch_config.dlDmrsSymbPos, @@ -648,10 +636,40 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ first_symbol_with_data++; } + c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; + memset(ptrs_phase_per_slot, 0, ue->frame_parms.nb_antennas_rx*NR_SYMBOLS_PER_SLOT*sizeof(c16_t)); + + int32_t ptrs_re_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT]; + memset(ptrs_re_per_slot, 0, ue->frame_parms.nb_antennas_rx*NR_SYMBOLS_PER_SLOT*sizeof(c16_t)); + + uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT] = {0}; + uint32_t llr_offset[NR_SYMBOLS_PER_SLOT] = {0}; + + const uint32_t rx_size = NR_SYMBOLS_PER_SLOT* + dlsch[0].dlsch_config.number_rbs* + NR_NB_SC_PER_RB; + __attribute__ ((aligned(32))) int32_t dl_ch_estimates_ext[ue->frame_parms.nb_antennas_rx][rx_size]; + memset(dl_ch_estimates_ext, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t)); + + __attribute__ ((aligned(32))) int32_t rxdataF_ext[ue->frame_parms.nb_antennas_rx][rx_size]; + memset(rxdataF_ext, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t)); + + __attribute__ ((aligned(32))) int32_t rxdataF_comp[ue->frame_parms.nb_antennas_rx][rx_size]; + memset(rxdataF_comp, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t)); + + __attribute__ ((aligned(32))) int32_t dl_ch_mag[ue->frame_parms.nb_antennas_rx][rx_size]; + memset(dl_ch_mag, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t)); + + __attribute__ ((aligned(32))) int32_t dl_ch_magb[ue->frame_parms.nb_antennas_rx][rx_size]; + memset(dl_ch_magb, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t)); + + __attribute__ ((aligned(32))) int32_t dl_ch_magr[ue->frame_parms.nb_antennas_rx][rx_size]; + memset(dl_ch_magr, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t)); + + int32_t log2_maxh = 0; start_meas(&ue->rx_pdsch_stats); for (m = s0; m < (s1 + s0); m++) { - gNB_id_i = gNB_id+1; if (m==first_symbol_with_data) first_symbol_flag = 1; else @@ -666,13 +684,25 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ if (nr_rx_pdsch(ue, proc, dlsch, - gNB_id, - gNB_id_i, - frame_rx, - nr_slot_rx, m, first_symbol_flag, - harq_pid) < 0) + harq_pid, + pdsch_est_size, + pdsch_dl_ch_estimates, + llr, + ptrs_phase_per_slot, + ptrs_re_per_slot, + dl_valid_re, + rx_size, + dl_ch_estimates_ext, + rxdataF_ext, + rxdataF_comp, + dl_ch_mag, + dl_ch_magb, + dl_ch_magr, + rxdataF, + llr_offset, + &log2_maxh) < 0) return -1; stop_meas(&ue->dlsch_llr_stats_parallelization[slot]); @@ -683,27 +713,40 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_ } } // CRNTI active stop_meas(&ue->rx_pdsch_stats); + + UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp, sizeof(struct complex16), ue->frame_parms.nb_antennas_rx, rx_size); + + if (ue->phy_sim_pdsch_rxdataF_comp) + memcpy(ue->phy_sim_pdsch_rxdataF_comp, rxdataF_comp, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx); + if (ue->phy_sim_pdsch_rxdataF_ext) + memcpy(ue->phy_sim_pdsch_rxdataF_ext, rxdataF_ext, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx); + if (ue->phy_sim_pdsch_dl_ch_estimates_ext) + memcpy(ue->phy_sim_pdsch_dl_ch_estimates_ext, dl_ch_estimates_ext, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx); + if (ue->phy_sim_pdsch_dl_ch_estimates) + memcpy(ue->phy_sim_pdsch_dl_ch_estimates, dl_ch_estimates_ext, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx); } return 0; } bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - int gNB_id, - NR_UE_DLSCH_t *dlsch0, - NR_UE_DLSCH_t *dlsch1) { + NR_UE_DLSCH_t dlsch[2], + int16_t* llr[2]) { - if (dlsch0==NULL) - AssertFatal(0,"dlsch0 should be defined at this level \n"); + if (dlsch[0].active == false) { + LOG_E(PHY, "DLSCH should be active when calling this function\n"); + return 1; + } + + int gNB_id = proc->gNB_id; bool dec = false; - int harq_pid = dlsch0->dlsch_config.harq_process_nbr; + int harq_pid = dlsch[0].dlsch_config.harq_process_nbr; int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; uint32_t ret = UINT32_MAX, ret1 = UINT32_MAX; - NR_UE_PDSCH *pdsch_vars; NR_DL_UE_HARQ_t *dl_harq0 = &ue->dl_harq_processes[0][harq_pid]; - NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[NR_MAX_NB_LAYERS>4 ? 1:0][harq_pid]; - uint16_t dmrs_len = get_num_dmrs(dlsch0->dlsch_config.dlDmrsSymbPos); + NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[1][harq_pid]; + uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind)); uint16_t number_pdus = 1; @@ -711,45 +754,40 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id]; uint8_t is_cw0_active = dl_harq0->status; - uint16_t nb_symb_sch = dlsch0->dlsch_config.number_symbols; - uint16_t start_symbol = dlsch0->dlsch_config.start_symbol; - uint8_t dmrs_type = dlsch0->dlsch_config.dmrsConfigType; + uint8_t is_cw1_active = dl_harq1->status; + uint16_t nb_symb_sch = dlsch[0].dlsch_config.number_symbols; + uint16_t start_symbol = dlsch[0].dlsch_config.start_symbol; + uint8_t dmrs_type = dlsch[0].dlsch_config.dmrsConfigType; uint8_t nb_re_dmrs; if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { - nb_re_dmrs = 6*dlsch0->dlsch_config.n_dmrs_cdm_groups; + nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups; } else { - nb_re_dmrs = 4*dlsch0->dlsch_config.n_dmrs_cdm_groups; + nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups; } - uint8_t is_cw1_active = 0; - if(dlsch1) - is_cw1_active = dl_harq1->status; - LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw0_active); LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw1_active); - pdsch_vars = ue->pdsch_vars[gNB_id]; - // exit dlsch procedures as there are no active dlsch if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE) return false; // start ldpc decode for CW 0 - dl_harq0->G = nr_get_G(dlsch0->dlsch_config.number_rbs, + dl_harq0->G = nr_get_G(dlsch[0].dlsch_config.number_rbs, nb_symb_sch, nb_re_dmrs, dmrs_len, - dlsch0->dlsch_config.qamModOrder, - dlsch0->Nl); + dlsch[0].dlsch_config.qamModOrder, + dlsch[0].Nl); start_meas(&ue->dlsch_unscrambling_stats); - nr_dlsch_unscrambling(pdsch_vars->llr[0], + nr_dlsch_unscrambling(llr[0], dl_harq0->G, 0, ue->frame_parms.Nid_cell, - dlsch0->rnti); + dlsch[0].rnti); stop_meas(&ue->dlsch_unscrambling_stats); @@ -759,9 +797,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, ret = nr_dlsch_decoding(ue, proc, gNB_id, - pdsch_vars->llr[0], + llr[0], &ue->frame_parms, - dlsch0, + &dlsch[0], dl_harq0, frame_rx, nb_symb_sch, @@ -775,7 +813,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, dec = true; int ind_type = -1; - switch(dlsch0->rnti_type) { + switch(dlsch[0].rnti_type) { case _RA_RNTI_: ind_type = FAPI_NR_RX_PDU_TYPE_RAR; break; @@ -789,14 +827,14 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, break; default: - AssertFatal(true, "Invalid DLSCH type %d\n", dlsch0->rnti_type); + AssertFatal(true, "Invalid DLSCH type %d\n", dlsch[0].rnti_type); break; } - nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL); - nr_fill_rx_indication(rx_ind, ind_type, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, NULL); + nr_fill_rx_indication(rx_ind, ind_type, ue, &dlsch[0], NULL, number_pdus, proc, NULL); - LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->dlsch_config.TBS, dlsch0->dlsch_config.TBS / 8); + LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch[0].dlsch_config.TBS, dlsch[0].dlsch_config.TBS / 8); stop_meas(&ue->dlsch_decoding_stats); if (cpumeas(CPUMEAS_GETSTATE)) { @@ -808,18 +846,18 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if(is_cw1_active) { // start ldpc decode for CW 1 - dl_harq1->G = nr_get_G(dlsch1->dlsch_config.number_rbs, + dl_harq1->G = nr_get_G(dlsch[1].dlsch_config.number_rbs, nb_symb_sch, nb_re_dmrs, dmrs_len, - dlsch1->dlsch_config.qamModOrder, - dlsch1->Nl); + dlsch[1].dlsch_config.qamModOrder, + dlsch[1].Nl); start_meas(&ue->dlsch_unscrambling_stats); - nr_dlsch_unscrambling(pdsch_vars->llr[1], + nr_dlsch_unscrambling(llr[1], dl_harq1->G, 0, ue->frame_parms.Nid_cell, - dlsch1->rnti); + dlsch[1].rnti); stop_meas(&ue->dlsch_unscrambling_stats); start_meas(&ue->dlsch_decoding_stats); @@ -827,9 +865,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, ret1 = nr_dlsch_decoding(ue, proc, gNB_id, - pdsch_vars->llr[1], + llr[1], &ue->frame_parms, - dlsch1, + &dlsch[1], dl_harq1, frame_rx, nb_symb_sch, @@ -844,7 +882,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n", frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0)); } - LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch0->dlsch_config.TBS); + LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch[1].dlsch_config.TBS); } // send to mac if (ue->if_inst && ue->if_inst->dl_indication) { @@ -996,11 +1034,11 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - uint8_t gNB_id, nr_phy_data_t *phy_data) { int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; + int gNB_id = proc->gNB_id; fapi_nr_config_request_t *cfg = &ue->nrUE_config; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; @@ -1012,6 +1050,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ****** \n", frame_rx%1024, nr_slot_rx); + const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP; + __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; // checking if current frame is compatible with SSB periodicity if (cfg->ssb_table.ssb_period == 0 || !(frame_rx%(1<<(cfg->ssb_table.ssb_period-1)))){ @@ -1039,17 +1079,23 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_slot_fep(ue, proc, (ssb_start_symbol+i)%(fp->symbols_per_slot), - nr_slot_rx); + rxdataF); start_meas(&ue->dlsch_channel_estimation_stats); - nr_pbch_channel_estimation(ue, estimateSz, dl_ch_estimates, - dl_ch_estimates_time, proc, gNB_id, - nr_slot_rx, (ssb_start_symbol+i)%(fp->symbols_per_slot), - i-1, ssb_index&7, ssb_slot_2 == nr_slot_rx); + nr_pbch_channel_estimation(ue, + estimateSz, + dl_ch_estimates, + dl_ch_estimates_time, + proc, + (ssb_start_symbol+i)%(fp->symbols_per_slot), + i-1, + ssb_index&7, + ssb_slot_2 == nr_slot_rx, + rxdataF); stop_meas(&ue->dlsch_channel_estimation_stats); } - nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, nr_slot_rx); + nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, rxdataF); // resetting ssb index for PBCH detection if there is a stronger SSB index if(ue->measurements.ssb_rsrp_dBm[ssb_index] > ue->measurements.ssb_rsrp_dBm[fp->ssb_index]) @@ -1058,23 +1104,23 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if(ssb_index == fp->ssb_index) { LOG_D(PHY," ------ Decode MIB: frame.slot %d.%d ------ \n", frame_rx%1024, nr_slot_rx); - nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates, phy_data); + nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF); if (ue->no_timing_correction==0) { - LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); - nr_adjust_synch_ue(fp, - ue, - gNB_id, - fp->ofdm_symbol_size, - dl_ch_estimates_time, - frame_rx, - nr_slot_rx, - 0, - 16384); + LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction); + nr_adjust_synch_ue(fp, + ue, + gNB_id, + fp->ofdm_symbol_size, + dl_ch_estimates_time, + frame_rx, + nr_slot_rx, + 0, + 16384); } } LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__); - nr_ue_rrc_measurements(ue, proc, nr_slot_rx); + nr_ue_rrc_measurements(ue, proc, rxdataF); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_OUT); } } @@ -1096,9 +1142,14 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_slot_fep(ue, proc, (j%fp->symbols_per_slot), - nr_slot_rx); + rxdataF); } - nr_prs_channel_estimation(gNB_id,rsc_id,i,ue,proc,fp); + nr_prs_channel_estimation(rsc_id, + i, + ue, + proc, + fp, + rxdataF); } } // for i } // for rsc_id @@ -1132,7 +1183,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_slot_fep(ue, proc, l, - nr_slot_rx); + rxdataF); } // Hold the channel estimates in frequency domain. @@ -1147,19 +1198,18 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_pdcch_channel_estimation(ue, proc, - gNB_id, - nr_slot_rx, l, &phy_pdcch_config->pdcch_config[n_ss].coreset, fp->first_carrier_offset, phy_pdcch_config->pdcch_config[n_ss].BWPStart, pdcch_est_size, - pdcch_dl_ch_estimates); + pdcch_dl_ch_estimates, + rxdataF); stop_meas(&ue->ofdm_demod_stats); } - dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss); + dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF); } phy_pdcch_config->nb_search_space = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT); @@ -1181,7 +1231,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, nr_slot_fep(ue, proc, m, //to be updated from higher layer - nr_slot_rx); + rxdataF); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT); } @@ -1194,27 +1244,47 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, start_meas(&ue->generic_stat); // do procedures for C-RNTI int ret_pdsch = 0; - if (dlsch->active) { + if (dlsch[0].active) { + + uint8_t nb_re_dmrs; + if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups; + } + else { + nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups; + } + uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos); + + const uint32_t rx_llr_size = nr_get_G(dlsch[0].dlsch_config.number_rbs, + dlsch[0].dlsch_config.number_symbols, + nb_re_dmrs, + dmrs_len, + dlsch[0].dlsch_config.qamModOrder, + dlsch[0].Nl); + const uint32_t rx_llr_buf_sz = ((rx_llr_size+15)/16)*16; + const uint32_t nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1; + int16_t* llr[2]; + for (int i=0; i<nb_codewords; i++) + llr[i] = (int16_t *)malloc16_clear(rx_llr_buf_sz*sizeof(int16_t)); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN); ret_pdsch = nr_ue_pdsch_procedures(ue, proc, - gNB_id, - dlsch); + dlsch, + llr, + rxdataF); - nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx, dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT); + UEscopeCopy(ue, pdschLlr, llr[0], sizeof(int16_t), 1, rx_llr_size); + LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d\n", nr_slot_rx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); start_meas(&ue->dlsch_procedures_stat); - NR_UE_DLSCH_t *dlsch1 = NULL; - if (NR_MAX_NB_LAYERS>4) - dlsch1 = &phy_data->dlsch[1]; - if (ret_pdsch >= 0) - nr_ue_dlsch_procedures(ue, proc, gNB_id, dlsch, dlsch1); + nr_ue_dlsch_procedures(ue, proc, dlsch, llr); stop_meas(&ue->dlsch_procedures_stat); if (cpumeas(CPUMEAS_GETSTATE)) { @@ -1222,8 +1292,14 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0)); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + if (ue->phy_sim_rxdataF) + memcpy(ue->phy_sim_rxdataF, rxdataF, sizeof(int32_t)*rxdataF_sz*ue->frame_parms.nb_antennas_rx); + if (ue->phy_sim_pdsch_llr) + memcpy(ue->phy_sim_pdsch_llr, llr[0], sizeof(int16_t)*rx_llr_buf_sz); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + for (int i=0; i<nb_codewords; i++) + free(llr[i]); } // do procedures for CSI-IM @@ -1238,10 +1314,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, } l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]; if(nr_slot_fep_done == false) { - nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], nr_slot_rx); + nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], rxdataF); } } - nr_ue_csi_im_procedures(ue, proc, gNB_id); + nr_ue_csi_im_procedures(ue, proc, rxdataF); ue->csiim_vars[gNB_id]->active = 0; } @@ -1249,10 +1325,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) { for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) { if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu,symb)) { - nr_slot_fep(ue, proc, symb, nr_slot_rx); + nr_slot_fep(ue, proc, symb, rxdataF); } } - nr_ue_csi_rs_procedures(ue, proc, gNB_id); + nr_ue_csi_rs_procedures(ue, proc, rxdataF); ue->csirs_vars[gNB_id]->active = 0; } @@ -1298,24 +1374,22 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx.p_time/(cpuf*1000.0)); LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, nr_slot_rx); + UEscopeCopy(ue, commonRxdataF, rxdataF, sizeof(int32_t), ue->frame_parms.nb_antennas_rx, rxdataF_sz); return (0); } // todo: // - power control as per 38.213 ch 7.4 -void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc) { + int gNB_id = proc->gNB_id; int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp uint8_t mod_id = ue->Mod_id; - uint8_t nr_prach = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); - nr_prach = nr_ue_get_rach(&ue->prach_vars[gNB_id]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx); - LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources : %d\n", __FUNCTION__, frame_tx, nr_slot_tx,nr_prach); - - if (nr_prach == GENERATE_PREAMBLE) { + if (ue->prach_vars[gNB_id]->active) { fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu; ue->tx_power_dBm[nr_slot_tx] = prach_pdu->prach_tx_power; @@ -1345,15 +1419,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t dB_fixed(prach_power), ue->prach_vars[gNB_id]->amp); - } else if (nr_prach == WAIT_CONTENTION_RESOLUTION) { - LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id); - ue->UE_mode[gNB_id] = RA_WAIT_CR; - } else if (nr_prach == RA_SUCCEEDED) { - LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id); - ue->UE_mode[gNB_id] = PUSCH; - } else if(nr_prach == RA_FAILED){ - LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id); - ue->UE_mode[gNB_id] = PRACH; + ue->prach_vars[gNB_id]->active = false; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index a10e6a29b47903c41e0c8f589658b6391d1d3b89..5e53b3e17b7f4fb721262a90499694a1f9d1cdcf 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -199,11 +199,10 @@ void nr_generate_pucch3_4(int32_t **txdataF, *********************************************************************/ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, - uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data) { - int nr_slot_tx = proc->nr_slot_tx; + int nr_slot_tx = proc->nr_slot_tx; fapi_nr_ul_config_pucch_pdu *pucch_pdu; NR_UE_PUCCH *pucch_vars = &phy_data->pucch_vars; diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h index 7f8bf13da3d7efe9c7f93420ca39f0031f89006a..26404427ce5c5c2156b620ce47f30112b5694fe3 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h @@ -60,7 +60,6 @@ /*************** FUNCTIONS ****************************************/ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, - uint8_t gNB_id, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data); diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index e7c8f92cab788619f3070bb32ac2d87db0d50a2f..585f77ac71aa150987caca4382564b152ad84caa 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -433,7 +433,7 @@ int main(int argc, char **argv) nr_ue_dlsch_init(dlsch_ue, num_codeword, 5); for (int i=0; i < num_codeword; i++) dlsch_ue[0].rnti = n_rnti; - nr_init_dl_harq_processes(UE->dl_harq_processes[0], 8, nb_rb); + nr_init_dl_harq_processes(UE->dl_harq_processes, 8, nb_rb); unsigned char harq_pid = 0; //dlsch->harq_ids[subframe]; processingData_L1tx_t msgDataTx; @@ -639,9 +639,7 @@ int main(int argc, char **argv) free(RC.gNB[0]); free(RC.gNB); - int num_cw = NR_MAX_NB_LAYERS > 4? 2:1; - for (int i = 0; i < num_cw; i++) - free_nr_ue_dl_harq(UE->dl_harq_processes[i], 8, nb_rb); + free_nr_ue_dl_harq(UE->dl_harq_processes, 8, nb_rb); term_nr_ue_signal(UE, 1); free(UE); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 40125fb2c31ae50a378f3013835ce129f24c4668..dd49f1d01097c4a3fb3be8836ee3cd0e7da059eb 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -893,8 +893,10 @@ int main(int argc, char **argv) UE->frame_parms.nb_antennas_rx = n_rx; UE->max_ldpc_iterations = max_ldpc_iterations; - if (run_initial_sync==1) UE->is_synchronized = 0; - else {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;} + if (run_initial_sync==1) + UE->is_synchronized = 0; + else + UE->is_synchronized = 1; if (init_nr_ue_signal(UE, 1) != 0) { @@ -984,6 +986,14 @@ int main(int argc, char **argv) msgDataTx->frame = frame; memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t)); + // Buffers to store internal memory of slot process + UE->phy_sim_rxdataF = calloc(frame_parms->samples_per_slot_wCP*sizeof(int32_t), frame_parms->nb_antennas_rx); + UE->phy_sim_pdsch_llr = calloc((8*(3*8*8448))*sizeof(int16_t), 1); //Max length + UE->phy_sim_pdsch_rxdataF_ext = calloc(14*frame_parms->N_RB_DL*12*sizeof(int32_t), frame_parms->nb_antennas_rx); + UE->phy_sim_pdsch_rxdataF_comp = calloc(14*frame_parms->N_RB_DL*12*sizeof(int32_t), frame_parms->nb_antennas_rx); + UE->phy_sim_pdsch_dl_ch_estimates = calloc(14*frame_parms->ofdm_symbol_size*sizeof(int32_t), frame_parms->nb_antennas_rx); + UE->phy_sim_pdsch_dl_ch_estimates_ext = calloc(14*frame_parms->N_RB_DL*12*sizeof(int32_t), frame_parms->nb_antennas_rx); + for (SNR = snr0; SNR < snr1; SNR += .2) { varArray_t *table_tx=initVarArray(1000,sizeof(double)); @@ -1022,6 +1032,7 @@ int main(int argc, char **argv) UE->rx_offset=0; UE_proc.frame_rx = frame; UE_proc.nr_slot_rx = slot; + UE_proc.gNB_id = 0; dcireq.frame = frame; dcireq.slot = slot; @@ -1203,7 +1214,6 @@ int main(int argc, char **argv) phy_procedures_nrUE_RX(UE, &UE_proc, - 0, &phy_data); //---------------------------------------------------------- @@ -1213,8 +1223,7 @@ int main(int argc, char **argv) if (dlsch0->last_iteration_cnt >= dlsch0->max_ldpc_iterations+1) n_errors[round]++; - NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars; - int16_t *UE_llr = pdsch_vars[0]->llr[0]; + int16_t *UE_llr = (int16_t*)UE->phy_sim_pdsch_llr; TBS = dlsch0->dlsch_config.TBS;//rel15->TBSize[0]; uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos); @@ -1352,11 +1361,11 @@ int main(int argc, char **argv) LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1); if (UE->frame_parms.nb_antennas_rx>1) LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1); - LOG_M("rxF0.m","rxF0", UE->common_vars.rxdataF[0], frame_parms->samples_per_slot_wCP, 1, 1); - LOG_M("rxF_ext.m","rxFe",&UE->pdsch_vars[0]->rxdataF_ext[0][0],g_rbSize*12*14,1,1); - LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1); - write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1); - LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[0]->llr[0],available_bits,1,0); + LOG_M("rxF0.m","rxF0", UE->phy_sim_rxdataF, frame_parms->samples_per_slot_wCP, 1, 1); + LOG_M("rxF_ext.m","rxFe",UE->phy_sim_pdsch_rxdataF_ext,g_rbSize*12*14,1,1); + LOG_M("chestF0.m","chF0",UE->phy_sim_pdsch_dl_ch_estimates_ext,g_rbSize*12*14,1,1); + write_output("rxF_comp.m","rxFc",UE->phy_sim_pdsch_rxdataF_comp,N_RB_DL*12*14,1,1); + LOG_M("rxF_llr.m","rxFllr",UE->phy_sim_pdsch_llr,available_bits,1,0); break; } @@ -1387,6 +1396,12 @@ int main(int argc, char **argv) free(txdata); free(test_input_bit); free(estimated_output_bit); + free(UE->phy_sim_rxdataF); + free(UE->phy_sim_pdsch_llr); + free(UE->phy_sim_pdsch_rxdataF_ext); + free(UE->phy_sim_pdsch_rxdataF_comp); + free(UE->phy_sim_pdsch_dl_ch_estimates); + free(UE->phy_sim_pdsch_dl_ch_estimates_ext); if (output_fd) fclose(output_fd); diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index 1ca43dfa30cbd58c68d50b802f9950e74d080a40..6e7398858b39c7feb2265a57818a4d50db480d7e 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -108,11 +108,9 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind, fapi_nr_rx_indication_t *rx_ind, UE_nr_rxtx_proc_t *proc, PHY_VARS_NR_UE *ue, - uint8_t gNB_id, void *phy_data) {} void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, uint8_t pdu_type, - uint8_t gNB_id, PHY_VARS_NR_UE *ue, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, @@ -122,28 +120,28 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} -int nr_ue_pdcch_procedures(uint8_t gNB_id, - PHY_VARS_NR_UE *ue, +int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t pdcch_est_size, int32_t pdcch_dl_ch_estimates[][pdcch_est_size], nr_phy_data_t *phy_data, - int n_ss) { + int n_ss, + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { return 0; } int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - int eNB_id, - NR_UE_DLSCH_t *dlsch) { + NR_UE_DLSCH_t dlsch[2], + int16_t *llr[2], + c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) { return 0; } bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, - int gNB_id, - NR_UE_DLSCH_t *dlsch0, - NR_UE_DLSCH_t *dlsch1) { + NR_UE_DLSCH_t dlsch[2], + int16_t *llr[2]) { return false; } @@ -633,6 +631,8 @@ int main(int argc, char **argv) processingData_L1tx_t msgDataTx; // generate signal + const uint32_t rxdataF_sz = UE->frame_parms.samples_per_slot_wCP; + __attribute__ ((aligned(32))) c16_t rxdataF[UE->frame_parms.nb_antennas_rx][rxdataF_sz]; if (input_fd==NULL) { for (i=0; i<frame_parms->Lmax; i++) { @@ -797,14 +797,16 @@ int main(int argc, char **argv) UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index); int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1)); + proc.nr_slot_rx = ssb_slot; + proc.gNB_id = 0; for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) { nr_slot_fep(UE, &proc, i%frame_parms->symbols_per_slot, - ssb_slot); + rxdataF); nr_pbch_channel_estimation(UE,estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc, - 0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf); + i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf,rxdataF); } fapiPbch_t result; @@ -813,11 +815,11 @@ int main(int argc, char **argv) estimateSz, dl_ch_estimates, UE->pbch_vars[0], frame_parms, - 0, ssb_index%8, SISO, &phy_data, - &result); + &result, + rxdataF); if (ret==0) { //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index; //not yet detected automatically diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index dd71aecacdb697117fd3067a39676143bf9d4475..f18a36d2991360d7955b307d8b97d0ae41bc7fe4 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -241,11 +241,10 @@ int main(int argc, char **argv) uint16_t nb_rb = 50; int Imcs = 9; uint8_t precod_nbr_layers = 1; - int gNB_id = 0; int tx_offset; int32_t txlev_sum = 0, atxlev[4]; int start_rb = 0; - int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault) + int UE_id = 0; int print_perf = 0; cpuf = get_cpu_freq_GHz(); int msg3_flag = 0; @@ -1038,6 +1037,7 @@ int main(int argc, char **argv) UE_proc.nr_slot_tx = slot; UE_proc.frame_tx = frame; + UE_proc.gNB_id = 0; UL_tti_req->SFN = frame; UL_tti_req->Slot = slot; @@ -1181,7 +1181,7 @@ int main(int argc, char **argv) /////////////////////////phy_procedures_nr_ue_TX/////////////////////// /////////// - phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, &phy_data); + phy_procedures_nrUE_TX(UE, &UE_proc, &phy_data); if (n_trials == 1) { LOG_M("txsig0.m", "txs0", &UE->common_vars.txdata[0][slot_offset], slot_length, 1, 1); diff --git a/openair1/SIMULATION/RF/rf.c b/openair1/SIMULATION/RF/rf.c index bff3453de0c30ae3df4696a756b0202dbe80be62..081a102bbb21dcb3cd823f805b8897086b845683 100644 --- a/openair1/SIMULATION/RF/rf.c +++ b/openair1/SIMULATION/RF/rf.c @@ -26,21 +26,7 @@ //#include "PHY/defs.h" #include "SIMULATION/TOOLS/sim.h" #include "rf.h" -/* -extern void randominit(void); -extern double gaussdouble(double,double); - //free(input_data); - -//extern int LOG_M(const char *,const char *,void *,int,int,char); -//flag change -extern int LOG_M(const char *,const char *,void *,int,int,char); -*/ - -//double pn[1024]; - -//#define DEBUG_RF 1 -//free(input_data); void rf_rx(double **r_re, double **r_im, double **r_re_i1, diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 863012f69a97142ff95cd799059383ac1cdc2c65..df45199006470953884ab9136f4b8868c7dafa46 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -26,57 +26,67 @@ #include "sim.h" -static unsigned int seed, iy, ir[98]; -/* -@defgroup _uniformdouble -@ingroup numerical Uniform linear congruential random number generator. -*/ - -/*!\brief Initialization routine for Uniform/Gaussian random number generators. */ - -#define a 1664525lu -#define mod 4294967296.0 /* is 2**32 */ +static unsigned int urseed, iy, ir[98]; /// uniformrandom +static bool tableNordDone = false; /// gaussZiggurat -#if 1 -void randominit(unsigned seed_init) +/*!\brief Generate a random number form `/dev/urandom`. */ +void fill_random(void *buf, size_t sz) { - int i; - // this need to be integrated with the existing rng, like taus: navid - - if (seed_init == 0) { - srand((unsigned)time(NULL)); - - seed = (unsigned int) rand(); - } else { - seed = seed_init; + const char* fn = "/dev/urandom"; + FILE* f = fopen(fn, "rb"); + if (f == NULL) { + fprintf(stderr, "could not open %s for seed generation: %d %s\n", fn, errno, strerror(errno)); + abort(); } - printf("Initializing random number generator, seed %x\n",seed); + int rc = fread(buf, sz, 1, f); + if (rc < 0) { + fprintf(stderr, "could not read %s for seed generation: %d %s\n", fn, errno, strerror(errno)); + abort(); + } + fclose(f); +} + - if (seed % 2 == 0) seed += 1; /* seed and mod are relative prime */ +static const unsigned int a = 1664525lu; - for (i=1; i<=97; i++) { - seed = a*seed; /* mod 2**32 */ - ir[i]= seed; /* initialize the shuffle table */ +/*!\brief Initialization routine for Uniform/Gaussian random number generators. */ +void randominit(unsigned long seed_init) +{ + unsigned long seed = seed_init; + if (seed_init == 0) + fill_random(&seed, sizeof(seed)); + printf("Initializing random number generator, seed %ld\n", seed); + + // initialize uniformrandom RNG + urseed = (unsigned int) seed; + if (urseed % 2 == 0) + urseed += 1; /* urseed and mod are relative prime */ + for (int i = 1; i <= 97; i++) { + urseed = a * urseed; /* mod 2**32 */ + ir[i] = urseed; /* initialize the shuffle table */ } + iy = 1; - iy=1; + // initialize gaussZiggurat RNG + tableNor(seed); + tableNordDone = true; } -#endif + +/* +@defgroup _uniformdouble +@ingroup numerical Uniform linear congruential random number generator. +*/ /*!\brief Uniform linear congruential random number generator on \f$[0,1)\f$. Returns a double-precision floating-point number.*/ double uniformrandom(void) { -#define a 1664525lu -#define mod 4294967296.0 /* is 2**32 */ - - int j; - - j=1 + 97.0*iy/mod; - iy=ir[j]; - seed = a*seed; /* mod 2**32 */ - ir[j] = seed; - return( (double) iy/mod ); + const double mod = 4294967296.0; /* is 2**32 */ + int j = 1 + 97.0 * iy / mod; + iy = ir[j]; + urseed = a * urseed; /* mod 2**32 */ + ir[j] = urseed; + return (double)iy / mod; } /* @@ -109,8 +119,12 @@ double __attribute__ ((no_sanitize_address)) gaussdouble(double mean, double var } } + +/* +@defgroup _gaussZiggurat +@ingroup numerical ziggurat random number generator for exponentially distributed numbers +*/ // Ziggurat -static bool tableNordDone=false; static double wn[128], fn[128]; static uint32_t iz, jz, jsr = 123456789, kn[128]; static int32_t hz; @@ -180,9 +194,9 @@ double __attribute__ ((no_sanitize_address)) gaussZiggurat(double mean, double v { if (!tableNordDone) { // let's make reasonnable constant tables - struct timespec t; - clock_gettime(CLOCK_MONOTONIC, &t); - tableNor((long)(t.tv_nsec%INT_MAX)); + unsigned long seed; + fill_random(&seed, sizeof(seed)); + tableNor(seed); } hz = SHR3; iz = hz & 127; diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 92c11c8da5695b822a8465059f503c8bcf587d6d..b23aaac4b5e84dfe7737bbeb56a69daf0d33c6da 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -523,8 +523,9 @@ the value \f$\mathrm{sgn}(u)i\f$. The search requires at most \f$Nbits-1\f$ com */ int gauss(unsigned int *gauss_LUT,unsigned char Nbits); +void fill_random(void *buf, size_t sz); double gaussdouble(double,double); -void randominit(unsigned int seed_init); +void randominit(unsigned long seed_init); double uniformrandom(void); double gaussZiggurat(double mean, double variance); void tableNor(unsigned long seed); diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c index a9d2750c06374d80d4b0575176c7bd65e56feccf..5280cceafb6edbeeabde8388c5b83a0e548cac76 100644 --- a/openair1/SIMULATION/TOOLS/taus.c +++ b/openair1/SIMULATION/TOOLS/taus.c @@ -23,7 +23,7 @@ #include <stdlib.h> #include <fcntl.h> #include <unistd.h> -//#include "SIMULATION/TOOLS/sim.h" +#include "sim.h" static unsigned int s0, s1, s2; @@ -52,20 +52,9 @@ void set_taus_seed(unsigned int seed_init) unsigned long result = 0; if (seed_init == 0) { - unsigned int data[3]; - int fd = open("/dev/urandom", O_RDONLY); - if (fd == -1) - { - abort(); - } - if (read(fd, data, sizeof(data)) != sizeof(data)) - { - abort(); - } - close(fd); - s0 = data[0]; - s1 = data[1]; - s2 = data[2]; + fill_random(&s0, sizeof(s0)); + fill_random(&s1, sizeof(s1)); + fill_random(&s2, sizeof(s2)); } else { /* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */ srand48_r((long int)seed_init, &buffer); diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index f28e0e5ddfc1989db3329a74feef9e487e94f279..5db598409fe0a0ce8c0853f1e06997b7c5123f34 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -40,7 +40,6 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_ul_r MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req) MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd) - /* RRC -> F1AP messages */ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message ) //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) @@ -49,6 +48,5 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_se MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req) MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp) - - - +/* CU -> DU*/ +MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index cbc4d1c6f2dedc169e7c7fd64e97d6a90a09d833..e615005991926fa2d89fe76596a42885a89a401f 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -50,6 +50,8 @@ #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req #define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req +#define F1AP_PAGING_IND(mSGpTR) (mSGpTR)->ittiMsg.f1ap_paging_ind + /* Length of the transport layer address string * 160 bits / 8 bits by char. */ @@ -424,4 +426,15 @@ typedef struct f1ap_ue_context_release_s { } f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cplt_t; +typedef struct f1ap_paging_ind_s { + uint16_t ueidentityindexvalue; + uint64_t fiveg_s_tmsi; + uint8_t fiveg_s_tmsi_length; + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + uint64_t nr_cellid; + uint8_t paging_drx; +} f1ap_paging_ind_t; + #endif /* F1AP_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index f053fe7f1e5f69eed557cc92bb54b636be123653..47dac57832a97134c6b48a6d7ceeeadf8c21eace 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -119,6 +119,10 @@ #define CH_OFFSET 0x0004 #define CH_SHIFT 2 +// RLC Entity +#define RLC_TX_MAXSIZE 10000000 +#define RLC_RX_MAXSIZE 10000000 + // RLC_AM_SEND_MRW # define SEND_MRW_OFF 15 # define SEND_MRW_ON 240 diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c deleted file mode 100644 index 7825d7faea2082cfb788670465173777f486a22b..0000000000000000000000000000000000000000 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ /dev/null @@ -1,3797 +0,0 @@ -/* - * 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 flexran_agent_ran_api.c - * \brief FlexRAN RAN API abstraction - * \author N. Nikaein, X. Foukas, S. SHARIAT BAGHERI and R. Schmidt - * \date 2017 - * \version 0.1 - */ - -#include <dlfcn.h> -#include "flexran_agent_ran_api.h" -#include "s1ap_eNB_ue_context.h" -#include "s1ap_eNB_management_procedures.h" -#include "openair2/LAYER2/MAC/slicing/slicing.h" - -#include "common/ran_context.h" -extern RAN_CONTEXT_t RC; - -static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) { - return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id]; -} - -static inline int mac_is_present(mid_t mod_id) { - return RC.mac && RC.mac[mod_id]; -} - -static inline int rrc_is_present(mid_t mod_id) { - return RC.rrc && RC.rrc[mod_id]; -} - -uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag) { - if (!mac_is_present(mod_id)) return 0; - - if (subframe_flag == 1) - return RC.mac[mod_id]->frame*10 + RC.mac[mod_id]->subframe; - else - return RC.mac[mod_id]->frame*10; -} - -frame_t flexran_get_current_frame(mid_t mod_id) { - if (!mac_is_present(mod_id)) return 0; - - // #warning "SFN will not be in [0-1023] when oaisim is used" - return RC.mac[mod_id]->frame; -} - -frame_t flexran_get_current_system_frame_num(mid_t mod_id) { - return flexran_get_current_frame(mod_id) % 1024; -} - -sub_frame_t flexran_get_current_subframe(mid_t mod_id) { - if (!mac_is_present(mod_id)) return 0; - - return RC.mac[mod_id]->subframe; -} - -uint32_t flexran_get_sfn_sf(mid_t mod_id) { - if (!mac_is_present(mod_id)) return 0; - - return flexran_get_current_frame(mod_id) * 10 + flexran_get_current_subframe(mod_id); -} - -uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) { - if (!mac_is_present(mod_id)) return 0; - - frame_t frame = flexran_get_current_system_frame_num(mod_id); - sub_frame_t subframe = flexran_get_current_subframe(mod_id); - uint16_t sfn_sf, frame_mask, sf_mask; - int additional_frames; - subframe = (subframe + ahead_of_time) % 10; - - if (subframe < flexran_get_current_subframe(mod_id)) - frame = (frame + 1) % 1024; - - additional_frames = ahead_of_time / 10; - frame = (frame + additional_frames) % 1024; - frame_mask = (1 << 12) - 1; - sf_mask = (1 << 4) - 1; - sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4); - return sfn_sf; -} - -int flexran_get_mac_num_ues(mid_t mod_id) { - if (!mac_is_present(mod_id)) return 0; - - return RC.mac[mod_id]->UE_info.num_UEs; -} - -int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return 0; - - // Not sure whether this is needed: if (!rrc_is_present(mod_id)) return 0; - const rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); - const int s = mac_eNB_get_rrc_status(mod_id, rnti); - - if (s < RRC_CONNECTED) - return 0; - else if (s == RRC_CONNECTED) - return 1; - else - return 3; -} - -int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti) { - int n; - - if (!mac_is_present(mod_id)) return 0; - - /* get the (active) UE with RNTI i */ - for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[mod_id]->UE_info.active[n] == true - && rnti == UE_RNTI(mod_id, n)) { - return n; - } - } - - return 0; -} - -int flexran_get_mac_ue_id(mid_t mod_id, int i) { - int n; - - if (!mac_is_present(mod_id)) return 0; - - /* get the (i+1)'th active UE */ - for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[mod_id]->UE_info.active[n] == true) { - if (i == 0) - return n; - - --i; - } - } - - return 0; -} - -rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return 0; - - return UE_RNTI(mod_id, ue_id); -} - -int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid) { - if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].ul_buffer_info[lcid]; -} - -int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return 0; - - return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info; -} - -uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return 0; - - return RC.mac[mod_id]->UE_info.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) { - if (!mac_is_present(mod_id)) return 0; - - rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); - frame_t frame = flexran_get_current_frame(mod_id); - sub_frame_t subframe = flexran_get_current_subframe(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0, 0 - ); - return rlc_status.bytes_in_buffer; -} - -rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - if (!mac_is_present(mod_id)) return 0; - - rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id); - frame_t frame = flexran_get_current_frame(mod_id); - sub_frame_t subframe = flexran_get_current_subframe(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0, 0 - ); - return rlc_status.pdus_in_buffer; -} - -frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) { - if (!mac_is_present(mod_id)) return 0; - - rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id); - frame_t frame = flexran_get_current_frame(mod_id); - sub_frame_t subframe = flexran_get_current_subframe(mod_id); - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0, 0 - ); - return rlc_status.head_sdu_creation_time; -} - -int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - int32_t tau = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update; - - switch (flexran_get_N_RB_DL(mod_id, cc_id)) { - case 6: - return tau; - - case 15: - return tau / 2; - - case 25: - return tau / 4; - - case 50: - return tau / 8; - - case 75: - return tau / 12; - - case 100: - if (flexran_get_threequarter_fs(mod_id, cc_id) == 0) - return tau / 16; - else - return tau / 12; - - default: - return 0; - } -} - -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_info.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; - - uint64_t bytes = 0; - - for (int i = 0; i < NB_RB_MAX; ++i) { - bytes += RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].num_bytes_rx[i]; - } - - return bytes; -} - -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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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_info.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) { - /* - UE_info_t *UE_info=&eNB_mac_inst[mod_id].UE_info; - UE_sched_ctrl *ue_sched_ctl = &UE_info->UE_sched_ctrl[ue_id]; - - if (ue_sched_ctl->ta_timer == 0) { - - // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ... - // LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti); - //ue_sched_ctl->ta_timer = 20; // wait 20 subframes before taking TA measurement from PHY - ue_sched_ctl->ta_update = flexran_get_TA(mod_id, ue_id, CC_id); - - // clear the update in case PHY does not have a new measurement after timer expiry - // eNB_UE_stats->timing_advance_update = 0; - } else { - ue_sched_ctl->ta_timer--; - ue_sched_ctl->ta_update = 0; // don't trigger a timing advance command - } - #warning "Implement flexran_update_TA() in RAN API" - */ -} - -/* TODO needs to be revised, looks suspicious: why do we need UE stats? */ -int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - /* - #warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API" - */ - if (!phy_is_present(mod_id, cc_id)) return 0; - - /* UE_stats can not be null, they are an array in RC - LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti); - - if (eNB_UE_stats == NULL) { - return 0; - } - */ - - if (flexran_get_TA(mod_id, ue_id, cc_id) != 0) { - return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA; - } else { - return 0; - } -} - -int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return 0; - - return RC.mac[mod_id]->UE_info.numactiveCCs[ue_id]; -} - -uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].rank; -} - -int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - /* before: tested that UL_rssi != NULL and set parameter ([0]), but it is a - * static array -> target_rx_power is useless in old ifs?! */ - int pCCid = UE_PCCID(mod_id,ue_id); - int32_t target_rx_power = RC.eNB[mod_id][pCCid]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH; - int32_t normalized_rx_power = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].UL_rssi[0]; - int tpc; - - if (normalized_rx_power > target_rx_power + 1) - tpc = 0; //-1 - else if (normalized_rx_power < target_rx_power - 1) - tpc = 2; //+1 - else - tpc = 1; //0 - - return tpc; -} - -int flexran_get_harq(mid_t mod_id, - uint8_t cc_id, - mid_t ue_id, - frame_t frame, - sub_frame_t subframe, - uint8_t *pid, - uint8_t *round, - uint8_t harq_flag) { - /* TODO: Add int TB in function parameters to get the status of the second - * TB. This can be done to by editing in get_ue_active_harq_pid function in - * line 272 file: phy_procedures_lte_eNB.c to add DLSCH_ptr = - * PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/ - /* TODO IMPLEMENT */ - /* - uint8_t harq_pid; - uint8_t harq_round; - - if (mac_xface_not_ready()) return 0 ; - - uint16_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id); - if (harq_flag == openair_harq_DL){ - - mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL); - - } else if (harq_flag == openair_harq_UL){ - - mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,round,openair_harq_UL); - } - else { - - LOG_W(FLEXRAN_AGENT,"harq_flag is not recongnized"); - } - - - *pid = harq_pid; - *round = harq_round;*/ - /* if (round > 0) { */ - /* *status = 1; */ - /* } else { */ - /* *status = 0; */ - /* } */ - /*return *round;*/ - /* - #warning "Implement flexran_get_harq() in RAN API" - */ - return 0; -} - -int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm; -} - -int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH; -} - -int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update; -} - -int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0; - return 0; -} - - -/* - * ************************************ - * Get Messages for eNB Configuration Reply - * ************************************ - */ -uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.threequarter_fs; -} - - -uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset; -} - -Protocol__FlexHoppingMode flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return -1; - - switch (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode) { - case interSubFrame: - return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER; - - case intraAndInterSubFrame: - return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA; - } - - return -1; -} - -uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB; -} - -Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == true) - return PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM; - else - return PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; -} - -Protocol__FlexPhichDuration flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return -1; - - switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration) { - case normal: - return PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL; - - case extended: - return PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED; - } - - return -1; -} - -Protocol__FlexPhichResource flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return -1; - - switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) { - case oneSixth: - return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH; - - case half: - return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF; - - case one: - return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE; - - case two: - return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO; - } - - return -1; -} - -uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN; -} - -uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI; -} - -uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift; -} - -uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex; -} - -uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset; -} - -uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx; -} - -Protocol__FlexUlCyclicPrefixLength flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return -1; - - switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL) { - case EXTENDED: - return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED; - - case NORMAL: - return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL; - } - - return -1; -} - -Protocol__FlexDlCyclicPrefixLength flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return -1; - - switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp) { - case EXTENDED: - return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED; - - case NORMAL: - return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL; - } - - return -1; -} - -uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.Nid_cell; -} - -uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig; -} - -uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig; -} - -uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_MaxUpPts; -} - -uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL; -} - -uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL; -} - -uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.N_RBG; -} - -uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config; -} - -uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config_S; -} - -long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].rach_raResponseWindowSize; -} - -long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].rach_macContentionResolutionTimer; -} - -Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - switch (RC.eNB[mod_id][cc_id]->frame_parms.frame_type) { - case TDD: - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD; - - case FDD: - return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD; - - default: - return -1; - } -} - -long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id) { - if (!rrc_is_present(mod_id) || !RC.rrc[mod_id]->carrier[cc_id].sib1) return 0; - - return RC.rrc[mod_id]->carrier[cc_id].sib1->si_WindowLength; -} - -uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1; -} - -uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols; -} - - - -/* - * ************************************ - * Get Messages for UE Configuration Reply - * ************************************ - */ -int flexran_get_rrc_num_ues(mid_t mod_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->Nb_ue; -} - -rnti_t flexran_get_rrc_rnti_nth_ue(mid_t mod_id, int index) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = NULL; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) { - if (index == 0) return ue_context_p->ue_context.rnti; - - --index; - } - return 0; -} - -int flexran_get_rrc_rnti_list(mid_t mod_id, rnti_t *list, int max_list) { - if (!rrc_is_present(mod_id)) return 0; - - int n = 0; - struct rrc_eNB_ue_context_s *ue_context_p = NULL; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) { - if (n >= max_list) break; - - list[n] = ue_context_p->ue_context.rnti; - ++n; - } - return n; -} - -LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig) return -1; - - return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated; -} - -Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measGapConfig) return -1; - - if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1; - - switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { - case LTE_MeasGapConfig__setup__gapOffset_PR_gp0: - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; - - case LTE_MeasGapConfig__setup__gapOffset_PR_gp1: - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; - - default: - return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; - } -} - - -long flexran_get_meas_gap_config_offset(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measGapConfig) return -1; - - if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1; - - switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { - case LTE_MeasGapConfig__setup__gapOffset_PR_gp0: - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - - case LTE_MeasGapConfig__setup__gapOffset_PR_gp1: - return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp1; - - default: - return -1; - } -} - -uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return RRC_INACTIVE; - - return ue_context_p->ue_context.StatusRrc; -} - -uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return 0; - - return 0; //RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL; -} - -uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return 0; - - return 0; //RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL; -} - -int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.UE_Capability) return -1; - - LTE_SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA; - - for (int i = 0; i < bands->list.count; i++) { - if (bands->list.array[i]->halfDuplex > 0) return 1; - } - - return 0; -} - -int flexran_get_intra_sf_hopping(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.UE_Capability) return -1; - - if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; - - /* According to TS 36.331 Annex B.1, Intra SF Hopping is bit 1 (leftmost bit) - * in this bitmap, i.e. the eighth bit (from right) in the first bye (from - * left) */ - BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; - uint8_t buf = fgi->buf[0]; - return (buf >> 7) & 1; -} - -int flexran_get_type2_sb_1(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.UE_Capability) return -1; - - if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; - - /* According to TS 36.331 Annex B.1, Predefined intra- and inter-sf or - * predfined inter-sf frequency hopping for PUSCH with N_sb>1 is bit 21 (bit - * 1 is leftmost bit) in this bitmap, i.e. the fourth bit (from right) in the - * third byte (from left) */ - BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; - uint8_t buf = fgi->buf[2]; - return (buf >> 3) & 1; -} - -long flexran_get_ue_category(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.UE_Capability) return -1; - - return ue_context_p->ue_context.UE_Capability->ue_Category; -} - -int flexran_get_res_alloc_type1(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.UE_Capability) return -1; - - if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1; - - /* According to TS 36.331 Annex B.1, Resource allocation type 1 for PDSCH is - * bit 2 (bit 1 is leftmost bit) in this bitmap, i.e. the seventh bit (from - * right) in the first byte (from left) */ - BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators; - uint8_t buf = fgi->buf[0]; - return (buf >> 6) & 1; -} - -long flexran_get_ue_transmission_mode(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; - - return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode; -} - -BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; - - return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling; -} - -long flexran_get_maxHARQ_TX(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1; - - return *(ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx); -} - -long flexran_get_beta_offset_ack_index(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; - - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index; -} - -long flexran_get_beta_offset_ri_index(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; - - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index; -} - -long flexran_get_beta_offset_cqi_index(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1; - - return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index; -} - -BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) return -1; - - return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI; -} - -BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, uint8_t cc_id) { - if (!rrc_is_present(mod_id)) return -1; - - if (!RC.rrc[mod_id]->carrier[cc_id].sib2) return -1; - - return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; -} - -Protocol__FlexAperiodicCqiReportMode flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1; - - switch (*ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) { - case LTE_CQI_ReportModeAperiodic_rm12: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM12; - - case LTE_CQI_ReportModeAperiodic_rm20: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM20; - - case LTE_CQI_ReportModeAperiodic_rm22: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM22; - - case LTE_CQI_ReportModeAperiodic_rm30: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM30; - - case LTE_CQI_ReportModeAperiodic_rm31: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM31; - - case LTE_CQI_ReportModeAperiodic_rm32_v1250: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM32_v1250; - - case LTE_CQI_ReportModeAperiodic_rm10_v1310: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM10_v1310; - - case LTE_CQI_ReportModeAperiodic_rm11_v1310: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM11_v1310; - - default: - return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE; - } -} - -long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) return -1; - - return *(ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode); -} - -long flexran_get_ack_nack_repetition_factor(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1; - - return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor; -} - -long flexran_get_extended_bsr_size(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig->ext2) return -1; - - if (!ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020) return -1; - - return *(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10); -} - -int flexran_get_ue_transmission_antenna(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; - - if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; - - switch (ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup) { - case LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop: - return 2; - - case LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop: - return 1; - - default: - return 0; - } -} - -uint64_t flexran_get_ue_imsi(mid_t mod_id, rnti_t rnti) { - uint64_t imsi; - - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return 0; - - imsi = ue_context_p->ue_context.imsi.digit15; - imsi += ue_context_p->ue_context.imsi.digit14 * 10; // pow(10, 1) - imsi += ue_context_p->ue_context.imsi.digit13 * 100; // pow(10, 2) - imsi += ue_context_p->ue_context.imsi.digit12 * 1000; // pow(10, 3) - imsi += ue_context_p->ue_context.imsi.digit11 * 10000; // pow(10, 4) - imsi += ue_context_p->ue_context.imsi.digit10 * 100000; // pow(10, 5) - imsi += ue_context_p->ue_context.imsi.digit9 * 1000000; // pow(10, 6) - imsi += ue_context_p->ue_context.imsi.digit8 * 10000000; // pow(10, 7) - imsi += ue_context_p->ue_context.imsi.digit7 * 100000000; // pow(10, 8) - imsi += ue_context_p->ue_context.imsi.digit6 * 1000000000; // pow(10, 9) - imsi += ue_context_p->ue_context.imsi.digit5 * 10000000000; // pow(10, 10) - imsi += ue_context_p->ue_context.imsi.digit4 * 100000000000; // pow(10, 11) - imsi += ue_context_p->ue_context.imsi.digit3 * 1000000000000; // pow(10, 12) - imsi += ue_context_p->ue_context.imsi.digit2 * 10000000000000; // pow(10, 13) - imsi += ue_context_p->ue_context.imsi.digit1 * 100000000000000; // pow(10, 14) - return imsi; -} - -long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id) { - if (!mac_is_present(mod_id)) return 0; - - return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].lcgidmap[lc_id]; -} - -/* TODO Navid: needs to be revised */ -int flexran_get_direction(mid_t ue_id, mid_t lc_id) { - switch (lc_id) { - case DCCH: - case DCCH1: - return 2; - - case DTCH: - return 1; - - default: - return -1; - } -} - -uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB; -} - -uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000; -} - -uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000; -} - -uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.eutra_band; -} - -int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id) { - if (!phy_is_present(mod_id, cc_id)) return 0; - - return RC.eNB[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower; -} - -long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].pusch_p0_Nominal; -} - -void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz) { - if (phy_is_present(mod_id, cc_id)) { - RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq = dl_freq_mhz * 1000000; - } else { - LOG_E(FLEXRAN_AGENT, "can not set dl_CarrierFreq to %d MHz in PHY: PHY is not present\n", dl_freq_mhz); - } - - if (rrc_is_present(mod_id)) { - RC.rrc[mod_id]->configuration.downlink_frequency[cc_id] = dl_freq_mhz * 1000000; - } else { - LOG_E(FLEXRAN_AGENT, "can not set downlink_frequency to %d MHz in RRC: RRC is not present\n", dl_freq_mhz); - } -} - -void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset) { - if (phy_is_present(mod_id, cc_id)) { - uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset; - RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq = new_ul_freq_mhz * 1000000; - } else { - LOG_E(FLEXRAN_AGENT, "can not set ul_CarrierFreq using offset %d MHz in PHY: PHY is not present\n", ul_freq_mhz_offset); - } - - if (rrc_is_present(mod_id)) { - RC.rrc[mod_id]->configuration.uplink_frequency_offset[cc_id] = ul_freq_mhz_offset; - } else { - LOG_E(FLEXRAN_AGENT, "can not set uplink_frequency_offset to %d MHz in RRC: RRC is not present\n", ul_freq_mhz_offset); - } -} - -void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band) { - if (phy_is_present(mod_id, cc_id)) { - RC.eNB[mod_id][cc_id]->frame_parms.eutra_band = eutra_band; - } else { - LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in PHY: PHY is not present\n", eutra_band); - } - - if (rrc_is_present(mod_id)) { - RC.rrc[mod_id]->configuration.eutra_band[cc_id] = eutra_band; - } else { - LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in RRC: RRC is not present\n", eutra_band); - } -} - -/* Sets both DL/UL */ -void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB) { - if (phy_is_present(mod_id, cc_id)) { - RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL = N_RB; - RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL = N_RB; - } else { - LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL and N_RB_UL to %d in PHY: PHY is not present\n", N_RB); - } - - if (rrc_is_present(mod_id)) { - RC.rrc[mod_id]->configuration.N_RB_DL[cc_id] = N_RB; - } else { - LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL to %d in RRC: RRC is not present\n", N_RB); - } -} - -void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, frame_type_t frame_type) { - if (phy_is_present(mod_id, cc_id)) { - RC.eNB[mod_id][cc_id]->frame_parms.frame_type = frame_type; - } else { - LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in PHY: PHY is not present\n", frame_type); - } - - if (rrc_is_present(mod_id)) { - RC.rrc[mod_id]->configuration.frame_type[cc_id] = frame_type; - } else { - LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in RRC: RRC is not present\n", frame_type); - } -} - -/*********** PDCP *************/ - -uint16_t flexran_get_pdcp_uid_from_rnti(mid_t mod_id, rnti_t rnti) { - if (rnti == NOT_A_RNTI) return 0; - - if (mod_id < 0 || mod_id >= RC.nb_inst) - return 0; - - for (uint16_t pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) { - if (pdcp_enb[mod_id].rnti[pdcp_uid] == rnti) - return pdcp_uid; - } - - return 0; -} - -/*PDCP super frame counter flexRAN*/ -uint32_t flexran_get_pdcp_sfn(mid_t mod_id) { - if (mod_id < 0 || mod_id >= RC.nb_inst) - return 0; - - return pdcp_enb[mod_id].sfn; -} - -/*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_tx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB) - return; - - Pdcp_stats_tx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000; -} - -/*PDCP super frame counter flexRAN*/ -void flexran_set_pdcp_rx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB) - return; - - Pdcp_stats_rx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000; -} - -/*PDCP num tx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_tx(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_tx[mod_id][uid][lcid]; -} - -/*PDCP num tx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_tx_bytes[mod_id][uid][lcid]; -} - -/*PDCP number of transmit packet / second status flexRAN*/ -uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_tx_w[mod_id][uid][lcid]; -} - -/*PDCP throughput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_tx_bytes_w[mod_id][uid][lcid]; -} - -/*PDCP tx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_tx_sn[mod_id][uid][lcid]; -} - -/*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_tx_aiat[mod_id][uid][lcid]; -} - -/*PDCP tx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_tx_aiat_w[mod_id][uid][lcid]; -} - -/*PDCP num rx pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx[mod_id][uid][lcid]; -} - -/*PDCP num rx bytes status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx_bytes[mod_id][uid][lcid]; -} - -/*PDCP number of received packet / second flexRAN*/ -uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx_w[mod_id][uid][lcid]; -} - -/*PDCP gootput (bit/s) status flexRAN*/ -uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx_bytes_w[mod_id][uid][lcid]; -} - -/*PDCP rx sequence number flexRAN*/ -uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx_sn[mod_id][uid][lcid]; -} - -/*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx_aiat[mod_id][uid][lcid]; -} - -/*PDCP rx aggregated packet arrival flexRAN*/ -uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx_aiat_w[mod_id][uid][lcid]; -} - -/*PDCP num of received outoforder pdu status flexRAN*/ -uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid) { - if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0 - || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX) - return 0; - - return Pdcp_stats_rx_outoforder[mod_id][uid][lcid]; -} - -/******************** RRC *****************************/ -/* RRC Wrappers */ -int flexran_call_rrc_reconfiguration (mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - protocol_ctxt_t ctxt; - memset(&ctxt, 0, sizeof(ctxt)); - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id); - flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0); - return 0; -} - -int flexran_call_rrc_trigger_handover (mid_t mod_id, rnti_t rnti, int target_cell_id) { - if (!rrc_is_present(mod_id)) return -1; - - protocol_ctxt_t ctxt; - memset(&ctxt, 0, sizeof(ctxt)); - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id); - return flexran_rrc_eNB_trigger_handover(mod_id, &ctxt, ue_context_p, target_cell_id); -} - -/* RRC Getters */ - -LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measResults) return -1; - - return ue_context_p->ue_context.measResults->measId; -} - -float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measResults) return -1; - - return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult]; -} - -float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measResults) return -1; - - return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult]; -} - -/*Number of neighbouring cells for specific UE*/ -int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return 0; - - if (!ue_context_p->ue_context.measResults) return 0; - - if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0; - - //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0; - return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count; -} - -long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measResults) return -1; - - if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; - - //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; - if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; - - return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; -} - -int flexran_get_rrc_neigh_cgi(mid_t mod_id, rnti_t rnti, long cell_id) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return 0; - - if (!ue_context_p->ue_context.measResults) return 0; - - if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0; - - //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0; - if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return 0; - - return (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info)?0:1; -} - -uint32_t flexran_get_rrc_neigh_cgi_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) { - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - uint8_t *cId = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.cellIdentity.buf; - return ((cId[0] << 20) + (cId[1] << 12) + (cId[2] << 4) + (cId[3] >> 4)); -} - -uint32_t flexran_get_rrc_neigh_cgi_tac(mid_t mod_id, rnti_t rnti, long cell_id) { - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - uint8_t *tac = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->trackingAreaCode.buf; - return (tac[0] << 8) + (tac[1]); -} - -int flexran_get_rrc_neigh_cgi_num_mnc(mid_t mod_id, rnti_t rnti, long cell_id) { - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count; -} - -int flexran_get_rrc_neigh_cgi_num_mcc(mid_t mod_id, rnti_t rnti, long cell_id) { - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count; -} - -uint32_t flexran_get_rrc_neigh_cgi_mnc(mid_t mod_id, rnti_t rnti, long cell_id, int mnc_id) { - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - int num_mnc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count; - return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.array[mnc_id]) * - ((uint32_t) pow(10, num_mnc - mnc_id - 1)); -} - -uint32_t flexran_get_rrc_neigh_cgi_mcc(mid_t mod_id, rnti_t rnti, long cell_id, int mcc_id) { - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - int num_mcc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count; - return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.array[mcc_id]) * - ((uint32_t) pow(10, num_mcc - mcc_id - 1)); -} - -float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measResults) return -1; - - if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; - - //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; - if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; - - if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return -1; - - return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; -} - -float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measResults) return -1; - - if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; - - //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; - if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return -1; - - return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; -} - -/* Measurement offsets */ - -long flexran_get_rrc_ofp(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - return ue_context_p->ue_context.measurement_info->offsetFreq; -} - -long flexran_get_rrc_ofn(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - return ue_context_p->ue_context.measurement_info->offsetFreq; -} - -long flexran_get_rrc_ocp(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[0]) { - case LTE_Q_OffsetRange_dB_24: - return -24; - - case LTE_Q_OffsetRange_dB_22: - return -22; - - case LTE_Q_OffsetRange_dB_20: - return -20; - - case LTE_Q_OffsetRange_dB_18: - return -18; - - case LTE_Q_OffsetRange_dB_16: - return -16; - - case LTE_Q_OffsetRange_dB_14: - return -14; - - case LTE_Q_OffsetRange_dB_12: - return -12; - - case LTE_Q_OffsetRange_dB_10: - return -10; - - case LTE_Q_OffsetRange_dB_8: - return -8; - - case LTE_Q_OffsetRange_dB_6: - return -6; - - case LTE_Q_OffsetRange_dB_5: - return -5; - - case LTE_Q_OffsetRange_dB_4: - return -4; - - case LTE_Q_OffsetRange_dB_3: - return -3; - - case LTE_Q_OffsetRange_dB_2: - return -2; - - case LTE_Q_OffsetRange_dB_1: - return -1; - - case LTE_Q_OffsetRange_dB0: - return 0; - - case LTE_Q_OffsetRange_dB1: - return 1; - - case LTE_Q_OffsetRange_dB2: - return 2; - - case LTE_Q_OffsetRange_dB3: - return 3; - - case LTE_Q_OffsetRange_dB4: - return 4; - - case LTE_Q_OffsetRange_dB5: - return 5; - - case LTE_Q_OffsetRange_dB6: - return 6; - - case LTE_Q_OffsetRange_dB8: - return 8; - - case LTE_Q_OffsetRange_dB10: - return 10; - - case LTE_Q_OffsetRange_dB12: - return 12; - - case LTE_Q_OffsetRange_dB14: - return 14; - - case LTE_Q_OffsetRange_dB16: - return 16; - - case LTE_Q_OffsetRange_dB18: - return 18; - - case LTE_Q_OffsetRange_dB20: - return 20; - - case LTE_Q_OffsetRange_dB22: - return 22; - - case LTE_Q_OffsetRange_dB24: - return 24; - - default: - return -99; - } -} - -long flexran_get_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1]) { - case LTE_Q_OffsetRange_dB_24: - return -24; - - case LTE_Q_OffsetRange_dB_22: - return -22; - - case LTE_Q_OffsetRange_dB_20: - return -20; - - case LTE_Q_OffsetRange_dB_18: - return -18; - - case LTE_Q_OffsetRange_dB_16: - return -16; - - case LTE_Q_OffsetRange_dB_14: - return -14; - - case LTE_Q_OffsetRange_dB_12: - return -12; - - case LTE_Q_OffsetRange_dB_10: - return -10; - - case LTE_Q_OffsetRange_dB_8: - return -8; - - case LTE_Q_OffsetRange_dB_6: - return -6; - - case LTE_Q_OffsetRange_dB_5: - return -5; - - case LTE_Q_OffsetRange_dB_4: - return -4; - - case LTE_Q_OffsetRange_dB_3: - return -3; - - case LTE_Q_OffsetRange_dB_2: - return -2; - - case LTE_Q_OffsetRange_dB_1: - return -1; - - case LTE_Q_OffsetRange_dB0: - return 0; - - case LTE_Q_OffsetRange_dB1: - return 1; - - case LTE_Q_OffsetRange_dB2: - return 2; - - case LTE_Q_OffsetRange_dB3: - return 3; - - case LTE_Q_OffsetRange_dB4: - return 4; - - case LTE_Q_OffsetRange_dB5: - return 5; - - case LTE_Q_OffsetRange_dB6: - return 6; - - case LTE_Q_OffsetRange_dB8: - return 8; - - case LTE_Q_OffsetRange_dB10: - return 10; - - case LTE_Q_OffsetRange_dB12: - return 12; - - case LTE_Q_OffsetRange_dB14: - return 14; - - case LTE_Q_OffsetRange_dB16: - return 16; - - case LTE_Q_OffsetRange_dB18: - return 18; - - case LTE_Q_OffsetRange_dB20: - return 20; - - case LTE_Q_OffsetRange_dB22: - return 22; - - case LTE_Q_OffsetRange_dB24: - return 24; - - default: - return -99; - } -} - -long flexran_get_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRP) { - case LTE_FilterCoefficient_fc0: - return 0; - - case LTE_FilterCoefficient_fc1: - return 1; - - case LTE_FilterCoefficient_fc2: - return 2; - - case LTE_FilterCoefficient_fc3: - return 3; - - case LTE_FilterCoefficient_fc4: - return 4; - - case LTE_FilterCoefficient_fc5: - return 5; - - case LTE_FilterCoefficient_fc6: - return 6; - - case LTE_FilterCoefficient_fc7: - return 7; - - case LTE_FilterCoefficient_fc8: - return 8; - - case LTE_FilterCoefficient_fc9: - return 9; - - case LTE_FilterCoefficient_fc11: - return 11; - - case LTE_FilterCoefficient_fc13: - return 13; - - case LTE_FilterCoefficient_fc15: - return 15; - - case LTE_FilterCoefficient_fc17: - return 17; - - case LTE_FilterCoefficient_fc19: - return 19; - - case LTE_FilterCoefficient_spare1: - return -1; /* spare means no coefficient */ - - default: - return -1; - } -} - -long flexran_get_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ) { - case LTE_FilterCoefficient_fc0: - return 0; - - case LTE_FilterCoefficient_fc1: - return 1; - - case LTE_FilterCoefficient_fc2: - return 2; - - case LTE_FilterCoefficient_fc3: - return 3; - - case LTE_FilterCoefficient_fc4: - return 4; - - case LTE_FilterCoefficient_fc5: - return 5; - - case LTE_FilterCoefficient_fc6: - return 6; - - case LTE_FilterCoefficient_fc7: - return 7; - - case LTE_FilterCoefficient_fc8: - return 8; - - case LTE_FilterCoefficient_fc9: - return 9; - - case LTE_FilterCoefficient_fc11: - return 11; - - case LTE_FilterCoefficient_fc13: - return 13; - - case LTE_FilterCoefficient_fc15: - return 15; - - case LTE_FilterCoefficient_fc17: - return 17; - - case LTE_FilterCoefficient_fc19: - return 19; - - case LTE_FilterCoefficient_spare1: - return -1; /* spare means no coefficient */ - - default: - return -1; - } -} - -/* Periodic event */ - -long flexran_get_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1; - - return ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells; -} - -/* A3 event */ - -long flexran_get_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - return ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis; -} - -long flexran_get_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - switch (ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger) { - case LTE_TimeToTrigger_ms0: - return 0; - - case LTE_TimeToTrigger_ms40: - return 40; - - case LTE_TimeToTrigger_ms64: - return 64; - - case LTE_TimeToTrigger_ms80: - return 80; - - case LTE_TimeToTrigger_ms100: - return 100; - - case LTE_TimeToTrigger_ms128: - return 128; - - case LTE_TimeToTrigger_ms160: - return 160; - - case LTE_TimeToTrigger_ms256: - return 256; - - case LTE_TimeToTrigger_ms320: - return 320; - - case LTE_TimeToTrigger_ms480: - return 480; - - case LTE_TimeToTrigger_ms512: - return 512; - - case LTE_TimeToTrigger_ms640: - return 640; - - case LTE_TimeToTrigger_ms1024: - return 1024; - - case LTE_TimeToTrigger_ms1280: - return 1280; - - case LTE_TimeToTrigger_ms2560: - return 2560; - - case LTE_TimeToTrigger_ms5120: - return 5120; - - default: - return -1; - } -} - -long flexran_get_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - return ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells; -} - -long flexran_get_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - return ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset; -} - -int flexran_get_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - return ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave; -} - -/* RRC Setters */ - -/* Measurement offsets */ - -int flexran_set_rrc_ofp(mid_t mod_id, rnti_t rnti, long offsetFreq) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1; - - ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq; - return 0; -} - -int flexran_set_rrc_ofn(mid_t mod_id, rnti_t rnti, long offsetFreq) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1; - - ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq; - return 0; -} - -int flexran_set_rrc_ocp(mid_t mod_id, rnti_t rnti, long cellIndividualOffset) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[0]; - - switch (cellIndividualOffset) { - case -24: - *cio = LTE_Q_OffsetRange_dB_24; - break; - - case -22: - *cio = LTE_Q_OffsetRange_dB_22; - break; - - case -20: - *cio = LTE_Q_OffsetRange_dB_20; - break; - - case -18: - *cio = LTE_Q_OffsetRange_dB_18; - break; - - case -16: - *cio = LTE_Q_OffsetRange_dB_16; - break; - - case -14: - *cio = LTE_Q_OffsetRange_dB_14; - break; - - case -12: - *cio = LTE_Q_OffsetRange_dB_12; - break; - - case -10: - *cio = LTE_Q_OffsetRange_dB_10; - break; - - case -8: - *cio = LTE_Q_OffsetRange_dB_8; - break; - - case -6: - *cio = LTE_Q_OffsetRange_dB_6; - break; - - case -5: - *cio = LTE_Q_OffsetRange_dB_5; - break; - - case -4: - *cio = LTE_Q_OffsetRange_dB_4; - break; - - case -3: - *cio = LTE_Q_OffsetRange_dB_3; - break; - - case -2: - *cio = LTE_Q_OffsetRange_dB_2; - break; - - case -1: - *cio = LTE_Q_OffsetRange_dB_1; - break; - - case 0: - *cio = LTE_Q_OffsetRange_dB0; - break; - - case 1: - *cio = LTE_Q_OffsetRange_dB1; - break; - - case 2: - *cio = LTE_Q_OffsetRange_dB2; - break; - - case 3: - *cio = LTE_Q_OffsetRange_dB3; - break; - - case 4: - *cio = LTE_Q_OffsetRange_dB4; - break; - - case 5: - *cio = LTE_Q_OffsetRange_dB5; - break; - - case 6: - *cio = LTE_Q_OffsetRange_dB6; - break; - - case 8: - *cio = LTE_Q_OffsetRange_dB8; - break; - - case 10: - *cio = LTE_Q_OffsetRange_dB10; - break; - - case 12: - *cio = LTE_Q_OffsetRange_dB12; - break; - - case 14: - *cio = LTE_Q_OffsetRange_dB14; - break; - - case 16: - *cio = LTE_Q_OffsetRange_dB16; - break; - - case 18: - *cio = LTE_Q_OffsetRange_dB18; - break; - - case 20: - *cio = LTE_Q_OffsetRange_dB20; - break; - - case 22: - *cio = LTE_Q_OffsetRange_dB22; - break; - - case 24: - *cio = LTE_Q_OffsetRange_dB24; - break; - - default: - return -1; - } - - return 0; -} - -int flexran_set_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id, long cellIndividualOffset) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1]; - - switch (cellIndividualOffset) { - case -24: - *cio = LTE_Q_OffsetRange_dB_24; - break; - - case -22: - *cio = LTE_Q_OffsetRange_dB_22; - break; - - case -20: - *cio = LTE_Q_OffsetRange_dB_20; - break; - - case -18: - *cio = LTE_Q_OffsetRange_dB_18; - break; - - case -16: - *cio = LTE_Q_OffsetRange_dB_16; - break; - - case -14: - *cio = LTE_Q_OffsetRange_dB_14; - break; - - case -12: - *cio = LTE_Q_OffsetRange_dB_12; - break; - - case -10: - *cio = LTE_Q_OffsetRange_dB_10; - break; - - case -8: - *cio = LTE_Q_OffsetRange_dB_8; - break; - - case -6: - *cio = LTE_Q_OffsetRange_dB_6; - break; - - case -5: - *cio = LTE_Q_OffsetRange_dB_5; - break; - - case -4: - *cio = LTE_Q_OffsetRange_dB_4; - break; - - case -3: - *cio = LTE_Q_OffsetRange_dB_3; - break; - - case -2: - *cio = LTE_Q_OffsetRange_dB_2; - break; - - case -1: - *cio = LTE_Q_OffsetRange_dB_1; - break; - - case 0: - *cio = LTE_Q_OffsetRange_dB0; - break; - - case 1: - *cio = LTE_Q_OffsetRange_dB1; - break; - - case 2: - *cio = LTE_Q_OffsetRange_dB2; - break; - - case 3: - *cio = LTE_Q_OffsetRange_dB3; - break; - - case 4: - *cio = LTE_Q_OffsetRange_dB4; - break; - - case 5: - *cio = LTE_Q_OffsetRange_dB5; - break; - - case 6: - *cio = LTE_Q_OffsetRange_dB6; - break; - - case 8: - *cio = LTE_Q_OffsetRange_dB8; - break; - - case 10: - *cio = LTE_Q_OffsetRange_dB10; - break; - - case 12: - *cio = LTE_Q_OffsetRange_dB12; - break; - - case 14: - *cio = LTE_Q_OffsetRange_dB14; - break; - - case 16: - *cio = LTE_Q_OffsetRange_dB16; - break; - - case 18: - *cio = LTE_Q_OffsetRange_dB18; - break; - - case 20: - *cio = LTE_Q_OffsetRange_dB20; - break; - - case 22: - *cio = LTE_Q_OffsetRange_dB22; - break; - - case 24: - *cio = LTE_Q_OffsetRange_dB24; - break; - - default: - return -1; - } - - return 0; -} - -int flexran_set_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRP) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRP; - - switch (filterCoefficientRSRP) { - case 0: - *fc = LTE_FilterCoefficient_fc0; - break; - - case 1: - *fc = LTE_FilterCoefficient_fc1; - break; - - case 2: - *fc = LTE_FilterCoefficient_fc2; - break; - - case 3: - *fc = LTE_FilterCoefficient_fc3; - break; - - case 4: - *fc = LTE_FilterCoefficient_fc4; - break; - - case 5: - *fc = LTE_FilterCoefficient_fc5; - break; - - case 6: - *fc = LTE_FilterCoefficient_fc6; - break; - - case 7: - *fc = LTE_FilterCoefficient_fc7; - break; - - case 8: - *fc = LTE_FilterCoefficient_fc8; - break; - - case 9: - *fc = LTE_FilterCoefficient_fc9; - break; - - case 11: - *fc = LTE_FilterCoefficient_fc11; - break; - - case 13: - *fc = LTE_FilterCoefficient_fc13; - break; - - case 15: - *fc = LTE_FilterCoefficient_fc15; - break; - - case 17: - *fc = LTE_FilterCoefficient_fc17; - break; - - case 19: - *fc = LTE_FilterCoefficient_fc19; - break; - - case -1: - *fc = LTE_FilterCoefficient_spare1; - break; - - default: - return -1; - } - - return 0; -} - -int flexran_set_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRQ) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ; - - switch (filterCoefficientRSRQ) { - case 0: - *fc = LTE_FilterCoefficient_fc0; - break; - - case 1: - *fc = LTE_FilterCoefficient_fc1; - break; - - case 2: - *fc = LTE_FilterCoefficient_fc2; - break; - - case 3: - *fc = LTE_FilterCoefficient_fc3; - break; - - case 4: - *fc = LTE_FilterCoefficient_fc4; - break; - - case 5: - *fc = LTE_FilterCoefficient_fc5; - break; - - case 6: - *fc = LTE_FilterCoefficient_fc6; - break; - - case 7: - *fc = LTE_FilterCoefficient_fc7; - break; - - case 8: - *fc = LTE_FilterCoefficient_fc8; - break; - - case 9: - *fc = LTE_FilterCoefficient_fc9; - break; - - case 11: - *fc = LTE_FilterCoefficient_fc11; - break; - - case 13: - *fc = LTE_FilterCoefficient_fc13; - break; - - case 15: - *fc = LTE_FilterCoefficient_fc15; - break; - - case 17: - *fc = LTE_FilterCoefficient_fc17; - break; - - case 19: - *fc = LTE_FilterCoefficient_fc19; - break; - - case -1: - *fc = LTE_FilterCoefficient_spare1; - break; - - default: - return -1; - } - - return 0; -} - -/* Periodic event */ - -int flexran_set_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1; - - if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1; - - ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells = maxReportCells; - return 0; -} - -/* A3 event */ - -int flexran_set_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti, long hysteresis) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - if (!((hysteresis >=0) && (hysteresis <= 30))) return -1; - - ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis = hysteresis; - return 0; -} - -int flexran_set_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti, long timeToTrigger) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - LTE_TimeToTrigger_t *ttt = &ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger; - - switch (timeToTrigger) { - case 0: - *ttt = LTE_TimeToTrigger_ms0; - break; - - case 40: - *ttt = LTE_TimeToTrigger_ms40; - break; - - case 64: - *ttt = LTE_TimeToTrigger_ms64; - break; - - case 80: - *ttt = LTE_TimeToTrigger_ms80; - break; - - case 100: - *ttt = LTE_TimeToTrigger_ms100; - break; - - case 128: - *ttt = LTE_TimeToTrigger_ms128; - break; - - case 160: - *ttt = LTE_TimeToTrigger_ms160; - break; - - case 256: - *ttt = LTE_TimeToTrigger_ms256; - break; - - case 320: - *ttt = LTE_TimeToTrigger_ms320; - break; - - case 480: - *ttt = LTE_TimeToTrigger_ms480; - break; - - case 512: - *ttt = LTE_TimeToTrigger_ms512; - break; - - case 640: - *ttt = LTE_TimeToTrigger_ms640; - break; - - case 1024: - *ttt = LTE_TimeToTrigger_ms1024; - break; - - case 1280: - *ttt = LTE_TimeToTrigger_ms1280; - break; - - case 2560: - *ttt = LTE_TimeToTrigger_ms2560; - break; - - case 5120: - *ttt = LTE_TimeToTrigger_ms5120; - break; - - default: - return -1; - } - - return 0; -} - -int flexran_set_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1; - - ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells = maxReportCells; - return 0; -} - -int flexran_set_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti, long a3_offset) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - if (!((a3_offset >= -30) && (a3_offset <= 30))) return -1; - - ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset = a3_offset; - return 0; -} - -int flexran_set_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti, int reportOnLeave) { - if (!rrc_is_present(mod_id)) return -1; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return -1; - - if (!ue_context_p->ue_context.measurement_info) return -1; - - if (!ue_context_p->ue_context.measurement_info->events) return -1; - - if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1; - - if (!((reportOnLeave == 0) || (reportOnLeave == 1))) return -1; - - ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave = reportOnLeave; - return 0; -} - -int flexran_set_x2_ho_net_control(mid_t mod_id, int x2_ho_net_control) { - if (!rrc_is_present(mod_id)) return -1; - - if (!((x2_ho_net_control == 0) || (x2_ho_net_control == 1))) return -1; - - RC.rrc[mod_id]->x2_ho_net_control = x2_ho_net_control; - return 0; -} - -int flexran_get_x2_ho_net_control(mid_t mod_id) { - if (!rrc_is_present(mod_id)) return -1; - - return RC.rrc[mod_id]->x2_ho_net_control; -} - -uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->configuration.num_plmn; -} - -uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->configuration.mcc[index]; -} - -uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->configuration.mnc[index]; -} - -uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->configuration.mnc_digit_length[index]; -} - -int flexran_get_rrc_num_adj_cells(mid_t mod_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->num_neigh_cells; -} - -int flexran_agent_rrc_gtp_num_e_rab(mid_t mod_id, rnti_t rnti) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return 0; - - return ue_context_p->ue_context.setup_e_rabs; -} - -int flexran_agent_rrc_gtp_get_e_rab_id(mid_t mod_id, rnti_t rnti, int index) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return 0; - - return ue_context_p->ue_context.e_rab[index].param.e_rab_id; -} - -int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return 0; - - return ue_context_p->ue_context.enb_gtp_teid[index]; -} - -int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index) { - if (!rrc_is_present(mod_id)) return 0; - - struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - - if (!ue_context_p) return 0; - - return ue_context_p->ue_context.e_rab[index].param.gtp_teid; -} - -uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti) -{ - if (!rrc_is_present(mod_id)) return 0; - struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti); - if (!ue_context_p) return -1; - return ue_context_p->ue_context.eNB_ue_s1ap_id; -} - -/**************************** SLICING ****************************/ -Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id) { - if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None; - - switch (RC.mac[mod_id]->pre_processor_dl.algorithm) { - case STATIC_SLICING: - return PROTOCOL__FLEX_SLICE_ALGORITHM__Static; - default: - return PROTOCOL__FLEX_SLICE_ALGORITHM__None; - } -} - -int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) { - if (!mac_is_present(mod_id)) return 0; - eNB_MAC_INST *mac = RC.mac[mod_id]; - const int cc_id = 0; - - pp_impl_param_t dl = mac->pre_processor_dl; - switch (algo) { - case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: - mac->pre_processor_dl = static_dl_init(mod_id, cc_id); - break; - default: - mac->pre_processor_dl.algorithm = 0; - mac->pre_processor_dl.dl = dlsch_scheduler_pre_processor; - mac->pre_processor_dl.dl_algo.data = mac->pre_processor_dl.dl_algo.setup(); - mac->pre_processor_dl.slices = NULL; - break; - } - if (dl.slices) - dl.destroy(&dl.slices); - if (dl.dl_algo.data) - dl.dl_algo.unset(&dl.dl_algo.data); - return 1; -} - -Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id) { - if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None; - - switch (RC.mac[mod_id]->pre_processor_ul.algorithm) { - case STATIC_SLICING: - return PROTOCOL__FLEX_SLICE_ALGORITHM__Static; - default: - return PROTOCOL__FLEX_SLICE_ALGORITHM__None; - } -} - -int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) { - if (!mac_is_present(mod_id)) return 0; - eNB_MAC_INST *mac = RC.mac[mod_id]; - const int cc_id = 0; - - pp_impl_param_t ul = mac->pre_processor_ul; - switch (algo) { - case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: - mac->pre_processor_ul = static_ul_init(mod_id, cc_id); - break; - default: - mac->pre_processor_ul.algorithm = 0; - mac->pre_processor_ul.ul = ulsch_scheduler_pre_processor; - mac->pre_processor_ul.ul_algo.data = mac->pre_processor_ul.ul_algo.setup(); - mac->pre_processor_ul.slices = NULL; - break; - } - if (ul.slices) - ul.destroy(&ul.slices); - if (ul.ul_algo.data) - ul.ul_algo.unset(&ul.ul_algo.data); - return 1; -} - -int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return -1; - slice_info_t *slices = RC.mac[mod_id]->pre_processor_dl.slices; - if (!slices) return -1; - const int idx = slices->UE_assoc_slice[ue_id]; - return slices->s[idx]->id; -} - -int flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return 0; - int idx = flexran_find_dl_slice(mod_id, slice_id); - if (idx < 0) return 0; - pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; - dl->move_UE(dl->slices, ue_id, idx); - return 1; -} - -int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { - if (!mac_is_present(mod_id)) return -1; - slice_info_t *slices = RC.mac[mod_id]->pre_processor_ul.slices; - if (!slices) return -1; - const int idx = slices->UE_assoc_slice[ue_id]; - return slices->s[idx]->id; -} - -int flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return 0; - int idx = flexran_find_ul_slice(mod_id, slice_id); - if (idx < 0) return 0; - pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; - ul->move_UE(ul->slices, ue_id, idx); - return 1; -} - -int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) { - if (!mac_is_present(mod_id)) return 0; - void *params = NULL; - switch (s->params_case) { - case PROTOCOL__FLEX_SLICE__PARAMS_STATIC: - params = malloc(sizeof(static_slice_param_t)); - if (!params) return 0; - ((static_slice_param_t *)params)->posLow = s->static_->poslow; - ((static_slice_param_t *)params)->posHigh = s->static_->poshigh; - break; - default: - break; - } - pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; - char *l = s->label ? strdup(s->label) : NULL; - void *algo = &dl->dl_algo; // default scheduler - if (s->scheduler) { - algo = dlsym(object, s->scheduler); - if (!algo) { - free(params); - LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); - return -15; - } - } - return dl->addmod_slice(dl->slices, s->id, l, algo, params); -} - -int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) { - if (!mac_is_present(mod_id)) return 0; - const int idx = flexran_find_dl_slice(mod_id, s->id); - if (idx < 0) return 0; - pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; - return dl->remove_slice(dl->slices, idx); -} - -int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return -1; - slice_info_t *si = RC.mac[mod_id]->pre_processor_dl.slices; - for (int i = 0; i < si->num; ++i) - if (si->s[i]->id == slice_id) - return i; - return -1; -} - -void flexran_get_dl_slice(mid_t mod_id, - int slice_idx, - Protocol__FlexSlice *slice, - Protocol__FlexSliceAlgorithm algo) { - if (!mac_is_present(mod_id)) return; - slice_t *s_ = RC.mac[mod_id]->pre_processor_dl.slices->s[slice_idx]; - slice->has_id = 1; - slice->id = s_->id; - slice->label = s_->label; - slice->scheduler = s_->dl_algo.name; - slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET; - switch (algo) { - case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: - slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic)); - if (!slice->static_) return; - protocol__flex_slice_static__init(slice->static_); - slice->static_->has_poslow = 1; - slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow; - slice->static_->has_poshigh = 1; - slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh; - slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC; - break; - default: - break; - } -} - -int flexran_get_num_dl_slices(mid_t mod_id) { - if (!mac_is_present(mod_id)) return 0; - if (!RC.mac[mod_id]->pre_processor_dl.slices) return 0; - return RC.mac[mod_id]->pre_processor_dl.slices->num; -} - -int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) { - if (!mac_is_present(mod_id)) return -1; - void *params = NULL; - switch (s->params_case) { - case PROTOCOL__FLEX_SLICE__PARAMS_STATIC: - params = malloc(sizeof(static_slice_param_t)); - if (!params) return 0; - ((static_slice_param_t *)params)->posLow = s->static_->poslow; - ((static_slice_param_t *)params)->posHigh = s->static_->poshigh; - break; - default: - break; - } - pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; - char *l = s->label ? strdup(s->label) : NULL; - void *algo = &ul->ul_algo; // default scheduler - if (s->scheduler) { - algo = dlsym(object, s->scheduler); - if (!algo) { - free(params); - LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); - return -15; - } - } - return ul->addmod_slice(ul->slices, s->id, l, algo, params); -} - -int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) { - if (!mac_is_present(mod_id)) return 0; - const int idx = flexran_find_ul_slice(mod_id, s->id); - if (idx < 0) return 0; - pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; - return ul->remove_slice(ul->slices, idx); -} - -int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return -1; - slice_info_t *si = RC.mac[mod_id]->pre_processor_ul.slices; - for (int i = 0; i < si->num; ++i) - if (si->s[i]->id == slice_id) - return i; - return -1; -} - -void flexran_get_ul_slice(mid_t mod_id, - int slice_idx, - Protocol__FlexSlice *slice, - Protocol__FlexSliceAlgorithm algo) { - if (!mac_is_present(mod_id)) return; - slice_t *s_ = RC.mac[mod_id]->pre_processor_ul.slices->s[slice_idx]; - slice->has_id = 1; - slice->id = s_->id; - slice->label = s_->label; - slice->scheduler = s_->ul_algo.name; - slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET; - switch (algo) { - case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: - slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic)); - if (!slice->static_) return; - protocol__flex_slice_static__init(slice->static_); - slice->static_->has_poslow = 1; - slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow; - slice->static_->has_poshigh = 1; - slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh; - slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC; - break; - default: - break; - } - -} - -int flexran_get_num_ul_slices(mid_t mod_id) { - if (!mac_is_present(mod_id)) return 0; - if (!RC.mac[mod_id]->pre_processor_ul.slices) return 0; - return RC.mac[mod_id]->pre_processor_ul.slices->num; -} - -char *flexran_get_dl_scheduler_name(mid_t mod_id) { - if (!mac_is_present(mod_id)) return NULL; - return RC.mac[mod_id]->pre_processor_dl.dl_algo.name; -} - -int flexran_set_dl_scheduler(mid_t mod_id, char *sched, void *object) { - if (!mac_is_present(mod_id)) return -1; - void *d = dlsym(object, sched); - if (!d) return -2; - pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl; - dl_pp->dl_algo.unset(&dl_pp->dl_algo.data); - dl_pp->dl_algo = *(default_sched_dl_algo_t *) d; - dl_pp->dl_algo.data = dl_pp->dl_algo.setup(); - return 0; -} - -char *flexran_get_ul_scheduler_name(mid_t mod_id) { - if (!mac_is_present(mod_id)) return NULL; - return RC.mac[mod_id]->pre_processor_ul.ul_algo.name; -} - -int flexran_set_ul_scheduler(mid_t mod_id, char *sched, void *object) { - if (!mac_is_present(mod_id)) return -1; - void *d = dlsym(object, sched); - if (!d) return -2; - pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul; - ul_pp->ul_algo.unset(&ul_pp->ul_algo.data); - ul_pp->ul_algo = *(default_sched_ul_algo_t *) d; - ul_pp->ul_algo.data = ul_pp->ul_algo.setup(); - return 0; -} - -/************************** S1AP **************************/ -int flexran_get_s1ap_mme_pending(mid_t mod_id){ - if (!rrc_is_present(mod_id)) return -1; - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return -1; - return s1ap->s1ap_mme_pending_nb; -} - -int flexran_get_s1ap_mme_connected(mid_t mod_id){ - if (!rrc_is_present(mod_id)) return -1; - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return -1; - return s1ap->s1ap_mme_associated_nb; -} - -char* flexran_get_s1ap_enb_s1_ip(mid_t mod_id){ - if (!rrc_is_present(mod_id)) return NULL; - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return NULL; - if (s1ap->eNB_s1_ip.ipv4) - return &s1ap->eNB_s1_ip.ipv4_address[0]; - if (s1ap->eNB_s1_ip.ipv6) - return &s1ap->eNB_s1_ip.ipv6_address[0]; - return NULL; -} - -char* flexran_get_s1ap_enb_name(mid_t mod_id){ - if (!rrc_is_present(mod_id)) return NULL; - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return NULL; - return s1ap->eNB_name; -} - -int flexran_get_s1ap_nb_mme(mid_t mod_id) { - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return 0; - struct s1ap_eNB_mme_data_s *mme = NULL; - int count = 0; - RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { - count++; - } - return count; -} - -int flexran_get_s1ap_nb_ue(mid_t mod_id) { - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return 0; - struct s1ap_eNB_ue_context_s *ue = NULL; - int count = 0; - RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head) { - count++; - } - return count; -} - -int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apMme * mme_conf){ - if (!rrc_is_present(mod_id)) return -1; - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return -1; - - struct served_gummei_s *gummei_p = NULL; - struct plmn_identity_s *served_plmn_p = NULL; - struct served_group_id_s *group_id_p = NULL; - struct mme_code_s *mme_code_p = NULL; - int i = 0; - Protocol__FlexGummei **served_gummeis; - Protocol__FlexPlmn **requested_plmns; - - struct s1ap_eNB_mme_data_s *mme = NULL; - - RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head){ - if (mme_index == 0) break; - mme_index--; - } - if (mme_index > 0) return -1; - - if (mme->mme_s1_ip.ipv4) { - mme_conf->s1_ip = (char*) &mme->mme_s1_ip.ipv4_address[0]; - } else if (mme->mme_s1_ip.ipv6) { - mme_conf->s1_ip = (char*) &mme->mme_s1_ip.ipv6_address[0]; - } - mme_conf->name = mme->mme_name; - mme_conf->has_state = 1; - mme_conf->state = mme->state; - - mme_conf->n_served_gummeis = 0; - STAILQ_FOREACH(gummei_p, &mme->served_gummei, next) { - mme_conf->n_served_gummeis++; - } - if (mme_conf->n_served_gummeis > 0) { - served_gummeis = calloc(mme_conf->n_served_gummeis, sizeof(Protocol__FlexGummei*)); - if(served_gummeis == NULL) return -1; - - STAILQ_FOREACH(gummei_p, &mme->served_gummei, next) { - served_plmn_p = STAILQ_FIRST(&gummei_p->served_plmns); - group_id_p = STAILQ_FIRST(&gummei_p->served_group_ids); - mme_code_p = STAILQ_FIRST(&gummei_p->mme_codes); - - served_gummeis[i] = malloc(sizeof(Protocol__FlexGummei)); - if (!served_gummeis[i]) return -1; - protocol__flex_gummei__init(served_gummeis[i]); - served_gummeis[i]->plmn = malloc(sizeof(Protocol__FlexPlmn)); - if (!served_gummeis[i]->plmn) return -1; - protocol__flex_plmn__init(served_gummeis[i]->plmn); - - if (served_plmn_p) { - served_gummeis[i]->plmn->has_mcc = 1; - served_gummeis[i]->plmn->mcc = served_plmn_p->mcc; - served_gummeis[i]->plmn->has_mnc = 1; - served_gummeis[i]->plmn->mnc = served_plmn_p->mnc; - served_gummeis[i]->plmn->has_mnc_length = 1; - served_gummeis[i]->plmn->mnc_length = served_plmn_p-> mnc_digit_length; - STAILQ_NEXT(served_plmn_p, next); - } - if (group_id_p) { - served_gummeis[i]->has_mme_group_id = 1; - served_gummeis[i]->mme_group_id = group_id_p->mme_group_id; - STAILQ_NEXT(group_id_p, next); - } - if (mme_code_p){ - served_gummeis[i]->has_mme_code = 1; - served_gummeis[i]->mme_code = mme_code_p->mme_code; - STAILQ_NEXT(mme_code_p, next); - } - i++; - } - - mme_conf->served_gummeis = served_gummeis; - } - - // requested PLMNS - mme_conf->n_requested_plmns = mme->broadcast_plmn_num; - if (mme_conf->n_requested_plmns > 0){ - requested_plmns = calloc(mme_conf->n_requested_plmns, sizeof(Protocol__FlexPlmn*)); - if(requested_plmns == NULL) return -1; - for(int i = 0; i < mme_conf->n_requested_plmns; i++) { - requested_plmns[i] = malloc(sizeof(Protocol__FlexPlmn)); - if (!requested_plmns[i]) return -1; - protocol__flex_plmn__init(requested_plmns[i]); - requested_plmns[i]->mcc = s1ap->mcc[mme->broadcast_plmn_index[i]]; - requested_plmns[i]->has_mcc = 1; - requested_plmns[i]->mnc = s1ap->mnc[mme->broadcast_plmn_index[i]]; - requested_plmns[i]->has_mnc = 1; - requested_plmns[i]->mnc_length = s1ap->mnc_digit_length[mme->broadcast_plmn_index[i]]; - requested_plmns[i]->has_mnc_length = 1; - } - mme_conf->requested_plmns = requested_plmns; - } - - mme_conf->has_rel_capacity = 1; - mme_conf->rel_capacity = mme->relative_mme_capacity; - return 0; -} - -int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return -1; - if (!rrc_is_present(mod_id)) return -2; - - /* Reconstruct S1AP_REGISTER_ENB_REQ */ - MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, 0, S1AP_REGISTER_ENB_REQ); - RCconfig_S1(m, mod_id); - - const int CC_id = 0; - eNB_RRC_INST *rrc = RC.rrc[CC_id]; - RrcConfigurationReq *conf = &rrc->configuration; - S1AP_REGISTER_ENB_REQ(m).num_plmn = conf->num_plmn; - for (int i = 0; i < conf->num_plmn; ++i) { - S1AP_REGISTER_ENB_REQ(m).mcc[i] = conf->mcc[i]; - S1AP_REGISTER_ENB_REQ(m).mnc[i] = conf->mnc[i]; - S1AP_REGISTER_ENB_REQ(m).mnc_digit_length[i] = conf->mnc_digit_length[i]; - } - - /* reconstruct MME list, it might have been updated since initial - * configuration */ - S1AP_REGISTER_ENB_REQ(m).nb_mme = 0; - struct s1ap_eNB_mme_data_s *mme = NULL; - RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { - const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; - S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = mme->mme_s1_ip.ipv4; - strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme->mme_s1_ip.ipv4_address); - S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = mme->mme_s1_ip.ipv6; - strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6_address, mme->mme_s1_ip.ipv6_address); - S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = mme->broadcast_plmn_num; - for (int i = 0; i < mme->broadcast_plmn_num; ++i) - S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = mme->broadcast_plmn_index[i]; - S1AP_REGISTER_ENB_REQ(m).mme_port[n] = mme->mme_port; - S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; - } - - if (S1AP_REGISTER_ENB_REQ(m).nb_mme + n_mme > S1AP_MAX_NB_MME_IP_ADDRESS) - return -1; - - const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; - strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]); - S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1; - S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0; - S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn; - for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i) - S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i; - S1AP_REGISTER_ENB_REQ(m).mme_port[n] = S1AP_PORT_NUMBER; - S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; - - itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); - - return 0; -} - -int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return -1; - struct s1ap_eNB_mme_data_s *mme = NULL; - RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { - if (mme->mme_s1_ip.ipv4 - && strncmp(mme->mme_s1_ip.ipv4_address, mme_ipv4[0], 16) == 0) - break; - } - if (!mme) - return -2; - - MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, 0, SCTP_CLOSE_ASSOCIATION); - SCTP_CLOSE_ASSOCIATION(m).assoc_id = mme->assoc_id; - itti_send_msg_to_task (TASK_SCTP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); - - switch (mme->state) { - case S1AP_ENB_STATE_WAITING: - s1ap->s1ap_mme_nb -= 1; - if (s1ap->s1ap_mme_pending_nb > 0) - s1ap->s1ap_mme_pending_nb -= 1; - break; - case S1AP_ENB_STATE_CONNECTED: - case S1AP_ENB_OVERLOAD: /* I am not sure the decrements are right here */ - s1ap->s1ap_mme_nb -= 1; - s1ap->s1ap_mme_associated_nb -= 1; - break; - case S1AP_ENB_STATE_DISCONNECTED: - default: - break; - } - RB_REMOVE(s1ap_mme_map, &s1ap->s1ap_mme_head, mme); - - return 0; -} - -int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id) { - if (!rrc_is_present(mod_id)) - return -1; - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) - return -2; - - eNB_RRC_INST *rrc = RC.rrc[CC_id]; - RrcConfigurationReq *conf = &rrc->configuration; - - uint8_t num_plmn_old = conf->num_plmn; - uint16_t mcc[PLMN_LIST_MAX_SIZE]; - uint16_t mnc[PLMN_LIST_MAX_SIZE]; - uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; - for (int i = 0; i < num_plmn_old; ++i) { - mcc[i] = conf->mcc[i]; - mnc[i] = conf->mnc[i]; - mnc_digit_length[i] = conf->mnc_digit_length[i]; - } - - conf->num_plmn = (uint8_t) n_plmn; - for (int i = 0; i < conf->num_plmn; ++i) { - conf->mcc[i] = plmn_id[i]->mcc; - conf->mnc[i] = plmn_id[i]->mnc; - conf->mnc_digit_length[i] = plmn_id[i]->mnc_length; - } - - rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id]; - extern uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, - int Mod_id, - int CC_id, - BOOLEAN_t brOption, - RrcConfigurationReq *configuration); - carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, false, conf); - if (carrier->sizeof_SIB1 < 0) - return -1337; /* SIB1 encoding failed, hell will probably break loose */ - - s1ap->num_plmn = (uint8_t) n_plmn; - for (int i = 0; i < conf->num_plmn; ++i) { - s1ap->mcc[i] = plmn_id[i]->mcc; - s1ap->mnc[i] = plmn_id[i]->mnc; - s1ap->mnc_digit_length[i] = plmn_id[i]->mnc_length; - } - - int bpn_failed = 0; - struct s1ap_eNB_mme_data_s *mme = NULL; - RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { - for (int i = 0; i < mme->broadcast_plmn_num; ++i) { - /* search the new index and update. If we don't find, we count this using - * bpn_failed to now how many broadcast_plmns could not be updated */ - int idx = mme->broadcast_plmn_index[i]; - int omcc = mcc[idx]; - int omnc = mnc[idx]; - int omncl = mnc_digit_length[idx]; - int j = 0; - for (j = 0; j < s1ap->num_plmn; ++j) { - if (s1ap->mcc[j] == omcc - && s1ap->mnc[j] == omnc - && s1ap->mnc_digit_length[j] == omncl) { - mme->broadcast_plmn_index[i] = j; - break; - } - } - if (j == s1ap->num_plmn) /* could not find the old PLMN in the new ones */ - bpn_failed++; - } - } - if (bpn_failed > 0) - return -10000 - bpn_failed; - return 0; -} - -int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){ - if (!rrc_is_present(mod_id)) return -1; - s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); - if (!s1ap) return -1; - - uint32_t enb_ue_s1ap_id = flexran_get_rrc_enb_ue_s1ap_id(mod_id, rnti); - struct s1ap_eNB_ue_context_s *ue = NULL; - RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head){ - if (ue->eNB_ue_s1ap_id == enb_ue_s1ap_id) break; - } - if (!ue) return 0; // UE does not exist: it might be connected but CN did not answer - - if (ue->mme_ref->mme_s1_ip.ipv4) - ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv4_address[0]; - else if (ue->mme_ref->mme_s1_ip.ipv6) - ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv6_address[0]; - - ue_conf->has_enb_ue_s1ap_id = 1; - ue_conf->enb_ue_s1ap_id = ue->eNB_ue_s1ap_id; - ue_conf->has_mme_ue_s1ap_id = 1; - ue_conf->mme_ue_s1ap_id = ue->mme_ue_s1ap_id; - - ue_conf->selected_plmn = malloc(sizeof(Protocol__FlexPlmn)); - if (!ue_conf->selected_plmn) return -1; - protocol__flex_plmn__init(ue_conf->selected_plmn); - - ue_conf->selected_plmn->has_mcc = 1; - ue_conf->selected_plmn->mcc = s1ap->mcc[ue->selected_plmn_identity]; - ue_conf->selected_plmn->has_mnc = 1; - ue_conf->selected_plmn->mnc = s1ap->mnc[ue->selected_plmn_identity]; - ue_conf->selected_plmn->has_mnc_length = 1; - ue_conf->selected_plmn->mnc_length = s1ap->mnc_digit_length[ue->selected_plmn_identity]; - return 0; -} - -/**************************** General BS info ****************************/ -uint64_t flexran_get_bs_id(mid_t mod_id) { - if (!rrc_is_present(mod_id)) return 0; - - return RC.rrc[mod_id]->nr_cellid; -} - -size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) { - if (!caps) return 0; - - if (!rrc_is_present(mod_id)) return 0; - - size_t n_caps = 0; - - switch (RC.rrc[mod_id]->node_type) { - case ngran_eNB_CU: - case ngran_ng_eNB_CU: - case ngran_gNB_CU: - case ngran_gNB_CUCP: - case ngran_gNB_CUUP: - n_caps = 4; - *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); - AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", - n_caps * sizeof(Protocol__FlexBsCapability)); - (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP; - (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP; - (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__RRC; - (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__S1AP; - break; - case ngran_eNB_DU: - case ngran_gNB_DU: - n_caps = 5; - *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); - AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", - n_caps * sizeof(Protocol__FlexBsCapability)); - (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY; - (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY; - (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC; - (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC; - (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC; - break; - case ngran_eNB: - case ngran_ng_eNB: - case ngran_gNB: - n_caps = 9; - *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability)); - AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n", - n_caps * sizeof(Protocol__FlexBsCapability)); - (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY; - (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY; - (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC; - (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC; - (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC; - (*caps)[5] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP; - (*caps)[6] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP; - (*caps)[7] = PROTOCOL__FLEX_BS_CAPABILITY__RRC; - (*caps)[8] = PROTOCOL__FLEX_BS_CAPABILITY__S1AP; - break; - case ngran_eNB_MBMS_STA: - AssertFatal(0, "MBMS STA not supported by FlexRAN!\n"); - break; - } - - return n_caps; -} - -uint32_t flexran_get_capabilities_mask(mid_t mod_id) { - if (!rrc_is_present(mod_id)) return 0; - uint32_t mask = 0; - switch (RC.rrc[mod_id]->node_type) { - case ngran_eNB_CU: - case ngran_ng_eNB_CU: - case ngran_gNB_CU: - case ngran_gNB_CUCP: - case ngran_gNB_CUUP: - mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP); - break; - case ngran_eNB_DU: - case ngran_gNB_DU: - mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC); - break; - case ngran_eNB: - case ngran_ng_eNB: - case ngran_gNB: - mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC) - | (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP); - break; - case ngran_eNB_MBMS_STA: - AssertFatal(0, "MBMS STA not supported by FlexRAN!\n"); - break; - } - - return mask; -} - -size_t flexran_get_splits(mid_t mod_id, Protocol__FlexBsSplit **splits) { - size_t n_splits = 0; - *splits = NULL; - if (rrc_is_present(mod_id) && !NODE_IS_MONOLITHIC(RC.rrc[mod_id]->node_type)) - n_splits++; - if (NFAPI_MODE != NFAPI_MONOLITHIC) - n_splits++; - if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south != LOCAL_RF) - n_splits++; - if (n_splits == 0) - return 0; - - AssertFatal(n_splits < 3, "illegal number of splits (%lu)\n", n_splits); - *splits = calloc(n_splits, sizeof(Protocol__FlexBsSplit)); - AssertFatal(*splits, "could not allocate Protocol__FlexBsSplit array\n"); - int n = 0; - if (rrc_is_present(mod_id) && !NODE_IS_MONOLITHIC(RC.rrc[mod_id]->node_type)) - (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__F1; - if (NFAPI_MODE != NFAPI_MONOLITHIC) - (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__nFAPI; - if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south == REMOTE_IF4p5) - (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__IF4p5; - if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south == REMOTE_IF5) - (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__IF5; - DevAssert(n == n_splits); - return n_splits; -} diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c index 08a5b906eedce8060e5413a0db9dd4f8c0e1c219..afb4a1048af9b4c4a585f0288471875c3a71c601 100644 --- a/openair2/F1AP/dummy_enb.c +++ b/openair2/F1AP/dummy_enb.c @@ -52,3 +52,10 @@ abort(); int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { abort(); } + +int rrc_gNB_generate_pcch_msg(uint32_t tmsi, + uint8_t paging_drx, + instance_t instance, + uint8_t CC_id) { + abort(); +} diff --git a/openair2/F1AP/f1ap_cu_paging.c b/openair2/F1AP/f1ap_cu_paging.c index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..f0e68bf1fcf57fc3240b821685aa9e1e84ce9225 100644 --- a/openair2/F1AP/f1ap_cu_paging.c +++ b/openair2/F1AP/f1ap_cu_paging.c @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU +/*! \file f1ap_cu_paging.c + * \brief f1ap interface paging for CU * \author EURECOM/NTUST * \date 2018 * \version 0.1 @@ -28,4 +28,93 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ + +#include "f1ap_common.h" +#include "f1ap_encoder.h" +#include "f1ap_itti_messaging.h" +#include "f1ap_cu_paging.h" + +extern f1ap_setup_req_t *f1ap_du_data_from_du; + +int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) { + F1AP_F1AP_PDU_t pdu = {0}; + + pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; + asn1cCalloc(pdu.choice.initiatingMessage, msg); + msg->procedureCode = F1AP_ProcedureCode_id_Paging; + msg->criticality = F1AP_Criticality_reject; + msg->value.present = F1AP_InitiatingMessage__value_PR_Paging; + + /* mandatory */ + /* UEIdentityIndexValue */ + { + asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list, + F1AP_PagingIEs_t, ie); + ie->id = F1AP_ProtocolIE_ID_id_UEIdentityIndexValue; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_PagingIEs__value_PR_UEIdentityIndexValue; + ie->value.choice.UEIdentityIndexValue.present = + F1AP_UEIdentityIndexValue_PR_indexLength10; + UEIDENTITYINDEX_TO_BIT_STRING( + paging->ueidentityindexvalue, + &ie->value.choice.UEIdentityIndexValue.choice.indexLength10); + } + + /* mandatory */ + /* PagingIdentity */ + { + asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list, + F1AP_PagingIEs_t, ie); + ie->id = F1AP_ProtocolIE_ID_id_PagingIdentity; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_PagingIEs__value_PR_PagingIdentity; + ie->value.choice.PagingIdentity.present = + F1AP_PagingIdentity_PR_cNUEPagingIdentity; + asn1cCalloc(ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity, id); + id->present = F1AP_CNUEPagingIdentity_PR_fiveG_S_TMSI; + FIVEG_S_TMSI_TO_BIT_STRING(paging->fiveg_s_tmsi, &id->choice.fiveG_S_TMSI); + } + + /* optional */ + /* PagingDRX */ + { + asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list, + F1AP_PagingIEs_t, ie); + ie->id = F1AP_ProtocolIE_ID_id_PagingDRX; + ie->criticality = F1AP_Criticality_ignore; + ie->value.present = F1AP_PagingIEs__value_PR_PagingDRX; + ie->value.choice.PagingDRX = paging->paging_drx; + } + + /* mandatory */ + /* PagingCell_list */ + { + asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list, + F1AP_PagingIEs_t, ie); + ie->id = F1AP_ProtocolIE_ID_id_PagingCell_List; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_PagingIEs__value_PR_PagingCell_list; + asn1cSequenceAdd(ie->value.choice.PagingCell_list, + F1AP_PagingCell_ItemIEs_t, itemies); + itemies->id = F1AP_ProtocolIE_ID_id_PagingCell_Item; + itemies->criticality = F1AP_Criticality_reject; + itemies->value.present = F1AP_PagingCell_ItemIEs__value_PR_PagingCell_Item; + F1AP_NRCGI_t *nRCGI = &itemies->value.choice.PagingCell_Item.nRCGI; + MCC_MNC_TO_PLMNID(paging->mcc, paging->mnc, paging->mnc_digit_length, + &nRCGI->pLMN_Identity); + NR_CELL_ID_TO_BIT_STRING(paging->nr_cellid, &nRCGI->nRCellIdentity); + } + + uint8_t *buffer; + uint32_t len; + /* encode */ + if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 Paging failure\n"); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); + return -1; + } + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu); + f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0); + return 0; +} diff --git a/openair2/F1AP/f1ap_cu_paging.h b/openair2/F1AP/f1ap_cu_paging.h index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..5cff651fcc4d823ef03be0f6c50ef9b0c1aee5e1 100644 --- a/openair2/F1AP/f1ap_cu_paging.h +++ b/openair2/F1AP/f1ap_cu_paging.h @@ -19,8 +19,8 @@ * contact@openairinterface.org */ -/*! \file f1ap_du_interface_management.h - * \brief f1ap interface management for DU +/*! \file f1ap_cu_paging.h + * \brief f1ap interface paging for CU * \author EURECOM/NTUST * \date 2018 * \version 0.1 @@ -28,4 +28,9 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ + +#ifndef F1AP_CU_PAGING_H_ +#define F1AP_CU_PAGING_H_ +int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging); +#endif /* F1AP_DU_PAGING_H_ */ diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index d8ce0c7868937f3eb988b28a19f5f56ba9a5df89..de6abf0a7b41e876e9f1a861acdec6fc13891fdb 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -34,6 +34,7 @@ #include "f1ap_cu_interface_management.h" #include "f1ap_cu_rrc_message_transfer.h" #include "f1ap_cu_ue_context_management.h" +#include "f1ap_cu_paging.h" #include "f1ap_cu_task.h" #include <openair3/ocp-gtpu/gtp_itf.h> @@ -195,6 +196,12 @@ void *F1AP_CU_task(void *arg) { &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg)); break; + case F1AP_PAGING_IND: + LOG_I(F1AP, "CU Task Received F1AP_PAGING_IND\n"); + CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &F1AP_PAGING_IND(received_msg)); + break; + // case F1AP_SETUP_RESPONSE: // This is from RRC // CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp) // break; diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c index 47e1f274d3f22bc217a620fff92bcded451463af..04c4ae18ee9129c639d4725037954f933efe8214 100644 --- a/openair2/F1AP/f1ap_decoder.c +++ b/openair2/F1AP/f1ap_decoder.c @@ -83,6 +83,10 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) { LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__); break; + case F1AP_ProcedureCode_id_Paging: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_Paging\n", __func__); + break; + // case F1AP_ProcedureCode_id_InitialContextSetup: // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); // message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG; diff --git a/openair2/F1AP/f1ap_du_paging.c b/openair2/F1AP/f1ap_du_paging.c index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..46f17fd64d0430b970dcd07534786cb93b70dfd8 100644 --- a/openair2/F1AP/f1ap_du_paging.c +++ b/openair2/F1AP/f1ap_du_paging.c @@ -28,4 +28,70 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ +#include "f1ap_common.h" +#include "f1ap_du_paging.h" +#include "conversions.h" +#include "asn1_conversions.h" +#include "openair2/RRC/LTE/rrc_proto.h" + +int DU_handle_Paging(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + F1AP_Paging_t *paging; + F1AP_PagingIEs_t *ie; + long tmsi; + uint8_t pagingdrx; + uint8_t *fiveg_tmsi_buf = NULL; + + DevAssert(pdu); + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu); + } + + paging = &pdu->choice.initiatingMessage->value.choice.Paging; + // get UEIdentityIndexValue + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_UEIdentityIndexValue, true); + + LOG_D(F1AP, "indexLength10 %d\n", BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue.choice.indexLength10)); + + // get PagingIdentity + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_PagingIdentity, true); + + if(ie != NULL){ + fiveg_tmsi_buf = ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf; + + tmsi = ((long)fiveg_tmsi_buf[0] << 40) + + ((long)fiveg_tmsi_buf[1] << 32) + + (fiveg_tmsi_buf[2] << 24) + + (fiveg_tmsi_buf[3] << 16) + + (fiveg_tmsi_buf[4] << 8) + + fiveg_tmsi_buf[5]; + + LOG_D(F1AP, "tmsi %ld\n", tmsi); + } + + // get PagingDRX + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_PagingDRX, true); + + if(ie != NULL) { + pagingdrx = (uint8_t)ie->value.choice.PagingDRX; + } + + LOG_D(F1AP, "pagingdrx %u\n", pagingdrx); + + // get PagingCell_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging, + F1AP_ProtocolIE_ID_id_PagingCell_List, true); + + for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + rrc_gNB_generate_pcch_msg((uint32_t)tmsi, pagingdrx, instance, CC_id); + } + + return 0; +} \ No newline at end of file diff --git a/openair2/F1AP/f1ap_du_paging.h b/openair2/F1AP/f1ap_du_paging.h index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..3e1806ae0223c9096c0b1aa28c48134de42fc32a 100644 --- a/openair2/F1AP/f1ap_du_paging.h +++ b/openair2/F1AP/f1ap_du_paging.h @@ -28,4 +28,14 @@ * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr * \note * \warning - */ \ No newline at end of file + */ + +#ifndef F1AP_DU_PAGING_H_ +#define F1AP_DU_PAGING_H_ + +int DU_handle_Paging(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu); + +#endif /* F1AP_DU_PAGING_H_ */ diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index 0812a976f634363b81f7368a56269540129675ab..f3db249e096258cef36ad4f6dbb7088b4bc50071 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -38,6 +38,7 @@ #include "f1ap_du_rrc_message_transfer.h" #include "f1ap_cu_ue_context_management.h" #include "f1ap_du_ue_context_management.h" +#include "f1ap_du_paging.h" /* Handlers matrix. Only f1 related procedure present here */ f1ap_message_processing_t f1ap_messages_processing[][3] = { @@ -61,7 +62,7 @@ f1ap_message_processing_t f1ap_messages_processing[][3] = { { 0, 0, 0 }, /* UEInactivityNotification */ { 0, 0, 0 }, /* GNBDUResourceCoordination */ { 0, 0, 0 }, /* SystemInformationDeliveryCommand */ - { 0, 0, 0 }, /* Paging */ + { DU_handle_Paging, 0, 0 }, /* Paging */ { 0, 0, 0 }, /* Notify */ { 0, 0, 0 }, /* WriteReplaceWarning */ { 0, 0, 0 }, /* PWSCancel */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 10a03e30af00a4f037a8ff238714f5cb15735654..1f98723deb667ca9242c8194750fce7ecb4259bb 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -273,7 +273,7 @@ typedef struct { // DCI pdu structures. Used by both gNB and UE. typedef struct { - uint16_t val; + uint32_t val; uint8_t nbits; } dci_field_t; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index e5b7e741693151e6d616f1e4213f7caf8ca36a4e..fb20092ed53a51f6a8ad15a374e54324aefe76ce 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2476,7 +2476,7 @@ static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8 // Table 5.1.2.2.1-1 38.214 uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) { - AssertFatal(bwp_size<276,"BWP Size > 275\n"); + AssertFatal(bwp_size < 276,"Invalid BWP Size > 275\n"); if (bwp_size < 37) return (rbg_size_config ? 4 : 2); if (bwp_size < 73) return (rbg_size_config ? 8 : 4); @@ -2487,8 +2487,7 @@ uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) { uint8_t getNRBG(uint16_t bwp_size, uint16_t bwp_start, long rbg_size_config) { uint8_t rbg_size = getRBGSize(bwp_size,rbg_size_config); - - return (uint8_t)ceil((bwp_size+(bwp_start % rbg_size))/rbg_size); + return (uint8_t)ceil((float)(bwp_size+(bwp_start % rbg_size))/(float)rbg_size); } uint8_t getAntPortBitWidth(NR_SetupRelease_DMRS_DownlinkConfig_t *typeA, NR_SetupRelease_DMRS_DownlinkConfig_t *typeB) { @@ -2770,7 +2769,7 @@ uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servi NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, nr_srs_feedback_t *srs_feedback, - uint16_t *val) + uint32_t *val) { uint8_t nbits = 0; @@ -2892,7 +2891,7 @@ uint8_t compute_precoding_information(NR_PUSCH_Config_t *pusch_Config, dci_field_t srs_resource_indicator, nr_srs_feedback_t *srs_feedback, const uint8_t *nrOfLayers, - uint16_t *val) { + uint32_t *val) { // It is only applicable to codebook based transmission. This field occupies 0 bits for non-codebook based // transmission. It also occupies 0 bits for codebook based transmission using a single antenna port. @@ -3191,10 +3190,15 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP, case NR_UL_DCI_FORMAT_0_0: /// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20 size += 20; - size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated + dci_pdu->frequency_domain_assignment.nbits = (uint8_t)ceil(log2((N_RB * (N_RB + 1)) >>1)); // Freq domain assignment -- hopping scenario to be updated + size += dci_pdu->frequency_domain_assignment.nbits; int dci_10_size = nr_dci_size(initialDownlinkBWP,initialUplinkBWP,cg,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id, coreset_id, cset0_bwp_size); - AssertFatal(dci_10_size >= size, "NR_UL_DCI_FORMAT_0_0 size is bigger than NR_DL_DCI_FORMAT_1_0! 3GPP TS 38.212 Section 7.3.1.0: DCI size alignment is not fully implemented"); - size += dci_10_size - size; // Padding to match 1_0 size + if(dci_10_size >= size) + size += dci_10_size - size; // Padding to match 1_0 size + else { + dci_pdu->frequency_domain_assignment.nbits -= (size - dci_10_size); + size = dci_10_size; + } // UL/SUL indicator assumed to be 0 break; diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 507d4469a51eada0e71b31515c236b0399eeba16..7f88216cbd59d68ffefebe50975c7aeacb987ccf 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -32,10 +32,8 @@ #define __LAYER2_NR_MAC_COMMON_H__ #include "NR_MIB.h" -#include "NR_PDSCH-Config.h" #include "NR_CellGroupConfig.h" #include "nr_mac.h" -#include "openair1/PHY/impl_defs_nr.h" #include "common/utils/nr/nr_common.h" typedef enum { @@ -68,14 +66,14 @@ uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servi NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, nr_srs_feedback_t *srs_feedback, - uint16_t *val); + uint32_t *val); uint8_t compute_precoding_information(NR_PUSCH_Config_t *pusch_Config, NR_SRS_Config_t *srs_config, dci_field_t srs_resource_indicator, nr_srs_feedback_t *srs_feedback, const uint8_t *nrOfLayers, - uint16_t *val); + uint32_t *val); uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP, const NR_BWP_UplinkCommon_t *initialULBWP, diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 909a0428d4c39a9429f2f31835684829a2a837f6..a9160e84ba30ca6fe426b8f52a019f85fbaa6cf6 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -432,7 +432,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, @returns void */ -void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format){ +void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint32_t *bwp_ind, uint8_t *dci_format) +{ NR_ServingCellConfig_t *scd = mac->cg->spCellConfig->spCellConfigDedicated; @@ -471,7 +472,6 @@ void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format } LOG_D(MAC, "In %s setting DL_BWP_Id %ld UL_BWP_Id %ld \n", __FUNCTION__, mac->DL_BWP_Id, mac->UL_BWP_Id); - } /** \brief This function is relavant for the UE procedures for control. It loads the search spaces, the BWPs and the CORESETs into the MAC instance and diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index e5fe2e377f8431a366784238cded580f6b85a7c9..18c34d29e0260d01996c9a886a6b17a0a5389736 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -228,7 +228,6 @@ typedef struct { typedef enum { RA_UE_IDLE = 0, - GENERATE_IDLE = 0, GENERATE_PREAMBLE = 1, WAIT_RAR = 2, WAIT_CONTENTION_RESOLUTION = 3, @@ -281,8 +280,8 @@ typedef struct { uint8_t RA_active; /// Random-access preamble index int ra_PreambleIndex; - /// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot - RA_state_t generate_nr_prach; + // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble + uint8_t ssb_nb_in_ro; /// Random-access window counter int16_t RA_window_cnt; @@ -385,6 +384,7 @@ typedef struct { long physCellId; //// MAC config int first_sync_frame; + bool sib1_decoded; NR_DRX_Config_t *drx_Config; NR_SchedulingRequestConfig_t *schedulingRequestConfig; NR_BSR_Config_t *bsr_Config; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 97deda6d81980fe3b83f519ae582de9f79a94ab0..b8b533705a093dbc38150d977936569d9646a4bb 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -406,8 +406,7 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 @param gNB_id gNB index @param nr_slot_tx slot for PRACH transmission @returns indication to generate PRACH to phy */ -uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, - module_id_t mod_id, +uint8_t nr_ue_get_rach(module_id_t mod_id, int CC_id, frame_t frame, uint8_t gNB_id, @@ -423,7 +422,6 @@ void nr_get_prach_resources(module_id_t mod_id, int CC_id, uint8_t gNB_id, NR_PRACH_RESOURCES_t *prach_resources, - fapi_nr_ul_config_prach_pdu *prach_pdu, NR_RACH_ConfigDedicated_t * rach_ConfigDedicated); void init_RA(module_id_t mod_id, @@ -453,7 +451,7 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac); -void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format); +void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint32_t *bwp_ind, uint8_t *dci_format); void configure_ss_coreset(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 1e254ded42d78b849ecece1a9be4e9f446dd7e42..e9eb77b9c1d8f96057e6d03a8d3f718441af5b04 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -51,6 +51,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { //init mac here nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST); nr_ue_mac_inst->first_sync_frame = -1; + nr_ue_mac_inst->sib1_decoded = false; for (int j=0;j<NB_NR_UE_MAC_INST;j++) { nr_ue_init_mac(j); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index b205c6356fdf47941407e08274f9ce332820f28c..8b71713eb6b2e2c9db1778e504c1b8b1aa0fa2c8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -31,7 +31,6 @@ */ /* RRC */ -#include "NR_RACH-ConfigCommon.h" #include "RRC/NR_UE/rrc_proto.h" /* MAC */ @@ -403,7 +402,7 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m return receivedTargerPower; } -void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){ +void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon){ // Determine the SSB to RACH mapping ratio // ======================================= @@ -467,7 +466,7 @@ void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_ if ((true == multiple_ssb_per_ro) && (ssb_rach_ratio > 1)) { total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio; - ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro; + ssb_nb_in_ro = ra->ssb_nb_in_ro; ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro; } else { total_preambles_per_ssb = numberOfRA_Preambles; @@ -657,7 +656,6 @@ void nr_get_prach_resources(module_id_t mod_id, int CC_id, uint8_t gNB_id, NR_PRACH_RESOURCES_t *prach_resources, - fapi_nr_ul_config_prach_pdu *prach_pdu, NR_RACH_ConfigDedicated_t *rach_ConfigDedicated){ NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); @@ -667,7 +665,7 @@ void nr_get_prach_resources(module_id_t mod_id, mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup : mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; - LOG_D(PHY, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3); + LOG_D(MAC, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3); if (rach_ConfigDedicated) { if (rach_ConfigDedicated->cfra){ @@ -679,7 +677,7 @@ void nr_get_prach_resources(module_id_t mod_id, /* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */ int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm) : 0; - ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu); + ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon); ra_preambles_config(prach_resources, mac, dl_pathloss); LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex); } @@ -738,8 +736,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot * @gNB_id gNB ID * @nr_slot_tx current UL TX slot */ -uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, - module_id_t mod_id, +uint8_t nr_ue_get_rach(module_id_t mod_id, int CC_id, frame_t frame, uint8_t gNB_id, @@ -896,13 +893,11 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, if(ra->cfra) { // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213) nr_ra_succeeded(mod_id, frame, nr_slot_tx); - } else { - ra->generate_nr_prach = GENERATE_IDLE; } } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) { - LOG_I(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx); + LOG_W(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx); nr_ra_failed(mod_id, CC_id, prach_resources, frame, nr_slot_tx); @@ -912,8 +907,8 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, // Fill in preamble and PRACH resources ra->RA_window_cnt--; - if (ra->generate_nr_prach == GENERATE_PREAMBLE) { - nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + if (ra->ra_state == GENERATE_PREAMBLE) { + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, rach_ConfigDedicated); } } else if (ra->RA_backoff_cnt > 0) { @@ -921,10 +916,9 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, ra->RA_backoff_cnt--; - if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) { - nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated); + if ((ra->RA_backoff_cnt > 0 && ra->ra_state == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) { + nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, rach_ConfigDedicated); } - } } } @@ -933,8 +927,7 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu, nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources); } - LOG_D(MAC,"ra->generate_nr_prach %d ra->ra_state %d (GENERATE_IDLE %d)\n",ra->generate_nr_prach,ra->ra_state,GENERATE_IDLE); - return ra->generate_nr_prach; + return ra->ra_state; } void nr_get_RA_window(NR_UE_MAC_INST_t *mac){ @@ -1041,7 +1034,6 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){ LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id); ra->RA_active = 0; - ra->generate_nr_prach = GENERATE_IDLE; ra->ra_state = RA_SUCCEEDED; } @@ -1060,7 +1052,6 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res ra->first_Msg3 = 1; ra->ra_PreambleIndex = -1; - ra->generate_nr_prach = RA_FAILED; ra->ra_state = RA_UE_IDLE; prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 4cf87ebcbd210e7778b3561fc017c7cbe3b65880..cef268d517b59ce1815617d580dccd23b624f1e7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -39,10 +39,6 @@ /* RRC*/ #include "RRC/NR_UE/rrc_proto.h" -#include "NR_RACH-ConfigCommon.h" -#include "NR_RACH-ConfigGeneric.h" -#include "NR_FrequencyInfoDL.h" -#include "NR_PDCCH-ConfigCommon.h" /* MAC */ #include "NR_MAC_COMMON/nr_mac.h" @@ -374,7 +370,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, else ssb_sc_offset_norm = ssb_subcarrier_offset; - if (mac->first_sync_frame == -1) + if (!mac->sib1_decoded) { nr_ue_sib1_scheduler(module_id, cc_id, ssb_start_symbol, @@ -384,18 +380,20 @@ int8_t nr_ue_decode_mib(module_id_t module_id, ssb_start_subcarrier, mac->frequency_range, phy_data); + mac->first_sync_frame = frame; + } } else { NR_ServingCellConfigCommon_t *scc = mac->scc; scs_ssb = *scc->ssbSubcarrierSpacing; band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index); + if (mac->first_sync_frame == -1) + mac->first_sync_frame = frame; } mac->dl_config_request.sfn = frame; mac->dl_config_request.slot = ssb_start_symbol/14; - if (mac->first_sync_frame == -1) - mac->first_sync_frame = frame; return 0; } @@ -408,6 +406,8 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, uint32_t pdu_len) { if(ack_nack) { LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n"); + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + mac->sib1_decoded = true; nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len); } else @@ -425,11 +425,11 @@ uint32_t get_ssb_frame(uint32_t test){ * These tables and functions are going to be called by function nr_ue_process_dci */ int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu, - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t riv - ){ + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu, + uint16_t n_RB_ULBWP, + uint16_t n_RB_DLBWP, + uint16_t riv) +{ /* * TS 38.214 subclause 5.1.2.2 Resource allocation in frequency domain (downlink) @@ -3248,7 +3248,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, #endif if (dci_pdu_rel15->format_indicator == 1) return 1; // discard dci, format indicator not corresponding to dci_format - fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); + fsize = dci_pdu_rel15->frequency_domain_assignment.nbits; pos+=fsize; dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); #ifdef DEBUG_EXTRACT_DCI @@ -3312,7 +3312,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, #endif if (dci_pdu_rel15->format_indicator == 1) return 1; // discard dci, format indicator not corresponding to dci_format - fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) ); + fsize = dci_pdu_rel15->frequency_domain_assignment.nbits; pos+=fsize; dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1); #ifdef DEBUG_EXTRACT_DCI diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index a51ebfa868c2a20c56a48132c38fbf41babe21c6..902bb2aec8ba1b0473a95616c118be1efc3d6244 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -35,13 +35,6 @@ /* exe */ #include <common/utils/nr/nr_common.h> -/* RRC*/ -#include "RRC/NR_UE/rrc_proto.h" -#include "NR_RACH-ConfigCommon.h" -#include "NR_RACH-ConfigGeneric.h" -#include "NR_FrequencyInfoDL.h" -#include "NR_PDCCH-ConfigCommon.h" - /* MAC */ #include "NR_MAC_COMMON/nr_mac.h" #include "NR_MAC_COMMON/nr_mac_common.h" @@ -1154,8 +1147,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } else if (ul_info) { int cc_id = ul_info->cc_id; - //frame_t rx_frame = ul_info->frame_rx; - //slot_t rx_slot = ul_info->slot_rx; frame_t frame_tx = ul_info->frame_tx; slot_t slot_tx = ul_info->slot_tx; module_id_t mod_id = ul_info->module_id; @@ -1169,6 +1160,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in LOG_E(NR_MAC, "mac->ul_config is null!\n"); } + nr_ue_get_rach(mod_id, cc_id, frame_tx, gNB_index, slot_tx); // Periodic SRS scheduling nr_ue_periodic_srs_scheduling(mod_id, frame_tx, slot_tx); @@ -2659,12 +2651,12 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) { // - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { - uint16_t format, format0, format1, ncs; - int is_nr_prach_slot; - prach_occasion_info_t *prach_occasion_info_p; - NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); RA_config_t *ra = &mac->ra; + ra->RA_offset = 2; // to compensate the rx frame offset at the gNB + if(ra->ra_state != GENERATE_PREAMBLE) + return; + fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP); if (!ul_config) { LOG_E(NR_MAC, "mac->ul_config is null! \n"); @@ -2683,8 +2675,6 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s else setup = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; - ra->RA_offset = 2; // to compensate the rx frame offset at the gNB - ra->generate_nr_prach = GENERATE_IDLE; // Reset flag for PRACH generation NR_TDD_UL_DL_ConfigCommon_t *tdd_config = scc==NULL ? scc_SIB->tdd_UL_DL_ConfigurationCommon : scc->tdd_UL_DL_ConfigurationCommon; if (is_nr_UL_slot(tdd_config, slotP, mac->frame_type)) { @@ -2694,22 +2684,21 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s uint8_t selected_gnb_ssb_idx = mac->mib_ssb; // Get any valid PRACH occasion in the current slot for the selected SSB index - is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx, + prach_occasion_info_t *prach_occasion_info_p; + int is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx, (int)frameP, (int)slotP, &prach_occasion_info_p); - if (is_nr_prach_slot && ra->ra_state == GENERATE_PREAMBLE) { + if (is_nr_prach_slot) { AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); - ra->generate_nr_prach = GENERATE_PREAMBLE; - init_RA(module_idP, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated); nr_get_RA_window(mac); - format = prach_occasion_info_p->format; - format0 = format & 0xff; // single PRACH format - format1 = (format >> 8) & 0xff; // dual PRACH format + uint16_t format = prach_occasion_info_p->format; + uint16_t format0 = format & 0xff; // single PRACH format + uint16_t format1 = (format >> 8) & 0xff; // dual PRACH format AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); @@ -2723,7 +2712,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); - ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); + uint16_t ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); prach_config_pdu->phys_cell_id = mac->physCellId; prach_config_pdu->num_prach_ocas = 1; @@ -2736,15 +2725,17 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s prach_config_pdu->restricted_set = prach_config->restricted_set_config; prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1; - LOG_D(NR_MAC,"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", + LOG_I(NR_MAC,"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) - for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) { - if (prach_occasion_info_p->mapped_ssb_idx[prach_config_pdu->ssb_nb_in_ro] == selected_gnb_ssb_idx) + for (int ssb_nb_in_ro=0; ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; ssb_nb_in_ro++) { + if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb_in_ro] == selected_gnb_ssb_idx) { + ra->ssb_nb_in_ro = ssb_nb_in_ro; break; + } } - AssertFatal(prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx); + AssertFatal(ra->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx); if (format1 != 0xff) { switch(format0) { // dual PRACH format @@ -2800,7 +2791,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s } } // if format1 - nr_get_prach_resources(module_idP, 0, 0, &ra->prach_resources, prach_config_pdu, ra->rach_ConfigDedicated); + nr_get_prach_resources(module_idP, 0, 0, &ra->prach_resources, ra->rach_ConfigDedicated); prach_config_pdu->ra_PreambleIndex = ra->ra_PreambleIndex; prach_config_pdu->prach_tx_power = get_prach_tx_power(module_idP); set_ra_rnti(mac, prach_config_pdu); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 4334525637e9d56b62782129f4a8d02ad951d4f7..e1ec0f6bafadf4440b8c1584dafcc64ee30a697b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -513,7 +513,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, int nr_ulstart_slot = 0; if (tdd) { nr_dl_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0); - nr_ulstart_slot = tdd->nrofDownlinkSlots; + nr_ulstart_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols); nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); } else diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 36dc919ad37ab0f98fb455e09f864d95a17670cf..35850a1a2d71660abbe23b16a8b8eda32b0d3bab 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -893,7 +893,7 @@ void nr_get_Msg3alloc(module_id_t module_id, const int n_slots_frame = nr_slots_per_frame[mu]; uint8_t k2 = 0; if (frame_type == TDD) { - int msg3_slot = tdd->nrofDownlinkSlots; // first uplink slot + int msg3_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols); if (tdd->nrofUplinkSymbols < 3) msg3_slot++; // we can't trasmit msg3 in mixed slot if there are less than 3 symbols else { @@ -1934,10 +1934,6 @@ void nr_fill_rar(uint8_t Mod_idP, NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1); NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2); unsigned char csi_req = 0, tpc_command; - //uint8_t N_UL_Hop; - uint8_t valid_bits; - uint32_t ul_grant; - uint16_t f_alloc, prb_alloc, bwp_size, truncation=0; tpc_command = 3; // this is 0 dB @@ -1973,24 +1969,15 @@ void nr_fill_rar(uint8_t Mod_idP, ra->msg3_TPC = tpc_command; - bwp_size = pusch_pdu->bwp_size; - prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size); - if (bwp_size>180) { - AssertFatal(1==0,"Initial UBWP larger than 180 currently not supported"); - } - else { - valid_bits = (uint8_t)ceil(log2(bwp_size*(bwp_size+1)>>1)); - } - - if (pusch_pdu->frequency_hopping){ + if (pusch_pdu->frequency_hopping) AssertFatal(1==0,"PUSCH with frequency hopping currently not supported"); - } else { - for (int i=0; i<valid_bits; i++) - truncation |= (1<<i); - f_alloc = (prb_alloc&truncation); - } - ul_grant = csi_req | (tpc_command << 1) | (pusch_pdu->mcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26); + int bwp_size = pusch_pdu->bwp_size; + int prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size); + int valid_bits = 14; + int f_alloc = prb_alloc & ((1 << valid_bits) - 1); + + uint32_t ul_grant = csi_req | (tpc_command << 1) | (pusch_pdu->mcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26); rar->UL_GRANT_1 = (uint8_t) (ul_grant >> 24) & 0x07; rar->UL_GRANT_2 = (uint8_t) (ul_grant >> 16) & 0xff; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index af76867ef345de9ebda6288434586eeb4e593d04..c400a8ac1366d244c6320cc159d736b15636043e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -64,7 +64,7 @@ const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon if (tdd && tdd->nrofDownlinkSymbols > 1) { // if there is a mixed slot where we can transmit DL const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1; - if ((slot%nr_slots_period) == tdd->nrofDownlinkSlots) + if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots) return 2; } return 0; // if FDD or not mixed slot in TDD, for now use default TDA @@ -628,7 +628,7 @@ void pf_dl(module_id_t module_id, } } - qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator); + qsort(UE_sched, sizeofArray(UE_sched), sizeof(UEsched_t), comparator); UEsched_t *iterator = UE_sched; const int min_rbSize = 5; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index e9ca17bd1a7bb3684bdbe81eb1a94e207f4923e6..403ae15df779d221e199f75e6e96a9403c275c6a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1670,7 +1670,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, pos=1; *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos); // Freq domain assignment max 16 bit - fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1)); + fsize = dci_pdu_rel15->frequency_domain_assignment.nbits; pos+=fsize; *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos); // Time domain assignment 4bit @@ -1695,7 +1695,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, pos+=2; *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc & 0x3) << (dci_size - pos); // Padding bits - for (int a = pos; a < 32; a++) + for (int a = pos; a < dci_size; a++) *dci_pdu |= ((uint64_t)dci_pdu_rel15->padding & 1) << (dci_size - pos++); // UL/SUL indicator – 1 bit /* commented for now (RK): need to get this from BWP descriptor @@ -1723,7 +1723,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, pos=1; *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos); // Freq domain assignment max 16 bit - fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1)); + fsize = dci_pdu_rel15->frequency_domain_assignment.nbits; pos+=fsize; *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos); // Time domain assignment 4bit @@ -2756,23 +2756,21 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { } -void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, +int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, nr_dci_format_t dci_format, uint8_t *pdsch_to_harq_feedback) { if (dci_format == NR_DL_DCI_FORMAT_1_0) { - for (int i=0; i<8; i++) - pdsch_to_harq_feedback[i] = i+1; + for (int i = 0; i < 8; i++) + pdsch_to_harq_feedback[i] = i + 1; + return 8; } else { - AssertFatal(pucch_Config!=NULL,"pucch_Config shouldn't be null here\n"); - if(pucch_Config->dl_DataToUL_ACK != NULL) { - for (int i=0; i<8; i++) { - pdsch_to_harq_feedback[i] = *pucch_Config->dl_DataToUL_ACK->list.array[i]; - } + AssertFatal(pucch_Config != NULL && pucch_Config->dl_DataToUL_ACK != NULL,"dl_DataToUL_ACK shouldn't be null here\n"); + for (int i = 0; i < pucch_Config->dl_DataToUL_ACK->list.count; i++) { + pdsch_to_harq_feedback[i] = *pucch_Config->dl_DataToUL_ACK->list.array[i]; } - else - AssertFatal(0==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n"); + return pucch_Config->dl_DataToUL_ACK->list.count; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index a9386e6c2332ec26aebb44bb1cd6795196c79248..f2d4c7946d1da22d6fa4f5bbf630680a7cbee85a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -135,7 +135,7 @@ int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_P { // PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots // this functions return the index to the structure for slot passed to the function - const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; + const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0; const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame; const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; const int n_ul_slots_frame = n_slots_frame / nr_slots_period * n_ul_slots_period; @@ -1099,7 +1099,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || mac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n"); const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; - const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; + const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; @@ -1112,9 +1112,9 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, dci_format = UE->current_DL_BWP.dci_format; uint8_t pdsch_to_harq_feedback[8]; - get_pdsch_to_harq_feedback(pucch_Config, dci_format, pdsch_to_harq_feedback); + int fb_size = get_pdsch_to_harq_feedback(pucch_Config, dci_format, pdsch_to_harq_feedback); - for (int f=0; f<8; f++) { + for (int f = 0; f < fb_size; f++) { // can't schedule ACKNACK before minimum feedback time if(pdsch_to_harq_feedback[f] < minfbtime) continue; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index d6a9553c1075899ae5a8e6fb676178095452ed6d..0d25e160fa8f01173bceb3e7584f32564ec58531 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -47,7 +47,7 @@ const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *sc if (tdd && tdd->nrofUplinkSymbols > 1) { // if there is uplink symbols in mixed slot const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1; - if ((slot%nr_slots_period) == tdd->nrofDownlinkSlots) + if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots) return 2; } @@ -1305,8 +1305,7 @@ long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, return 3; } -static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, - int CC_id, NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity) +static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, int CC_id, NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity) { const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int now = frame * n + slot; @@ -1317,10 +1316,9 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; int num_slots_per_period; int last_ul_slot; - int tdd_period_len[8] = {500,625,1000,1250,2000,2500,5000,10000}; if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot) - num_slots_per_period = n*tdd_period_len[tdd->dl_UL_TransmissionPeriodicity]/10000; - last_ul_slot=1+tdd->nrofDownlinkSlots; + num_slots_per_period = n / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); + last_ul_slot = 1 + tdd->nrofDownlinkSlots; } else { num_slots_per_period = n; last_ul_slot = sched_ctrl->last_ul_slot; @@ -1705,7 +1703,7 @@ void pf_ul(module_id_t module_id, curUE++; } - qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator); + qsort(UE_sched, sizeofArray(UE_sched), sizeof(UEsched_t), comparator); UEsched_t *iterator=UE_sched; /* Loop UE_sched to find max coeff and allocate transmission */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 51b261ddf1abeffb3e0c74ccff1ced0b92d05586..fc569c4eee1d14432b36d6e82f3e743332fa793b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -221,9 +221,9 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac, int r_pucch, int do_common); -void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, - nr_dci_format_t dci_format, - uint8_t *pdsch_to_harq_feedback); +int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, + nr_dci_format_t dci_format, + uint8_t *pdsch_to_harq_feedback); void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, nr_scs_e scs_common, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 31dbfefd5ea4ee11e9898e71c4262b04f5124d83..d841260475918ee1ca88f0498a0d749069771bef 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -758,8 +758,8 @@ static void add_rlc_srb(int rnti, struct NR_SRB_ToAddMod *s, NR_RLC_BearerConfig poll_byte = -1; max_retx_threshold = 8; sn_field_length = 12; - nr_rlc_am = new_nr_rlc_entity_am(10000000, - 10000000, + nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE, + RLC_TX_MAXSIZE, deliver_sdu, ue, successful_delivery, ue, max_retx_reached, ue, @@ -840,8 +840,8 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ if (ue->drb[drb_id-1] != NULL) { LOG_W(RLC, "%s:%d:%s: DRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - nr_rlc_am = new_nr_rlc_entity_am(10000000, - 10000000, + nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE, + RLC_TX_MAXSIZE, deliver_sdu, ue, successful_delivery, ue, max_retx_reached, ue, @@ -912,8 +912,8 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ if (ue->drb[drb_id-1] != NULL) { LOG_W(RLC, "DEBUG add_drb_um %s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - nr_rlc_um = new_nr_rlc_entity_um(100000000, - 100000000, + nr_rlc_um = new_nr_rlc_entity_um(RLC_RX_MAXSIZE, + RLC_TX_MAXSIZE, deliver_sdu, ue, t_reassembly, sn_field_length); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 28237903af473bbd2bb121cb7caaef420552fd5b..49305421af56a9a9b76e840e843f204dfa9305af 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -692,8 +692,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, if (pthread_mutex_lock(&mac->mutex_dl_info)) abort(); - if (dl_tti_request) - { + if (dl_tti_request) { frame = dl_tti_request->SFN; slot = dl_tti_request->Slot; LOG_D(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot); @@ -705,40 +704,34 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, incoming tx_data_request is also destined for the current UE. If the RAR hasn't been processed yet, we do not want to be filtering the tx_data_requests. */ - if (tx_data_request) - { + if (tx_data_request) { if (mac->nr_ue_emul_l1.expected_sib || mac->nr_ue_emul_l1.expected_rar || - mac->nr_ue_emul_l1.expected_dci) - { + mac->nr_ue_emul_l1.expected_dci) { frame = tx_data_request->SFN; slot = tx_data_request->Slot; LOG_D(NR_PHY, "[%d, %d] PDSCH in tx_request\n", frame, slot); copy_tx_data_req_to_dl_info(&mac->dl_info, tx_data_request); } - else - { + else { LOG_D(NR_MAC, "Unexpected tx_data_req\n"); } free_and_zero(tx_data_request); } - else if (ul_dci_request) - { + else if (ul_dci_request) { frame = ul_dci_request->SFN; slot = ul_dci_request->Slot; LOG_D(NR_PHY, "[%d, %d] ul_dci_request\n", frame, slot); copy_ul_dci_data_req_to_dl_info(&mac->dl_info, ul_dci_request); free_and_zero(ul_dci_request); } - else if (ul_tti_request) - { + else if (ul_tti_request) { frame = ul_tti_request->SFN; slot = ul_tti_request->Slot; LOG_T(NR_PHY, "[%d, %d] ul_tti_request\n", frame, slot); copy_ul_tti_data_req_to_dl_info(&mac->dl_info, ul_tti_request); } - else - { + else { if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort(); LOG_T(NR_MAC, "All indications were NULL in %s\n", __FUNCTION__); return; @@ -762,15 +755,12 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request, ul_info.slot_rx = slot; ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame; ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx; - ul_info.ue_sched_mode = SCHED_PUSCH; - if (mac->scc || mac->scc_SIB) - { + if (mac->scc || mac->scc_SIB) { if (is_nr_UL_slot(mac->scc ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon, ul_info.slot_tx, - mac->frame_type) && mac->ra.ra_state != RA_SUCCEEDED) - { + mac->frame_type) && mac->ra.ra_state != RA_SUCCEEDED) { nr_ue_scheduler(NULL, &ul_info); nr_ue_prach_scheduler(ul_info.module_id, ul_info.frame_tx, ul_info.slot_tx); } @@ -1137,8 +1127,8 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon; - LOG_T(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n", - __FUNCTION__, __LINE__, ul_info->ue_sched_mode, mac->ra.ra_state); + LOG_T(NR_MAC, "In %s():%d not calling scheduler mac->ra.ra_state = %d\n", + __FUNCTION__, __LINE__, mac->ra.ra_state); ret = nr_ue_scheduler(NULL, ul_info); if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type)) { diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 722b1be9ec580fbb4ab97589f1f4544ebd13b6af..e3adfe7d5344bf370d8c70eb06e214e098af173f 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -46,11 +46,6 @@ extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t; -typedef enum { - SCHED_PUSCH, - SCHED_PUCCH, -} NR_UE_SCHED_MODE_t; - typedef struct { /// module id module_id_t module_id; @@ -112,7 +107,6 @@ typedef struct { /// dci reception indication structure fapi_nr_dci_indication_t *dci_ind; - NR_UE_SCHED_MODE_t ue_sched_mode; void *phy_data; } nr_uplink_indication_t; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 4d1dfaf5aa46e7fec35a9d4cfa4de77166c3af32..f0fc2275ac431096878d6ae46ac5596247a555d4 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -917,11 +917,13 @@ typedef struct UE_RRC_INST_s { } UE_RRC_INST; typedef struct UE_PF_PO_s { - bool enable_flag; /* flag indicate whether current object is used */ + bool enable_flag; /* flag indicate whether current object is used */ uint16_t ue_index_value; /* UE index value */ uint8_t PF_min; /* minimal value of Paging Frame (PF) */ uint8_t PO; /* Paging Occasion (PO) */ uint32_t T; /* DRX cycle */ + uint8_t PF_offset; + uint8_t i_s; } UE_PF_PO_t; #include "rrc_proto.h" diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index c52fe891eb2a62185c2af3fc000d243a4e024e14..831d60dad7244e14b5af20f7c4ac8389c246a155 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -74,6 +74,8 @@ #include "NR_RRCReconfigurationComplete-IEs.h" #include "NR_DLInformationTransfer.h" #include "NR_RRCReestablishmentRequest.h" +#include "NR_PCCH-Message.h" +#include "NR_PagingRecord.h" #include "NR_UE-CapabilityRequestFilterNR.h" #include "common/utils/nr/nr_common.h" #if defined(NR_Rel16) @@ -136,6 +138,7 @@ #include "intertask_interface.h" #include "common/ran_context.h" +#include "conversions.h" //#define XER_PRINT @@ -223,16 +226,16 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n"); int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - frequency_range_t frequency_range = band<100?FR1:FR2; + frequency_range_t frequency_range = band < 100 ? FR1 : FR2; int ssb_subcarrier_offset = 31; // default value for NSA if (get_softmodem_params()->sa) { uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); int scs_scaling = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1; - ssb_subcarrier_offset = (absolute_diff/scs_scaling)%24; + ssb_subcarrier_offset = (absolute_diff/scs_scaling) % 24; if(frequency_range == FR2) ssb_subcarrier_offset >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for now) } - mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset&15; + mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset & 15; /* * The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables @@ -739,7 +742,7 @@ void fill_initial_SpCellConfig(int uid, scheduling_request_config(scc, pucch_Config); - set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing); SpCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->initialDownlinkBWP)); NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP; @@ -1193,8 +1196,7 @@ void fill_initial_cellGroupConfig(int uid, cellGroupConfig->mac_CellGroupConfig = mac_CellGroupConfig; physicalCellGroupConfig = calloc(1,sizeof(*physicalCellGroupConfig)); - physicalCellGroupConfig->p_NR_FR1 = calloc(1,sizeof(*physicalCellGroupConfig->p_NR_FR1)); - *physicalCellGroupConfig->p_NR_FR1 = 10; + physicalCellGroupConfig->p_NR_FR1 = NULL; physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook = NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic; cellGroupConfig->physicalCellGroupConfig = physicalCellGroupConfig; @@ -2098,3 +2100,42 @@ NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf) return mc; } + +uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) { + LOG_D(NR_RRC, "[gNB %d] do_NR_Paging start\n", Mod_id); + NR_PCCH_Message_t pcch_msg; + pcch_msg.message.present = NR_PCCH_MessageType_PR_c1; + asn1cCalloc(pcch_msg.message.choice.c1, c1); + c1->present = NR_PCCH_MessageType__c1_PR_paging; + c1->choice.paging = CALLOC(1, sizeof(NR_Paging_t)); + c1->choice.paging->pagingRecordList = CALLOC( + 1, sizeof(*pcch_msg.message.choice.c1->choice.paging->pagingRecordList)); + c1->choice.paging->nonCriticalExtension = NULL; + asn_set_empty(&c1->choice.paging->pagingRecordList->list); + c1->choice.paging->pagingRecordList->list.count = 0; + + asn1cSequenceAdd(c1->choice.paging->pagingRecordList->list, NR_PagingRecord_t, + paging_record_p); + /* convert ue_paging_identity_t to PagingUE_Identity_t */ + paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_ng_5G_S_TMSI; + // set ng_5G_S_TMSI + INT32_TO_BIT_STRING(tmsi, &paging_record_p->ue_Identity.choice.ng_5G_S_TMSI); + + /* add to list */ + LOG_D(NR_RRC, "[gNB %d] do_Paging paging_record: PagingRecordList.count %d\n", + Mod_id, c1->choice.paging->pagingRecordList->list.count); + asn_enc_rval_t enc_rval = uper_encode_to_buffer( + &asn_DEF_NR_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_PCCH_Message, &pcch_msg); + if(enc_rval.encoded == -1) { + LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; + } + + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg); + } + + return((enc_rval.encoded+7)/8); +} diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 997adb2bd27d7fd1266fa692c598f9e6e86b11f4..241c2deb483bd08b38ec6b545ad6411728dd9d42 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -193,5 +193,6 @@ do_RRCReestablishmentComplete( int64_t rrc_TransactionIdentifier); NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf); +uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi); #endif /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */ diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index e0ffa29bf77f2759b268140d7312f93d716b4888..7476286d5f9ade279b5b644605e2ad3908a8ae3a 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -756,14 +756,18 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){ } } -void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time) { - +void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time, NR_SubcarrierSpacing_t subcarrierSpacing) +{ pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); + const int n_slots_frame = slotsperframe[subcarrierSpacing]; long *delay[8]; - for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(*delay[i])); - *delay[i] = i+min_feedback_time; - ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); + for (int i = 0; i < 8; i++) { + int curr_delay = i + min_feedback_time; + if (curr_delay <= n_slots_frame) { + delay[i] = calloc(1,sizeof(*delay[i])); + *delay[i] = curr_delay; + ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); + } } } @@ -886,7 +890,7 @@ static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedul const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; int sr_slot = 1; // in FDD SR in slot 1 if(tdd) - sr_slot = tdd->nrofDownlinkSlots; // SR in the first uplink slot + sr_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols); schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); @@ -1238,7 +1242,7 @@ void config_uplinkBWP(NR_BWP_Uplink_t *ubwp, config_pucch_resset1(pucch_Config, uecap); set_pucch_power_config(pucch_Config, configuration->do_CSIRS); scheduling_request_config(scc, pucch_Config); - set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing); NR_PUSCH_Config_t *pusch_Config = NULL; if(servingcellconfigdedicated->uplinkConfig->uplinkBWP_ToAddModList && @@ -1286,7 +1290,7 @@ void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR_CSI_Re const int n_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; const int ideal_period = MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE AssertFatal(ideal_period < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n"); - const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0; + const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0; const int idx = (uid << 1) + is_rsrp; const int offset = first_ul_slot_period + idx % n_ul_slots_period + (idx / n_ul_slots_period) * n_slots_period; diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 52dd065b7d2b80ca9179c3dd2f8d5332af97ea43..d100750eac9cc073621073bc17f7411eefe72c61 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -57,7 +57,7 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay); void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, NR_UE_NR_Capability_t *uecap); void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, NR_UE_NR_Capability_t *uecap); -void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time); +void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time, NR_SubcarrierSpacing_t subcarrierSpacing); void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs); void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, NR_PUCCH_Config_t *pucch_Config); diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index e720a132d22db728d3fe3d7fa40a447154bdbb5c..b35387d1f9eb3350c457b791ae8f29c2313ab783 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -236,4 +236,10 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPenc, uint8_t *const kUPint, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + +int rrc_gNB_generate_pcch_msg(uint32_t tmsi, + uint8_t paging_drx, + instance_t instance, + uint8_t CC_id); + #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index c51c7a8d11cfc3ca426ca3c5b1e8c5523fc0392c..683f33ed85842fa8dacc45bf7db3b1e0d6f77e8a 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -4149,6 +4149,9 @@ void *rrc_gnb_task(void *args_p) { case E1AP_BEARER_CONTEXT_SETUP_RESP: LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_RESP for instance %d\n", (int)instance); rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance); + + case NGAP_PAGING_IND: + rrc_gNB_process_PAGING_IND(msg_p, msg_name_p, instance); break; default: @@ -4349,6 +4352,130 @@ rrc_gNB_generate_RRCRelease( ue_context_pP->ue_context.ue_release_timer_rrc = 1; } } + +int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){ + const unsigned int Ttab[4] = {32,64,128,256}; + uint8_t Tc; + uint8_t Tue; + uint32_t pfoffset; + uint32_t N; /* N: min(T,nB). total count of PF in one DRX cycle */ + uint32_t Ns = 0; /* Ns: max(1,nB/T) */ + uint8_t i_s; /* i_s = floor(UE_ID/N) mod Ns */ + uint32_t T; /* DRX cycle */ + uint32_t length; + uint8_t buffer[RRC_BUF_SIZE]; + struct NR_SIB1 *sib1 = RC.nrrrc[instance]->carrier.siblock1->message.choice.c1->choice.systemInformationBlockType1; + + /* get default DRX cycle from configuration */ + Tc = sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle; + + Tue = paging_drx; + /* set T = min(Tc,Tue) */ + T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; + /* set N = PCCH-Config->nAndPagingFrameOffset */ + switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present) { + case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneT: + N = T; + pfoffset = 0; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_halfT: + N = T/2; + pfoffset = 1; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_quarterT: + N = T/4; + pfoffset = 3; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneEighthT: + N = T/8; + pfoffset = 7; + break; + case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneSixteenthT: + N = T/16; + pfoffset = 15; + break; + default: + LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg: pfoffset error (pfoffset %d)\n", + instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present); + return (-1); + + } + + switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns) { + case NR_PCCH_Config__ns_four: + if(*sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->pagingSearchSpace == 0){ + LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg: ns error only 1 or 2 is allowed when pagingSearchSpace is 0\n", + instance); + return (-1); + } else { + Ns = 4; + } + break; + case NR_PCCH_Config__ns_two: + Ns = 2; + break; + case NR_PCCH_Config__ns_one: + Ns = 1; + break; + default: + LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg: ns error (ns %ld)\n", + instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns); + return (-1); + } + + /* insert data to UE_PF_PO or update data in UE_PF_PO */ + pthread_mutex_lock(&ue_pf_po_mutex); + uint8_t i = 0; + + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if ((UE_PF_PO[CC_id][i].enable_flag == true && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(tmsi%1024)) + || (UE_PF_PO[CC_id][i].enable_flag != true)) { + /* set T = min(Tc,Tue) */ + UE_PF_PO[CC_id][i].T = T; + /* set UE_ID */ + UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)(tmsi%1024); + /* calculate PF and PO */ + /* set PF_min and PF_offset: (SFN + PF_offset) mod T = (T div N)*(UE_ID mod N) */ + UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); + UE_PF_PO[CC_id][i].PF_offset = pfoffset; + /* set i_s */ + /* i_s = floor(UE_ID/N) mod Ns */ + i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); + UE_PF_PO[CC_id][i].i_s = i_s; + + // TODO,set PO + + if (UE_PF_PO[CC_id][i].enable_flag == true) { + //paging exist UE log + LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Update exist UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, + T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset); + } else { + /* set enable_flag */ + UE_PF_PO[CC_id][i].enable_flag = true; + //paging new UE log + LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Insert a new UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, + T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset); + } + break; + } + } + + pthread_mutex_unlock(&ue_pf_po_mutex); + + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_NR_Paging (instance, + buffer, + tmsi); + + if (length == -1) { + LOG_I(NR_RRC, "do_Paging error\n"); + return -1; + } + // TODO, send message to pdcp + + return 0; +} + void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) { MessageDef *message_p; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 8c263afbd6693a7b75c42f19e0d40171380f9e5d..98f76932fad241c109686d0b46a9561828ba272c 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1706,3 +1706,37 @@ void nr_rrc_rx_tx(void) { } +/*------------------------------------------------------------------------------*/ +int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance) { + + for (uint16_t tai_size = 0; tai_size < NGAP_PAGING_IND(msg_p).tai_size; tai_size++) { + LOG_I(NR_RRC,"[gNB %ld] In NGAP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, + NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, NGAP_PAGING_IND(msg_p).tac[tai_size]); + + for (uint8_t j = 0; j < RC.nrrrc[instance]->configuration.num_plmn; j++) { + if (RC.nrrrc[instance]->configuration.mcc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc + && RC.nrrrc[instance]->configuration.mnc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc + && RC.nrrrc[instance]->configuration.tac == NGAP_PAGING_IND(msg_p).tac[tai_size]) { + for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) { + MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND); + F1AP_PAGING_IND (m).mcc = RC.nrrrc[j]->configuration.mcc[0]; + F1AP_PAGING_IND (m).mnc = RC.nrrrc[j]->configuration.mnc[0]; + F1AP_PAGING_IND (m).mnc_digit_length = RC.nrrrc[j]->configuration.mnc_digit_length[0]; + F1AP_PAGING_IND (m).nr_cellid = RC.nrrrc[j]->nr_cellid; + F1AP_PAGING_IND (m).ueidentityindexvalue = (uint16_t)(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi%1024); + F1AP_PAGING_IND (m).fiveg_s_tmsi = NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi; + F1AP_PAGING_IND (m).paging_drx = NGAP_PAGING_IND(msg_p).paging_drx; + LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx); + itti_send_msg_to_task(TASK_CU_F1, instance, m); + } else { + rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id); + } // end of nodetype check + } // end of cc loop + } // end of mcc mnc check + } // end of num_plmn + } // end of tai size + + return 0; +} + diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h index 548c51c7f65cb825cad410cfffd14deb874e236c..6c8a861f03ec50a32099d880ac8fc3b0e3efd441 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.h +++ b/openair2/RRC/NR/rrc_gNB_NGAP.h @@ -195,4 +195,11 @@ rrc_gNB_get_ue_context_from_ngap_ids( const uint16_t ue_initial_idP, const uint32_t gNB_ue_ngap_idP ); + +int +rrc_gNB_process_PAGING_IND( + MessageDef *msg_p, + const char *msg_name, + instance_t instance); + #endif diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 0e5a199dd60986177b2e750f619df410fa6483f8..159144b406e34c38b93b25b35fd66fe957fbb2ec 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -139,8 +139,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig)); secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH=NULL; secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUSCH=NULL; - secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1=calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1)); - *secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1=20; + secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1 = NULL; secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook=NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic; secondaryCellGroup->physicalCellGroupConfig->tpc_SRS_RNTI=NULL; secondaryCellGroup->physicalCellGroupConfig->tpc_PUCCH_RNTI=NULL; diff --git a/openair2/UTIL/MATH/random.c b/openair2/UTIL/MATH/random.c deleted file mode 100644 index 30a6e9b1abba957f3257b924c67bb789bbe8c35a..0000000000000000000000000000000000000000 --- a/openair2/UTIL/MATH/random.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 - */ - -/* - random.c - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - ***************************************************************************/ -#include "rtos_header.h" -#include "platform_types.h" - -#include <sys/time.h> - - -/* Random generators */ -#define FACTOR 16807 -#define LASTXN 127773 -#define UPTOMOD -2836 - -static int seed; - - -void -init_uniform (void) -{ - struct timeval tv; - struct timezone tz; - - gettimeofday (&tv, &tz); - seed = (int) tv.tv_usec; -#ifdef NODE_MT -#warning TO DO seed = mobileId - //seed += mobileId; -#endif -#ifdef NODE_RG -#warning TO DO seed = rgId - //seed += rgId; -#endif -} - - -int -uniform (void) -{ - static int times, rest, prod1, prod2; - - times = seed / LASTXN; - rest = seed - times * LASTXN; - prod1 = times * UPTOMOD; - prod2 = rest * FACTOR; - seed = prod1 + prod2; - - return seed; -} diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h index e845315922ceaafe585c1a04adfb2bdb8bd84a60..84cdf4aac3125af770ccbf501d026a2c476abba1 100644 --- a/openair2/UTIL/OSA/osa_defs.h +++ b/openair2/UTIL/OSA/osa_defs.h @@ -61,6 +61,8 @@ int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, const uint8_t key[32], uint8_t **out); +int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star); + //#define derive_key_nas_enc(aLGiD, kEY, kNAS) derive_key(NAS_ENC_ALG, aLGiD, kEY, kNAS) //#define derive_key_nas_int(aLGiD, kEY, kNAS) derive_key(NAS_INT_ALG, aLGiD, kEY, kNAS) diff --git a/openair2/UTIL/OSA/osa_internal.h b/openair2/UTIL/OSA/osa_internal.h index f4a70c7e95415cef89c805cdaf6de7bc81ee0dfd..d66a42947289c50fc7c2a7efdd470a8c21548ee6 100644 --- a/openair2/UTIL/OSA/osa_internal.h +++ b/openair2/UTIL/OSA/osa_internal.h @@ -37,6 +37,7 @@ #define FC_KASME_TO_CK (0x16) #define NR_FC_ALG_KEY_DER (0x69) +#define NR_FC_ALG_KEY_NG_RAN_STAR_DER (0x70) #ifndef hton_int32 # define hton_int32(x) \ diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c index c02b99949066f301b0291fac20235728c4d8230b..a685eec729709aff75350263631a9469f29c418f 100644 --- a/openair2/UTIL/OSA/osa_key_deriver.c +++ b/openair2/UTIL/OSA/osa_key_deriver.c @@ -127,40 +127,38 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id, return 0; } -/* -int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB) +int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star) { - uint8_t string[7]; + uint8_t *out; + uint8_t s[10]; - // FC - string[0] = FC_KENB; - // P0 = Uplink NAS count - string[1] = (nas_count & 0xff000000) >> 24; - string[2] = (nas_count & 0x00ff0000) >> 16; - string[3] = (nas_count & 0x0000ff00) >> 8; - string[4] = (nas_count & 0x000000ff); + /* FC */ + s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER; - // Length of NAS count - string[5] = 0x00; - string[6] = 0x04; + /* P0 = PCI */ + s[1] = (pci & 0x0000ff00) >> 8; + s[2] = (pci & 0x000000ff); -#if defined(SECU_DEBUG) - { - int i; - char payload[6 * sizeof(string) + 1]; - int index = 0; - - for (i = 0; i < sizeof(string); i++) - index += sprintf(&payload[index], "0x%02x ", string[i]); - LOG_D(OSA, "KeNB deriver input string: %s\n", payload); - } -#endif + /* L0 = length(P0) = 2 */ + s[3] = 0x00; + s[4] = 0x02; + + /* P1 = NR ARFCN */ + s[5] = (nr_arfcn_dl & 0x00ff0000) >> 16; + s[6] = (nr_arfcn_dl & 0x0000ff00) >> 8; + s[7] = (nr_arfcn_dl & 0x000000ff); + + /* L1 = length(P1) = 3 */ + s[8] = 0x00; + s[9] = 0x03; - kdf(string, 7, key, 32, keNB, 32); + kdf(s, 10, key, 32, &out, 32); - return 0; + memcpy(key_ng_ran_star, out, 32); + free(out); + + return 0; } -*/ int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB) { diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index ad53c6f27d8243b247092f2ac54c5b1ec61079e3..6e961781f0fda11274f8cd144904e055fe3960bd 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -544,6 +544,27 @@ do { \ (bITsTRING)->bits_unused = 4; \ } while(0) +#define UEIDENTITYINDEX_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(2, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = (mACRO) >> 2; \ + (bITsTRING)->buf[1] = ((mACRO) & 0x03)<<6; \ + (bITsTRING)->size = 2; \ + (bITsTRING)->bits_unused = 6; \ +} while(0) + +#define FIVEG_S_TMSI_TO_BIT_STRING(mACRO, bITsTRING) \ +do { \ + (bITsTRING)->buf = calloc(6, sizeof(uint8_t)); \ + (bITsTRING)->buf[0] = ((mACRO) >> 40) & 0xff; \ + (bITsTRING)->buf[1] = ((mACRO) >> 32) & 0xff; \ + (bITsTRING)->buf[2] = ((mACRO) >> 24) & 0xff; \ + (bITsTRING)->buf[3] = ((mACRO) >> 16) & 0xff; \ + (bITsTRING)->buf[4] = ((mACRO) >> 8 ) & 0xff; \ + (bITsTRING)->buf[5] = ((mACRO) & 0xff); \ + (bITsTRING)->size = 6; \ + (bITsTRING)->bits_unused = 0; \ +} while(0) /* Used to format an uint32_t containing an ipv4 address */ #define IPV4_ADDR "%u.%u.%u.%u" diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index dd781a225e0188eb53667bce3f672e5e38d78e5d..84307ee39a52a58e1eccafbd9278f81b31087a83 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -19,7 +19,7 @@ extern "C" { #include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h> #include <openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h> #include "openair2/SDAP/nr_sdap/nr_sdap.h" -//#include <openair1/PHY/phy_extern.h> +#include "sim.h" #pragma pack(1) @@ -143,6 +143,12 @@ class gtpEndPoints { // the instance id will be the Linux socket handler, as this is uniq map<uint64_t, gtpEndPoint> instances; + gtpEndPoints() { + unsigned int seed; + fill_random(&seed, sizeof(seed)); + srandom(seed); + } + ~gtpEndPoints() { // automatically close all sockets on quit for (const auto &p : instances) diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index ca9f853b6995b83c6d380394620708f1d441d30b..c4b4774e48cba676c904d05b33b642402d1d090c 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -154,64 +154,6 @@ gNBs = ); -# Dedicated Serving Cell Configuration -servingCellConfigDedicated = ({ - # BWP-Downlink - # BWP 1 Configuration - dl_bwp-Id_1 = 1; - dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp1_subcarrierSpacing = 1; - - # BWP 2 Configuration - dl_bwp-Id_2 = 2; - dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp2_subcarrierSpacing = 1; - - # BWP 3 Configuration - dl_bwp-Id_3 = 3; - dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp3_subcarrierSpacing = 1; - - firstActiveDownlinkBWP-Id = 1; #BWP-Id - defaultDownlinkBWP-Id = 1; #BWP-Id - - # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, - # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, - # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, - # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } - - # UplinkConfig - # BWP-Uplink - # BWP 1 Configuration - ul_bwp-Id_1 = 1; - ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp1_subcarrierSpacing = 1; - - # BWP 2 Configuration - ul_bwp-Id_2 = 2; - ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp2_subcarrierSpacing = 1; - - # BWP 3 Configuration - ul_bwp-Id_3 = 3; - ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp3_subcarrierSpacing = 1; - - firstActiveUplinkBWP-Id = 1; #BWP-Id - } -); # ------- SCTP definitions SCTP : diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf index f73a060b0191054e6529c633b0fe87feff4385a8..7e67d417d1c876ddf50f95a8d2e345571db8489b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf @@ -49,8 +49,7 @@ gNBs = ( # initialDownlinkBWP # genericParameters - # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) - initialDLBWPlocationAndBandwidth = 31624; + initialDLBWPlocationAndBandwidth = 1099; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -72,7 +71,7 @@ gNBs = ( # initialUplinkBWP # genericParameters - initialULBWPlocationAndBandwidth = 31624; + initialULBWPlocationAndBandwidth = 1099; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -157,40 +156,6 @@ gNBs = ( ); - # Dedicated Serving Cell Configuration - servingCellConfigDedicated = ( - { - # BWP-Downlink - # BWP 1 Configuration - dl_bwp-Id_1 = 1; - dl_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp1_subcarrierSpacing = 1; - - firstActiveDownlinkBWP-Id = 1; #BWP-Id - defaultDownlinkBWP-Id = 1; #BWP-Id - - # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, - # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, - # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, - # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } - - # UplinkConfig - # BWP-Uplink - # BWP 1 Configuration - ul_bwp-Id_1 = 1; - ul_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp1_subcarrierSpacing = 1; - - firstActiveUplinkBWP-Id = 1; #BWP-Id - } - ); - - - # ------- SCTP definitions SCTP : { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf index 8bc681c67dc283418a95d39ddb59aec70bbfb0ce..4d3b120ab1f1d3a8ae01685d9562980b1608196b 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf @@ -158,65 +158,6 @@ gNBs = ); -# Dedicated Serving Cell Configuration -servingCellConfigDedicated = ({ - # BWP-Downlink - # BWP 1 Configuration - dl_bwp-Id_1 = 1; - dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp1_subcarrierSpacing = 1; - - # BWP 2 Configuration - dl_bwp-Id_2 = 2; - dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp2_subcarrierSpacing = 1; - - # BWP 3 Configuration - dl_bwp-Id_3 = 3; - dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp3_subcarrierSpacing = 1; - - firstActiveDownlinkBWP-Id = 1; #BWP-Id - defaultDownlinkBWP-Id = 1; #BWP-Id - - # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, - # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, - # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, - # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } - - # UplinkConfig - # BWP-Uplink - # BWP 1 Configuration - ul_bwp-Id_1 = 1; - ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp1_subcarrierSpacing = 1; - - # BWP 2 Configuration - ul_bwp-Id_2 = 2; - ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp2_subcarrierSpacing = 1; - - # BWP 3 Configuration - ul_bwp-Id_3 = 3; - ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp3_subcarrierSpacing = 1; - - firstActiveUplinkBWP-Id = 1; #BWP-Id - } -); - # ------- SCTP definitions SCTP : { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf index 513c167a690a535176b9a4d09d80ae21d5ad168e..785d06dde08ba067f36a61f309c3cfe1dc6a64d1 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf @@ -50,8 +50,7 @@ gNBs = dl_carrierBandwidth = 217; #initialDownlinkBWP #genericParameters - # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart)) - initialDLBWPlocationAndBandwidth = 31624; + initialDLBWPlocationAndBandwidth = 16499; # # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 @@ -72,7 +71,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 31624; + initialULBWPlocationAndBandwidth = 16499; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -159,39 +158,6 @@ gNBs = ); -# Dedicated Serving Cell Configuration -servingCellConfigDedicated = ({ - # BWP-Downlink - # BWP 1 Configuration - dl_bwp-Id_1 = 1; - dl_bwp1_locationAndBandwidth = 16499; // RBstart=0, L=217 (80 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - dl_bwp1_subcarrierSpacing = 1; - - firstActiveDownlinkBWP-Id = 1; #BWP-Id - defaultDownlinkBWP-Id = 1; #BWP-Id - - # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, - # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, - # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, - # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } - - # UplinkConfig - # BWP-Uplink - # BWP 1 Configuration - ul_bwp-Id_1 = 1; - ul_bwp1_locationAndBandwidth = 16499; // RBstart=0, L=217 (80 MHz BW) - # subcarrierSpacing - # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 - ul_bwp1_subcarrierSpacing = 1; - - firstActiveUplinkBWP-Id = 1; #BWP-Id - } -); - - - # ------- SCTP definitions SCTP : {