Commit 69962ef9 authored by Raphael Defosseux's avatar Raphael Defosseux

Merge branch 'integration_2024_w24' into 'develop'

Integration: `2024.w24`

See merge request oai/openairinterface5g!2801

* !2789 CI: Increase iperf/iperf3 command timeout
* !2762 improve nrUE NAS security: accept NEA1,NEA2,NIA1,NIA2
* !2791 fix regressions for large physical cell id values
* !2792 Add support for MIMO 2x2 with USRP B210 at 20 MHz BW and 3/4 sampling rate
* !2748 Small UE fixes
* !2745 Add google test testcases for nr_get_Pcmax
* !2785 Update FHI 7.2 interface, test bandwidths, fix integer overflows
parents 9fab2124 bbc82731
...@@ -463,7 +463,7 @@ add_library(f1ap ...@@ -463,7 +463,7 @@ add_library(f1ap
${F1AP_DIR}/f1ap_handlers.c ${F1AP_DIR}/f1ap_handlers.c
${F1AP_DIR}/f1ap_itti_messaging.c) ${F1AP_DIR}/f1ap_itti_messaging.c)
target_include_directories(f1ap PUBLIC F1AP_DIR) target_include_directories(f1ap PUBLIC F1AP_DIR)
target_link_libraries(f1ap PUBLIC asn1_f1ap) target_link_libraries(f1ap PUBLIC asn1_f1ap L2_NR)
target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE) target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE)
# LPP # LPP
...@@ -1181,9 +1181,10 @@ target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${lapacke_INCLUDE ...@@ -1181,9 +1181,10 @@ target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${lapacke_INCLUDE
add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON}) add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
add_library(PHY_NR ${PHY_NR_SRC}) add_library(PHY_NR ${PHY_NR_SRC})
target_link_libraries(PHY_NR nr_phy_common nr_common)
add_library(PHY_NR_UE ${PHY_NR_UE_SRC}) add_library(PHY_NR_UE ${PHY_NR_UE_SRC})
target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs) target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs nr_phy_common nr_common)
add_library(PHY_RU ${PHY_SRC_RU}) add_library(PHY_RU ${PHY_SRC_RU})
target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs) target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs)
...@@ -1413,7 +1414,6 @@ set (MAC_NR_SRC_UE ...@@ -1413,7 +1414,6 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/nr_ue_scheduler.c ${NR_UE_MAC_DIR}/nr_ue_scheduler.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
${NR_UE_MAC_DIR}/nr_ra_procedures.c ${NR_UE_MAC_DIR}/nr_ra_procedures.c
${NR_UE_MAC_DIR}/nr_ue_power_procedures.c
) )
set (ENB_APP_SRC set (ENB_APP_SRC
...@@ -1462,7 +1462,7 @@ endif() ...@@ -1462,7 +1462,7 @@ endif()
add_library(MAC_UE_NR ${MAC_NR_SRC_UE}) add_library(MAC_UE_NR ${MAC_NR_SRC_UE})
target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures)
add_library(L2_LTE ${L2_LTE_SRC}) add_library(L2_LTE ${L2_LTE_SRC})
target_link_libraries(L2_LTE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) target_link_libraries(L2_LTE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
...@@ -1481,7 +1481,7 @@ add_library(e1_if ...@@ -1481,7 +1481,7 @@ add_library(e1_if
target_link_libraries(e1_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap SECURITY ${OPENSSL_LIBRARIES} e1ap GTPV1U) target_link_libraries(e1_if PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap SECURITY ${OPENSSL_LIBRARIES} e1ap GTPV1U)
target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc) target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc nr_common)
if(E2_AGENT) if(E2_AGENT)
target_link_libraries(L2_NR PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup) target_link_libraries(L2_NR PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
target_compile_definitions(L2_NR PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT) target_compile_definitions(L2_NR PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
...@@ -1516,7 +1516,7 @@ target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs) ...@@ -1516,7 +1516,7 @@ target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs)
add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} ) add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
target_link_libraries(NR_L2_UE PRIVATE f1ap nr_rlc) target_link_libraries(NR_L2_UE PRIVATE f1ap nr_rlc)
target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common nr_ue_power_procedures)
add_library(MAC_NR_COMMON add_library(MAC_NR_COMMON
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
...@@ -2083,7 +2083,6 @@ add_executable(nr-softmodem ...@@ -2083,7 +2083,6 @@ add_executable(nr-softmodem
${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR_DIR}/common/utils/lte/ue_power.c ${OPENAIR_DIR}/common/utils/lte/ue_power.c
${OPENAIR_DIR}/common/utils/lte/prach_utils.c ${OPENAIR_DIR}/common/utils/lte/prach_utils.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${PHY_INTERFACE_DIR}/queue_t.c ${PHY_INTERFACE_DIR}/queue_t.c
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c ${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
) )
...@@ -2152,7 +2151,6 @@ add_executable(nr-uesoftmodem ...@@ -2152,7 +2151,6 @@ add_executable(nr-uesoftmodem
${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c ${OPENAIR1_DIR}/PHY/TOOLS/phy_scope_interface.c
) )
...@@ -2207,7 +2205,6 @@ target_link_libraries(rftest PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) ...@@ -2207,7 +2205,6 @@ target_link_libraries(rftest PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
add_executable(polartest add_executable(polartest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
) )
target_link_libraries(polartest PRIVATE target_link_libraries(polartest PRIVATE
-Wl,--start-group UTIL 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
...@@ -2216,7 +2213,6 @@ target_link_libraries(polartest PRIVATE ...@@ -2216,7 +2213,6 @@ target_link_libraries(polartest PRIVATE
add_executable(smallblocktest add_executable(smallblocktest
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c ${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
) )
target_link_libraries(smallblocktest PRIVATE target_link_libraries(smallblocktest PRIVATE
...@@ -2242,7 +2238,6 @@ target_link_libraries(ldpctest PRIVATE ...@@ -2242,7 +2238,6 @@ target_link_libraries(ldpctest PRIVATE
add_executable(nr_dlschsim add_executable(nr_dlschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
) )
target_link_libraries(nr_dlschsim PRIVATE target_link_libraries(nr_dlschsim PRIVATE
-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 -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
...@@ -2253,7 +2248,6 @@ target_link_libraries(nr_dlschsim PRIVATE asn1_nr_rrc_hdrs) ...@@ -2253,7 +2248,6 @@ target_link_libraries(nr_dlschsim PRIVATE asn1_nr_rrc_hdrs)
add_executable(nr_pbchsim add_executable(nr_pbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
) )
target_link_libraries(nr_pbchsim PRIVATE target_link_libraries(nr_pbchsim PRIVATE
-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 -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
...@@ -2264,7 +2258,6 @@ target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) ...@@ -2264,7 +2258,6 @@ target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_psbchsim add_executable(nr_psbchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/psbchsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${NR_UE_RRC_DIR}/rrc_nsa.c ${NR_UE_RRC_DIR}/rrc_nsa.c
...@@ -2282,7 +2275,6 @@ target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) ...@@ -2282,7 +2275,6 @@ target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_pucchsim add_executable(nr_pucchsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
) )
target_link_libraries(nr_pucchsim PRIVATE target_link_libraries(nr_pucchsim PRIVATE
-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 -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
...@@ -2293,7 +2285,6 @@ target_link_libraries(nr_pucchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) ...@@ -2293,7 +2285,6 @@ target_link_libraries(nr_pucchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_dlsim add_executable(nr_dlsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${NR_UE_RRC_DIR}/rrc_nsa.c ${NR_UE_RRC_DIR}/rrc_nsa.c
...@@ -2310,7 +2301,6 @@ target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) ...@@ -2310,7 +2301,6 @@ target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_prachsim add_executable(nr_prachsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
) )
target_link_libraries(nr_prachsim PRIVATE target_link_libraries(nr_prachsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB CONFIG_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 CONFIG_LIB -lz -Wl,--end-group
...@@ -2320,7 +2310,6 @@ target_link_libraries(nr_prachsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) ...@@ -2320,7 +2310,6 @@ target_link_libraries(nr_prachsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_ulschsim add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${PHY_INTERFACE_DIR}/queue_t.c ${PHY_INTERFACE_DIR}/queue_t.c
) )
target_link_libraries(nr_ulschsim PRIVATE target_link_libraries(nr_ulschsim PRIVATE
...@@ -2332,7 +2321,6 @@ target_link_libraries(nr_ulschsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs) ...@@ -2332,7 +2321,6 @@ target_link_libraries(nr_ulschsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_ulsim add_executable(nr_ulsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c
${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c ${OPENAIR1_DIR}/SIMULATION/NR_PHY/nr_dummy_functions.c
${OPENAIR_DIR}/common/utils/nr/nr_common.c
${OPENAIR_DIR}/executables/softmodem-common.c ${OPENAIR_DIR}/executables/softmodem-common.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${NR_UE_RRC_DIR}/rrc_nsa.c ${NR_UE_RRC_DIR}/rrc_nsa.c
...@@ -2410,7 +2398,7 @@ if (${T_TRACER}) ...@@ -2410,7 +2398,7 @@ if (${T_TRACER})
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX 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_UE_NR ngap L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_UE_NR ngap
CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT 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_t2 ldpc_cl ldpc_cuda ldpc dfts config_internals) ldpc_orig ldpc_optim ldpc_optim8seg ldpc_t2 ldpc_cl ldpc_cuda ldpc dfts config_internals nr_common)
if (TARGET ${i}) if (TARGET ${i})
add_dependencies(${i} generate_T) add_dependencies(${i} generate_T)
endif() endif()
...@@ -2507,6 +2495,21 @@ if(ENABLE_TESTS) ...@@ -2507,6 +2495,21 @@ if(ENABLE_TESTS)
# meta-target: each test is supposed to add_dependencies(tests ${NEWTEST}) # meta-target: each test is supposed to add_dependencies(tests ${NEWTEST})
# then, it is possible to build and execute all tests using "ninja tests && ctest" # then, it is possible to build and execute all tests using "ninja tests && ctest"
add_custom_target(tests) add_custom_target(tests)
find_package(GTest)
if (NOT GTest_FOUND)
message(STATUS "GTest package not found, will download googletest automatically. To prevent that install google test on your system (libgtest-dev)")
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 58d77fa8070e8cec2dc1ed015d66b454c8d78850 # 1.12.1
)
set(BUILD_GMOCK OFF)
set(INSTALL_GTEST OFF)
FetchContent_MakeAvailable(googletest)
add_library(GTest::gtest ALIAS gtest)
add_library(GTest::gtest_main ALIAS gtest_main)
endif()
endif() endif()
add_subdirectory(common) add_subdirectory(common)
......
...@@ -680,6 +680,8 @@ class Containerize(): ...@@ -680,6 +680,8 @@ class Containerize():
dockerfile = "ci-scripts/docker/Dockerfile.unittest.ubuntu20" dockerfile = "ci-scripts/docker/Dockerfile.unittest.ubuntu20"
ret = cmd.run(f'docker build --progress=plain --tag ran-unittests:{baseTag} --file {dockerfile} . &> {lSourcePath}/cmake_targets/log/unittest-build.log') ret = cmd.run(f'docker build --progress=plain --tag ran-unittests:{baseTag} --file {dockerfile} . &> {lSourcePath}/cmake_targets/log/unittest-build.log')
if ret.returncode != 0: if ret.returncode != 0:
build_log_name = f'build_log_{self.testCase_id}'
CopyLogsToExecutor(cmd, lSourcePath, build_log_name)
logging.error(f'Cannot build unit tests') logging.error(f'Cannot build unit tests')
HTML.CreateHtmlTestRow("Unit test build failed", 'KO', [dockerfile]) HTML.CreateHtmlTestRow("Unit test build failed", 'KO', [dockerfile])
HTML.CreateHtmlTabFooter(False) HTML.CreateHtmlTabFooter(False)
......
...@@ -810,7 +810,7 @@ class OaiCiTest(): ...@@ -810,7 +810,7 @@ class OaiCiTest():
with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr:
port = 5002 + idx port = 5002 + idx
cmd_ue.run(f'{ue.getCmdPrefix()} iperf -B {ueIP} -s -u -i1 >> {server_filename} &', timeout=iperf_time*1.5) cmd_ue.run(f'{ue.getCmdPrefix()} iperf -B {ueIP} -s -u -i1 >> {server_filename} &', timeout=iperf_time*1.5)
cmd_svr.run(f'{svr.getCmdPrefix()} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1 2>&1 | tee {client_filename}', timeout=iperf_time*1.5) cmd_svr.run(f'{svr.getCmdPrefix()} iperf -c {ueIP} -B {svrIP} {iperf_opt} -i1 2>&1 | tee {client_filename}', timeout=iperf_time*2.5)
cmd_ue.run(f'cp {client_filename} {logPath}/{client_filename}') cmd_ue.run(f'cp {client_filename} {logPath}/{client_filename}')
cmd_ue.run(f'cp {server_filename} {logPath}/{server_filename}') cmd_ue.run(f'cp {server_filename} {logPath}/{server_filename}')
status, msg = Iperf_analyzeV2UDP(server_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate) status, msg = Iperf_analyzeV2UDP(server_filename, self.iperf_bitrate_threshold, self.iperf_packetloss_threshold, target_bitrate)
...@@ -818,7 +818,7 @@ class OaiCiTest(): ...@@ -818,7 +818,7 @@ class OaiCiTest():
with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr: with cls_cmd.getConnection(ue.getHost()) as cmd_ue, cls_cmd.getConnection(EPC.IPAddress) as cmd_svr:
port = 5002 + idx port = 5002 + idx
# note: some core setups start an iperf3 server automatically, indicated in ci_infra by runIperf3Server: False` # note: some core setups start an iperf3 server automatically, indicated in ci_infra by runIperf3Server: False`
t = iperf_time * 1.5 t = iperf_time * 2.5
if runIperf3Server: if runIperf3Server:
cmd_svr.run(f'{svr.getCmdPrefix()} nohup timeout -vk3 {t} iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} &', timeout=t) cmd_svr.run(f'{svr.getCmdPrefix()} nohup timeout -vk3 {t} iperf3 -s -B {svrIP} -p {port} -1 {jsonReport} &', timeout=t)
cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False) cmd_ue.run(f'rm /tmp/{client_filename}', reportNonZero=False)
......
...@@ -27,6 +27,11 @@ ...@@ -27,6 +27,11 @@
FROM ran-base:develop as ran-tests FROM ran-base:develop as ran-tests
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
libgtest-dev
RUN rm -Rf /oai-ran RUN rm -Rf /oai-ran
WORKDIR /oai-ran WORKDIR /oai-ran
COPY . . COPY . .
......
...@@ -109,6 +109,8 @@ elseif (xran_VERSION_STRING STREQUAL "oran_e_maintenance_release_v1.1") ...@@ -109,6 +109,8 @@ elseif (xran_VERSION_STRING STREQUAL "oran_e_maintenance_release_v1.1")
set(xran_VERSION 5.1.1) set(xran_VERSION 5.1.1)
elseif (xran_VERSION_STRING STREQUAL "oran_e_maintenance_release_v1.2") elseif (xran_VERSION_STRING STREQUAL "oran_e_maintenance_release_v1.2")
set(xran_VERSION 5.1.2) set(xran_VERSION 5.1.2)
elseif (xran_VERSION_STRING STREQUAL "oran_e_maintenance_release_v1.3")
set(xran_VERSION 5.1.3)
endif() endif()
unset(xran_VERSION_LINE) unset(xran_VERSION_LINE)
unset(xran_VERSION_STRING) unset(xran_VERSION_STRING)
......
...@@ -7,7 +7,7 @@ index 7508117..0dbe0bd 100644 ...@@ -7,7 +7,7 @@ index 7508117..0dbe0bd 100644
#include <rte_mbuf.h> #include <rte_mbuf.h>
-#define VERSIONX "oran_e_maintenance_release_v1.0" -#define VERSIONX "oran_e_maintenance_release_v1.0"
+#define VERSIONX "oran_e_maintenance_release_v1.2" +#define VERSIONX "oran_e_maintenance_release_v1.3"
#define APP_O_DU 0 #define APP_O_DU 0
#define APP_O_RU 1 #define APP_O_RU 1
...@@ -114,7 +114,7 @@ index 7419ae1..a85f973 100644 ...@@ -114,7 +114,7 @@ index 7419ae1..a85f973 100644
* @ingroup xran * @ingroup xran
* *
diff --git a/fhi_lib/lib/api/xran_up_api.h b/fhi_lib/lib/api/xran_up_api.h diff --git a/fhi_lib/lib/api/xran_up_api.h b/fhi_lib/lib/api/xran_up_api.h
index 7d3afc5..3e00c5a 100644 index 7d3afc5..e2f1f21 100644
--- a/fhi_lib/lib/api/xran_up_api.h --- a/fhi_lib/lib/api/xran_up_api.h
+++ b/fhi_lib/lib/api/xran_up_api.h +++ b/fhi_lib/lib/api/xran_up_api.h
@@ -80,6 +80,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, @@ -80,6 +80,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
...@@ -125,6 +125,16 @@ index 7d3afc5..3e00c5a 100644 ...@@ -125,6 +125,16 @@ index 7d3afc5..3e00c5a 100644
union ecpri_seq_id *seq_id, union ecpri_seq_id *seq_id,
uint16_t *num_prbu, uint16_t *num_prbu,
uint16_t *start_prbu, uint16_t *start_prbu,
@@ -89,7 +90,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
int8_t expect_comp,
enum xran_comp_hdr_type staticComp,
uint8_t *compMeth,
- uint8_t *iqWidth);
+ uint8_t *iqWidth,
+ uint8_t *is_prach);
inline int xran_prepare_iq_symbol_portion(
struct rte_mbuf *mbuf,
diff --git a/fhi_lib/lib/ethernet/ethdi.c b/fhi_lib/lib/ethernet/ethdi.c diff --git a/fhi_lib/lib/ethernet/ethdi.c b/fhi_lib/lib/ethernet/ethdi.c
index b6ba257..b53325f 100644 index b6ba257..b53325f 100644
--- a/fhi_lib/lib/ethernet/ethdi.c --- a/fhi_lib/lib/ethernet/ethdi.c
...@@ -173,9 +183,18 @@ index e6d3067..8e0abee 100644 ...@@ -173,9 +183,18 @@ index e6d3067..8e0abee 100644
static int16_t saturateAbs(int16_t inVal) static int16_t saturateAbs(int16_t inVal)
{ {
diff --git a/fhi_lib/lib/src/xran_bfp_uplane.cpp b/fhi_lib/lib/src/xran_bfp_uplane.cpp diff --git a/fhi_lib/lib/src/xran_bfp_uplane.cpp b/fhi_lib/lib/src/xran_bfp_uplane.cpp
index a345df4..7831fa0 100644 index a345df4..109b05a 100644
--- a/fhi_lib/lib/src/xran_bfp_uplane.cpp --- a/fhi_lib/lib/src/xran_bfp_uplane.cpp
+++ b/fhi_lib/lib/src/xran_bfp_uplane.cpp +++ b/fhi_lib/lib/src/xran_bfp_uplane.cpp
@@ -90,7 +90,7 @@ namespace BFP_UPlane
{
const __m512i* rawData = reinterpret_cast<const __m512i*>(dataIn.dataExpanded);
/// Abs
- const auto rawDataAbs = _mm512_abs_epi16(rawData[0]);
+ const auto rawDataAbs = _mm512_abs_epi16(_mm512_loadu_epi16(rawData));
/// No need to do a full horizontal max operation here, just do a max IQ step,
/// compute the exponents and then use a reduce max over all exponent values. This
/// is the fastest way to handle a single RB.
@@ -116,7 +116,7 @@ namespace BFP_UPlane @@ -116,7 +116,7 @@ namespace BFP_UPlane
/// Get AVX512 pointer aligned to desired RB /// Get AVX512 pointer aligned to desired RB
const __m512i* rawDataIn = reinterpret_cast<const __m512i*>(dataIn.dataExpanded + numREOffset); const __m512i* rawDataIn = reinterpret_cast<const __m512i*>(dataIn.dataExpanded + numREOffset);
...@@ -195,10 +214,18 @@ index a345df4..7831fa0 100644 ...@@ -195,10 +214,18 @@ index a345df4..7831fa0 100644
dataOut->dataCompressed[thisRBExpAddr] = thisExp; dataOut->dataCompressed[thisRBExpAddr] = thisExp;
/// Now have 1 RB worth of bytes separated into 3 chunks (1 per lane) /// Now have 1 RB worth of bytes separated into 3 chunks (1 per lane)
diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c diff --git a/fhi_lib/lib/src/xran_common.c b/fhi_lib/lib/src/xran_common.c
index baa673f..edd4ecb 100644 index baa673f..00bfdf2 100644
--- a/fhi_lib/lib/src/xran_common.c --- a/fhi_lib/lib/src/xran_common.c
+++ b/fhi_lib/lib/src/xran_common.c +++ b/fhi_lib/lib/src/xran_common.c
@@ -656,6 +656,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) @@ -650,12 +650,15 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
uint8_t compMeth = 0;
uint8_t iqWidth = 0;
+ uint8_t is_prach = 0;
+
void *pHandle = NULL;
int ret = MBUF_FREE;
uint32_t mb_free = 0;
int32_t valid_res = 0; int32_t valid_res = 0;
int expect_comp = (p_dev_ctx->fh_cfg.ru_conf.compMeth != XRAN_COMPMETHOD_NONE); int expect_comp = (p_dev_ctx->fh_cfg.ru_conf.compMeth != XRAN_COMPMETHOD_NONE);
enum xran_comp_hdr_type staticComp = p_dev_ctx->fh_cfg.ru_conf.xranCompHdrType; enum xran_comp_hdr_type staticComp = p_dev_ctx->fh_cfg.ru_conf.xranCompHdrType;
...@@ -206,7 +233,7 @@ index baa673f..edd4ecb 100644 ...@@ -206,7 +233,7 @@ index baa673f..edd4ecb 100644
if (staticComp == XRAN_COMP_HDR_TYPE_STATIC) if (staticComp == XRAN_COMP_HDR_TYPE_STATIC)
{ {
@@ -674,6 +675,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) @@ -674,6 +677,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
&subframe_id, &subframe_id,
&slot_id, &slot_id,
&symb_id, &symb_id,
...@@ -214,7 +241,14 @@ index baa673f..edd4ecb 100644 ...@@ -214,7 +241,14 @@ index baa673f..edd4ecb 100644
&seq, &seq,
&num_prbu, &num_prbu,
&start_prbu, &start_prbu,
@@ -688,23 +690,9 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid) @@ -683,28 +687,15 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
expect_comp,
staticComp,
&compMeth,
- &iqWidth);
+ &iqWidth,
+ &is_prach);
if (num_bytes <= 0){
print_err("num_bytes is wrong [%d]\n", num_bytes); print_err("num_bytes is wrong [%d]\n", num_bytes);
return MBUF_FREE; return MBUF_FREE;
} }
...@@ -241,7 +275,16 @@ index baa673f..edd4ecb 100644 ...@@ -241,7 +275,16 @@ index baa673f..edd4ecb 100644
#ifndef FCN_ADAPT #ifndef FCN_ADAPT
if(valid_res != 0) { if(valid_res != 0) {
print_dbg("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.seq_id, num_bytes); print_dbg("valid_res is wrong [%d] ant %u (%u : %u : %u : %u) seq %u num_bytes %d\n", valid_res, Ant_ID, frame_id, subframe_id, slot_id, symb_id, seq.seq_id, num_bytes);
@@ -1189,7 +1177,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc @@ -756,7 +747,7 @@ process_mbuf(struct rte_mbuf *pkt, void* handle, struct xran_eaxc_info *p_cid)
print_dbg("Transport layer fragmentation (eCPRI) is not supported\n");
}
- } else if (Ant_ID >= p_dev_ctx->PrachCPConfig.eAxC_offset && p_dev_ctx->fh_cfg.prachEnable) {
+ } else if (/*Ant_ID >= p_dev_ctx->PrachCPConfig.eAxC_offset && */p_dev_ctx->fh_cfg.prachEnable && is_prach) {
/* PRACH packet has ruportid = num_eAxc + ant_id */
Ant_ID -= p_dev_ctx->PrachCPConfig.eAxC_offset;
symbol_total_bytes[p_dev_ctx->xran_port_id][CC_ID][Ant_ID] += num_bytes;
@@ -1189,7 +1180,7 @@ int generate_cpmsg_prach(void *pHandle, struct xran_cp_gen_params *params, struc
timeOffset += startSymId * (2048 + 144); timeOffset += startSymId * (2048 + 144);
} }
timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu timeOffset = timeOffset >> nNumerology; //original number is Tc, convert to Ts based on mu
...@@ -250,7 +293,7 @@ index baa673f..edd4ecb 100644 ...@@ -250,7 +293,7 @@ index baa673f..edd4ecb 100644
timeOffset += 16; timeOffset += 16;
params->dir = XRAN_DIR_UL; params->dir = XRAN_DIR_UL;
@@ -1295,8 +1283,7 @@ int32_t ring_processing_func(void* args) @@ -1295,8 +1286,7 @@ int32_t ring_processing_func(void* args)
for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){ for (i = 0; i < ctx->io_cfg.num_vfs && i < XRAN_VF_MAX; i++){
for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) { for(qi = 0; qi < ctx->rxq_per_port[i]; qi++) {
...@@ -430,7 +473,7 @@ index 36bd72c..f7f5678 100644 ...@@ -430,7 +473,7 @@ index 36bd72c..f7f5678 100644
int idx = 0; int idx = 0;
uint16_t *psrc = (uint16_t *)iq_data_start; uint16_t *psrc = (uint16_t *)iq_data_start;
diff --git a/fhi_lib/lib/src/xran_up_api.c b/fhi_lib/lib/src/xran_up_api.c diff --git a/fhi_lib/lib/src/xran_up_api.c b/fhi_lib/lib/src/xran_up_api.c
index 397853a..4a714b5 100644 index 397853a..8977e3d 100644
--- a/fhi_lib/lib/src/xran_up_api.c --- a/fhi_lib/lib/src/xran_up_api.c
+++ b/fhi_lib/lib/src/xran_up_api.c +++ b/fhi_lib/lib/src/xran_up_api.c
@@ -329,6 +329,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, @@ -329,6 +329,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
...@@ -441,7 +484,26 @@ index 397853a..4a714b5 100644 ...@@ -441,7 +484,26 @@ index 397853a..4a714b5 100644
union ecpri_seq_id *seq_id, union ecpri_seq_id *seq_id,
uint16_t *num_prbu, uint16_t *num_prbu,
uint16_t *start_prbu, uint16_t *start_prbu,
@@ -387,6 +388,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, @@ -338,7 +339,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
int8_t expect_comp,
enum xran_comp_hdr_type staticComp,
uint8_t *compMeth,
- uint8_t *iqWidth)
+ uint8_t *iqWidth,
+ uint8_t *is_prach)
{
#if XRAN_MLOG_VAR
uint32_t mlogVar[10];
@@ -374,6 +376,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
return 0; /* packet too short */
radio_hdr->sf_slot_sym.value = rte_be_to_cpu_16(radio_hdr->sf_slot_sym.value);
+ if (radio_hdr->data_feature.filter_id > 0) *is_prach = 1;
+ else *is_prach = 0;
if (frame_id)
*frame_id = radio_hdr->frame_id;
@@ -387,6 +391,8 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
if (symb_id) if (symb_id)
*symb_id = radio_hdr->sf_slot_sym.symb_id; *symb_id = radio_hdr->sf_slot_sym.symb_id;
...@@ -450,7 +512,7 @@ index 397853a..4a714b5 100644 ...@@ -450,7 +512,7 @@ index 397853a..4a714b5 100644
/* Process data section hdr */ /* Process data section hdr */
struct data_section_hdr *data_hdr = struct data_section_hdr *data_hdr =
(void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr)); (void *)rte_pktmbuf_adj(mbuf, sizeof(*radio_hdr));
@@ -401,6 +404,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf, @@ -401,6 +407,7 @@ int32_t xran_extract_iq_samples(struct rte_mbuf *mbuf,
*sym_inc = data_hdr->fields.sym_inc; *sym_inc = data_hdr->fields.sym_inc;
*rb = data_hdr->fields.rb; *rb = data_hdr->fields.rb;
*sect_id = data_hdr->fields.sect_id; *sect_id = data_hdr->fields.sect_id;
......
...@@ -10,3 +10,4 @@ if(ENABLE_WEBSRV) ...@@ -10,3 +10,4 @@ if(ENABLE_WEBSRV)
endif() endif()
add_subdirectory(T) add_subdirectory(T)
add_subdirectory(nr)
add_library(nr_common nr_common.c)
target_include_directories(nr_common PUBLIC .)
if (ENABLE_TESTS)
add_subdirectory(tests)
endif()
...@@ -1126,21 +1126,23 @@ int get_scan_ssb_first_sc(const double fc, const int nbRB, const int nrBand, con ...@@ -1126,21 +1126,23 @@ int get_scan_ssb_first_sc(const double fc, const int nbRB, const int nrBand, con
const double startFreq = get_start_freq(fc, nbRB, mu); const double startFreq = get_start_freq(fc, nbRB, mu);
const double stopFreq = get_stop_freq(fc, nbRB, mu); const double stopFreq = get_stop_freq(fc, nbRB, mu);
int scanGscnStart = -1; int scanGscnStart = 0;
int scanGscnStop = -1; int scanGscnStop = 0;
sync_raster_t tmpRaster = {0}; const sync_raster_t *tmpRaster = sync_raster;
for (const sync_raster_t *r = sync_raster; r < r + (sizeof(sync_raster) / sizeof(sync_raster_t)); r++) { const sync_raster_t * end=sync_raster + sizeofArray(sync_raster);
if (r->band == nrBand && r->scs_index == mu) { while (tmpRaster < end && (tmpRaster->band != nrBand || tmpRaster->scs_index != mu))
tmpRaster = *r; tmpRaster++;
break; if (tmpRaster >= end) {
} LOG_E(PHY, "raster not found nrband=%d, mu=%d\n", nrBand, mu);
return 0;
} }
find_gscn_to_scan(startFreq, stopFreq, tmpRaster, &scanGscnStart, &scanGscnStop);
find_gscn_to_scan(startFreq, stopFreq, *tmpRaster, &scanGscnStart, &scanGscnStop);
const double scs = MU_SCS(mu) * 1e3; const double scs = MU_SCS(mu) * 1e3;
const double pointA = fc - (nbRB / 2 * scs * NR_NB_SC_PER_RB); const double pointA = fc - (nbRB / 2 * scs * NR_NB_SC_PER_RB);
int numGscn = 0; int numGscn = 0;
for (int g = scanGscnStart; (g <= scanGscnStop) && (numGscn < MAX_GSCN_BAND); g += tmpRaster.step_gscn) { for (int g = scanGscnStart; (g <= scanGscnStop) && (numGscn < MAX_GSCN_BAND); g += tmpRaster->step_gscn) {
ssbInfo[numGscn].ssRef = get_ssref_from_gscn(g); ssbInfo[numGscn].ssRef = get_ssref_from_gscn(g);
ssbInfo[numGscn].ssbFirstSC = get_ssb_first_sc(pointA, ssbInfo[numGscn].ssRef, mu); ssbInfo[numGscn].ssbFirstSC = get_ssb_first_sc(pointA, ssbInfo[numGscn].ssRef, mu);
ssbInfo[numGscn].gscn = g; ssbInfo[numGscn].gscn = g;
...@@ -1174,38 +1176,6 @@ void init_delay_table(uint16_t ofdm_symbol_size, ...@@ -1174,38 +1176,6 @@ void init_delay_table(uint16_t ofdm_symbol_size,
} }
} }
void freq2time(uint16_t ofdm_symbol_size,
int16_t *freq_signal,
int16_t *time_signal)
{
const idft_size_idx_t idft_size = get_idft(ofdm_symbol_size);
idft(idft_size, freq_signal, time_signal, 1);
}
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay)
{
freq2time(ofdm_symbol_size, (int16_t *)ls_est, (int16_t *)ch_estimates_time);
int max_pos = delay->delay_max_pos;
int max_val = delay->delay_max_val;
const int sync_pos = 0;
for (int i = 0; i < ofdm_symbol_size; i++) {
int temp = c16amp2(ch_estimates_time[i]) >> 1;
if (temp > max_val) {
max_pos = i;
max_val = temp;
}
}
if (max_pos > ofdm_symbol_size / 2)
max_pos = max_pos - ofdm_symbol_size;
delay->delay_max_pos = max_pos;
delay->delay_max_val = max_val;
delay->est_delay = max_pos - sync_pos;
}
void nr_timer_start(NR_timer_t *timer) void nr_timer_start(NR_timer_t *timer)
{ {
timer->active = true; timer->active = true;
......
...@@ -241,12 +241,6 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB, ...@@ -241,12 +241,6 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA, int scs); int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA, int scs);
int get_delay_idx(int delay, int max_delay_comp); int get_delay_idx(int delay, int max_delay_comp);
void freq2time(uint16_t ofdm_symbol_size,
int16_t *freq_signal,
int16_t *time_signal);
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay);
int get_scan_ssb_first_sc(const double fc, int get_scan_ssb_first_sc(const double fc,
const int nbRB, const int nbRB,
const int nrBand, const int nrBand,
......
add_executable(test_nr_common test_nr_common.cpp)
target_link_libraries(test_nr_common PRIVATE nr_common GTest::gtest minimal_lib)
add_dependencies(tests test_nr_common)
add_test(NAME test_nr_common
COMMAND ./test_nr_common)
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <gtest/gtest.h>
extern "C" {
#include "nr_common.h"
#include "common/utils/LOG/log.h"
}
TEST(nr_common, nr_timer) {
NR_timer_t timer;
nr_timer_setup(&timer, 10, 1);
nr_timer_start(&timer);
EXPECT_TRUE(is_nr_timer_active(timer));
EXPECT_FALSE(nr_timer_expired(timer));
for (auto i = 0; i < 10; i++) {
nr_timer_tick(&timer);
}
EXPECT_FALSE(is_nr_timer_active(timer));
EXPECT_TRUE(nr_timer_expired(timer));
}
int main(int argc, char **argv)
{
logInit();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
...@@ -391,6 +391,8 @@ Compile the fronthaul interface library by calling `make` and the option ...@@ -391,6 +391,8 @@ Compile the fronthaul interface library by calling `make` and the option
environment variables `RTE_SDK` for the path to the source tree of DPDK, and environment variables `RTE_SDK` for the path to the source tree of DPDK, and
`XRAN_DIR` to set the path to the fronthaul library. `XRAN_DIR` to set the path to the fronthaul library.
**Note**: you need at least gcc-11 and g++-11.
```bash ```bash
cd ~/phy/fhi_lib/lib cd ~/phy/fhi_lib/lib
make clean make clean
...@@ -790,7 +792,6 @@ Edit the sample OAI gNB configuration file and check following parameters: ...@@ -790,7 +792,6 @@ Edit the sample OAI gNB configuration file and check following parameters:
compression compression
* `iq_width_prach`: Width of PRACH IQ samples: if 16, no compression, if <16, applies * `iq_width_prach`: Width of PRACH IQ samples: if 16, no compression, if <16, applies
compression compression
* `fft_size`: size of FFT performed by RU, set to 12 by default
* `prach_config`: PRACH-specific configuration * `prach_config`: PRACH-specific configuration
* `eAxC_offset`: PRACH antenna offset * `eAxC_offset`: PRACH antenna offset
* `kbar`: the PRACH guard interval, provided in RU * `kbar`: the PRACH guard interval, provided in RU
......
...@@ -8,8 +8,9 @@ explaining how to test with cmake and ctest; it is a suggested read, and the ...@@ -8,8 +8,9 @@ explaining how to test with cmake and ctest; it is a suggested read, and the
following just lists the main points of how to compile the tests and how to add following just lists the main points of how to compile the tests and how to add
new ones. new ones.
At the time of writing, only the NR RLC tests have been integrated. The author GoogleTest is a C++ unit testing framework that has been added as an external dependency. While using GoogleTest is not a requirement it can simplify writing unit tests.
hopes that more tests follow suit. See [primer](http://google.github.io/googletest/primer.html) for a quick introduction. To add it to your test executable link against
`GTest::gtest` or `GTest::gtest_main`.
# How to compile tests # How to compile tests
......
...@@ -912,7 +912,7 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file) ...@@ -912,7 +912,7 @@ static void fill_rf_config(RU_t *ru, char *rf_config_file)
} }
} }
static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, int slots_per_frame) static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_request_scf_t *config, int slots_per_frame, uint16_t ofdm_symbol_size)
{ {
const nfapi_nr_prach_config_t *prach_config = &config->prach_config; const nfapi_nr_prach_config_t *prach_config = &config->prach_config;
const nfapi_nr_tdd_table_t *tdd_table = &config->tdd_table; const nfapi_nr_tdd_table_t *tdd_table = &config->tdd_table;
...@@ -934,6 +934,8 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_ ...@@ -934,6 +934,8 @@ static void fill_split7_2_config(split7_config_t *split7, const nfapi_nr_config_
} }
} }
} }
split7->fftSize = log2(ofdm_symbol_size);
} }
/* this function maps the RU tx and rx buffers to the available rf chains. /* this function maps the RU tx and rx buffers to the available rf chains.
...@@ -1157,7 +1159,7 @@ void *ru_thread( void *param ) { ...@@ -1157,7 +1159,7 @@ void *ru_thread( void *param ) {
nr_dump_frame_parms(fp); nr_dump_frame_parms(fp);
nr_phy_init_RU(ru); nr_phy_init_RU(ru);
fill_rf_config(ru, ru->rf_config_file); fill_rf_config(ru, ru->rf_config_file);
fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp->slots_per_frame); fill_split7_2_config(&ru->openair0_cfg.split7, &ru->config, fp->slots_per_frame, fp->ofdm_symbol_size);
if(!emulate_rf) { if(!emulate_rf) {
// Start IF device if any // Start IF device if any
...@@ -1342,6 +1344,7 @@ void *ru_thread( void *param ) { ...@@ -1342,6 +1344,7 @@ void *ru_thread( void *param ) {
rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false; rx_tti_busy[info->slot_rx % RU_RX_SLOT_DEPTH] = false;
if ((info->slot_rx % RU_RX_SLOT_DEPTH) == (proc->tti_rx % RU_RX_SLOT_DEPTH)) if ((info->slot_rx % RU_RX_SLOT_DEPTH) == (proc->tti_rx % RU_RX_SLOT_DEPTH))
not_done = false; not_done = false;
delNotifiedFIFO_elt(res);
} }
if (!res) if (!res)
break; break;
......
...@@ -735,6 +735,7 @@ void *UE_thread(void *arg) ...@@ -735,6 +735,7 @@ void *UE_thread(void *arg)
readFrame(UE, &sync_timestamp, false); readFrame(UE, &sync_timestamp, false);
notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch); notifiedFIFO_elt_t *Msg = newNotifiedFIFO_elt(sizeof(syncData_t), 0, &nf, UE_synch);
syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg); syncData_t *syncMsg = (syncData_t *)NotifiedFifoData(Msg);
*syncMsg = (syncData_t){0};
NR_DL_FRAME_PARMS *fp = &UE->frame_parms; NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
if (UE->UE_scan_carrier) { if (UE->UE_scan_carrier) {
// Get list of GSCN in this band for UE's bandwidth and center frequency. // Get list of GSCN in this band for UE's bandwidth and center frequency.
...@@ -743,10 +744,7 @@ void *UE_thread(void *arg) ...@@ -743,10 +744,7 @@ void *UE_thread(void *arg)
get_scan_ssb_first_sc(fp->dl_CarrierFreq, fp->N_RB_DL, fp->nr_band, fp->numerology_index, syncMsg->gscnInfo); get_scan_ssb_first_sc(fp->dl_CarrierFreq, fp->N_RB_DL, fp->nr_band, fp->numerology_index, syncMsg->gscnInfo);
} else { } else {
LOG_W(PHY, "SSB position provided\n"); LOG_W(PHY, "SSB position provided\n");
nr_gscn_info_t *g = syncMsg->gscnInfo; syncMsg->gscnInfo[0] = (nr_gscn_info_t){.ssbFirstSC = fp->ssb_start_subcarrier};
g->ssbFirstSC = fp->ssb_start_subcarrier;
g->gscn = 0;
g->ssRef = 0;
syncMsg->numGscn = 1; syncMsg->numGscn = 1;
} }
syncMsg->UE = UE; syncMsg->UE = UE;
......
...@@ -4,3 +4,4 @@ add_boolean_option(ENABLE_NRSCOPE OFF "Whether to build the 5G scope" OFF) ...@@ -4,3 +4,4 @@ add_boolean_option(ENABLE_NRSCOPE OFF "Whether to build the 5G scope" OFF)
if(ENABLE_UESCOPE OR ENABLE_ENBSCOPE OR ENABLE_NRSCOPE) if(ENABLE_UESCOPE OR ENABLE_ENBSCOPE OR ENABLE_NRSCOPE)
add_subdirectory(TOOLS) add_subdirectory(TOOLS)
endif() endif()
add_subdirectory(nr_phy_common)
...@@ -160,7 +160,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy ...@@ -160,7 +160,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
} //rb } //rb
} // symb } // symb
int nb_rb=0; int nb_rb=0;
int32_t n0_subband_tot=0; int64_t n0_subband_tot=0;
int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx]; int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx];
memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT)); memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT));
...@@ -200,7 +200,7 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB, ...@@ -200,7 +200,7 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB,
unsigned char symbol, unsigned char symbol,
uint8_t nrOfLayers) uint8_t nrOfLayers)
{ {
int rx_power_tot = 0; uint32_t rx_power_tot = 0;
unsigned short rx_power_avg_dB; unsigned short rx_power_avg_dB;
unsigned short rx_power_tot_dB; unsigned short rx_power_tot_dB;
RU_t *ru = gNB->RU_list[0]; RU_t *ru = gNB->RU_list[0];
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h" #include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
#include "nr_phy_common.h"
//#define DEBUG_CH //#define DEBUG_CH
......
...@@ -316,6 +316,12 @@ void rx_nr_prach_ru(RU_t *ru, ...@@ -316,6 +316,12 @@ void rx_nr_prach_ru(RU_t *ru,
dftlen >>= 1; dftlen >>= 1;
break; break;
case 23040:
// 20 MHz @ 23.04 Ms/s
Ncp = (Ncp * 3) / 4;
dftlen = (dftlen * 3) / 4;
break;
case 30720: case 30720:
// 20, 25, 30 MHz @ 30.72 Ms/s // 20, 25, 30 MHz @ 30.72 Ms/s
break; break;
......
...@@ -454,10 +454,9 @@ static void nr_ulsch_channel_level(int **ul_ch_estimates_ext, ...@@ -454,10 +454,9 @@ static void nr_ulsch_channel_level(int **ul_ch_estimates_ext,
avg128U = simde_mm_add_epi32(avg128U, simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[i], ul_ch128[i]), x)); avg128U = simde_mm_add_epi32(avg128U, simde_mm_srai_epi32(simde_mm_madd_epi16(ul_ch128[i], ul_ch128[i]), x));
} }
avg[aatx*frame_parms->nb_antennas_rx+aarx] = (((int32_t*)&avg128U)[0] + int32_t *avg32i = (int32_t *)&avg128U;
((int32_t*)&avg128U)[1] + int64_t avg64 = (int64_t)avg32i[0] + avg32i[1] + avg32i[2] + avg32i[3];
((int32_t*)&avg128U)[2] + avg[aatx * frame_parms->nb_antennas_rx + aarx] = avg64 / y;
((int32_t*)&avg128U)[3]) / y;
} }
} }
......
...@@ -237,7 +237,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, ...@@ -237,7 +237,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB,
uint8_t index=0; uint8_t index=0;
int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1 int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1
int signal_energy = 0, signal_energy_ant0 = 0; int64_t signal_energy = 0, signal_energy_ant0 = 0;
for (int l=0; l<pucch_pdu->nr_of_symbols; l++) { for (int l=0; l<pucch_pdu->nr_of_symbols; l++) {
uint8_t l2 = l + pucch_pdu->start_symbol_index; uint8_t l2 = l + pucch_pdu->start_symbol_index;
...@@ -1147,7 +1147,11 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, ...@@ -1147,7 +1147,11 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
uint32_t x1 = 0, x2 = 0, sGold = 0; uint32_t x1 = 0, x2 = 0, sGold = 0;
uint8_t *sGold8 = (uint8_t *)&sGold; uint8_t *sGold8 = (uint8_t *)&sGold;
x2 = (((1<<17)*((14*slot) + (pucch_pdu->start_symbol_index+symb) + 1)*((2*pucch_pdu->dmrs_scrambling_id) + 1)) + (2*pucch_pdu->dmrs_scrambling_id))%(1U<<31); // c_init calculation according to TS38.211 subclause const int scramble = pucch_pdu->dmrs_scrambling_id * 2;
// fixme: when MR2754 will be merged, use the gold sequence cache instead of regenerate each time
x2 = ((1ULL << 17) * ((NR_NUMBER_OF_SYMBOLS_PER_SLOT * slot + pucch_pdu->start_symbol_index + symb + 1) * (scramble + 1))
+ scramble)
% (1U << 31); // c_init calculation according to TS38.211 subclause
#ifdef DEBUG_NR_PUCCH_RX #ifdef DEBUG_NR_PUCCH_RX
printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n", printf("slot %d, start_symbol_index %d, symbol %d, dmrs_scrambling_id %d\n",
slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id); slot,pucch_pdu->start_symbol_index,symb,pucch_pdu->dmrs_scrambling_id);
......
...@@ -29,12 +29,13 @@ ...@@ -29,12 +29,13 @@
#include "PHY/NR_REFSIG/nr_mod_table.h" #include "PHY/NR_REFSIG/nr_mod_table.h"
#include "PHY/NR_TRANSPORT/nr_sch_dmrs.h" #include "PHY/NR_TRANSPORT/nr_sch_dmrs.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "common/utils/nr/nr_common.h" #include "nr_phy_common.h"
#include "filt16a_32.h" #include "filt16a_32.h"
#include "T.h" #include "T.h"
#include <openair1/PHY/TOOLS/phy_scope_interface.h> #include <openair1/PHY/TOOLS/phy_scope_interface.h>
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h" #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
extern openair0_config_t openair0_cfg[]; extern openair0_config_t openair0_cfg[];
// #define DEBUG_PDSCH // #define DEBUG_PDSCH
...@@ -651,12 +652,12 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, ...@@ -651,12 +652,12 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
unsigned char symbol, unsigned char symbol,
int dmrss, int dmrss,
uint8_t ssb_index, uint ssb_index,
uint8_t n_hf, uint n_hf,
int ssb_start_subcarrier, int ssb_start_subcarrier,
const c16_t rxdataF[][fp->samples_per_slot_wCP], const c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink, bool sidelink,
uint16_t Nid) uint Nid)
{ {
int Ns = proc->nr_slot_rx; int Ns = proc->nr_slot_rx;
c16_t pilot[200] __attribute__((aligned(16))); c16_t pilot[200] __attribute__((aligned(16)));
......
...@@ -75,12 +75,12 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp, ...@@ -75,12 +75,12 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
unsigned char symbol, unsigned char symbol,
int dmrss, int dmrss,
uint8_t ssb_index, uint ssb_index,
uint8_t n_hf, uint n_hf,
int ssb_start_subcarrier, int ssb_start_subcarrier,
const c16_t rxdataF[][fp->samples_per_slot_wCP], const c16_t rxdataF[][fp->samples_per_slot_wCP],
bool sidelink, bool sidelink,
uint16_t Nid); uint Nid);
int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
......
...@@ -47,9 +47,7 @@ ...@@ -47,9 +47,7 @@
#include "PHY/TOOLS/tools_defs.h" #include "PHY/TOOLS/tools_defs.h"
#include "nr-uesoftmodem.h" #include "nr-uesoftmodem.h"
//static nfapi_nr_config_request_t config_t; //#define DEBUG_INITIAL_SYNCH
//static nfapi_nr_config_request_t* config =&config_t;
// #define DEBUG_INITIAL_SYNCH
#define DUMP_PBCH_CH_ESTIMATES 0 #define DUMP_PBCH_CH_ESTIMATES 0
// structure used for multiple SSB detection // structure used for multiple SSB detection
...@@ -223,8 +221,7 @@ void nr_scan_ssb(void *arg) ...@@ -223,8 +221,7 @@ void nr_scan_ssb(void *arg)
ssbInfo->ssbOffset = sync_pos - fp->nb_prefix_samples; ssbInfo->ssbOffset = sync_pos - fp->nb_prefix_samples;
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2); LOG_I(PHY, "Initial sync : Estimated PSS position %d, Nid2 %d, ssb offset %d\n", sync_pos, nid2, ssbInfo->ssbOffset);
LOG_I(PHY, "sync_pos %d ssb_offset %d \n", sync_pos, ue->ssb_offset);
#endif #endif
/* check that SSS/PBCH block is continuous inside the received buffer */ /* check that SSS/PBCH block is continuous inside the received buffer */
if (ssbInfo->ssbOffset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) >= fp->samples_per_frame) { if (ssbInfo->ssbOffset + NR_N_SYMBOLS_SSB * (fp->ofdm_symbol_size + fp->nb_prefix_samples) >= fp->samples_per_frame) {
...@@ -256,10 +253,6 @@ void nr_scan_ssb(void *arg) ...@@ -256,10 +253,6 @@ void nr_scan_ssb(void *arg)
rxdataF, rxdataF,
link_type_dl); link_type_dl);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY, "Calling sss detection (normal CP)\n");
#endif
int freq_offset_sss = 0; int freq_offset_sss = 0;
int32_t metric_tdd_ncp = 0; int32_t metric_tdd_ncp = 0;
uint8_t phase_tdd_ncp; uint8_t phase_tdd_ncp;
...@@ -273,7 +266,15 @@ void nr_scan_ssb(void *arg) ...@@ -273,7 +266,15 @@ void nr_scan_ssb(void *arg)
&phase_tdd_ncp, &phase_tdd_ncp,
&freq_offset_sss, &freq_offset_sss,
rxdataF); rxdataF);
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,
"TDD Normal prefix: sss detection result; %d, CellId %d metric %d, phase %d, measured offset %d\n",
ssbInfo->syncRes.cell_detected,
ssbInfo->nidCell,
metric_tdd_ncp,
phase_tdd_ncp,
ssbInfo->syncRes.rx_offset);
#endif
ssbInfo->freqOffset = freq_offset_pss + freq_offset_sss; ssbInfo->freqOffset = freq_offset_pss + freq_offset_sss;
uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD]; uint32_t nr_gold_pbch_ref[2][64][NR_PBCH_DMRS_LENGTH_DWORD];
...@@ -315,23 +316,24 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, ...@@ -315,23 +316,24 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
for (int s = 0; s < numGscn; s++) { for (int s = 0; s < numGscn; s++) {
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(nr_ue_ssb_scan_t), gscnInfo[s].gscn, &nf, &nr_scan_ssb); notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(nr_ue_ssb_scan_t), gscnInfo[s].gscn, &nf, &nr_scan_ssb);
nr_ue_ssb_scan_t *ssbInfo = (nr_ue_ssb_scan_t *)NotifiedFifoData(req); nr_ue_ssb_scan_t *ssbInfo = (nr_ue_ssb_scan_t *)NotifiedFifoData(req);
ssbInfo->gscnInfo = gscnInfo[s]; *ssbInfo = (nr_ue_ssb_scan_t){.gscnInfo = gscnInfo[s],
.fp = &ue->frame_parms,
.proc = proc,
.syncRes.cell_detected = false,
.nFrames = n_frames,
.foFlag = ue->UE_fo_compensation,
.targetNidCell = ue->target_Nid_cell};
ssbInfo->rxdata = malloc16_clear(fp->nb_antennas_rx * sizeof(c16_t *)); ssbInfo->rxdata = malloc16_clear(fp->nb_antennas_rx * sizeof(c16_t *));
for (int ant = 0; ant < fp->nb_antennas_rx; ant++) { for (int ant = 0; ant < fp->nb_antennas_rx; ant++) {
ssbInfo->rxdata[ant] = malloc16_clear((fp->samples_per_frame * 2 + fp->ofdm_symbol_size) * sizeof(c16_t)); ssbInfo->rxdata[ant] = malloc16(sizeof(c16_t) * (fp->samples_per_frame * 2 + fp->ofdm_symbol_size));
memcpy(ssbInfo->rxdata[ant], ue->common_vars.rxdata[ant], sizeof(c16_t) * fp->samples_per_frame * 2); memcpy(ssbInfo->rxdata[ant], ue->common_vars.rxdata[ant], sizeof(c16_t) * fp->samples_per_frame * 2);
memset(ssbInfo->rxdata[ant] + fp->samples_per_frame * 2, 0, fp->ofdm_symbol_size * sizeof(c16_t));
} }
LOG_I(NR_PHY, LOG_I(NR_PHY,
"Scanning GSCN: %d, with SSB offset: %d, SSB Freq: %lf\n", "Scanning GSCN: %d, with SSB offset: %d, SSB Freq: %lf\n",
ssbInfo->gscnInfo.gscn, ssbInfo->gscnInfo.gscn,
ssbInfo->gscnInfo.ssbFirstSC, ssbInfo->gscnInfo.ssbFirstSC,
ssbInfo->gscnInfo.ssRef); ssbInfo->gscnInfo.ssRef);
ssbInfo->fp = &ue->frame_parms;
ssbInfo->proc = proc;
ssbInfo->syncRes.cell_detected = false;
ssbInfo->nFrames = n_frames;
ssbInfo->foFlag = ue->UE_fo_compensation;
ssbInfo->targetNidCell = ue->target_Nid_cell;
pushTpool(&get_nrUE_params()->Tpool, req); pushTpool(&get_nrUE_params()->Tpool, req);
} }
...@@ -437,16 +439,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, ...@@ -437,16 +439,6 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
res.syncRes.rx_offset = res.ssbOffset - sync_pos_frame; res.syncRes.rx_offset = res.ssbOffset - sync_pos_frame;
} }
#ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY,
"TDD Normal prefix: CellId %d metric %d, phase %d, pbch detected %d, measured offset %d\n",
fp->Nid_cell,
metric_tdd_ncp,
phase_tdd_ncp,
ret.cell_detected,
ret.rx_offset);
#endif
if (res.syncRes.cell_detected) { if (res.syncRes.cell_detected) {
LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n", ue->Mod_id, res.syncRes.rx_offset); LOG_I(PHY, "[UE%d] In synch, rx_offset %d samples\n", ue->Mod_id, res.syncRes.rx_offset);
LOG_I(PHY, "[UE %d] Measured Carrier Frequency offset %d Hz\n", ue->Mod_id, res.freqOffset); LOG_I(PHY, "[UE %d] Measured Carrier Frequency offset %d Hz\n", ue->Mod_id, res.freqOffset);
...@@ -455,7 +447,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, ...@@ -455,7 +447,7 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id); LOG_I(PHY,"[UE%d] Initial sync : PBCH not ok\n",ue->Mod_id);
LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2); LOG_I(PHY, "[UE%d] Initial sync : Estimated PSS position %d, Nid2 %d\n", ue->Mod_id, sync_pos, ue->common_vars.nid2);
LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id, LOG_I(PHY,"[UE%d] Initial sync : Estimated Nid_cell %d, Frame_type %d\n",ue->Mod_id,
frame_parms->Nid_cell,frame_parms->frame_type); fp->Nid_cell,fp->frame_type);
#endif #endif
} }
...@@ -481,10 +473,10 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc, ...@@ -481,10 +473,10 @@ nr_initial_sync_t nr_initial_sync(UE_nr_rxtx_proc_t *proc,
ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]); ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
#ifdef DEBUG_INITIAL_SYNCH #ifdef DEBUG_INITIAL_SYNCH
LOG_I(PHY, "[UE%d] Initial sync : Estimated power: %d dB\n", ue->Mod_id, ue->measurements.rx_power_avg_dB[0]); LOG_I(PHY, "[UE%d] Initial sync failed : Estimated power: %d dB\n", ue->Mod_id, ue->measurements.rx_power_avg_dB[0]);
#endif #endif
} else { } else {
LOG_A(PHY, "Initial sync successful\n"); LOG_A(PHY, "Initial sync successful, PCI: %d\n",fp->Nid_cell);
} }
// exit_fun("debug exit"); // exit_fun("debug exit");
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_INITIAL_UE_SYNC, VCD_FUNCTION_OUT);
......
...@@ -55,11 +55,12 @@ static uint16_t nr_pbch_extract(uint32_t rxdataF_sz, ...@@ -55,11 +55,12 @@ static uint16_t nr_pbch_extract(uint32_t rxdataF_sz,
uint32_t symbol, uint32_t symbol,
uint32_t s_offset, uint32_t s_offset,
int ssb_start_subcarrier, int ssb_start_subcarrier,
const NR_DL_FRAME_PARMS *frame_parms) const NR_DL_FRAME_PARMS *frame_parms,
int nid)
{ {
uint16_t rb; uint16_t rb;
uint8_t i, j, aarx; uint8_t i, j, aarx;
int nushiftmod4 = frame_parms->Nid_cell % 4; int nushiftmod4 = nid % 4;
AssertFatal(symbol>=1 && symbol<5, AssertFatal(symbol>=1 && symbol<5,
"symbol %d illegal for PBCH extraction\n", "symbol %d illegal for PBCH extraction\n",
symbol); symbol);
...@@ -418,7 +419,8 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue, ...@@ -418,7 +419,8 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
symbol, symbol,
symbol_offset, symbol_offset,
ssb_start_subcarrier, ssb_start_subcarrier,
frame_parms); frame_parms,
Nid_cell);
#ifdef DEBUG_PBCH #ifdef DEBUG_PBCH
LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size); LOG_I(PHY,"[PHY] PBCH Symbol %d ofdm size %d\n",symbol, frame_parms->ofdm_symbol_size);
LOG_I(PHY,"[PHY] PBCH starting channel_level\n"); LOG_I(PHY,"[PHY] PBCH starting channel_level\n");
......
...@@ -65,7 +65,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t ...@@ -65,7 +65,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
c16_t prach[(4688 + 4 * 24576) * 2] __attribute__((aligned(32))) = {0}; c16_t prach[(4688 + 4 * 24576) * 2] __attribute__((aligned(32))) = {0};
int16_t prachF_tmp[(4688+4*24576)*4*2] __attribute__((aligned(32))) = {0}; int16_t prachF_tmp[(4688+4*24576)*4*2] __attribute__((aligned(32))) = {0};
int16_t Ncp = 0; int Ncp = 0;
int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot; int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot;
fd_occasion = 0; fd_occasion = 0;
...@@ -332,6 +332,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t ...@@ -332,6 +332,12 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
dftlen >>= 1; dftlen >>= 1;
break; break;
case 23040:
// 20 MHz @ 23.04 Ms/s
Ncp = (Ncp * 3) / 4;
dftlen = (dftlen * 3) / 4;
break;
case 30720: case 30720:
// 20, 25, 30 MHz @ 30.72 Ms/s // 20, 25, 30 MHz @ 30.72 Ms/s
break; break;
......
...@@ -343,13 +343,13 @@ typedef struct { ...@@ -343,13 +343,13 @@ typedef struct {
/// \f$\log_2(\max|H_i|^2)\f$ /// \f$\log_2(\max|H_i|^2)\f$
int16_t log2_maxh; int16_t log2_maxh;
/// measured RX power based on DRS /// measured RX power based on DRS
int ulsch_power[8]; uint32_t ulsch_power[8];
/// total signal over antennas /// total signal over antennas
int ulsch_power_tot; uint32_t ulsch_power_tot;
/// measured RX noise power /// measured RX noise power
int ulsch_noise_power[8]; int ulsch_noise_power[8];
/// total noise over antennas /// total noise over antennas
int ulsch_noise_power_tot; uint32_t ulsch_noise_power_tot;
/// \brief llr values. /// \brief llr values.
/// - first index: ? [0..1179743] (hard coded) /// - first index: ? [0..1179743] (hard coded)
int16_t *llr; int16_t *llr;
......
add_library(nr_phy_common src/nr_phy_common.c)
target_include_directories(nr_phy_common PUBLIC inc/)
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __NR_PHY_COMMON__H__
#define __NR_PHY_COMMON__H__
#include "PHY/impl_defs_top.h"
#include "PHY/TOOLS/tools_defs.h"
void freq2time(uint16_t ofdm_symbol_size, int16_t *freq_signal, int16_t *time_signal);
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay);
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb);
#endif
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "nr_phy_common.h"
void freq2time(uint16_t ofdm_symbol_size, int16_t *freq_signal, int16_t *time_signal)
{
const idft_size_idx_t idft_size = get_idft(ofdm_symbol_size);
idft(idft_size, freq_signal, time_signal, 1);
}
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay)
{
freq2time(ofdm_symbol_size, (int16_t *)ls_est, (int16_t *)ch_estimates_time);
int max_pos = delay->delay_max_pos;
int max_val = delay->delay_max_val;
const int sync_pos = 0;
for (int i = 0; i < ofdm_symbol_size; i++) {
int temp = c16amp2(ch_estimates_time[i]) >> 1;
if (temp > max_val) {
max_pos = i;
max_val = temp;
}
}
if (max_pos > ofdm_symbol_size / 2)
max_pos = max_pos - ofdm_symbol_size;
delay->delay_max_pos = max_pos;
delay->delay_max_val = max_val;
delay->est_delay = max_pos - sync_pos;
}
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb)
{
// assume power at AMP is 20dBm
// if gain = 20 (power == 40)
int gain_dB = power_dBm - power_max_dBm;
double gain_lin;
gain_lin = pow(10, .1 * gain_dB);
if ((nb_rb > 0) && (nb_rb <= total_nb_rb)) {
return ((int)(AMP * sqrt(gain_lin * total_nb_rb / (double)nb_rb)));
} else {
LOG_E(PHY, "Illegal nb_rb/N_RB_UL combination (%d/%d)\n", nb_rb, total_nb_rb);
// mac_xface->macphy_exit("");
}
return (0);
}
...@@ -111,8 +111,6 @@ int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); ...@@ -111,8 +111,6 @@ int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
*/ */
void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx); void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx);
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb);
void set_tx_harq_id(NR_UE_ULSCH_t *ulsch, int harq_pid, int slot_tx); void set_tx_harq_id(NR_UE_ULSCH_t *ulsch, int harq_pid, int slot_tx);
int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx); int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx);
......
...@@ -407,23 +407,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, ...@@ -407,23 +407,6 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
return ret; return ret;
} }
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
{
int gain_dB = power_dBm - power_max_dBm;
double gain_lin;
gain_lin = pow(10,.1*gain_dB);
if ((nb_rb >0) && (nb_rb <= N_RB_UL)) {
return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
}
else {
LOG_E(PHY,"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
//mac_xface->macphy_exit("");
}
return(0);
}
int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue, int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
const UE_nr_rxtx_proc_t *proc, const UE_nr_rxtx_proc_t *proc,
int32_t pdcch_est_size, int32_t pdcch_est_size,
......
add_subdirectory(nr_rlc) add_subdirectory(nr_rlc)
add_subdirectory(NR_MAC_UE)
add_library(nr_ue_power_procedures nr_ue_power_procedures.c)
target_link_libraries(nr_ue_power_procedures PUBLIC asn1_nr_rrc ${T_LIB} MAC_NR_COMMON nr_common)
if (ENABLE_TESTS)
add_subdirectory(tests)
endif()
...@@ -227,7 +227,16 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, ...@@ -227,7 +227,16 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch, PUCCH_sched_t *pucch,
fapi_nr_ul_config_pucch_pdu *pucch_pdu); fapi_nr_ul_config_pucch_pdu *pucch_pdu);
int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb); int nr_get_Pcmax(int p_Max,
uint16_t nr_band,
frequency_range_t frequency_range,
int Qm,
bool powerBoostPi2BPSK,
int scs,
int N_RB_UL,
bool is_transform_precoding,
int n_prbs,
int start_prb);
int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame);
......
...@@ -79,7 +79,16 @@ void init_RA(NR_UE_MAC_INST_t *mac, ...@@ -79,7 +79,16 @@ void init_RA(NR_UE_MAC_INST_t *mac,
int n_prbs = get_N_RA_RB(prach_scs, mac->current_UL_BWP->scs); int n_prbs = get_N_RA_RB(prach_scs, mac->current_UL_BWP->scs);
int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP->BWPStart; int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP->BWPStart;
// PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
prach_resources->RA_PCMAX = nr_get_Pcmax(mac, 2, false, prach_scs, cfg->carrier_config.dl_grid_size[prach_scs], true, n_prbs, start_prb); prach_resources->RA_PCMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band,
mac->frequency_range,
2,
false,
prach_scs,
cfg->carrier_config.dl_grid_size[prach_scs],
true,
n_prbs,
start_prb);
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
prach_resources->POWER_OFFSET_2STEP_RA = 0; prach_resources->POWER_OFFSET_2STEP_RA = 0;
......
...@@ -85,16 +85,24 @@ static int get_deltatf(uint16_t nb_of_prbs, ...@@ -85,16 +85,24 @@ static int get_deltatf(uint16_t nb_of_prbs,
// -- Powerclass 3 capable UE (which is default power class unless otherwise stated) // -- Powerclass 3 capable UE (which is default power class unless otherwise stated)
// -- Maximum power reduction (MPR_c) for power class 3 // -- Maximum power reduction (MPR_c) for power class 3
// -- no additional MPR (A_MPR_c) // -- no additional MPR (A_MPR_c)
int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb) int nr_get_Pcmax(int p_Max,
uint16_t nr_band,
frequency_range_t frequency_range,
int Qm,
bool powerBoostPi2BPSK,
int scs,
int N_RB_UL,
bool is_transform_precoding,
int n_prbs,
int start_prb)
{ {
int nr_band = mac->nr_band; if (frequency_range == FR1) {
if(mac->frequency_range == FR1) { // TODO configure P-MAX from the upper layers according to 38.331
//TODO configure P-MAX from the upper layers according to 38.331
int p_powerclass = 23; // dBm assuming poweclass 3 UE int p_powerclass = 23; // dBm assuming poweclass 3 UE
int p_emax = mac->p_Max != INT_MIN ? mac->p_Max : p_powerclass; int p_emax = p_Max != INT_MIN ? p_Max : p_powerclass;
int delta_P_powerclass = 0; // for powerclass 2 needs to be changed int delta_P_powerclass = 0; // for powerclass 2 needs to be changed
if(mac->p_Max && Qm == 1 && powerBoostPi2BPSK && (nr_band == 40 || nr_band == 41 || nr_band == 77 || nr_band == 78 || nr_band == 79)) { if (p_Max && Qm == 1 && powerBoostPi2BPSK
&& (nr_band == 40 || nr_band == 41 || nr_band == 77 || nr_band == 78 || nr_band == 79)) {
p_emax += 3; p_emax += 3;
delta_P_powerclass -= 3; delta_P_powerclass -= 3;
} }
...@@ -103,54 +111,52 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, ...@@ -103,54 +111,52 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs,
int delta_T_IB = 0; int delta_T_IB = 0;
// TODO in case of band 41 and PRB allocation within 4MHz of the upper or lower limit of the band -> delta_TC = 1.5 // TODO in case of band 41 and PRB allocation within 4MHz of the upper or lower limit of the band -> delta_TC = 1.5
if(nr_band == 41) if (nr_band == 41)
LOG_E(NR_MAC, "Need to implement delta_TC for band 41\n"); LOG_E(NR_MAC, "Need to implement delta_TC for band 41\n");
int delta_TC = 0; int delta_TC = 0;
float MPR = 0; float MPR = 0;
frame_type_t frame_type = get_frame_type(nr_band, scs); frame_type_t frame_type = get_frame_type(nr_band, scs);
if(compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) { if (compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) {
int rb_low = (n_prbs / 2) > 1 ? (n_prbs / 2) : 1; int rb_low = (n_prbs / 2) > 1 ? (n_prbs / 2) : 1;
int rb_high = N_RB_UL - rb_low - n_prbs; int rb_high = N_RB_UL - rb_low - n_prbs;
bool is_inner_rb = start_prb >= rb_low && start_prb <= rb_high && n_prbs <= ((N_RB_UL / 2) + (N_RB_UL & 1)); bool is_inner_rb = start_prb >= rb_low && start_prb <= rb_high && n_prbs <= ((N_RB_UL / 2) + (N_RB_UL & 1));
// Table 6.2.2-1 in 38.101 // Table 6.2.2-1 in 38.101
switch (Qm) { switch (Qm) {
case 1 : case 1:
AssertFatal(false, "MPR for Pi/2 BPSK not implemented yet\n"); AssertFatal(false, "MPR for Pi/2 BPSK not implemented yet\n");
break; break;
case 2 : case 2:
if (is_transform_precoding) { if (is_transform_precoding) {
if(!is_inner_rb) if (!is_inner_rb)
MPR = 1; MPR = 1;
} } else {
else { if (is_inner_rb)
if(is_inner_rb)
MPR = 1.5; MPR = 1.5;
else else
MPR = 3; MPR = 3;
} }
break; break;
case 4 : case 4:
if (is_transform_precoding) { if (is_transform_precoding) {
if(is_inner_rb) if (is_inner_rb)
MPR = 1; MPR = 1;
else else
MPR = 2; MPR = 2;
} } else {
else { if (is_inner_rb)
if(is_inner_rb)
MPR = 2; MPR = 2;
else else
MPR = 3; MPR = 3;
} }
break; break;
case 6 : case 6:
if (is_transform_precoding) if (is_transform_precoding)
MPR = 2.5; MPR = 2.5;
else else
MPR = 3.5; MPR = 3.5;
break; break;
case 8 : case 8:
if (is_transform_precoding) if (is_transform_precoding)
MPR = 4.5; MPR = 4.5;
else else
...@@ -170,12 +176,12 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, ...@@ -170,12 +176,12 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs,
if (P_MPR > total_reduction) if (P_MPR > total_reduction)
total_reduction = P_MPR; total_reduction = P_MPR;
int pcmax_high, pcmax_low; int pcmax_high, pcmax_low;
if(mac->p_Max) { if (p_Max) {
pcmax_high = p_emax < (p_powerclass - delta_P_powerclass) ? p_emax : (p_powerclass - delta_P_powerclass); pcmax_high = p_emax < (p_powerclass - delta_P_powerclass) ? p_emax : (p_powerclass - delta_P_powerclass);
pcmax_low = (p_emax - delta_TC) < (p_powerclass - delta_P_powerclass - total_reduction) ? pcmax_low = (p_emax - delta_TC) < (p_powerclass - delta_P_powerclass - total_reduction)
(p_emax - delta_TC) : (p_powerclass - delta_P_powerclass - total_reduction); ? (p_emax - delta_TC)
} : (p_powerclass - delta_P_powerclass - total_reduction);
else { } else {
pcmax_high = p_powerclass - delta_P_powerclass; pcmax_high = p_powerclass - delta_P_powerclass;
pcmax_low = p_powerclass - delta_P_powerclass - total_reduction; pcmax_low = p_powerclass - delta_P_powerclass - total_reduction;
} }
...@@ -183,8 +189,7 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, ...@@ -183,8 +189,7 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs,
int pcmax = (pcmax_low + pcmax_high) / 2; int pcmax = (pcmax_low + pcmax_high) / 2;
LOG_D(MAC, "Configured maximum output power: %d dBm <= PCMAX %d dBm <= %d dBm \n", pcmax_low, pcmax, pcmax_high); LOG_D(MAC, "Configured maximum output power: %d dBm <= PCMAX %d dBm <= %d dBm \n", pcmax_low, pcmax, pcmax_high);
return pcmax; return pcmax;
} } else {
else {
// FR2 TODO it is even more complex because it is radiated power // FR2 TODO it is even more complex because it is radiated power
return 23; return 23;
} }
...@@ -294,7 +299,16 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -294,7 +299,16 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
// PUCCH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) // PUCCH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
// TODO: P_CMAX for format 2 // TODO: P_CMAX for format 2
int P_CMAX = nr_get_Pcmax(mac, 2, false, mac->current_UL_BWP->scs, mac->current_UL_BWP->BWPSize, true, 1, start_prb); int P_CMAX = nr_get_Pcmax(mac->p_Max,
mac->nr_band,
mac->frequency_range,
2,
false,
mac->current_UL_BWP->scs,
mac->current_UL_BWP->BWPSize,
true,
1,
start_prb);
int P_CMIN = -40; // TODO: minimum TX power, possibly 38.101-1 6.3.1 int P_CMIN = -40; // TODO: minimum TX power, possibly 38.101-1 6.3.1
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
...@@ -358,3 +372,27 @@ static int get_deltatf(uint16_t nb_of_prbs, ...@@ -358,3 +372,27 @@ static int get_deltatf(uint16_t nb_of_prbs,
} }
return DELTA_TF; return DELTA_TF;
} }
// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16
// Assumptions:
// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE
// Measurement units:
// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm)
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm)
{
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
int referenceSignalPower = cfg->ssb_config.ss_pbch_power;
//TODO improve PL measurements. Probably not correct as it is.
int16_t pathloss = (int16_t)(referenceSignalPower - ssb_rsrp_dBm);
LOG_D(NR_MAC, "pathloss %d dB, referenceSignalPower %d dBm/RE (%f mW), RSRP %d dBm (%f mW)\n",
pathloss,
referenceSignalPower,
pow(10, referenceSignalPower/10),
ssb_rsrp_dBm,
pow(10, ssb_rsrp_dBm/10));
return pathloss;
}
...@@ -1368,7 +1368,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, ...@@ -1368,7 +1368,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac,
// if temp_dai is less or equal than cumulative highest dai for given slot // if temp_dai is less or equal than cumulative highest dai for given slot
// it's an indication dai was reset due to modulo 4 operation // it's an indication dai was reset due to modulo 4 operation
if (temp_dai <= highest_dai) { if (temp_dai <= highest_dai) {
int mod4_count = (highest_dai / 4) + 1; // to take into account how many times dai wrapped up (modulo 4) int mod4_count = (highest_dai + 1) / 4; // to take into account how many times dai wrapped up (modulo 4)
current_harq->dai_cumul += (mod4_count * 4); current_harq->dai_cumul += (mod4_count * 4);
} }
LOG_D(NR_MAC, LOG_D(NR_MAC,
...@@ -3945,26 +3945,3 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d ...@@ -3945,26 +3945,3 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
return; return;
} }
// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16
// Assumptions:
// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE
// Measurement units:
// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm)
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm)
{
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
int referenceSignalPower = cfg->ssb_config.ss_pbch_power;
//TODO improve PL measurements. Probably not correct as it is.
int16_t pathloss = (int16_t)(referenceSignalPower - ssb_rsrp_dBm);
LOG_D(NR_MAC, "pathloss %d dB, referenceSignalPower %d dBm/RE (%f mW), RSRP %d dBm (%f mW)\n",
pathloss,
referenceSignalPower,
pow(10, referenceSignalPower/10),
ssb_rsrp_dBm,
pow(10, ssb_rsrp_dBm/10));
return pathloss;
}
...@@ -1768,13 +1768,25 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac) ...@@ -1768,13 +1768,25 @@ static void build_ssb_list(NR_UE_MAC_INST_t *mac)
uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[ssb_index / 32].ssb_mask; uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[ssb_index / 32].ssb_mask;
// check if if current SSB is transmitted // check if if current SSB is transmitted
if ((curr_mask >> (31 - (ssb_index % 32))) & 0x01) { if ((curr_mask >> (31 - (ssb_index % 32))) & 0x01) {
ssb_list->nb_ssb_per_index[ssb_index]=ssb_list->nb_tx_ssb; ssb_list->nb_ssb_per_index[ssb_index] = ssb_list->nb_tx_ssb;
ssb_list->nb_tx_ssb++; ssb_list->nb_tx_ssb++;
} }
else
ssb_list->nb_ssb_per_index[ssb_index] = -1;
} }
ssb_list->tx_ssb = calloc(ssb_list->nb_tx_ssb, sizeof(*ssb_list->tx_ssb)); ssb_list->tx_ssb = calloc(ssb_list->nb_tx_ssb, sizeof(*ssb_list->tx_ssb));
} }
static int get_ssb_idx_from_list(ssb_list_info_t *ssb_list, int idx)
{
for (int ssb_index = 0; ssb_index < MAX_NB_SSB; ssb_index++) {
if (ssb_list->nb_ssb_per_index[ssb_index] == idx)
return ssb_index;
}
AssertFatal(false, "Couldn't find SSB index in SSB list\n");
return 0;
}
// Map the transmitted SSBs to the ROs and create the association pattern according to the config // Map the transmitted SSBs to the ROs and create the association pattern according to the config
static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
{ {
...@@ -1863,7 +1875,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) ...@@ -1863,7 +1875,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
// WIP: only one possible association period so the starting PRACH configuration period is automatically 0 // WIP: only one possible association period so the starting PRACH configuration period is automatically 0
// WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO // WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO
// this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule
int ssb_idx = 0; int idx = 0;
bool done = false; bool done = false;
for (int i = 0; i < prach_period->nb_of_prach_conf_period && !done; i++, prach_configuration_period_idx++) { for (int i = 0; i < prach_period->nb_of_prach_conf_period && !done; i++, prach_configuration_period_idx++) {
prach_period->prach_conf_period_list[i] = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx]; prach_period->prach_conf_period_list[i] = &prach_assoc_pattern->prach_conf_period_list[prach_configuration_period_idx];
...@@ -1880,9 +1892,10 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) ...@@ -1880,9 +1892,10 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
// Go through the list of transmitted SSBs and map the required amount of SSBs to this RO // Go through the list of transmitted SSBs and map the required amount of SSBs to this RO
// WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO // WIP: For the moment, only map each SSB idx once per association period if configuration is multiple SSBs per RO
// this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule // this is true if no PRACH occasions are conflicting with SSBs nor TDD_UL_DL_ConfigurationCommon schedule
for (; ssb_idx < ssb_list->nb_tx_ssb; ssb_idx++) { for (; idx < ssb_list->nb_tx_ssb; idx++) {
ssb_info_t *tx_ssb = ssb_list->tx_ssb + ssb_idx; ssb_info_t *tx_ssb = ssb_list->tx_ssb + idx;
// Map only the transmitted ssb_idx // Map only the transmitted ssb_idx
int ssb_idx = get_ssb_idx_from_list(ssb_list, idx);
ro_p->mapped_ssb_idx[ro_p->nb_mapped_ssb] = ssb_idx; ro_p->mapped_ssb_idx[ro_p->nb_mapped_ssb] = ssb_idx;
ro_p->nb_mapped_ssb++; ro_p->nb_mapped_ssb++;
AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1, AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1,
...@@ -1903,11 +1916,11 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) ...@@ -1903,11 +1916,11 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
tx_ssb->nb_mapped_ro); tx_ssb->nb_mapped_ro);
// If all the required SSBs are mapped to this RO, exit the loop of SSBs // If all the required SSBs are mapped to this RO, exit the loop of SSBs
if (ro_p->nb_mapped_ssb == ssb_rach_ratio) { if (ro_p->nb_mapped_ssb == ssb_rach_ratio) {
ssb_idx++; idx++;
break; break;
} }
} }
done = MAX_NB_SSB == ssb_idx; done = MAX_NB_SSB == idx;
} }
} }
} }
...@@ -1919,8 +1932,8 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) ...@@ -1919,8 +1932,8 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
for (prach_association_period_t *prach_period = prach_assoc_pattern->prach_association_period_list; prach_period < end; for (prach_association_period_t *prach_period = prach_assoc_pattern->prach_association_period_list; prach_period < end;
prach_period++) { prach_period++) {
// Go through the list of transmitted SSBs // Go through the list of transmitted SSBs
for (int ssb_idx = 0; ssb_idx < ssb_list->nb_tx_ssb; ssb_idx++) { for (int idx = 0; idx < ssb_list->nb_tx_ssb; idx++) {
ssb_info_t *tx_ssb = ssb_list->tx_ssb + ssb_idx; ssb_info_t *tx_ssb = ssb_list->tx_ssb + idx;
uint8_t nb_mapped_ro_in_association_period=0; // Reset the nb of mapped ROs for the new SSB index uint8_t nb_mapped_ro_in_association_period=0; // Reset the nb of mapped ROs for the new SSB index
bool done = false; bool done = false;
// Map all the required ROs to this SSB // Map all the required ROs to this SSB
...@@ -1936,6 +1949,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) ...@@ -1936,6 +1949,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac)
for (int ro_in_freq = 0; ro_in_freq < slot_map->nb_of_prach_occasion_in_freq && !done; ro_in_freq++) { for (int ro_in_freq = 0; ro_in_freq < slot_map->nb_of_prach_occasion_in_freq && !done; ro_in_freq++) {
prach_occasion_info_t *ro_p = prach_occasion_info_t *ro_p =
slot_map->prach_occasion + ro_in_time * slot_map->nb_of_prach_occasion_in_freq + ro_in_freq; slot_map->prach_occasion + ro_in_time * slot_map->nb_of_prach_occasion_in_freq + ro_in_freq;
int ssb_idx = get_ssb_idx_from_list(ssb_list, idx);
ro_p->mapped_ssb_idx[0] = ssb_idx; ro_p->mapped_ssb_idx[0] = ssb_idx;
ro_p->nb_mapped_ssb = 1; ro_p->nb_mapped_ssb = 1;
AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1, AssertFatal(MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN > tx_ssb->nb_mapped_ro + 1,
......
add_executable(test_nr_ue_power_procedures
test_nr_ue_power_procedures.cpp)
target_link_libraries(test_nr_ue_power_procedures PRIVATE nr_ue_power_procedures GTest::gtest minimal_lib)
add_dependencies(tests test_nr_ue_power_procedures)
add_test(NAME test_nr_ue_power_procedures
COMMAND ./test_nr_ue_power_procedures)
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "gtest/gtest.h"
extern "C" {
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "executables/softmodem-common.h"
uint64_t get_softmodem_optmask(void) {return 0;}
static softmodem_params_t softmodem_params;
softmodem_params_t *get_softmodem_params(void) {
return &softmodem_params;
}
}
#include <cstdio>
#include "common/utils/LOG/log.h"
TEST(power_procedures_fr1, test_prach_max_tx_power_mpr)
{
// Inner PRB, MPR = 1.5
int prb_start = 4;
int N_RB_UL = 51; // 10Mhz
EXPECT_EQ(22, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start));
// Outer PRB, MPR = 3
prb_start = 0;
EXPECT_EQ(21, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start));
// Channel bandwidth conditon not met, no MPR
N_RB_UL = 106;
EXPECT_EQ(23, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start));
}
TEST(power_procedures_fr1, test_not_implemented)
{
int N_RB_UL = 51;
EXPECT_DEATH(nr_get_Pcmax(23, 20, FR1, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet");
}
int main(int argc, char** argv)
{
logInit();
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
...@@ -65,6 +65,7 @@ static void schedule_ssb(frame_t frame, ...@@ -65,6 +65,7 @@ static void schedule_ssb(frame_t frame,
dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t); dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n"); AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n");
AssertFatal(*scc->physCellId < 1008 && *scc->physCellId >=0, "5G physicall cell id out of range: %ld\n", *scc->physCellId);
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId; dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0; dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb; dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb;
......
This diff is collapsed.
...@@ -89,11 +89,12 @@ typedef struct { ...@@ -89,11 +89,12 @@ typedef struct {
uint8_t kseaf[32]; uint8_t kseaf[32];
uint8_t kamf[32]; uint8_t kamf[32];
uint8_t knas_int[16]; uint8_t knas_int[16];
uint8_t knas_enc[16];
uint8_t res[16]; uint8_t res[16];
uint8_t rand[16]; uint8_t rand[16];
uint8_t kgnb[32]; uint8_t kgnb[32];
uint32_t mm_counter; uint32_t nas_count_ul;
uint32_t sm_counter; uint32_t nas_count_dl;
} ue_sa_security_key_t; } ue_sa_security_key_t;
typedef struct { typedef struct {
......
...@@ -88,25 +88,36 @@ static uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c) ...@@ -88,25 +88,36 @@ static uint64_t MUL64(uint64_t V, uint64_t P, uint64_t c)
return result; return result;
} }
/* mask32bit. /* read a big endian uint64_t at given address (potentially not 64-bits aligned)
* Input n: an integer in 1-32. * don't read more than 'available_bytes'
* Output : a 32 bit mask. * (use 0 if no byte to read)
* Prepares a 32 bit mask with required number of 1 bits on the MSB side. * (note: the compiler will optimize this, no need to do better)
*/ */
static uint32_t mask32bit(int n) static inline uint64_t U64(uint8_t *p, int available_bytes)
{ {
uint32_t mask=0x0; uint64_t a = 0;
uint64_t b = 0;
if ( n%32 == 0 ) uint64_t c = 0;
return 0xffffffff; uint64_t d = 0;
uint64_t e = 0;
while (n--) uint64_t f = 0;
mask = (mask>>1) ^ 0x80000000; uint64_t g = 0;
uint64_t h = 0;
switch (available_bytes) {
case 8: h = p[7]; /* falltrough */
case 7: g = p[6]; /* falltrough */
case 6: f = p[5]; /* falltrough */
case 5: e = p[4]; /* falltrough */
case 4: d = p[3]; /* falltrough */
case 3: c = p[2]; /* falltrough */
case 2: b = p[1]; /* falltrough */
case 1: a = p[0];
}
return mask; return (a << (32+24)) | (b << (32+16)) | (c << (32+8)) | (d << 32)
| (e << 24) | (f << 16) | (g << 8) | h;
} }
/*! /*!
* @brief Create integrity cmac t for a given message. * @brief Create integrity cmac t for a given message.
* @param[in] stream_cipher Structure containing various variables to setup encoding * @param[in] stream_cipher Structure containing various variables to setup encoding
...@@ -125,11 +136,8 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o ...@@ -125,11 +136,8 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o
uint64_t c; uint64_t c;
uint64_t M_D_2; uint64_t M_D_2;
int rem_bits; int rem_bits;
uint32_t mask = 0;
uint32_t *message;
uint8_t *key = (uint8_t *)stream_cipher->context; uint8_t *key = (uint8_t *)stream_cipher->context;
message = (uint32_t*)stream_cipher->message; /* To operate 32 bit message internally. */
/* Load the Integrity Key for SNOW3G initialization as in section 4.4. */ /* Load the Integrity Key for SNOW3G initialization as in section 4.4. */
memcpy(K+3,key+0,4); /*K[3] = key[0]; we assume memcpy(K+3,key+0,4); /*K[3] = key[0]; we assume
K[3]=key[0]||key[1]||...||key[31] , with key[0] the K[3]=key[0]||key[1]||...||key[31] , with key[0] the
...@@ -181,11 +189,14 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o ...@@ -181,11 +189,14 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o
EVAL = 0; EVAL = 0;
c = 0x1b; c = 0x1b;
AssertFatal(stream_cipher->blength % 8 == 0, "unsupported buffer length\n");
uint8_t *message = stream_cipher->message;
/* for 0 <= i <= D-3 */ /* for 0 <= i <= D-3 */
for (i=0; i<D-2; i++) { for (i=0; i<D-2; i++) {
V = EVAL ^ ( (uint64_t)hton_int32(message[2*i]) << 32 | (uint64_t)hton_int32(message[2*i+1]) ); V = EVAL ^ U64(&message[4 * 2*i], 8);
EVAL = MUL64(V,P,c); EVAL = MUL64(V,P,c);
//printf ("Mi: %16X %16X\tEVAL: %16lX\n",hton_int32(message[2*i]),hton_int32(message[2*i+1]), EVAL);
} }
/* for D-2 */ /* for D-2 */
...@@ -194,14 +205,7 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o ...@@ -194,14 +205,7 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o
if (rem_bits == 0) if (rem_bits == 0)
rem_bits = 64; rem_bits = 64;
mask = mask32bit(rem_bits%32); M_D_2 = U64(&message[4 * (2*(D-2))], rem_bits/8);
if (rem_bits > 32) {
M_D_2 = ( (uint64_t) hton_int32(message[2*(D-2)]) << 32 ) |
(uint64_t) (hton_int32(message[2*(D-2)+1]) & mask);
} else {
M_D_2 = ( (uint64_t) hton_int32(message[2*(D-2)]) & mask) << 32 ;
}
V = EVAL ^ M_D_2; V = EVAL ^ M_D_2;
EVAL = MUL64(V,P,c); EVAL = MUL64(V,P,c);
......
...@@ -195,6 +195,8 @@ typedef struct split7_config { ...@@ -195,6 +195,8 @@ typedef struct split7_config {
struct { struct {
symbol_direction_t sym_dir[14]; symbol_direction_t sym_dir[14];
} slot_dirs[160]; } slot_dirs[160];
/*! this is the exponent in 2^X for the FFT size */
uint16_t fftSize;
} split7_config_t; } split7_config_t;
/*! \brief RF frontend parameters set by application */ /*! \brief RF frontend parameters set by application */
......
# we need at least gcc-11 to build xran, so let's enforce it here
# (because xran might not check it, and we have control here)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0
OR CMAKE_C_COMPILER_VERSION VERSION_LESS 11.0)
message(FATAL_ERROR "you need to have at least gcc/g++-11 to use 7.2 FHI through xran")
endif()
# use env var PKG_CONFIG_PATH to override paths to libdpdk.pc # use env var PKG_CONFIG_PATH to override paths to libdpdk.pc
pkg_check_modules(dpdk REQUIRED libdpdk) pkg_check_modules(dpdk REQUIRED libdpdk)
pkg_check_modules(numa REQUIRED numa) pkg_check_modules(numa REQUIRED numa)
find_package(xran 5.1.2 EXACT REQUIRED) # E release -> 5 find_package(xran 5.1.3 EXACT REQUIRED) # E release -> 5
# Ignore xran-specific warning: we don't care/can't change the following warning, so suppress # Ignore xran-specific warning: we don't care/can't change the following warning, so suppress
# alignment 1 of 'struct XYZ' is less than 2 # alignment 1 of 'struct XYZ' is less than 2
......
...@@ -729,7 +729,7 @@ static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame ...@@ -729,7 +729,7 @@ static bool set_fh_frame_config(const openair0_config_t *oai0, struct xran_frame
return true; return true;
} }
static bool set_fh_ru_config(const paramdef_t *rup, int nru, struct xran_ru_config *ru_config) static bool set_fh_ru_config(const paramdef_t *rup, uint16_t fftSize, int nru, struct xran_ru_config *ru_config)
{ {
ru_config->xranTech = XRAN_RAN_5GNR; ru_config->xranTech = XRAN_RAN_5GNR;
ru_config->xranCat = XRAN_CATEGORY_A; ru_config->xranCat = XRAN_CATEGORY_A;
...@@ -740,7 +740,8 @@ static bool set_fh_ru_config(const paramdef_t *rup, int nru, struct xran_ru_conf ...@@ -740,7 +740,8 @@ static bool set_fh_ru_config(const paramdef_t *rup, int nru, struct xran_ru_conf
ru_config->iqWidth_PRACH = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH_PRACH)->uptr; ru_config->iqWidth_PRACH = *gpd(rup, nru, ORAN_RU_CONFIG_IQWIDTH_PRACH)->uptr;
AssertFatal(ru_config->iqWidth_PRACH <= 16, "IQ Width for PRACH cannot be > 16!\n"); AssertFatal(ru_config->iqWidth_PRACH <= 16, "IQ Width for PRACH cannot be > 16!\n");
ru_config->compMeth_PRACH = ru_config->iqWidth_PRACH < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE; ru_config->compMeth_PRACH = ru_config->iqWidth_PRACH < 16 ? XRAN_COMPMETHOD_BLKFLOAT : XRAN_COMPMETHOD_NONE;
ru_config->fftSize = *gpd(rup, nru, ORAN_RU_CONFIG_FFT_SIZE)->uptr; AssertFatal(fftSize > 0, "FFT size cannot be 0\n");
ru_config->fftSize = fftSize;
ru_config->byteOrder = XRAN_NE_BE_BYTE_ORDER; ru_config->byteOrder = XRAN_NE_BE_BYTE_ORDER;
ru_config->iqOrder = XRAN_I_Q_ORDER; ru_config->iqOrder = XRAN_I_Q_ORDER;
ru_config->xran_max_frame = 0; ru_config->xran_max_frame = 0;
...@@ -779,6 +780,7 @@ bool set_fh_config(int ru_idx, int num_rus, const openair0_config_t *oai0, struc ...@@ -779,6 +780,7 @@ bool set_fh_config(int ru_idx, int num_rus, const openair0_config_t *oai0, struc
DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]); DevAssert(oai0->rx_freq[0] == oai0->rx_freq[i]);
DevAssert(oai0->nr_band > 0); DevAssert(oai0->nr_band > 0);
DevAssert(oai0->nr_scs_for_raster > 0); DevAssert(oai0->nr_scs_for_raster > 0);
AssertFatal(oai0->threequarter_fs == 0, "cannot use three-quarter sampling with O-RAN 7.2 split\n");
// we simply assume that the loading process provides function to_nrarfcn() // we simply assume that the loading process provides function to_nrarfcn()
// to calculate the ARFCN numbers from frequency. That is not clean, but the // to calculate the ARFCN numbers from frequency. That is not clean, but the
...@@ -869,7 +871,7 @@ bool set_fh_config(int ru_idx, int num_rus, const openair0_config_t *oai0, struc ...@@ -869,7 +871,7 @@ bool set_fh_config(int ru_idx, int num_rus, const openair0_config_t *oai0, struc
return false; return false;
if (!set_fh_frame_config(oai0, &fh_config->frame_conf)) if (!set_fh_frame_config(oai0, &fh_config->frame_conf))
return false; return false;
if (!set_fh_ru_config(rup, nru, &fh_config->ru_conf)) if (!set_fh_ru_config(rup, oai0->split7.fftSize, nru, &fh_config->ru_conf))
return false; return false;
fh_config->bbdev_enc = NULL; fh_config->bbdev_enc = NULL;
......
...@@ -123,6 +123,14 @@ static struct xran_prb_map get_xran_prb_map_ul(const struct xran_fh_config *f) ...@@ -123,6 +123,14 @@ static struct xran_prb_map get_xran_prb_map_ul(const struct xran_fh_config *f)
return prbmap; return prbmap;
} }
static uint32_t next_power_2(uint32_t num)
{
uint32_t power = 2;
while (power < num)
power <<= 1;
return power;
}
static uint32_t oran_allocate_uplane_buffers( static uint32_t oran_allocate_uplane_buffers(
void *instHandle, void *instHandle,
struct xran_buffer_list list[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN], struct xran_buffer_list list[XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN],
...@@ -132,7 +140,10 @@ static uint32_t oran_allocate_uplane_buffers( ...@@ -132,7 +140,10 @@ static uint32_t oran_allocate_uplane_buffers(
{ {
xran_status_t status; xran_status_t status;
uint32_t pool; uint32_t pool;
uint32_t numBufs = XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT; // we need at least XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT
// buffers, but xran_bm_init() uses rte_pktmbuf_pool_create() which
// recommends to use a power of two for the buffers
uint32_t numBufs = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT);
status = xran_bm_init(instHandle, &pool, numBufs, bufSize); status = xran_bm_init(instHandle, &pool, numBufs, bufSize);
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status); AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, pool, numBufs, bufSize); printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, pool, numBufs, bufSize);
...@@ -211,14 +222,14 @@ static void oran_allocate_cplane_buffers(void *instHandle, ...@@ -211,14 +222,14 @@ static void oran_allocate_cplane_buffers(void *instHandle,
{ {
xran_status_t status; xran_status_t status;
uint32_t poolSec; uint32_t poolSec;
uint32_t numBufsSec = XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT * sect * XRAN_MAX_FRAGMENT; uint32_t numBufsSec = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT * sect * XRAN_MAX_FRAGMENT);
uint32_t bufSizeSec = sizeof(struct xran_section_desc); uint32_t bufSizeSec = sizeof(struct xran_section_desc);
status = xran_bm_init(instHandle, &poolSec, numBufsSec, bufSizeSec); status = xran_bm_init(instHandle, &poolSec, numBufsSec, bufSizeSec);
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status); AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, poolSec, numBufsSec, bufSizeSec); printf("xran_bm_init() hInstance %p poolIdx %u elements %u size %u\n", instHandle, poolSec, numBufsSec, bufSizeSec);
uint32_t poolPrb; uint32_t poolPrb;
uint32_t numBufsPrb = XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT; uint32_t numBufsPrb = next_power_2(XRAN_N_FE_BUF_LEN * ant * XRAN_NUM_OF_SYMBOL_PER_SLOT);
uint32_t bufSizePrb = size_of_prb_map; uint32_t bufSizePrb = size_of_prb_map;
status = xran_bm_init(instHandle, &poolPrb, numBufsPrb, bufSizePrb); status = xran_bm_init(instHandle, &poolPrb, numBufsPrb, bufSizePrb);
AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status); AssertFatal(XRAN_STATUS_SUCCESS == status, "Failed at xran_bm_init(), status %d\n", status);
......
...@@ -91,13 +91,11 @@ ...@@ -91,13 +91,11 @@
#define ORAN_RU_CONFIG_IQWIDTH "iq_width" #define ORAN_RU_CONFIG_IQWIDTH "iq_width"
#define ORAN_RU_CONFIG_IQWIDTH_PRACH "iq_width_prach" #define ORAN_RU_CONFIG_IQWIDTH_PRACH "iq_width_prach"
#define ORAN_RU_CONFIG_FFT_SIZE "fft_size"
// clang-format off // clang-format off
#define ORAN_RU_DESC {\ #define ORAN_RU_DESC {\
{ORAN_RU_CONFIG_IQWIDTH, "sample IQ width (16=uncompressed)\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=16, TYPE_UINT8, 0}, \ {ORAN_RU_CONFIG_IQWIDTH, "sample IQ width (16=uncompressed)\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=16, TYPE_UINT8, 0}, \
{ORAN_RU_CONFIG_IQWIDTH_PRACH, "PRACH sample IQ width (16=uncompressed)\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=16, TYPE_UINT8, 0}, \ {ORAN_RU_CONFIG_IQWIDTH_PRACH, "PRACH sample IQ width (16=uncompressed)\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=16, TYPE_UINT8, 0}, \
{ORAN_RU_CONFIG_FFT_SIZE, "Size of FFT at RU\n", PARAMFLAG_MANDATORY, .u8ptr=NULL, .defuintval=12, TYPE_UINT8, 0}, \
} }
// clang-format on // clang-format on
......
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#include "common/utils/threadPool/thread-pool.h" #include "common/utils/threadPool/thread-pool.h"
#include "oaioran.h" #include "oaioran.h"
// include the following file for VERSIONX, version of xran lib, to print it during
// startup. Only relevant for printing, if it ever makes problem, remove this
// line and the use of VERSIONX further below. It is relative to phy/fhi_lib/lib/api
#include "../../app/src/common.h"
typedef struct { typedef struct {
eth_state_t e; eth_state_t e;
rru_config_msg_type_t last_msg; rru_config_msg_type_t last_msg;
...@@ -309,7 +314,7 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d ...@@ -309,7 +314,7 @@ __attribute__((__visibility__("default"))) int transport_init(openair0_device *d
eth->last_msg = (rru_config_msg_type_t)-1; eth->last_msg = (rru_config_msg_type_t)-1;
printf("ORAN: %s\n", __FUNCTION__); LOG_I(HW, "Initializing O-RAN 7.2 FH interface through xran library (compiled against headers of %s)\n", VERSIONX);
initNotifiedFIFO(&oran_sync_fifo); initNotifiedFIFO(&oran_sync_fifo);
eth->oran_priv = oai_oran_initialize(openair0_cfg); eth->oran_priv = oai_oran_initialize(openair0_cfg);
......
...@@ -295,7 +295,6 @@ fhi_72 = { ...@@ -295,7 +295,6 @@ fhi_72 = {
ru_config = { ru_config = {
iq_width = 9; iq_width = 9;
iq_width_prach = 9; iq_width_prach = 9;
fft_size = 12;
}; };
prach_config = { prach_config = {
eAxC_offset = 4; eAxC_offset = 4;
......
...@@ -288,7 +288,6 @@ fhi_72 = { ...@@ -288,7 +288,6 @@ fhi_72 = {
ru_config = { ru_config = {
iq_width = 9; iq_width = 9;
iq_width_prach = 9; iq_width_prach = 9;
fft_size = 12;
}; };
prach_config = { prach_config = {
eAxC_offset = 4; eAxC_offset = 4;
......
...@@ -288,7 +288,6 @@ fhi_72 = { ...@@ -288,7 +288,6 @@ fhi_72 = {
ru_config = { ru_config = {
iq_width = 9; iq_width = 9;
iq_width_prach = 9; iq_width_prach = 9;
fft_size = 12;
}; };
prach_config = { prach_config = {
eAxC_offset = 4; eAxC_offset = 4;
......
...@@ -286,7 +286,6 @@ fhi_72 = { ...@@ -286,7 +286,6 @@ fhi_72 = {
ru_config = { ru_config = {
iq_width = 9; iq_width = 9;
iq_width_prach = 9; iq_width_prach = 9;
fft_size = 12;
}; };
prach_config = { prach_config = {
eAxC_offset = 4; eAxC_offset = 4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment