Compare commits

..

26 Commits

Author SHA1 Message Date
Karim Boutiba
7b496cbcfc revert commit aa6c8f1550 2026-04-16 15:11:29 +02:00
Karim Boutiba
34fbf47f05 Avoid segfault when PUCCH resource id out of index 2026-04-16 14:53:01 +02:00
Karim Boutiba
d4ce0a6a80 add beam index to periodic UE log 2026-04-16 13:45:05 +02:00
francescomani
32f11998c8 improve handling of UE context modification confirm/refuse 2026-04-16 11:26:01 +02:00
Karim Boutiba
1fcf919a93 Revert "Merge remote-tracking branch 'origin/fix_3870' into microamp_multi_beams"
This reverts commit cf85d8a8eb, reversing
changes made to 7e55ac311f.
2026-04-16 10:59:09 +02:00
Karim Boutiba
cf85d8a8eb Merge remote-tracking branch 'origin/fix_3870' into microamp_multi_beams 2026-04-16 10:29:27 +02:00
francescomani
7e55ac311f option to change TDA in case of MUX23 2026-04-16 10:11:56 +02:00
francescomani
5d795aa701 call functions to configure TDA in nr_mac_config_scc
this is done to be able to set DL TDA after calling config_sched_ctrlSIB1 and knowing the potential configuration of commonControlResourceSet for MUX pattern 3 which duration doesn't depend on the BWP size
2026-04-16 10:11:28 +02:00
Mario Joa-Ng
169eb9a134 Fix CSI-RS slot which should not be SSB_index / 2. 2026-04-16 10:01:51 +02:00
Mario Joa-Ng
15c10866f7 set ssb_index using get_ssbidx_from_beam() instead of using common_channels[0].ssb_index[] which was used in set_analog_beamforming = 1 previously 2026-04-16 09:59:57 +02:00
Mario Joa-Ng
c0ce54c3b8 handle start symbol on non-zeroth symbol for SIB for mux 3. 2026-04-16 09:58:56 +02:00
Mario Joa-Ng
0eae3ab55e Use reserve arrays so that MSG3 and PUSCH that are scheduled in advance will check if the slot which will be used by periodic UL signal (SR, SRS, CSI reports) 2026-04-16 09:55:44 +02:00
Mario Joa-Ng
9cd15a9c11 Get beam loc in beam_weights and use it to assign the corresponding uplink slot for SR. 2026-04-16 09:49:47 +02:00
Karim Boutiba
aa6c8f1550 temporary fixing SR slot to avoid bug 2026-04-16 09:46:19 +02:00
Mario Joa-Ng
b9d10b32be Limit the number of uplink slot dedicated to SR to 16 to allow enough slots for other UL signals when SSB >= 16 2026-04-15 16:20:29 +02:00
Mario Joa-Ng
a0245e324d Configure periodic CSI reports, periodic SRS and periodic SR according to userid on different non-PRACH uplink slots to avoid beam allocation conflict among uplink signals 2026-04-15 16:19:21 +02:00
francescomani
518eacab67 fix CSI-RS slot determination according to SSB index
reworked version of commit c30ad1d07b

Co-Authored-By: @mjoang_oai
2026-04-10 12:18:03 +02:00
Mario Joa-Ng
8ba92b53c4 set ssb_index using get_ssbidx_from_beam() instead of using common_channels[0].ssb_index[] which was used in set_analog_beamforming = 1 previously 2026-04-10 12:18:03 +02:00
francescomani
0e6a435349 harmonize update_cellGroupConfig functions 2026-04-10 12:18:01 +02:00
francescomani
fb414bc86b take into account the possibility to have multiple SSB in a slot when configuring CSI-RS according to SSB index 2026-04-10 12:13:03 +02:00
francescomani
f4e422b4dc apply the new csiMeasConfig to the cloned cellGroup to avoid nulling in the calling function
(this could have lead to no csiMeasConfig available if the reconfiguration fails)
2026-04-10 11:24:20 +02:00
francescomani
7a63d80d09 improve handling of UE context modification confirm/refuse 2026-04-10 11:24:20 +02:00
francescomani
e8927c992e trigger reconfiguration, conditional to having CSI-RS set 2026-04-10 11:24:20 +02:00
francescomani
2e37e2222a add assertion to prevent CSI-RS offset to go beyond period 2026-04-10 11:24:20 +02:00
francescomani
1b3421235c simplify tci handling of beam switching by not returning unused new beam index 2026-04-10 11:24:19 +02:00
francescomani
b32e61e436 fix formatting and remove unnecessary nulling of srs_Config 2026-04-10 11:24:19 +02:00
168 changed files with 3248 additions and 3977 deletions

View File

@@ -709,15 +709,14 @@ target_link_libraries(SCHED_LIB PRIVATE asn1_lte_rrc_hdrs)
set(SCHED_NR_SRC
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_gNB.c
${OPENAIR1_DIR}/SCHED_NR/nr_prach_procedures.c
${OPENAIR1_DIR}/SCHED_NR/nr_ru_procedures.c
${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
)
add_library(SCHED_NR_LIB ${SCHED_NR_SRC})
target_link_libraries(SCHED_NR_LIB PRIVATE asn1_nr_rrc_hdrs UTIL)
target_link_libraries(SCHED_NR_LIB PRIVATE NFAPI_LIB) # some FAPI messages pack "subPDUs"
set(SCHED_SRC_RU
${OPENAIR1_DIR}/SCHED/ru_procedures.c
${OPENAIR1_DIR}/SCHED_NR/nr_ru_procedures.c
${OPENAIR1_DIR}/SCHED/prach_procedures.c
)
add_library(SCHED_RU_LIB ${SCHED_SRC_RU})
@@ -753,7 +752,6 @@ set(NFAPI_SRC
add_library(NFAPI_LIB ${NFAPI_SRC})
target_link_libraries(NFAPI_LIB PUBLIC nfapi_common)
target_link_libraries(NFAPI_LIB PUBLIC nr_fapi_p5 nr_fapi_p7)
target_link_libraries(NFAPI_LIB PRIVATE z)
if(OAI_WLS)
target_compile_definitions(NFAPI_LIB PRIVATE ENABLE_WLS)
@@ -879,10 +877,6 @@ set(PHY_SRC
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pilots_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_coding.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_modulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pbch.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci.c
@@ -899,22 +893,22 @@ set(PHY_SRC
)
set(PHY_SRC_RU
${OPENAIR1_DIR}/PHY/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/drs_modulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz.c
${OPENAIR1_DIR}/PHY/MODULATION/gen_75KHz.cpp
${OPENAIR1_DIR}/PHY/MODULATION/beamforming.c
${OPENAIR1_DIR}/PHY/MODULATION/compute_bf_weights.c
${OPENAIR1_DIR}/PHY/INIT/lte_init_ru.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach.c
)
set(NR_PHY_SRC_RU
${OPENAIR1_DIR}/PHY/MODULATION/nr_beamforming.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_nr.c
${OPENAIR1_DIR}/PHY/INIT/nr_init_ru.c
${OPENAIR1_DIR}/PHY/if4_tools.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach.c
)
set(PHY_SRC_UE
@@ -1074,7 +1068,7 @@ add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
target_link_libraries(PHY_NR_COMMON PUBLIC UTIL)
add_library(PHY_NR ${PHY_NR_SRC})
target_link_libraries(PHY_NR nr_phy_common nr_common nr_fapi_p5 polar smallblock ds)
target_link_libraries(PHY_NR nr_phy_common nr_common nr_fapi_p5 polar smallblock)
add_library(PHY_NR_NO_AVX_256 ${PHY_NR_SRC})
target_link_libraries(PHY_NR_NO_AVX_256 nr_phy_common nr_common)
@@ -1086,8 +1080,6 @@ target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs nr_phy_common nr_common
add_library(PHY_RU ${PHY_SRC_RU})
target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs UTIL)
add_library(NR_PHY_RU ${NR_PHY_SRC_RU})
#Layer 2 library
#####################
set(MAC_DIR ${OPENAIR2_DIR}/LAYER2/MAC)
@@ -1750,7 +1742,7 @@ target_link_libraries(lte-softmodem PRIVATE
lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U SECURITY UTIL SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
${NAS_UE_LIB} ITTI SIMU radio_common softmodem_common
-Wl,--end-group dl)
-Wl,--end-group z dl)
target_link_libraries(lte-softmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-softmodem PRIVATE ${T_LIB})
@@ -1765,17 +1757,13 @@ add_executable(oairu
${OPENAIR_DIR}/executables/lte-ru.c
${OPENAIR_DIR}/executables/ru_control.c
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
${OPENAIR_DIR}/executables/main_ru.c
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
)
target_link_libraries(oairu PRIVATE
-Wl,--start-group
SCHED_RU_LIB PHY_COMMON PHY_RU UTIL radio_common softmodem_common
-Wl,--end-group dl)
-Wl,--end-group z dl)
target_link_libraries(oairu PRIVATE pthread m CONFIG_LIB rt ${T_LIB})
target_link_libraries(oairu PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -1804,7 +1792,7 @@ target_link_libraries(lte-uesoftmodem PRIVATE
SECURITY UTIL SCTP_CLIENT MME_APP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
PHY_UE PHY_RU L2_UE L2_LTE SIMU NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
${NAS_UE_LIB} ITTI radio_common softmodem_common
-Wl,--end-group dl)
-Wl,--end-group z dl)
target_link_libraries(lte-uesoftmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(lte-uesoftmodem PRIVATE ${T_LIB})
@@ -1820,12 +1808,11 @@ add_executable(nr-oru
${OPENAIR_DIR}/openair1/PHY/INIT/nr_parms.c
${OPENAIR_DIR}/openair1/SCHED_NR/phy_frame_config_nr.c
${OPENAIR_DIR}/openair1/SCHED_NR/nr_prach_procedures.c
${OPENAIR_DIR}/openair1/SCHED_NR/nr_ru_procedures.c
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
${OPENAIR_DIR}/executables/main_nr_ru.c
)
target_link_libraries(nr-oru PRIVATE
UTIL NR_PHY_RU PHY_NR shlib_loader dl
UTIL SCHED_RU_LIB PHY_COMMON PHY_RU PHY_NR shlib_loader z dl
radio_common softmodem_common)
target_link_libraries(nr-oru PRIVATE pthread m CONFIG_LIB rt ${T_LIB} utils
barrier actor)
@@ -1849,12 +1836,12 @@ add_executable(nr-softmodem
target_link_libraries(nr-softmodem PRIVATE
-Wl,--start-group
UTIL SCTP_CLIENT SCHED_LIB SCHED_NR_LIB PHY_NR PHY PHY_NR_COMMON NR_PHY_RU GTPV1U SECURITY
ITTI ${NAS_UE_LIB} nr_rrc
UTIL SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECURITY
ITTI ${NAS_UE_LIB} lte_rrc nr_rrc
ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU
x2ap f1ap m2ap m3ap e1ap radio_common
time_management softmodem_common
-Wl,--end-group dl)
-Wl,--end-group z dl)
target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt)
target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
@@ -1894,7 +1881,7 @@ target_link_libraries(nr-cuup PRIVATE
GTPV1U e1ap f1ap
time_management softmodem_common
alg
dl pthread ${T_LIB})
z dl pthread ${T_LIB})
target_link_libraries(nr-cuup PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
if(E2_AGENT)
target_link_libraries(nr-cuup PRIVATE e2_agent e2_agent_arg e2_ran_func_cuup)
@@ -1918,11 +1905,11 @@ add_executable(nr-uesoftmodem
target_link_libraries(nr-uesoftmodem PRIVATE
-Wl,--start-group
nr_rrc SECURITY UTIL SCHED_NR_UE_LIB
PHY_NR_COMMON PHY_NR_UE NR_L2_UE MAC_NR_COMMON NFAPI_LIB
nr_rrc SECURITY UTIL SCHED_RU_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_NR_UE NR_L2_UE MAC_NR_COMMON NFAPI_LIB
ITTI SIMU radio_common
time_management softmodem_common
-Wl,--end-group dl)
-Wl,--end-group z dl)
target_link_libraries(nr-uesoftmodem PRIVATE pthread m CONFIG_LIB rt nr_ue_phy_meas)
target_link_libraries(nr-uesoftmodem PRIVATE ${T_LIB})
@@ -1996,14 +1983,14 @@ target_link_libraries(physim_common PRIVATE UTIL)
add_executable(nr_dlschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c)
target_link_libraries(nr_dlschsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${T_LIB} ITTI dl physim_common
)
target_link_libraries(nr_dlschsim PRIVATE asn1_nr_rrc_hdrs)
add_executable(nr_pbchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c)
target_link_libraries(nr_pbchsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${T_LIB} ITTI dl physim_common
)
target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -2013,14 +2000,14 @@ add_executable(nr_psbchsim
${NFAPI_USER_DIR}/nfapi.c
)
target_link_libraries(nr_psbchsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB -Wl,--end-group
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB -Wl,--end-group
m pthread ${T_LIB} ITTI dl physim_common softmodem_common
)
target_link_libraries(nr_psbchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_pucchsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c)
target_link_libraries(nr_pucchsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${T_LIB} ITTI dl physim_common
)
target_link_libraries(nr_pucchsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -2032,15 +2019,15 @@ add_executable(nr_dlsim
${PHY_INTERFACE_DIR}/queue_t.c
)
target_link_libraries(nr_dlsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common NR_L2_UE
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common
softmodem_common
)
target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
add_executable(nr_prachsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c)
target_link_libraries(nr_prachsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR NR_PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB CONFIG_LIB -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 -Wl,--end-group
m pthread ${T_LIB} ITTI dl physim_common)
target_link_libraries(nr_prachsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -2048,7 +2035,7 @@ add_executable(nr_ulschsim
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
)
target_link_libraries(nr_ulschsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
m pthread ${T_LIB} ITTI dl physim_common
)
target_link_libraries(nr_ulschsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -2061,8 +2048,8 @@ add_executable(nr_ulsim
)
target_link_libraries(nr_ulsim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common softmodem_common NR_L2_UE
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON CONFIG_LIB L2_NR -Wl,--end-group
m pthread ${T_LIB} ITTI dl nr_ue_phy_meas physim_common softmodem_common
)
target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
@@ -2072,7 +2059,7 @@ add_executable(nr_srssim
)
target_link_libraries(nr_srssim PRIVATE
-Wl,--start-group UTIL SIMU PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON -Wl,--end-group
-Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_UE_NR MAC_NR_COMMON -Wl,--end-group
m pthread ITTI dl nr_ue_phy_meas physim_common softmodem_common
)
@@ -2141,7 +2128,7 @@ if (${T_TRACER})
SECURITY SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
MISC_NFAPI_LTE_LIB
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU NR_PHY_RU
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU
L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_UE_NR ngap
GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE SIMU
dfts config_internals nr_common crc_byte)

View File

@@ -1,20 +0,0 @@
repos:
# Clang-Format: Ensures code style is consistent
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: 'v22.1.3'
hooks:
- id: clang-format
# Cppcheck: Static analysis to find bugs
- repo: https://github.com/pocc/pre-commit-hooks
rev: 'v1.3.5'
hooks:
- id: cppcheck
# Basic sanity checks (trailing whitespace, end of file, etc.)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 'v6.0.0'
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: end-of-file-fixer

View File

@@ -219,6 +219,28 @@ pipeline {
}
}
}
stage ("cppcheck") {
steps {
script {
triggerSlaveJob ('RAN-cppcheck', 'cppcheck')
}
}
post {
always {
script {
// Using a unique variable name for each test stage to avoid overwriting on a global variable
// due to parallel-time concurrency
cppcheckStatus = finalizeSlaveJob('RAN-cppcheck')
}
}
failure {
script {
currentBuild.result = 'FAILURE'
failingStages += cppcheckStatus
}
}
}
}
stage ("ARM-Cross-Compile") {
steps {
script {

View File

@@ -22,7 +22,7 @@ import constants as CONST
#-----------------------------------------------------------
def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER):
force_local = False
date_fmt = None
@@ -53,6 +53,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
RAN.ranRepository=matchReg.group(1)
HTML.ranRepository=matchReg.group(1)
CONTAINERS.ranRepository=matchReg.group(1)
SCA.ranRepository=matchReg.group(1)
CLUSTER.ranRepository=matchReg.group(1)
elif re.match(r'^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE):
@@ -65,6 +66,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
RAN.ranAllowMerge=True
HTML.ranAllowMerge=True
CONTAINERS.ranAllowMerge=True
SCA.ranAllowMerge=True
CLUSTER.ranAllowMerge=True
elif re.match(r'^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE):
@@ -75,6 +77,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
RAN.ranBranch=matchReg.group(1)
HTML.ranBranch=matchReg.group(1)
CONTAINERS.ranBranch=matchReg.group(1)
SCA.ranBranch=matchReg.group(1)
CLUSTER.ranBranch=matchReg.group(1)
elif re.match(r'^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE):
@@ -85,6 +88,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
RAN.ranCommitID=matchReg.group(1)
HTML.ranCommitID=matchReg.group(1)
CONTAINERS.ranCommitID=matchReg.group(1)
SCA.ranCommitID=matchReg.group(1)
CLUSTER.ranCommitID=matchReg.group(1)
elif re.match(r'^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE):
if re.match(r'^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE):
@@ -95,6 +99,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
RAN.ranTargetBranch=matchReg.group(1)
HTML.ranTargetBranch=matchReg.group(1)
CONTAINERS.ranTargetBranch=matchReg.group(1)
SCA.ranTargetBranch=matchReg.group(1)
CLUSTER.ranTargetBranch=matchReg.group(1)
elif re.match(r'^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE):
print("parameters --eNB*IPAddress ignored")
@@ -107,6 +112,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER):
matchReg = re.match(r'^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE)
RAN.eNBSourceCodePath=matchReg.group(1)
CONTAINERS.eNBSourceCodePath=matchReg.group(1)
SCA.eNBSourceCodePath=matchReg.group(1)
CLUSTER.eNBSourceCodePath=matchReg.group(1)
elif re.match(r'^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE):
print("parameter --eNB1SourceCodePath ignored")

View File

@@ -184,6 +184,11 @@ class Containerize():
self.services = ''
self.deploymentTag = ''
self.cli = ''
self.cliBuildOptions = ''
self.dockerfileprefix = ''
self.host = ''
self.num_attempts = 1
self.flexricTag = ''
@@ -198,7 +203,18 @@ class Containerize():
cmd = cls_cmd.getConnection(node)
log_files = []
dockerfileprefix = '.ubuntu'
# Checking the hostname to get adapted on cli and dockerfileprefixes
cmd.run('hostnamectl')
result = re.search('Ubuntu|Red Hat', cmd.getBefore())
self.host = result.group(0)
if self.host == 'Ubuntu':
self.cli = 'docker'
self.dockerfileprefix = '.ubuntu'
self.cliBuildOptions = ''
elif self.host == 'Red Hat':
self.cli = 'sudo podman'
self.dockerfileprefix = '.rhel9'
self.cliBuildOptions = '--disable-compression'
# we always build the ran-build image with all targets
# Creating a tupple with the imageName, the DockerFile prefix pattern, targetName and sanitized option
@@ -216,20 +232,23 @@ class Containerize():
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup', ''))
imageNames.append(('oai-lte-ue', 'lteUE', 'oai-lte-ue', ''))
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
imageNames.append(('oai-lte-ru', 'lteRU', 'oai-lte-ru', ''))
# Building again the 5G images with Address Sanitizer
imageNames.append(('ran-build', 'build', 'ran-build-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-enb', 'eNB', 'oai-enb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-lte-ue', 'lteUE', 'oai-lte-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('ran-build-fhi72', 'build.fhi72', 'ran-build-fhi72', ''))
imageNames.append(('oai-gnb', 'gNB.fhi72', 'oai-gnb-fhi72', ''))
imageNames.append(('oai-nr-oru', 'nrORU.fhi72', 'oai-nr-oru', ''))
if self.host == 'Red Hat':
imageNames.append(('oai-physim', 'phySim', 'oai-physim', ''))
if self.host == 'Ubuntu':
imageNames.append(('oai-lte-ru', 'lteRU', 'oai-lte-ru', ''))
# Building again the 5G images with Address Sanitizer
imageNames.append(('ran-build', 'build', 'ran-build-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-enb', 'eNB', 'oai-enb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-lte-ue', 'lteUE', 'oai-lte-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup-asan', '--build-arg "BUILD_OPTION=--sanitize"'))
imageNames.append(('ran-build-fhi72', 'build.fhi72', 'ran-build-fhi72', ''))
imageNames.append(('oai-gnb', 'gNB.fhi72', 'oai-gnb-fhi72', ''))
imageNames.append(('oai-nr-oru', 'nrORU.fhi72', 'oai-nr-oru', ''))
result = re.search('build_cross_arm64', self.imageKind)
if result is not None:
dockerfileprefix = '.ubuntu.cross-arm64'
self.dockerfileprefix = '.ubuntu.cross-arm64'
result = re.search('native_armv9', self.imageKind)
if result is not None:
imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', ''))
@@ -244,6 +263,10 @@ class Containerize():
imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', ''))
cmd.cd(lSourcePath)
# if asterix, copy the entitlement and subscription manager configurations
if self.host == 'Red Hat':
cmd.run('mkdir -p ./etc-pki-entitlement')
cmd.run('cp /etc/pki/entitlement/*.pem ./etc-pki-entitlement/')
baseImage = 'ran-base'
baseTag = 'develop'
@@ -252,7 +275,7 @@ class Containerize():
if (self.ranAllowMerge):
imageTag = 'ci-temp'
if self.ranTargetBranch == 'develop':
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{dockerfileprefix} | grep --colour=never -i INDEX')
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{self.dockerfileprefix} | grep --colour=never -i INDEX')
result = re.search('index', cmd.getBefore())
if result is not None:
forceBaseImageBuild = True
@@ -266,30 +289,31 @@ class Containerize():
forceBaseImageBuild = True
# Let's remove any previous run artifacts if still there
cmd.run(f"docker image prune --force")
cmd.run(f"{self.cli} image prune --force")
for image,pattern,name,option in imageNames:
cmd.run(f"docker image rm {name}:{imageTag}", reportNonZero=False)
cmd.run(f"{self.cli} image rm {name}:{imageTag}", reportNonZero=False)
cmd.run(f'docker login -u oaicicd -p oaicicd {DEFAULT_REGISTRY}')
ubuntuImage = "ubuntu:noble"
# Build the base image only on Push Events (not on Merge Requests)
# On when the base image docker file is being modified.
if forceBaseImageBuild:
cmd.run(f"docker image rm {baseImage}:{baseTag}")
cmd.run(f"{self.cli} image rm {baseImage}:{baseTag}")
logfile = f'{lSourcePath}/cmake_targets/log/ran-base.docker.log'
option = f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
cmd.run(f"docker build --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{dockerfileprefix} {option} . &> {logfile}", timeout=1600)
if self.host == 'Ubuntu':
option = f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
cmd.run(f"{self.cli} build {self.cliBuildOptions} --target {baseImage} --tag {baseImage}:{baseTag} --file docker/Dockerfile.base{self.dockerfileprefix} {option} . &> {logfile}", timeout=1600)
t = ("ran-base", archiveArtifact(cmd, ctx, logfile))
log_files.append(t)
# First verify if the base image was properly created.
ret = cmd.run(f"docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {baseImage}:{baseTag}")
allImagesSize = {}
if ret.returncode != 0:
logging.error('\u001B[1m Could not build properly ran-base\u001B[0m')
# Recover the name of the failed container?
cmd.run(f"docker ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty docker rm -f")
cmd.run(f"docker image prune --force")
cmd.run(f"{self.cli} ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty {self.cli} rm -f")
cmd.run(f"{self.cli} image prune --force")
cmd.close()
logging.error('\u001B[1m Building OAI Images Failed\u001B[0m')
HTML.CreateHtmlTestRow(self.imageKind, 'KO', CONST.ALL_PROCESSES_OK)
@@ -309,31 +333,32 @@ class Containerize():
for image,pattern,name,option in imageNames:
# the archived Dockerfiles have "ran-base:latest" as base image
# we need to update them with proper tag
cmd.run(f'git checkout -- docker/Dockerfile.{pattern}{dockerfileprefix}')
cmd.run(f'sed -i -e "s#{baseImage}:latest#{baseImage}:{baseTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
cmd.run(f'git checkout -- docker/Dockerfile.{pattern}{self.dockerfileprefix}')
cmd.run(f'sed -i -e "s#{baseImage}:latest#{baseImage}:{baseTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
# target images should use the proper ran-build image
if image != 'ran-build' and "-asan" in name:
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build-asan:{imageTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build-asan:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
elif "fhi72" in name or name == "oai-nr-oru":
cmd.run(f'sed -i -e "s#ran-build-fhi72:latest#ran-build-fhi72:{imageTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
cmd.run(f'sed -i -e "s#ran-build-fhi72:latest#ran-build-fhi72:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
elif image != 'ran-build':
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{dockerfileprefix}')
cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}')
if image == 'oai-gnb-aerial':
cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2026.01.07.tar.gz .')
logfile = f'{lSourcePath}/cmake_targets/log/{name}.docker.log'
option = option + f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
ret = cmd.run(f'docker build --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{dockerfileprefix} {option} . > {logfile} 2>&1', timeout=1200)
if self.host == 'Ubuntu':
option = option + f" --build-arg UBUNTU_IMAGE={DEFAULT_REGISTRY}/{ubuntuImage}"
ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > {logfile} 2>&1', timeout=1200)
t = (name, archiveArtifact(cmd, ctx, logfile))
log_files.append(t)
if image == 'oai-gnb-aerial':
cmd.run('rm -f nvipc_src.2026.01.07.tar.gz')
# check the status of the build
ret = cmd.run(f"docker image inspect --format=\'Size = {{{{.Size}}}} bytes\' {name}:{imageTag}")
ret = cmd.run(f"{self.cli} image inspect --format=\'Size = {{{{.Size}}}} bytes\' {name}:{imageTag}")
if ret.returncode != 0:
logging.error('\u001B[1m Could not build properly ' + name + '\u001B[0m')
status = False
# Here we should check if the last container corresponds to a failed command and destroy it
cmd.run(f"docker ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty docker rm -f")
cmd.run(f"{self.cli} ps --quiet --filter \"status=exited\" -n1 | xargs --no-run-if-empty {self.cli} rm -f")
allImagesSize[name] = 'N/A -- Build Failed'
break
else:
@@ -347,16 +372,16 @@ class Containerize():
logging.debug(f'{name} size is unknown')
allImagesSize[name] = 'unknown'
# Now pruning dangling images in between target builds
cmd.run(f"docker image prune --force")
cmd.run(f"{self.cli} image prune --force")
cmd.run(f'docker logout {DEFAULT_REGISTRY}')
# Remove all intermediate build images and clean up
cmd.run(f"docker image rm ran-build:{imageTag} ran-build-asan:{imageTag} ran-build-fhi72:{imageTag} || true")
cmd.run(f"docker volume prune --force")
cmd.run(f"{self.cli} image rm ran-build:{imageTag} ran-build-asan:{imageTag} ran-build-fhi72:{imageTag} || true")
cmd.run(f"{self.cli} volume prune --force")
# Remove some cached artifacts to prevent out of diskspace problem
logging.debug(cmd.run("df -h").stdout)
logging.debug(cmd.run("docker system df").stdout)
cmd.run(f"docker buildx prune --filter until=1h --force")
cmd.run(f"{self.cli} buildx prune --filter until=1h --force")
logging.debug(cmd.run("df -h").stdout)
logging.debug(cmd.run("docker system df").stdout)
@@ -464,12 +489,20 @@ class Containerize():
cmd = cls_cmd.getConnection(node)
cmd.cd(lSourcePath)
ret = cmd.run('hostnamectl')
result = re.search('Ubuntu', ret.stdout)
host = result.group(0)
if host != 'Ubuntu':
cmd.close()
raise Exception("Can build unit tests only on Ubuntu server")
logging.debug('running on Ubuntu as expected')
# check that ran-base image exists as we expect it
baseImage = 'ran-base'
baseTag = 'develop'
if self.ranAllowMerge:
if self.ranTargetBranch == 'develop':
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base.ubuntu | grep --colour=never -i INDEX')
cmd.run(f'git diff HEAD..origin/develop -- cmake_targets/build_oai cmake_targets/tools/build_helper docker/Dockerfile.base{self.dockerfileprefix} | grep --colour=never -i INDEX')
result = re.search('index', cmd.getBefore())
if result is not None:
baseTag = 'ci-temp'

View File

@@ -379,6 +379,90 @@ class HTMLManagement():
self.htmlFile.write(' </tr>\n')
self.htmlFile.close()
def CreateHtmlTestRowCppCheckResults(self, CCR):
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
return
self.htmlFile = open('test_results.html', 'a')
vId = 0
for version in CCR.versions:
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan="6"><b> Results for cppcheck v ' + version + ' </b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> NB ERRORS</b></td>\n')
if CCR.nbErrors[vId] == 0:
myColor = 'lightgreen'
elif CCR.nbErrors[vId] < 20:
myColor = 'orange'
else:
myColor = 'lightcoral'
self.htmlFile.write(' <td colspan="3" bgcolor = "' + myColor + '"><b>' + str(CCR.nbErrors[vId]) + '</b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> NB WARNINGS</b></td>\n')
if CCR.nbWarnings[vId] == 0:
myColor = 'lightgreen'
elif CCR.nbWarnings[vId] < 20:
myColor = 'orange'
else:
myColor = 'lightcoral'
self.htmlFile.write(' <td colspan="3" bgcolor = "' + myColor + '"><b>' + str(CCR.nbWarnings[vId]) + '</b></td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan="6"> ----------------- </td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Memory leak</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbMemLeaks[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Possible null pointer deference</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbNullPtrs[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Uninitialized variable</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbUninitVars[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Undefined behaviour shifting</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbTooManyBitsShift[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Signed integer overflow</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbIntegerOverflow[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr bgcolor = "#F0F0F0" >\n')
self.htmlFile.write(' <td colspan="6"> </td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Printf formatting issues</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbInvalidPrintf[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Modulo result is predetermined</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbModuloAlways[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Opposite Condition -> dead code</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbOppoInnerCondition[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
self.htmlFile.write(' <tr>\n')
self.htmlFile.write(' <td></td>\n')
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" ><b> Wrong Scanf Nb Args</b></td>\n')
self.htmlFile.write(' <td colspan="3">' + str(CCR.nbWrongScanfArg[vId]) + '</td>\n')
self.htmlFile.write(' </tr>\n')
vId += 1
def CreateHtmlTestRowPhySimTestResult(self, testSummary, testResult):
if (self.htmlFooterCreated or (not self.htmlHeaderCreated)):
return

View File

@@ -27,30 +27,160 @@ import constants as CONST
import cls_cmd
from cls_ci_helper import archiveArtifact
#-----------------------------------------------------------
# Class Declaration
#-----------------------------------------------------------
class CppCheckResults():
def __init__(self):
self.variants = ['bionic', 'focal']
self.versions = ['','']
self.nbErrors = [0,0]
self.nbWarnings = [0,0]
self.nbNullPtrs = [0,0]
self.nbMemLeaks = [0,0]
self.nbUninitVars = [0,0]
self.nbInvalidPrintf = [0,0]
self.nbModuloAlways = [0,0]
self.nbTooManyBitsShift = [0,0]
self.nbIntegerOverflow = [0,0]
self.nbWrongScanfArg = [0,0]
self.nbPtrAddNotNull = [0,0]
self.nbOppoInnerCondition = [0,0]
class StaticCodeAnalysis():
def LicenceAndFormattingCheck(ctx, node, HTML, d, branch, allowMerge, targetBranch):
def __init__(self):
self.ranRepository = ''
self.ranBranch = ''
self.ranAllowMerge = False
self.ranCommitID = ''
self.ranTargetBranch = ''
self.eNBSourceCodePath = ''
def CppCheckAnalysis(self, ctx, node, HTML):
if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '':
HELP.GenericHelp(CONST.Version)
sys.exit('Insufficient Parameter')
lSourcePath = self.eNBSourceCodePath
if not lSourcePath or not node:
raise ValueError(f"{lSourcePath=} {node=}")
logging.debug('Building on server: ' + node)
cmd = cls_cmd.getConnection(node)
# on RedHat/CentOS .git extension is mandatory
result = re.search(r'([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository)
if result is not None:
full_ran_repo_name = self.ranRepository.replace('git/', 'git')
else:
full_ran_repo_name = self.ranRepository + '.git'
cmd.cd(lSourcePath)
logDir = f'{lSourcePath}/cmake_targets/log'
cmd.run(f'mkdir -p {logDir}')
cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal')
cmd.run(f'sed -e "s@xenial@bionic@" {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.xenial > {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.bionic')
cmd.run(f'docker build --tag oai-cppcheck:bionic --file {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.bionic . > {logDir}/cppcheck-bionic.txt 2>&1')
cmd.run(f'sed -e "s@xenial@focal@" {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.xenial > {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.focal')
cmd.run(f'docker build --tag oai-cppcheck:focal --file {lSourcePath}/ci-scripts/docker/Dockerfile.cppcheck.focal . > {logDir}/cppcheck-focal.txt 2>&1')
cmd.run('docker image rm oai-cppcheck:bionic oai-cppcheck:focal')
bionic = archiveArtifact(cmd, ctx, f'{logDir}/cppcheck-bionic.txt')
focal = archiveArtifact(cmd, ctx, f'{logDir}/cppcheck-focal.txt')
cmd.close()
CCR = CppCheckResults()
CCR_ref = CppCheckResults()
vId = 0
for variant in CCR.variants:
filename = ctx.baseFilename() + '-cppcheck-'+ variant + '.txt'
logging.info(f"will check file '{filename}'")
if not os.path.isfile(filename):
raise FileNotFoundError(f"{filename} is not a file")
else:
xmlStart = False
with open(filename, 'r') as logfile:
for line in logfile:
ret = re.search(r'cppcheck version="(?P<version>[0-9\.]+)"', str(line))
if ret is not None:
CCR.versions[vId] = ret.group('version')
if re.search('RUN cat cmake_targets/log/cppcheck.xml', str(line)) is not None:
xmlStart = True
if xmlStart:
if re.search('severity="error"', str(line)) is not None:
CCR.nbErrors[vId] += 1
if re.search('severity="warning"', str(line)) is not None:
CCR.nbWarnings[vId] += 1
if re.search('id="memleak"', str(line)) is not None:
CCR.nbMemLeaks[vId] += 1
if re.search('id="nullPointer"', str(line)) is not None:
CCR.nbNullPtrs[vId] += 1
if re.search('id="uninitvar"', str(line)) is not None:
CCR.nbUninitVars[vId] += 1
if re.search('id="invalidPrintfArgType_sint"|id="invalidPrintfArgType_uint"', str(line)) is not None:
CCR.nbInvalidPrintf[vId] += 1
if re.search('id="moduloAlwaysTrueFalse"', str(line)) is not None:
CCR.nbModuloAlways[vId] += 1
if re.search('id="shiftTooManyBitsSigned"', str(line)) is not None:
CCR.nbTooManyBitsShift[vId] += 1
if re.search('id="integerOverflow"', str(line)) is not None:
CCR.nbIntegerOverflow[vId] += 1
if re.search('id="wrongPrintfScanfArgNum"|id="invalidScanfArgType_int"', str(line)) is not None:
CCR.nbWrongScanfArg[vId] += 1
if re.search('id="pointerAdditionResultNotNull"', str(line)) is not None:
CCR.nbPtrAddNotNull[vId] += 1
if re.search('id="oppositeInnerCondition"', str(line)) is not None:
CCR.nbOppoInnerCondition[vId] += 1
vMsg = ''
vMsg += '======== Variant ' + variant + ' - ' + CCR.versions[vId] + ' ========\n'
vMsg += ' ' + str(CCR.nbErrors[vId]) + ' errors\n'
vMsg += ' ' + str(CCR.nbWarnings[vId]) + ' warnings\n'
vMsg += ' -- Details --\n'
vMsg += ' Memory leak: ' + str(CCR.nbMemLeaks[vId]) + '\n'
vMsg += ' Possible null pointer deference: ' + str(CCR.nbNullPtrs[vId]) + '\n'
vMsg += ' Uninitialized variable: ' + str(CCR.nbUninitVars[vId]) + '\n'
vMsg += ' Undefined behaviour shifting: ' + str(CCR.nbTooManyBitsShift[vId]) + '\n'
vMsg += ' Signed integer overflow: ' + str(CCR.nbIntegerOverflow[vId]) + '\n'
vMsg += '\n'
vMsg += ' Printf formatting issue: ' + str(CCR.nbInvalidPrintf[vId]) + '\n'
vMsg += ' Modulo result is predetermined: ' + str(CCR.nbModuloAlways[vId]) + '\n'
vMsg += ' Opposite Condition -> dead code: ' + str(CCR.nbOppoInnerCondition[vId]) + '\n'
vMsg += ' Wrong Scanf Nb Args: ' + str(CCR.nbWrongScanfArg[vId]) + '\n'
for vLine in vMsg.split('\n'):
logging.debug(vLine)
vId += 1
HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK)
HTML.CreateHtmlTestRowCppCheckResults(CCR)
logging.info('\u001B[1m Static Code Analysis Pass\u001B[0m')
return True
def LicenceAndFormattingCheck(self, ctx, node, HTML):
# Workspace is no longer recreated from scratch.
# It implies that this method shall be called last within a build pipeline
# where workspace is already created
lSourcePath = self.eNBSourceCodePath
if not node or not d:
raise ValueError(f"{d=} {node=}")
if not node or not lSourcePath:
raise ValueError(f"{lSourcePath=} {node=}")
logging.debug('Building on server: ' + node)
cmd = cls_cmd.getConnection(node)
check_options = ''
if allowMerge:
check_options = f'--build-arg MERGE_REQUEST=true --build-arg SRC_BRANCH={branch}'
if targetBranch == '':
if branch != 'develop' and branch != 'origin/develop':
if self.ranAllowMerge:
check_options = f'--build-arg MERGE_REQUEST=true --build-arg SRC_BRANCH={self.ranBranch}'
if self.ranTargetBranch == '':
if self.ranBranch != 'develop' and self.ranBranch != 'origin/develop':
check_options += ' --build-arg TARGET_BRANCH=develop'
else:
check_options += f' --build-arg TARGET_BRANCH={targetBranch}'
check_options += f' --build-arg TARGET_BRANCH={self.ranTargetBranch}'
logDir = f'{d}/cmake_targets/log/'
logDir = f'{lSourcePath}/cmake_targets/log/'
cmd.run(f'mkdir -p {logDir}')
cmd.run('docker image rm oai-formatting-check:latest')
cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {d}/ci-scripts/docker/Dockerfile.formatting.ubuntu {d} > {logDir}/oai-formatting-check.txt 2>&1')
cmd.run(f'docker build --target oai-formatting-check --tag oai-formatting-check:latest {check_options} --file {lSourcePath}/ci-scripts/docker/Dockerfile.formatting.ubuntu {lSourcePath} > {logDir}/oai-formatting-check.txt 2>&1')
cmd.run('docker image rm oai-formatting-check:latest')
cmd.run('docker image prune --force')

View File

@@ -17,7 +17,6 @@ gNBs =
// Tracking area code, 0x0000 and 0xfffe are reserved values
tracking_area_code = 1;
plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) });
cu_sibs = ( 2, 3, 4 );
@include "neighbour-config.conf"
nr_cellid = 12345678L;

View File

@@ -5,57 +5,6 @@
# for the 2-cell rfsim setup (gNB_ID 0xe00 & 0xb00) #
############################################################
############################################################
# SIB2 #
############################################################
sib2_config : {
q_Hyst = 0;
cellReselectionPriority = 0;
threshServingLowP = 0;
threshServingLowQ = 0;
s_NonIntraSearchP = -1;
s_NonIntraSearchQ = -1;
q_RxLevMin = -56;
q_QualMin = -1;
s_IntraSearchP = 22;
s_IntraSearchQ = -1;
t_ReselectionNR = 1;
deriveSSB_IndexFromCell = 1;
speed_t_Evaluation = 0;
speed_t_HystNormal = 0;
speed_n_CellChangeMedium = 1;
speed_n_CellChangeHigh = 2;
speed_sf_Medium = 1;
speed_sf_High = 0;
};
############################################################
# Per-frequency SIB4 inter-frequency configuration #
############################################################
frequency_list = (
{
absoluteFrequencySSB = 621312;
subcarrierSpacing = 1; # 30 kHz
band = 78;
frequency_config = (
{
cellReselectionPriority = 5;
threshX_HighP = 10;
threshX_LowP = 6;
threshX_HighQ = -1;
threshX_LowQ = -1;
q_OffsetFreq = 0;
q_RxLevMin = -56;
t_ReselectionNR = 1;
}
);
}
);
neighbour_list = (
##########################################################
# Entry USED BY gNB_ID = 0xe00 (nr_cellid = 1) #
@@ -72,9 +21,6 @@ neighbour_list = (
band = 78;
plmn = { mcc = 208; mnc = 99; mnc_length = 2 };
tracking_area_code = 1;
q_OffsetCell = 2;
q_RxLevMinOffsetCell= 2;
q_QualMinOffsetCell = 1;
}
);
},
@@ -94,9 +40,6 @@ neighbour_list = (
band = 78;
plmn = { mcc = 208; mnc = 99; mnc_length = 2 };
tracking_area_code = 1;
q_OffsetCell = 2;
q_RxLevMinOffsetCell= 2;
q_QualMinOffsetCell = 1;
}
);
}

View File

@@ -0,0 +1,41 @@
# SPDX-License-Identifier: LicenseRef-CSSL-1.0
#---------------------------------------------------------------------
#
# Dockerfile for the Open-Air-Interface BUILD service
# Valid for Ubuntu 22.04
#
#---------------------------------------------------------------------
FROM ubuntu:xenial AS oai-cppcheck
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get upgrade --yes && \
apt-get install --yes \
build-essential \
vim \
cppcheck
WORKDIR /oai-ran
COPY . .
WORKDIR /oai-ran/common/utils/T
RUN make
WORKDIR /oai-ran
RUN mkdir -p cmake_targets/log && \
cppcheck --enable=warning --force --xml --xml-version=2 \
--inline-suppr \
-i openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder.c \
--suppressions-list=ci-scripts/cppcheck_suppressions.list \
-I common/utils \
-I openair3/NAS/COMMON/UTIL \
-j`nproc` . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt
RUN grep -E -c 'severity="error' cmake_targets/log/cppcheck.xml
RUN grep -E -c 'severity="warning' cmake_targets/log/cppcheck.xml
RUN cat cmake_targets/log/cppcheck.xml

View File

@@ -22,7 +22,7 @@ import constants as CONST
import cls_oaicitest #main class for OAI CI test framework
import cls_containerize #class Containerize for all container-based operations on RAN/UE objects
import cls_static_code_analysis as SCA
import cls_static_code_analysis #class for static code analysis
import cls_cluster # class for building/deploying on cluster
import cls_native # class for all native/source-based operations
from cls_ci_helper import TestCaseCtx
@@ -64,6 +64,7 @@ def ExecuteActionWithParam(action, ctx, node):
global RAN
global HTML
global CONTAINERS
global SCA
global CLUSTER
if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy' or action == "Build_Cluster_Image" or action == "Build_Run_Tests":
RAN.Build_eNB_args=test.findtext('Build_eNB_args')
@@ -195,7 +196,10 @@ def ExecuteActionWithParam(action, ctx, node):
success = CONTAINERS.Create_Workspace(node, HTML)
elif action == 'LicenceAndFormattingCheck':
success = SCA.StaticCodeAnalysis.LicenceAndFormattingCheck(ctx, node, HTML, RAN.eNBSourceCodePath, RAN.ranBranch, RAN.ranAllowMerge, RAN.ranTargetBranch)
success = SCA.LicenceAndFormattingCheck(ctx, node, HTML)
elif action == 'Cppcheck_Analysis':
success = SCA.CppCheckAnalysis(ctx, node, HTML)
elif action == 'Push_Local_Registry':
tag_prefix = test.findtext('tag_prefix') or ""
@@ -293,6 +297,7 @@ CiTestObj = cls_oaicitest.OaiCiTest()
RAN = ran.RANManagement()
HTML = cls_oai_html.HTMLManagement()
CONTAINERS = cls_containerize.Containerize()
SCA = cls_static_code_analysis.StaticCodeAnalysis()
CLUSTER = cls_cluster.Cluster()
#-----------------------------------------------------------
@@ -302,7 +307,7 @@ CLUSTER = cls_cluster.Cluster()
import args_parse
# Force local execution, move all execution targets to localhost
force_local = False
mode, force_local, date_fmt = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,CONTAINERS,HELP,CLUSTER)
mode, force_local, date_fmt = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,CONTAINERS,HELP,SCA,CLUSTER)
fmt = "%(levelname)8s: %(message)s"
if date_fmt:
fmt = "[%(asctime)s] %(levelname)s %(message)s"

View File

@@ -23,6 +23,7 @@
- Deploy_Object
- Stop_Object
- Undeploy_Object
- Cppcheck_Analysis
- Deploy_Run_OC_PhySim
- Build_Deploy_PhySim
- LicenceAndFormattingCheck

View File

@@ -0,0 +1,20 @@
<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->
<testCaseList>
<htmlTabRef>build-tab</htmlTabRef>
<htmlTabName>CPPCHECK Analysis</htmlTabName>
<htmlTabIcon>wrench</htmlTabIcon>
<testCase>
<class>Create_Workspace</class>
<desc>Create new Workspace</desc>
<node>carabe</node>
</testCase>
<testCase>
<class>Cppcheck_Analysis</class>
<desc>Static Code Analysis with cppcheck</desc>
<node>carabe</node>
</testCase>
</testCaseList>

View File

@@ -166,7 +166,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: l2sim4g-trf-gen
networks:

View File

@@ -166,7 +166,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: rfsim4g-trf-gen
networks:

View File

@@ -166,7 +166,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: rfsim4g-trf-gen
networks:

View File

@@ -166,7 +166,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: rfsim4g-trf-gen
networks:

View File

@@ -166,7 +166,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: rfsim4g-trf-gen
networks:

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -75,7 +75,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -74,7 +74,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -38,11 +38,11 @@ Password:
Now pull images.
```bash
$ docker pull mysql:9.6
$ docker pull oaisoftwarealliance/oai-amf:v2.2.1
$ docker pull oaisoftwarealliance/oai-smf:v2.2.1
$ docker pull oaisoftwarealliance/oai-upf:v2.2.1
$ docker pull oaisoftwarealliance/trf-gen-cn5g:latest
$ docker pull mysql:8.0
$ docker pull oaisoftwarealliance/oai-amf:v2.1.10
$ docker pull oaisoftwarealliance/oai-smf:v2.1.10
$ docker pull oaisoftwarealliance/oai-upf:v2.1.10
$ docker pull oaisoftwarealliance/trf-gen-cn5g:focal
$ docker pull oaisoftwarealliance/oai-gnb:develop
$ docker pull oaisoftwarealliance/oai-nr-ue:develop
@@ -570,7 +570,7 @@ runs the gnb service with modified gNB executable.
```bash
docker compose -f docker-compose.yaml -f local-override.yaml up -d oai-gnb
```
This command rebuilds both the gNB & nrUE and runs the oai-nr-ue container with
This command rebuilds both the gNB & nrUE and runs the oai-nr-ue container with
modified nrUE executable.
```bash
docker compose -f docker-compose.yaml -f local-override.yaml up -d oai-nr-ue

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -74,7 +74,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -74,7 +74,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -74,7 +74,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -74,7 +74,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
@@ -23,7 +23,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -35,7 +35,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -47,7 +47,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -70,7 +70,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
@@ -23,7 +23,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:ci-tmp-pr-372-26c14bcd
environment:
- TZ=Europe/paris
volumes:
@@ -35,7 +35,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.9
environment:
- TZ=Europe/Paris
volumes:
@@ -47,7 +47,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.9
environment:
- TZ=Europe/Paris
volumes:
@@ -70,7 +70,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -74,7 +74,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ../5g_rfsimulator/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
@@ -25,7 +25,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -37,7 +37,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -49,7 +49,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -72,7 +72,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\
"ip route add 12.1.1.0/24 via 192.168.72.134 dev eth0; sleep infinity"

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris
@@ -74,7 +74,7 @@ services:
oai-ext-dn:
privileged: true
container_name: rfsim5g-oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
init: true
entrypoint: /bin/bash -c \
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\

View File

@@ -3,7 +3,7 @@
services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -26,7 +26,7 @@ services:
ipv4_address: 192.168.71.131
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -38,7 +38,7 @@ services:
ipv4_address: 192.168.71.132
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -50,7 +50,7 @@ services:
ipv4_address: 192.168.71.133
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -12,7 +12,7 @@ services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -36,7 +36,7 @@ services:
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -49,7 +49,7 @@ services:
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -62,7 +62,7 @@ services:
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -12,7 +12,7 @@ services:
mysql:
container_name: "rfsim5g-mysql"
image: mysql:9.6
image: mysql:8.0
init: true
volumes:
- ../5g_rfsimulator/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
@@ -36,7 +36,7 @@ services:
oai-amf:
container_name: "rfsim5g-oai-amf"
image: oaisoftwarealliance/oai-amf:v2.2.1
image: oaisoftwarealliance/oai-amf:v2.1.10
environment:
- TZ=Europe/paris
volumes:
@@ -49,7 +49,7 @@ services:
oai-smf:
container_name: "rfsim5g-oai-smf"
image: oaisoftwarealliance/oai-smf:v2.2.1
image: oaisoftwarealliance/oai-smf:v2.1.10
environment:
- TZ=Europe/Paris
volumes:
@@ -62,7 +62,7 @@ services:
oai-upf:
container_name: "rfsim5g-oai-upf"
image: oaisoftwarealliance/oai-upf:v2.2.1
image: oaisoftwarealliance/oai-upf:v2.1.10
init: true
environment:
- TZ=Europe/Paris

View File

@@ -184,7 +184,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: prod-trf-gen
networks:

View File

@@ -168,7 +168,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: prod-trf-gen
networks:

View File

@@ -168,7 +168,7 @@ services:
retries: 5
trf_gen:
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:focal
privileged: true
container_name: prod-trf-gen
networks:

View File

@@ -48,8 +48,8 @@ typedef union checkedparam {
int num_okintval; /* number of valid values in the checkingval array */
} s1a;
struct {
int (*f2)(const configmodule_interface_t *cfg,
const paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */
int (*f2)(configmodule_interface_t *cfg,
paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */
int okintrange[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store min and max values */
} s2;

View File

@@ -183,35 +183,14 @@ int config_check_intval(configmodule_interface_t *cfg, paramdef_t *param)
return -1;
}
if (param->type == TYPE_INT32 || param->type == TYPE_INT) {
if (param->iptr == NULL) {
fprintf(stderr, "[CONFIG] config_check_intval: %s: NULL iptr\n", param->optname);
return -1;
for ( int i=0; i<param->chkPptr->s1.num_okintval ; i++) {
if( *(param->uptr) == param->chkPptr->s1.okintval[i] ) {
return 0;
}
const int v = *param->iptr;
for (int i = 0; i < param->chkPptr->s1.num_okintval; i++) {
if (v == param->chkPptr->s1.okintval[i])
return 0;
}
fprintf(stderr, "[CONFIG] config_check_intval: %s: %i invalid value, authorized values:\n ", param->optname, v);
for (int i = 0; i < param->chkPptr->s1.num_okintval; i++) {
fprintf(stderr, " %i", param->chkPptr->s1.okintval[i]);
}
fprintf(stderr, " \n");
return -1;
} else {
if (param->uptr == NULL) {
fprintf(stderr, "[CONFIG] config_check_intval: %s: NULL uptr\n", param->optname);
return -1;
}
for (int i = 0; i < param->chkPptr->s1.num_okintval; i++) {
if (*(param->uptr) == (uint32_t)param->chkPptr->s1.okintval[i]) {
return 0;
}
}
print_intvalueerror(param, "config_check_intval", param->chkPptr->s1.okintval, param->chkPptr->s1.num_okintval);
return -1;
}
print_intvalueerror(param,"config_check_intval", param->chkPptr->s1.okintval,param->chkPptr->s1.num_okintval);
return -1;
}
int config_check_modify_integer(configmodule_interface_t *cfg, paramdef_t *param)
@@ -232,38 +211,15 @@ int config_check_modify_integer(configmodule_interface_t *cfg, paramdef_t *param
return -1;
}
int config_check_intrange(const configmodule_interface_t *cfg, const paramdef_t *param)
int config_check_intrange(configmodule_interface_t *cfg, paramdef_t *param)
{
UNUSED(cfg);
if( *(param->iptr) >= param->chkPptr->s2.okintrange[0] && *(param->iptr) <= param->chkPptr->s2.okintrange[1] ) {
return 0;
}
fprintf(stderr,
"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n",
param->optname,
(int)*(param->iptr),
param->chkPptr->s2.okintrange[0],
param->chkPptr->s2.okintrange[1]);
return -1;
}
int config_check_uintrange(const configmodule_interface_t *cfg, const paramdef_t *param)
{
(void)cfg;
const uint32_t *v = param->uptr;
const int *range = param->chkPptr->s2.okintrange;
if (*v >= (uint32_t)range[0] && *v <= (uint32_t)range[1]) {
return 0;
}
fprintf(stderr,
"[CONFIG] config_check_uintrange: %s: %u invalid, authorized range: %i %i\n",
param->optname,
*v,
range[0],
range[1]);
fprintf(stderr,"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n",
param->optname, (int)*(param->uptr), param->chkPptr->s2.okintrange[0], param->chkPptr->s2.okintrange[1]);
return -1;
}

View File

@@ -51,8 +51,7 @@ int config_get_processedint(configmodule_interface_t *cfg, paramdef_t *cfgoption
/* functions to be used in parameters definition, to check parameters values */
int config_check_intval(configmodule_interface_t *cfg, paramdef_t *param);
int config_check_modify_integer(configmodule_interface_t *cfg, paramdef_t *param);
int config_check_intrange(const configmodule_interface_t *cfg, const paramdef_t *param);
int config_check_uintrange(const configmodule_interface_t *cfg, const paramdef_t *param);
int config_check_intrange(configmodule_interface_t *cfg, paramdef_t *param);
int config_check_strval(configmodule_interface_t *cfg, paramdef_t *param);
int config_checkstr_assign_integer(configmodule_interface_t *cfg, paramdef_t *param);
const paramdef_t *config_get_paramdef_from_name(const paramdef_t *pd, int num, const char *name);

View File

@@ -66,6 +66,7 @@
#define RETURNok (0)
#define RETURNerror (-1)
#define DEFAULT_NAS_PATH "PWD"
#define UNUSED_VARIABLE(vARIABLE) (void)(vARIABLE)
#define NUM_PRACH_RX_FOR_NOISE_ESTIMATE 100
// SDAP

View File

@@ -16,7 +16,7 @@ add_subdirectory(nr)
add_subdirectory(LOG)
add_subdirectory(threadPool)
add_subdirectory(time_manager)
add_library(utils utils.c system.c time_meas.c time_stat.c tuntap_if.c reverse_bits.c fsn.c)
add_library(utils utils.c system.c time_meas.c time_stat.c tuntap_if.c reverse_bits.c)
target_include_directories(utils PUBLIC .)
target_link_libraries(utils PRIVATE ${T_LIB})
add_subdirectory(barrier)

View File

@@ -67,26 +67,18 @@ the T tracer and only output on the terminal). The default is
## Run a tracer
Go into the directory `common/utils/T/tracer` and run for example the
Go into the directory `common/utils/T/tracer` (or
`cmake_targets/ran_build/build/common/utils/T/tracer`) and run for example the
`enb` tracer:
```shell
#in common/utils/T/tracer directory
./enb -d ../T_messages.txt
```
You can also run it from `cmake_targets/ran_build/build/` directory:
```shell
# in cmake_targets/ran_build/build directory
./common/utils/T/tracer/enb -d ../../../common/utils/T/T_messages.txt
```
To trace a remote program, use the `-ip` option. For example,
if you want to trace a program running on `192.168.12.148` do:
```shell
# in common/utils/T/tracer directory
./enb -d ../T_messages.txt -ip 192.168.12.148
```

View File

@@ -44,7 +44,6 @@ Or, from an existing build directory using cmake:
```shell
cd cmake_targets/ran_build/build
cmake -DT_RECORD_DB=ON .
# use make or ninja
make T_tools
```
@@ -54,9 +53,6 @@ The binary is then available in:
cmake_targets/ran_build/build/common/utils/T/tracer/record_db
```
**NOTE*: Unlike other docs on T Tracer for `record_db` we are building in cmake
directory rather than in the directory of T.
## Prerequisites
- a running ClickHouse server reachable from `record_db`
@@ -88,8 +84,8 @@ To enable all events except the most verbose groups and write them to
ClickHouse:
```shell
cd cmake_targets/ran_build/build/
./common/utils/T/tracer/record_db -d ../../../common/utils/T/T_messages.txt \
cd cmake_targets/ran_build/build/common/utils/T/tracer
./record_db -d ../T_messages.txt \
-ON \
-off VCD \
-off HEAVY \
@@ -112,7 +108,7 @@ The event selection rules are the same as for [`record`](./record.md):
These options are processed in order. For example:
```shell
./common/utils/T/tracer/record_db -d ../../../common/utils/T/T_messages.txt -OFF -on GNB_PHY_UL_FD_PUSCH_IQ -on GNB_PHY_UL_PAYLOAD_RX_BITS
./record_db -d ../T_messages.txt -OFF -on GNB_PHY_UL_FD_PUSCH_IQ -on GNB_PHY_UL_PAYLOAD_RX_BITS
```
This starts from everything disabled and enables only the two listed

View File

@@ -4,7 +4,7 @@
#ifndef ACTOR_H
#define ACTOR_H
#include "common/utils/threadPool/notified_fifo.h"
#include "notified_fifo.h"
#define INIT_ACTOR(ptr, name, core_affinity) init_actor((Actor_t *)ptr, name, core_affinity);

View File

@@ -6,7 +6,6 @@ add_library(ds OBJECT
seq_arr.c
hashtable.c
obj_hashtable.c
spsc_q.c
)
target_include_directories(ds PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -10,6 +10,36 @@
#include "assertions.h"
//-------------------------------------------------------------------------------------------------------------------------------
char *hashtable_rc_code2string(hashtable_rc_t rcP)
//-------------------------------------------------------------------------------------------------------------------------------
{
switch (rcP) {
case HASH_TABLE_OK:
return "HASH_TABLE_OK";
break;
case HASH_TABLE_INSERT_OVERWRITTEN_DATA:
return "HASH_TABLE_INSERT_OVERWRITTEN_DATA";
break;
case HASH_TABLE_KEY_NOT_EXISTS:
return "HASH_TABLE_KEY_NOT_EXISTS";
break;
case HASH_TABLE_KEY_ALREADY_EXISTS:
return "HASH_TABLE_KEY_ALREADY_EXISTS";
break;
case HASH_TABLE_BAD_PARAMETER_HASHTABLE:
return "HASH_TABLE_BAD_PARAMETER_HASHTABLE";
break;
default:
return "UNKNOWN hashtable_rc_t";
}
}
//-------------------------------------------------------------------------------------------------------------------------------
/*
* free int function
* hash_free_int_func() is used when this hashtable is used to store int values as data (pointer = value).
@@ -117,6 +147,41 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtblP, cons
return HASH_TABLE_KEY_NOT_EXISTS;
}
//-------------------------------------------------------------------------------------------------------------------------------
hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP )
//-------------------------------------------------------------------------------------------------------------------------------
{
hash_node_t *node = NULL;
unsigned int i = 0;
if (hashtblP == NULL) {
*remaining_bytes_in_buffer_pP = snprintf(
buffer_pP,
*remaining_bytes_in_buffer_pP,
"HASH_TABLE_BAD_PARAMETER_HASHTABLE");
return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
}
while ((i < hashtblP->size) && (*remaining_bytes_in_buffer_pP > 0)) {
if (hashtblP->nodes[i] != NULL) {
node=hashtblP->nodes[i];
while(node) {
*remaining_bytes_in_buffer_pP = snprintf(
buffer_pP,
*remaining_bytes_in_buffer_pP,
"Key 0x%"PRIx64" Element %p\n",
node->key,
node->data);
node=node->next;
}
}
i += 1;
}
return HASH_TABLE_OK;
}
//-------------------------------------------------------------------------------------------------------------------------------
/*

View File

@@ -44,10 +44,12 @@ typedef struct hash_table_iterator_s {
const hash_table_t* const hashtbl;
} hash_table_iterator_s;
char *hashtable_rc_code2string(hashtable_rc_t rcP);
void hash_free_int_func(void *memoryP);
hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void *));
hashtable_rc_t hashtable_destroy(hash_table_t **hashtbl);
hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtbl, const uint64_t key);
hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP );
hashtable_rc_t hashtable_insert (hash_table_t *const hashtbl, const hash_key_t key, void *data);
hashtable_rc_t hashtable_remove (hash_table_t *const hashtbl, const hash_key_t key);
hashtable_rc_t hashtable_get (const hash_table_t *const hashtbl, const hash_key_t key, void **dataP);

View File

@@ -1,90 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "spsc_q.h"
spsc_q_t spsc_q_alloc(size_t cnt, size_t elsiz)
{
/* internally, use one element more: the ringbuffer is full if
* (write_idx + 1) % cnt == read_idx, so it's full if one element is still
* free (because otherwise write_idx == read_idx, but this is the empty
* condition) */
cnt += 1;
spsc_q_t rb = {.cnt = cnt, .elsiz = elsiz};
rb.buf = calloc(cnt, elsiz);
return rb;
}
void spsc_q_free(spsc_q_t *rb)
{
free(rb->buf);
memset(rb, 0, sizeof(*rb));
}
bool spsc_q_put(spsc_q_t *rb, const void *src, size_t elsiz)
{
assert(elsiz == rb->elsiz);
size_t w = atomic_load_explicit(&rb->write_idx, memory_order_relaxed);
size_t r = atomic_load_explicit(&rb->read_idx, memory_order_acquire);
if ((w + 1) % rb->cnt == r) {
return false;
}
uint8_t *bufpos = &rb->buf[w * rb->elsiz];
memcpy(bufpos, src, elsiz);
atomic_store_explicit(&rb->write_idx, (w + 1) % rb->cnt, memory_order_release);
return true;
}
bool spsc_q_get_if(spsc_q_t *rb, pred p, void *user, void *dest, size_t elsiz)
{
assert(elsiz == rb->elsiz);
size_t w = atomic_load_explicit(&rb->write_idx, memory_order_acquire);
size_t r = atomic_load_explicit(&rb->read_idx, memory_order_relaxed);
if (w == r) {
return false;
}
uint8_t *bufpos = &rb->buf[rb->read_idx * rb->elsiz];
if (!p(bufpos, user)) {
return false;
}
if (dest)
memcpy(dest, bufpos, elsiz);
atomic_store_explicit(&rb->read_idx, (r + 1) % rb->cnt, memory_order_release);
return true;
}
static bool always(const void *data, void *user)
{
(void) data;
(void) user;
return true;
}
bool spsc_q_get(spsc_q_t *rb, void *dest, size_t elsiz)
{
return spsc_q_get_if(rb, always, NULL, dest, elsiz);
}
int spsc_q_get_while(spsc_q_t *rb, pred p, void *user, void *dest, size_t elsiz, size_t max_len)
{
assert(elsiz == rb->elsiz);
size_t count = 0;
while (count < max_len && spsc_q_get_if(rb, p, user, dest + elsiz * count, elsiz))
count++;
return count;
}
int spsc_q_drop_while(spsc_q_t *rb, pred p, void *user)
{
size_t dropped = 0;
while (spsc_q_get_if(rb, p, user, NULL, rb->elsiz))
dropped++;
return dropped;
}

View File

@@ -1,37 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#ifndef SPSC_Q_H_
#define SPSC_Q_H_
#include <stdint.h>
#include <stdbool.h>
#include <stdatomic.h>
#if defined(__cplusplus)
// use atomic_size_t to help interworking with C++
using std::atomic_size_t;
#endif
typedef struct spsc_q {
uint8_t *buf;
size_t elsiz;
size_t cnt;
atomic_size_t write_idx;
atomic_size_t read_idx;
} spsc_q_t;
spsc_q_t spsc_q_alloc(size_t cnt, size_t elsiz);
void spsc_q_free(spsc_q_t *rb);
bool spsc_q_put(spsc_q_t *rb, const void *src, size_t elsiz);
bool spsc_q_get(spsc_q_t *rb, void *dest, size_t elsiz);
typedef bool (*pred)(const void *data, void *user);
bool spsc_q_get_if(spsc_q_t *rb, pred p, void *user, void *dest, size_t elsiz);
int spsc_q_drop_while(spsc_q_t *rb, pred p, void *user);
int spsc_q_get_while(spsc_q_t *rb, pred p, void *user, void *dest, size_t elsiz, size_t max_len);
#endif /* SPSC_Q_H_ */

View File

@@ -8,11 +8,5 @@ add_test(NAME test_seq_arr COMMAND test_seq_arr) # no options required
add_executable(test_hashtable test_hashtable.cpp)
add_dependencies(tests test_hashtable)
target_link_libraries(test_hashtable PRIVATE ds GTest::gtest)
add_test(NAME test_hashtable COMMAND ./test_hashtable)
add_executable(test_spsc_q test_spsc_q.cpp)
target_link_libraries(test_spsc_q ds GTest::gtest)
add_dependencies(tests test_spsc_q)
add_test(NAME test_spsc_q COMMAND test_spsc_q)
add_executable(test_spsc_q_perf test_spsc_q_perf.cpp)
target_link_libraries(test_spsc_q_perf PRIVATE ds benchmark::benchmark)
add_test(NAME test_hashtable
COMMAND ./test_hashtable)

View File

@@ -1,135 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include "gtest/gtest.h"
extern "C" {
#include "spsc_q.h"
}
TEST(spsc_q, basic_test) {
spsc_q_t rb = spsc_q_alloc(2, sizeof(int));
int a = 1;
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
EXPECT_FALSE(spsc_q_put(&rb, &a, sizeof(a)));
int b;
EXPECT_TRUE(spsc_q_get(&rb, &b, sizeof(b)));
EXPECT_EQ(a, b);
EXPECT_TRUE(spsc_q_get(&rb, &b, sizeof(b)));
EXPECT_EQ(a, b);
EXPECT_FALSE(spsc_q_get(&rb, &b, sizeof(b)));
spsc_q_free(&rb);
}
TEST(spsc_q, cont_write) {
spsc_q_t rb = spsc_q_alloc(10, sizeof(int));
int a = 1;
for (int i = 0; i < 1111; ++i) {
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
a++;
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
a++;
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
a++;
int b;
EXPECT_TRUE(spsc_q_get(&rb, &b, sizeof(b)));
EXPECT_EQ(b, a - 3);
EXPECT_TRUE(spsc_q_get(&rb, &b, sizeof(b)));
EXPECT_EQ(b, a - 2);
EXPECT_TRUE(spsc_q_get(&rb, &b, sizeof(b)));
EXPECT_EQ(b, a - 1);
}
spsc_q_free(&rb);
}
bool count(const void *data, void *user)
{
EXPECT_TRUE(data != NULL);
int *c = (int *)user;
(*c)++;
return true; /* count all */
}
TEST(spsc_q, iterator) {
spsc_q_t rb = spsc_q_alloc(10, sizeof(int));
int n = 8;
for (int i = 0; i < n; ++i)
EXPECT_TRUE(spsc_q_put(&rb, &i, sizeof(i)));
int c = 0;
int results[n];
int ret = spsc_q_get_while(&rb, count, &c, results, sizeof(*results), n);
EXPECT_EQ(c, n);
EXPECT_EQ(ret, n);
for (int i = 0; i < n; ++i)
EXPECT_EQ(results[i], i);
int b;
EXPECT_FALSE(spsc_q_get(&rb, &b, sizeof(b))); /* empty! */
spsc_q_free(&rb);
}
bool drop(const void *data, void *user)
{
const int *e = (const int *)data;
int *c = (int *)user;
EXPECT_EQ(*e, *c);
(*c)++;
return true; /* drop all */
}
TEST(spsc_q, drop) {
spsc_q_t rb = spsc_q_alloc(10, sizeof(int));
int n = 8;
for (int i = 0; i < n; ++i)
EXPECT_TRUE(spsc_q_put(&rb, &i, sizeof(i)));
int c = 0;
int ret = spsc_q_drop_while(&rb, drop, &c);
EXPECT_EQ(c, n);
EXPECT_EQ(ret, n);
int b;
EXPECT_FALSE(spsc_q_get(&rb, &b, sizeof(b))); /* empty! */
spsc_q_free(&rb);
}
TEST(spsc_q, full) {
int n = 3;
spsc_q_t rb = spsc_q_alloc(n, sizeof(int));
int a = 1;
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
a++;
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
a++;
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
a++;
EXPECT_FALSE(spsc_q_put(&rb, &a, sizeof(a))); /* full! */
int b;
EXPECT_TRUE(spsc_q_get(&rb, &b, sizeof(b)));
EXPECT_EQ(b, a - n);
EXPECT_TRUE(spsc_q_put(&rb, &a, sizeof(a)));
a++;
EXPECT_FALSE(spsc_q_put(&rb, &a, sizeof(a))); /* full! */
EXPECT_TRUE(spsc_q_get(&rb, &b, sizeof(b)));
EXPECT_EQ(b, a - n);
spsc_q_free(&rb);
}
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,75 +0,0 @@
#include "benchmark/benchmark.h"
#include "stdio.h"
#include "assert.h"
#include "pthread.h"
extern "C" {
#include "spsc_q.h"
}
typedef struct q_args {
spsc_q_t q;
int range;
} q_args_t;
static void *producer(void *arg)
{
q_args_t *a = (q_args_t *) arg;
int i = 0;
while (i <= a->range) {
if (spsc_q_put(&a->q, &i, sizeof(i)))
i++;
}
return NULL;
}
static void *consumer(void *arg)
{
q_args_t *a = (q_args_t *) arg;
int i = 0;
while (i != a->range) {
int r;
if (spsc_q_get(&a->q, &r, sizeof(r))) {
assert(r == i);
i++;
}
}
return NULL;
}
static void run_test(int range, int q_size)
{
q_args_t args = {
.q = spsc_q_alloc(q_size, sizeof(int)),
.range = range,
};
pthread_t p, c;
int ret;
// start
ret = pthread_create(&p, NULL, producer, &args);
assert(ret == 0);
ret = pthread_create(&c, NULL, consumer, &args);
assert(ret == 0);
ret = pthread_join(p, NULL);
assert(ret == 0);
ret = pthread_join(c, NULL);
assert(ret == 0);
// stop
// data/time => throughput
spsc_q_free(&args.q);
}
static void BM_spsc_q(benchmark::State &state)
{
int range = 500000;
int q_size = state.range(0);
for (auto _ : state)
run_test(range, q_size);
}
BENCHMARK(BM_spsc_q)->RangeMultiplier(2)->Range(10, 160);
BENCHMARK_MAIN();

View File

@@ -1,55 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include "fsn.h"
#include <assert.h>
static int num_slots[5] = {10, 20, 40, 80, 160};
fsn_t fsn_add_delta(fsn_t fsn, uint32_t delta)
{
const int slots_frame = num_slots[fsn.mu];
int next_f = fsn.f + delta / slots_frame;
int next_s = fsn.s + delta % slots_frame;
fsn_t res = {
.f = (next_f + next_s / slots_frame) % 1024,
.s = next_s % slots_frame,
.mu = fsn.mu,
};
return res;
}
int fsn_get_diff(fsn_t a, fsn_t b)
{
assert(a.mu == b.mu);
const int slots_frame = num_slots[a.mu];
int diff = (a.f * slots_frame + a.s) - (b.f * slots_frame + b.s);
if (diff < -512 * slots_frame)
diff += 1024 * slots_frame;
else if (diff > 512 * slots_frame)
diff -= 1024 * slots_frame;
return diff;
}
fsn_t fsn_get_max(fsn_t a, fsn_t b)
{
if (fsn_get_diff(a, b) <= 0) {
return b;
} else {
return a;
}
}
bool fsn_equal(fsn_t a, fsn_t b)
{
assert(a.mu == b.mu);
return a.f == b.f && a.s == b.s && a.mu == b.mu;
}
bool fsn_in_the_past(fsn_t old, fsn_t new)
{
int diff = fsn_get_diff(old, new);
return diff < 0;
}

View File

@@ -1,36 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#ifndef FSN_H_
#define FSN_H_
#include <stdint.h>
#include <stdbool.h>
/// helper type to encapsulate a frame/slot combination in a single type.
typedef struct fsn {
uint16_t f; /// frame
uint16_t s; /// slot
uint8_t mu; /// numerology
} fsn_t;
/* \brief Add delta slots to fsn. Note that this depends also on the stored
* numerology inside fsn. */
fsn_t fsn_add_delta(fsn_t fsn, uint32_t delta);
/* \brief Get difference of slots for a and b.
* \note asserts if numerology not the same. */
int fsn_get_diff(fsn_t a, fsn_t b);
/* \brief Gets the larger of two fsns */
fsn_t fsn_get_max(fsn_t a, fsn_t b);
/* \brief Compare if both fsn_t's are equal */
bool fsn_equal(fsn_t a, fsn_t b);
/* \brief Determine if told is in the past of tnew. The threshold is 512
* frames. */
bool fsn_in_the_past(fsn_t told, fsn_t tnew);
#endif /* FSN_H_ */

View File

@@ -13,7 +13,6 @@
#include <stdlib.h>
#include "assertions.h"
#include "common/utils/utils.h"
#include "common/utils/ds/byte_array.h"
#define MAX_SI_GROUPS 3
#define NR_MAX_PDSCH_TBS 3824
@@ -80,32 +79,10 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
// the total shift is 2 * 15, in dB scale thats 10log10(2^(15*2))
#define SQ15_SQUARED_NORM_FACTOR_DB 90.3089986992
typedef enum {
NR_SIB_1 = 1,
NR_SIB_2,
NR_SIB_3,
NR_SIB_4,
NR_SIB_5,
NR_SIB_6,
NR_SIB_7,
NR_SIB_8,
NR_SIB_9,
NR_SIB_10,
NR_SIB_11,
NR_SIB_12,
NR_SIB_13,
NR_SIB_14,
NR_SIB_15,
NR_SIB_16,
NR_SIB_17,
NR_SIB_18,
NR_SIB_19,
NR_SIB_20,
NR_SIB_21,
} nr_sib_type_t;
typedef struct {
nr_sib_type_t SIB_type;
uint8_t *SIB_buffer;
int SIB_size;
int SIB_type;
} nr_SIBs_t;
typedef struct nr_bandentry_s {

View File

@@ -2,10 +2,3 @@
add_executable(test_tpool_vs_actors test_tpool_vs_actors.c)
target_link_libraries(test_tpool_vs_actors PRIVATE thread-pool pthread LOG minimal_lib actor)
add_test(NAME test_tpool_vs_actors COMMAND ./test_tpool_vs_actors)
add_dependencies(tests test_tpool_vs_actors)
add_executable(test_fsn test_fsn.cpp)
add_dependencies(tests test_fsn)
target_link_libraries(test_fsn PRIVATE utils GTest::gtest)
add_test(NAME test_fsn COMMAND ./test_fsn)

View File

@@ -1,84 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include <gtest/gtest.h>
extern "C" {
#include "fsn.h"
}
TEST(fsn, test_mu0_fsn_add) {
fsn_t current = {123, 5, 0};
fsn_t next = current;
next = fsn_add_delta(next, 12);
EXPECT_EQ(next.f, 124);
EXPECT_EQ(next.s, 7);
EXPECT_EQ(next.mu, 0);
next = fsn_add_delta(next, 10);
EXPECT_EQ(next.f, 125);
EXPECT_EQ(next.s, 7);
EXPECT_EQ(next.mu, 0);
next = fsn_add_delta(next, 10 * 1024);
EXPECT_EQ(next.f, 125);
EXPECT_EQ(next.s, 7);
EXPECT_EQ(next.mu, 0);
}
TEST(fsn, test_mu0_get_diff) {
fsn_t current = {123, 5, 0};
fsn_t next = fsn_add_delta(current, 12);
int diff;
diff = fsn_get_diff(current, next);
EXPECT_EQ(diff, -12);
diff = fsn_get_diff(next, current);
EXPECT_EQ(diff, 12);
}
TEST(fsn, test_mu0_get_max) {
fsn_t current = {123, 5, 0};
fsn_t next = {125, 7, 0};
fsn_t max = fsn_get_max(current, next);
EXPECT_EQ(max.f, next.f);
EXPECT_EQ(max.s, next.s);
EXPECT_EQ(max.mu, next.mu);
}
TEST(fsn, test_mu0_equal) {
fsn_t a = {123, 5, 0};
fsn_t b = a;
fsn_t c = {123, 6, 0};
EXPECT_TRUE(fsn_equal(a, b));
EXPECT_FALSE(fsn_equal(a, c));
}
TEST(fsn, test_mu0_in_the_past) {
fsn_t a = {0, 0, 0};
fsn_t n = {100, 9, 0};
fsn_t b_bef = {511, 9, 0};
fsn_t b_ex = {512, 0, 0};
fsn_t b_aft = {512, 1, 0};
// a is in the past of n
EXPECT_TRUE(fsn_in_the_past(a, n));
// similarly, a is in the past of b_bef
EXPECT_TRUE(fsn_in_the_past(a, b_bef));
// difference "to both sides" is 512 frames, so we consider a still in the
// past of b_ex
EXPECT_TRUE(fsn_in_the_past(a, b_ex));
// (b_aft - a) < (a - b_aft) => b_aft is in the past of a because of
// wrap-around
EXPECT_TRUE(fsn_in_the_past(b_aft, a));
}
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1967,7 +1967,7 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_TRANSPORT/dci_NB_IoT.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_TRANSPORT/group_hopping.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/if4_tools.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_TRANSPORT/if4_tools.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_TRANSPORT/uci_tools.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_TRANSPORT/prach.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_TRANSPORT/edci.c \

View File

@@ -154,7 +154,7 @@ These modes of operation are supported:
- RedCap SIB1 v17 IEs supported
- Coexistence of RedCap and Normal UEs
- Handling of RedCap capability for small PDCP/RLC SN size
- Scheduling of other SIBs (2, 3, 4, 19)
- Scheduling of other SIBs (2, 19)
- NTN
- Support downlinkHARQ-FeedbackDisabled-r17
- Support for 32 PDSCH and PUSCH HARQ processes per UE
@@ -194,7 +194,7 @@ These modes of operation are supported:
- NR RRC (38.331) Rel 17 messages using new [asn1c](https://github.com/mouse07410/asn1c)
- LTE RRC (36.331) also updated to Rel 15
- Generation of system information (SIB2, SIB3, SIB4)
- Generation of system information (SIB2)
- RRC can configure PDCP and SDAP (through E1), and RLC and MAC (through F1)
- Interface with GTP-U (tunnel creation/handling for S1-U (NSA), N3 (SA), F1 interfaces)
- Integration of RRC messages and procedures supporting UE 5G SA connection
@@ -380,7 +380,7 @@ These modes of operation are supported:
- MIB processing
- Scheduling of system information block 1 (SIB1) reception
* Other system information
- Scheduling of other system information blocks reception (SIB2, SIB3, SIB4)
- Scheduling of other system information blocks reception
* Random access procedure (needs improvement, there is still not a clear separation between MAC and PHY)
- Mapping SSBs to multiple ROs
- Scheduling of PRACH

View File

@@ -135,7 +135,6 @@ The other SDRs (AW2S, LimeSDR, ...) have no READMEs.
- [clang-format.md](./clang-format.md): how to format the code. See also the
next entry for an error detection tool.
- [formatting](../tools/formatting/README.md) is a clang-format error detection tool
- [cppcheck](../tools/cppcheck/README.md) for static code analysis
- [sanitizers.md](./dev_tools/sanitizers.md): how to run with ASan/UBSan/MemSAN/TSan
- [iwyu](../tools/iwyu/README.md) is a tool to detect `#include` errors
- [docker-dev-env](../tools/docker-dev-env/README.md) is a ubuntu24 docker development environment

View File

@@ -633,98 +633,6 @@ sequenceDiagram
Note over TargetCU: Then: encode Handover Command, send NGAP HANDOVER REQUEST ACKNOWLEDGE
```
### Neighbour cells
#### SIB3/SIB4 and measurement-gap implementation
The following section documents the implementation-level control flow
for SIB3/SIB4 and measurement-gap handling in current OAI, using the configured
neighbor cell list as a shared input model.
Briefly, the three procedures are:
- SIB3: CU derives and provides intra-frequency neighbour SI, which DU broadcasts
and UE uses for autonomous idle/inactive intra-frequency reselection.
- SIB4: CU derives and provides inter-frequency carrier/neighbour SI, which DU
broadcasts and UE uses for autonomous idle/inactive inter-frequency reselection.
- MeasGap: CU/DU coordinate dedicated `MeasGapConfig` in UE `MeasConfig`, DU
scheduler interrupts transmission (`nr_measgap_scheduling()`) for the UE to
apply the MeasGap configuration in connected mode for gap-based measurements that
are sent as `MeasurementReport` and processed at CU-CP (`rrc_gNB_process_MeasurementReport()`).
Event-driven reports (for example A3) are used by CU-side mobility logic and can
trigger handover procedures.
### MeasGap
```mermaid
sequenceDiagram
participant DM as Data model (neighbour_cell_configuration)
participant CU as CU-CP (RRC)
participant DU as DU (MAC/RRC)
participant UE as UE
CU-->>DM: Read serving + neighbour frequency/PCI/band data
DM-->>CU: Provide neighbour/frequency inputs for MeasConfig
CU->>CU: nr_rrc_get_measconfig
Note over CU: Build UE MeasConfig
CU->>CU: get_meas_timing_config (cell.mtc, ue.measConfig)
Note over CU: Check distinct ssbFrequency
alt one frequency only
Note over CU: returns NULL, no meas_timing_config sent to DU
else multiple frequencies
CU->>DU: F1AP UE Context Setup Request
Note over CU,DU: Includes cu_to_du_rrc_info.meas_timing_config
DU->>DU: create_measgap_config
DU->>DU: encode_measgap_config
DU-->>CU: F1AP UE Context Setup Response
Note over DU,CU: Includes du_to_cu_rrc_info.meas_gap_config
CU->>CU: get_meas_gap_config
Note over CU: Decode/store gap in UE MeasConfig (UE.measConfig.measGapConfig)
CU->>UE: RRCReconfiguration
Note over CU,UE: Includes MeasConfig.measGapConfig
rect rgba(210, 235, 255, 0.35)
Note over DU,UE: Measurement-gap window
DU->>DU: nr_measgap_scheduling
Note over DU: Interrupt transmission for meas gap
UE->>UE: nr_rrc_handle_meas_indication
Note over UE: Perform gap-based neighbour/inter-frequency measurements
UE-->>CU: MeasurementReport
end
Note over UE,CU: UL-DCCH MeasurementReport for configured events (e.g. A3)
CU->>CU: rrc_gNB_process_MeasurementReport
Note over CU: Run mobility decision logic (may trigger handover)
end
```
### SIB3/SIB4
```mermaid
sequenceDiagram
participant DM as Data model (neighbour_cell_configuration)
participant CU as CU-CP (RRC)
participant DU as DU
participant UE as UE
CU->>CU: cp_f1_served_cell_info_to_cell
CU->>DM: get_cell_neighbour_list
DM-->>CU: neighbour_cell_configuration for serving cell
CU->>CU: get_ssb_arfcn
Note over CU: Derive serving_ssb_arfcn from cell MTC
loop for each configured neighbour
Note over CU: Compare neighbour.absoluteFrequencySSB vs serving_ssb_arfcn
alt equal
CU->>CU: get_sib3_intra_freq_neighbors
else different
CU->>CU: get_sib4_inter_freq_neighbors
end
end
CU-->>DU: F1AP F1 Setup Response
DU-->>UE: BCCH-DL-SCH-Message
Note over DU,UE: Broadcast SystemInformation including configured SIB3/SIB4
UE->>UE: nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message
Note over UE: Evaluate idle/inactive reselection criteria and timers
Note over UE,DU: After reselection, access/registration continues on selected cell DU as needed
```
## UE Context
UE context information is stored in `gNB_RRC_UE_t`, which includes:

View File

@@ -94,81 +94,7 @@ the [MAC configuration](../MAC/mac-usage.md) as well for SIB configuration.
deactivated, a transparent SDAP header is prepended to packets, but no
further processing is being done.
- `cu_sibs` (default: `[]`) list of SIBs to give to the DU for transmission.
Currently supported:
- SIB2: serving-cell reselection parameters (configured in `sib2_config`)
- SIB3: intra-frequency neighbour cell list (neighbours on the same SSB ARFCN as the serving cell)
- SIB4: inter-frequency carriers + neighbour lists, grouped per `(absoluteFrequencySSB, subcarrierSpacing)`. Per-frequency fields (e.g. `cellReselectionPriority`, `threshX_HighP`, `threshX_LowP`, `q_OffsetFreq`) come from `frequency_list`
Example activation:
```
cu_sibs = ( 2, 3, 4 );
```
SIB2 is configured per-gNB in `sib2_config` (see below). SIB3/SIB4 are derived from the neighbour configuration:
- `neighbour_list` / `neighbour_cell_configuration`: neighbour identity + per-neighbour offsets (`q_OffsetCell`, etc.)
- `frequency_list`: per-frequency SIB4 reselection parameters (priority/thresholds/`q_OffsetFreq`)
Example `gNBs.[0].sib2_config`:
```
cu_sibs = ( 2 );
sib2_config : {
q_Hyst = 0;
cellReselectionPriority = 0;
threshServingLowP = 0;
threshServingLowQ = 4;
s_NonIntraSearchP = 10;
s_NonIntraSearchQ = 8;
q_RxLevMin = -56;
q_QualMin = -18;
s_IntraSearchP = 22;
s_IntraSearchQ = 20;
t_ReselectionNR = 1;
deriveSSB_IndexFromCell = 1;
speed_t_Evaluation = 0;
speed_t_HystNormal = 0;
speed_n_CellChangeMedium = 1;
speed_n_CellChangeHigh = 2;
speed_sf_Medium = 1;
speed_sf_High = 0;
};
```
#### SIB3/SIB4 and measurement gaps
This section summarizes how SIB3/SIB4 and measurement gaps relate in NR and how OAI currently implements them.
From 3GPP TS 38.331:
- `SIB3` carries intra-frequency reselection information (`intraFreqNeighCellList`).
- `SIB4` carries inter-frequency reselection information (`interFreqCarrierFreqList`
and per-carrier neighbour lists).
- `MeasGapConfig` is part of dedicated `MeasConfig` (typically sent in
`RRCReconfiguration`) and controls measurement gaps in connected mode.
In other words:
- SIB3/SIB4 are broadcast SI for idle/inactive (`RRC_IDLE` / `RRC_INACTIVE`)
reselection behavior: UE performs autonomous cell reselection using broadcast
SI (SIB3 for intra-frequency, SIB4 for inter-frequency).
- `MeasGapConfig` is a dedicated UE measurement behavior and applies to
connected mode (`RRC_CONNECTED`): the network configures what the UE
measures and reports (periodic and event-based, e.g., A3), and those reports
are used by CU-CP mobility logic (including handover decisions).
MeasGap does not depend on SIB3/SIB4, however they share the same underlying
neighbour/frequency data model, which is the common source of serving +
neighbour frequency information (see also [Neighbor-gNB configuration](#neighbour-gnb-configuration)):
- SIB3/SIB4 generation is done on the CU-CP side (inside `rrc_gNB_du.c`) from
neighbour/frequency configuration and serving-cell MTC-derived ARFCN.
- Measurement-gap configuration also starts from the same neighbour/frequency
model: CU uses neighbour fields (frequency/PCI/band) to build UE
`MeasConfig` measurement objects, then DU derives/encodes gap parameters
from CU-provided timing (`meas_timing_config`) and returns `meas_gap_config`
for CU forwarding in dedicated `RRCReconfiguration`.
Detailed implementation flow and sequence diagrams are documented in [`rrc-dev.md`](./rrc-dev.md).
Currently, SIB2 is supported.
#### UE-specific configuration
@@ -179,64 +105,12 @@ Detailed implementation flow and sequence diagrams are documented in [`rrc-dev.m
Refer to the [handover tutorial](../handover-tutorial.md) for detailed information about gNB neighbors and handover procedures.
##### Configuration structure and key semantics
The neighbour configuration is a 2-level structure:
- Outer list: `neighbour_list`
- Key: `nr_cellid` of the serving cell
- One entry per serving cell
- Inner list: `neighbour_cell_configuration`
- Actual neighbour cells for that serving cell
- Contains neighbour fields such as `gNB_ID`, neighbour `nr_cellid`, `physical_cellId`, frequency, PLMN, etc.
This same core configuration model is reused by multiple RRC procedures.
- SIB3/SIB4 generation: uses neighbour identity/frequency/offset fields to derive
intra/inter-frequency SI.
- Connected-mode measurement config: uses neighbour frequency/PCI/band fields to build
UE `MeasConfig` measurement objects.
- Handover-related procedures: reuse neighbour identity fields (e.g., cell ID/PCI/PLMN
TAC, gNB ID) for target selection and for populating target-cell information carried
in NGAP handover messages.
Conceptually, for each serving cell the RRC keeps:
- A per-frequency table (`inter_freqs`): one entry per `(absoluteFrequencySSB,
subcarrierSpacing)` used for SIB4, containing the SIB4 per-frequency fields
(priority, thresholds, `q_OffsetFreq`, `q_RxLevMin`, `t_ReselectionNR`).
- A per-neighbour list (`neighbour_cells`): one entry per neighbour, with
identity (cell ID, PCI, PLMN, TAC), frequency (`absoluteFrequencySSB`,
`subcarrierSpacing`, `band`), and SIB3/SIB4 per-neighbour offsets
(`q_OffsetCell`, `q_RxLevMinOffsetCell`, `q_QualMinOffsetCell`).
- A link from neighbours to frequencies: each neighbour implicitly points to
the matching `inter_freqs` entry via its `(absoluteFrequencySSB,
subcarrierSpacing)`; if no such frequency exists, it is treated as having no
SIB4 per-frequency configuration.
Notes:
- In `neighbour_list`, only `nr_cellid` is used as the key for lookup.
- `physical_cellId` belongs to neighbour-cell entries in `neighbour_cell_configuration` (inner list).
- `nr_cellid` entries in `neighbour_list` should be unique to avoid ambiguous lookup.
- Intra-frequency neighbours (SIB3) are derived only from the per-cell
`neighbour_cell_configuration` on the serving carrier.
At configuration time (`gnb_config.c`), neighbours are parsed into `neighbour_cells`,
per-neighbour SIB3/SIB4 offsets are validated, and a per-frequency array `inter_freqs`
is built by grouping neighbours by `(absoluteFrequencySSB, subcarrierSpacing)` and
in-range SIB4 per-frequency fields (`cellReselectionPriority`, `threshX_HighP/L`,
`q_OffsetFreq`) across neighbours on the same ARFCN. At SIB4 build time, the RRC uses
`inter_freqs` to create one `InterFreqCarrierFreqInfo` per ARFCN for inter-frequency
carriers (ARFCN different from the serving SSB ARFCN) and attaches all neighbours whose
`inter_freq_idx` points to that frequency entry.
##### Required configuration parameters
To define a neighbour cell in the configuration file, the following parameters are required:
To define a neighbor cell in the configuration file, the following parameters are required:
- `gNB_ID` - identifier of the neighbour gNB (e.g., `0xe01`)
- `nr_cellid` - cell identifier of the neighbour cell (e.g., `11111111`)
- `gNB_ID` - identifier of the neighbor gNB (e.g., `0xe01`)
- `nr_cellid` - cell identifier of the neighbor cell (e.g., `11111111`)
- `physical_cellId` - physical cell ID for radio identification (e.g., `1`)
- `absoluteFrequencySSB` - SSB frequency in ARFCN notation (e.g., `643296`)
- `subcarrierSpacing` - numerology index: 0=15kHz, 1=30kHz, 2=60kHz, 3=120kHz
@@ -249,45 +123,19 @@ To define a neighbour cell in the configuration file, the following parameters a
Example configuration structure:
```
# Per-frequency SIB4 configuration (one entry per ARFCN), shared by all cells
frequency_list = (
{
absoluteFrequencySSB = 643296;
subcarrierSpacing = 1; # 30 kHz
band = 78;
frequency_config = (
{
cellReselectionPriority = 5;
threshX_HighP = 10;
threshX_LowP = 6;
q_OffsetFreq = 0;
# Optional: threshX_HighQ, threshX_LowQ, etc.
}
);
}
);
# Per-cell neighbour configuration; neighbours reference frequency_list via ARFCN/SCS
neighbour_list = (
{
nr_cellid = 12345678;
neighbour_cell_configuration = (
{
gNB_ID = 0xe01;
nr_cellid = 11111111;
physical_cellId = 1;
absoluteFrequencySSB = 643296; # ARFCN used to look up matching entry in frequency_list
subcarrierSpacing = 1; # 30 kHz
absoluteFrequencySSB = 643296;
subcarrierSpacing = 1; # 30 kHz
band = 78;
plmn = { mcc = 001; mnc = 01; mnc_length = 2 };
tracking_area_code = 1;
# Example per-neighbour offsets (SIB3/SIB4)
q_OffsetCell = 0;
q_RxLevMinOffsetCell = -1;
q_QualMinOffsetCell = -1;
}
);
}

View File

@@ -96,6 +96,10 @@ information on how the images are built.
- orion: Cross-compilation from Intel to ARM
- base image from `Dockerfile.base.ubuntu.cross-arm64`
- build image from `Dockerfile.build.ubuntu.cross-arm64` (no target images)
- [RAN-cppcheck](https://jenkins-oai.eurecom.fr/job/RAN-cppcheck/)
~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
- bellatrix
- performs static code analysis, currently not actively enforced
- [RAN-RHEL8-Cluster-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-RHEL8-Cluster-Image-Builder/)
~BUILD-ONLY ~4G-LTE ~5G-NR ~nrUE
- cluster (`Asterix-OC-oaicicd-session` resource): RHEL image build using the OpenShift Cluster (using gcc/clang)

View File

@@ -512,16 +512,8 @@ configuration, e.g. [neighbour-config-rfsim.conf](../../ci-scripts/conf_files/ne
This configuration can also be present in a different file and included in the
gNB configuration file with `@include "neighbour-config-rfsim.conf"`.
The neighbor configuration is nested:
- `neighbour_list` outer entries are keyed by serving `nr_cellid`
- each outer entry contains `neighbour_cell_configuration`, i.e., the list of neighbor cells for that serving cell
In this model:
- outer `nr_cellid` entries should be unique
- neighbor `physical_cellId` values are defined in inner neighbor entries
- the same serving-cell keyed neighbor mapping is used for both F1 and N2 handover logic
For each gNB there is a `neighbour_cell_configuration` linked to its serving
cell ID.
See the example above for `neighbour-config-ho.conf`. The same configuration
is for both F1 and N2 handover.

View File

@@ -1,7 +1,7 @@
services:
mysql:
container_name: "mysql"
image: mysql:9.6
image: mysql:8.0
volumes:
- ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ./healthscripts/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
@@ -172,7 +172,7 @@ services:
privileged: true
init: true
container_name: oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:jammy
entrypoint: /bin/bash -c \
"ip route add 10.0.0.0/16 via 192.168.70.134 dev eth0; ip route; sleep infinity"
command: ["/bin/bash", "-c", "trap : SIGTERM SIGINT; sleep infinity & wait"]

View File

@@ -1,7 +1,7 @@
services:
mysql:
container_name: "mysql"
image: mysql:9.6
image: mysql:8.0
volumes:
- ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql
- ./healthscripts/mysql-healthcheck.sh:/tmp/mysql-healthcheck.sh
@@ -154,9 +154,9 @@ services:
privileged: true
init: true
container_name: oai-ext-dn
image: oaisoftwarealliance/trf-gen-cn5g:latest
image: oaisoftwarealliance/trf-gen-cn5g:jammy
entrypoint: /bin/bash -c \
"ip route add 10.0.0.0/16 via 192.168.70.134 dev eth0; ip route; iperf3 -s -D; sleep infinity"
"ip route add 10.0.0.0/16 via 192.168.70.134 dev eth0; ip route; sleep infinity"
command: ["/bin/bash", "-c", "trap : SIGTERM SIGINT; sleep infinity & wait"]
healthcheck:
test: /bin/bash -c "ip r | grep 10.0.0"

View File

@@ -25,4 +25,4 @@ RUN /bin/sh oaienv && \
CFLAGS="-Werror" CXXFLAGS="-Werror -Wno-vla-cxx-extension" \
./build_oai --phy_simulators --gNB --eNB --nrUE --UE \
--ninja --build-tool-opt -k10 \
--noavx512 -c
--noavx512 --disable-T-Tracer -c

View File

@@ -24,7 +24,6 @@ RUN /bin/sh oaienv && \
-DAVX512=OFF -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \
-DENABLE_PHYSIM_TESTS=ON \
-DSANITIZE_ADDRESS=ON -DSANITIZE_UNDEFINED=ON \
-DT_TRACER=OFF \
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/opt/oai-physim/bin && \
ninja -k10 -j36

View File

@@ -20,7 +20,7 @@
#include "nfapi/oai_integration/vendor_ext.h"
#include "radio/COMMON/common_lib.h"
#include "PHY/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/phy_extern.h"

View File

@@ -28,7 +28,7 @@
#include "PHY/phy_extern.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"
#include "PHY/LTE_REFSIG/lte_refsig.h"
#include "PHY/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "SCHED/sched_common.h"
#include "common/utils/LOG/log.h"

View File

@@ -161,12 +161,7 @@ static void rx_func(processingData_L1_t *info)
NR_UL_IND_t UL_INFO = {.frame = frame_rx, .slot = slot_rx, .module_id = gNB->Mod_id, .CC_id = gNB->CC_id};
// Do PRACH RU processing
UL_INFO.rach_ind.pdu_list = UL_INFO.prach_pdu_indication_list;
UL_INFO.rach_ind.number_of_pdus = 0;
// even if processing is late, we might collect all PRACH
// the last PRACH's frame/slot is when all UE's appear to have accessed
prach_item_t p;
while (spsc_q_get(&gNB->prach_l1rx_queue, &p, sizeof(p)))
L1_nr_prach_procedures(gNB, &p, &UL_INFO.rach_ind);
L1_nr_prach_procedures(gNB, frame_rx, slot_rx, &UL_INFO.rach_ind);
//WA: comment rotation in tx/rx
if (gNB->phase_comp) {

View File

@@ -15,13 +15,12 @@
#include "common/utils/nr/nr_common.h"
#include "common/utils/assertions.h"
#include "common/utils/system.h"
#include "common/utils/fsn.h"
#include "common/ran_context.h"
#include "radio/COMMON/common_lib.h"
#include "radio/ETHERNET/ethernet_lib.h"
#include "PHY/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/defs_nr_common.h"
#include "PHY/phy_extern.h"
@@ -981,16 +980,11 @@ void *ru_thread(void *param)
proc->tti_rx * gNB->frame_parms.samples_per_slot_wCP);
// Do PRACH RU processing
fsn_t now = {.f = proc->frame_rx, .s = proc->tti_rx, .mu = fp->numerology_index};
prach_item_t p;
while (get_next_nr_prach(&gNB->prach_ru_queue, &now, &p)) {
prach_item_t *p =
find_nr_prach(&gNB->prach_list, proc->frame_rx, proc->tti_rx, gNB->frame_parms.nb_antennas_rx, NR_SEARCH_EXIST);
if (p) {
// need to extract RACH data for later processing by rx_nr_prach()
rx_nr_prach_ru(&p, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset);
bool success = spsc_q_put(&gNB->prach_l1rx_queue, &p, sizeof(p));
// assume prach_l1rx_queue never full: prach_ru_queue filled at
// constant pace, but prach_l1rx_queue emptied as fast as possible,
// see rx_func()
DevAssert(success);
rx_nr_prach_ru(p, ru->common.rxdata, ru->nr_frame_parms, ru->N_TA_offset);
} // end if (prach_id >= 0)
} // end if (ru->feprx)
} // end if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) {

View File

@@ -27,7 +27,7 @@
#include "radio/COMMON/common_lib.h"
#include "radio/ETHERNET/ethernet_lib.h"
#include "PHY/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "SCHED/sched_eNB.h"

View File

@@ -183,7 +183,7 @@ bool wls_pnf_nr_send_p5_message(pnf_t *pnf, nfapi_nr_p4_p5_message_header_t *msg
bool wls_pnf_nr_send_p7_message(pnf_p7_t *pnf_p7, nfapi_nr_p7_message_header_t *msg, uint32_t msg_len)
{
UNUSED(msg_len);
UNUSED_VARIABLE(msg_len);
if (pnf_p7->terminate) {
// don't send any further P7 messages after terminating
return false;

View File

@@ -410,7 +410,7 @@ int wls_fapi_nr_vnf_start(nfapi_vnf_config_t *cfg)
bool wls_vnf_nr_send_p5_message(vnf_t *vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t *msg, uint32_t msg_len)
{
UNUSED(p5_idx);
UNUSED_VARIABLE(p5_idx);
int packed_len =
vnf->_public.pack_func(msg, msg_len, vnf->tx_message_buffer, sizeof(vnf->tx_message_buffer), &vnf->_public.codec_config);

View File

@@ -50,8 +50,6 @@ int l1_north_init_gNB()
NR_gNB_PHY_STATS_t *get_phy_stats(PHY_VARS_gNB *gNB, uint16_t rnti)
{
// TODO reimplement with hashtable? also called from both UL/DL => not
// thread-safe
NR_gNB_PHY_STATS_t *stats;
int first_free = -1;
for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
@@ -143,6 +141,16 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
init_DLSCH_struct(gNB);
gNB->nr_srs_info = (nr_srs_info_t **)malloc16_clear(gNB->max_nb_srs * sizeof(nr_srs_info_t*));
for (int id = 0; id < gNB->max_nb_srs; id++) {
gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
gNB->nr_srs_info[id]->srs_generated_signal = malloc16_clear(MAX_NUM_NR_SRS_AP * sizeof(c16_t *));
for(int ap=0; ap<MAX_NUM_NR_SRS_AP; ap++) {
gNB->nr_srs_info[id]->srs_generated_signal[ap] =
malloc16_clear(fp->ofdm_symbol_size * MAX_NUM_NR_SRS_SYMBOLS * sizeof(c16_t));
}
}
/* Do NOT allocate per-antenna rxdataF: the gNB gets a pointer to the
* RU to copy/recover freq-domain memory from there */
common_vars->rxdataF = (c16_t ***)malloc16(common_vars->num_beams_period * sizeof(c16_t**));
@@ -166,7 +174,7 @@ void phy_init_nr_gNB(PHY_VARS_gNB *gNB)
common_vars->debugBuff_sample_offset = 0;
// PRACH
init_nr_prach(gNB);
init_prach_list(&gNB->prach_list);
int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value;
int n_buf = Prx*max_ul_mimo_layers;
@@ -204,11 +212,19 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
free_and_zero(meas->n0_subband_power);
for (int id = 0; id < gNB->max_nb_srs; id++) {
for(int i=0; i<MAX_NUM_NR_SRS_AP; i++) {
free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal[i]);
}
free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal);
free_and_zero(gNB->nr_srs_info[id]);
}
free_and_zero(gNB->nr_srs_info);
free_ul_reference_signal_sequences();
free_gnb_lowpapr_sequences();
reset_nr_transport(gNB);
reset_nr_prach(gNB);
destroy_DLSCH_struct(gNB);
@@ -421,14 +437,18 @@ void init_nr_transport(PHY_VARS_gNB *gNB)
else
buffer_ul_slots = (nb_ul_slots_period < slot_ahead) ? nb_ul_slots_period : slot_ahead;
gNB->max_nb_pucch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1;
gNB->max_nb_pusch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1;
gNB->max_nb_srs = buffer_ul_slots ? buffer_ul_slots << 1 : 1; // assuming at most 2 SRS per slot
int max_nb_pucch = buffer_ul_slots ? MAX_MOBILES_PER_GNB * buffer_ul_slots : 1;
gNB->pucch_queue = spsc_q_alloc(max_nb_pucch, sizeof(NR_gNB_PUCCH_job_t));
gNB->pusch_queue = spsc_q_alloc(gNB->max_nb_pusch, sizeof(NR_gNB_PUSCH_job_t));
gNB->pucch = (NR_gNB_PUCCH_t *)malloc16(gNB->max_nb_pucch * sizeof(NR_gNB_PUCCH_t));
for (int i = 0; i < gNB->max_nb_pucch; i++) {
memset(&gNB->pucch[i], 0, sizeof(gNB->pucch[i]));
}
int max_nb_srs = buffer_ul_slots ? buffer_ul_slots << 1 : 1; // assuming at most 2 SRS per slot
gNB->srs_queue = spsc_q_alloc(max_nb_srs, sizeof(NR_gNB_SRS_job_t));
gNB->srs = (NR_gNB_SRS_t *)malloc16(gNB->max_nb_srs * sizeof(NR_gNB_SRS_t));
for (int i = 0; i < gNB->max_nb_srs; i++)
gNB->srs[i].active = 0;
gNB->ulsch = (NR_gNB_ULSCH_t *)malloc16(gNB->max_nb_pusch * sizeof(NR_gNB_ULSCH_t));
for (int i = 0; i < gNB->max_nb_pusch; i++) {
@@ -445,9 +465,8 @@ void reset_nr_transport(PHY_VARS_gNB *gNB)
{
const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
spsc_q_free(&gNB->pucch_queue);
spsc_q_free(&gNB->pusch_queue);
spsc_q_free(&gNB->srs_queue);
free(gNB->pucch);
free(gNB->srs);
for (int i = 0; i < gNB->max_nb_pusch; i++)
free_gNB_ulsch(&gNB->ulsch[i], fp->N_RB_UL);

View File

@@ -3,6 +3,7 @@
*/
#include "PHY/phy_extern.h"
#include "SCHED/sched_common.h"
#include "assertions.h"
#include <math.h>
#include "openair1/PHY/defs_RU.h"

View File

@@ -251,6 +251,8 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
ue->nr_csi_info->csi_rs_generated_signal[i] =
malloc16_clear(fp->samples_per_slot_wCP * sizeof(**ue->nr_csi_info->csi_rs_generated_signal));
}
ue->nr_srs_info = malloc16_clear(sizeof(nr_srs_info_t));
}
ue->init_averaging = 1;
@@ -299,6 +301,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue)
free_and_zero(ue->nr_csi_info->csi_rs_generated_signal);
free_and_zero(ue->nr_csi_info);
free_and_zero(ue->nr_srs_info);
free_and_zero(ue->prach_vars[gNB_id]);
}

View File

@@ -3,6 +3,7 @@
*/
#include <stdio.h>
//#include "PHY/defs_eNB.h"
#include "PHY/defs_RU.h"
#include "PHY/TOOLS/alaw_lut.h"
//#include "PHY/phy_extern.h"

View File

@@ -4,7 +4,7 @@
#ifndef __IF4_TOOLS_H__
#define __IF4_TOOLS_H__
#include "openair1/PHY/defs_RU.h"
#include "PHY/defs_eNB.h"
/// Macro for IF4 packet type
#define IF4p5_PACKET_TYPE 0x080A

View File

@@ -7,7 +7,9 @@
*/
#include "PHY/sse_intrin.h"
#include "PHY/defs_eNB.h"
#include "PHY/if4_tools.h"
//#include "PHY/phy_extern.h"
//#include "prach.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "SCHED/sched_eNB.h"
#include "common/utils/LOG/vcd_signal_dumper.h"

View File

@@ -4255,7 +4255,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
LOG_D(PHY,"Format 0 DCI :ulsch (ue): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
LOG_D(PHY,"Format 0 DCI :ulsch (ue): phich status %d\n",ulsch->harq_processes[harq_pid]->status);
#else
UNUSED(dai);
UNUSED_VARIABLE(dai);
#endif
return(0);
} else {
@@ -4889,7 +4889,7 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
printf("ulsch (eNB): Nsymb_pusch %d\n",ulsch->harq_processes[harq_pid]->Nsymb_pusch);
printf("ulsch (eNB): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
#else
UNUSED(dai);
UNUSED_VARIABLE(dai);
#endif
return(0);
} else {

View File

@@ -10,7 +10,7 @@
#include "executables/lte-softmodem.h"
#include "PHY/phy_extern_ue.h"
//#include "prach.h"
#include "PHY/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "SCHED_UE/sched_UE.h"
#include "SCHED/sched_common_extern.h"

View File

@@ -9,6 +9,7 @@
#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/LTE_TRANSPORT/transport_eNB.h"
#include "modulation_eNB.h"
#include "nr_modulation.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
int beam_precoding(int32_t **txdataF,
@@ -79,3 +80,25 @@ int beam_precoding_one_eNB(int32_t **txdataF,
}
return 0;
}
void nr_beam_precoding(c16_t **txdataF,
c16_t **txdataF_BF,
NR_DL_FRAME_PARMS *frame_parms,
int32_t ***beam_weights,
int symbol,
int aa,
int nb_antenna_ports,
int offset)
{
// clear txdata_BF[aa][re] for each call of ue_spec_beamforming
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 0, sizeof(c16_t) *(frame_parms->ofdm_symbol_size));
for (int p = 0; p < nb_antenna_ports; p++) {
multadd_cpx_vector((c16_t *)&txdataF[p][(symbol * frame_parms->ofdm_symbol_size) + offset],
(c16_t *)beam_weights[p][aa],
(c16_t *)&txdataF_BF[aa][symbol * frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size,
15);
}
}

View File

@@ -1,27 +0,0 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include "nr_modulation.h"
#include "openair1/PHY/TOOLS/tools_defs.h"
void nr_beam_precoding(c16_t **txdataF,
c16_t **txdataF_BF,
NR_DL_FRAME_PARMS *frame_parms,
int32_t ***beam_weights,
int symbol,
int aa,
int nb_antenna_ports,
int offset)
{
// clear txdata_BF[aa][re] for each call of ue_spec_beamforming
memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], 0, sizeof(c16_t) *(frame_parms->ofdm_symbol_size));
for (int p = 0; p < nb_antenna_ports; p++) {
multadd_cpx_vector((c16_t *)&txdataF[p][(symbol * frame_parms->ofdm_symbol_size) + offset],
(c16_t *)beam_weights[p][aa],
(c16_t *)&txdataF_BF[aa][symbol * frame_parms->ofdm_symbol_size],
frame_parms->ofdm_symbol_size,
15);
}
}

View File

@@ -3,7 +3,6 @@
*/
#include "nr_modulation.h"
#include "openair1/PHY/TOOLS/tools_defs.h"
#include "PHY/NR_REFSIG/nr_mod_table.h"
#include "executables/softmodem-common.h"
#include <simde/x86/avx512.h>
@@ -689,12 +688,12 @@ c16_t nr_layer_precoder_cm(int n_layers,
int symSz,
c16_t datatx_F_precoding[n_layers][symSz],
int ap,
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS],
nfapi_nr_pm_pdu_t *pmi_pdu,
int offset)
{
c16_t precodatatx_F = {0};
for (int al = 0; al < n_layers; al++) {
c16_t prec_weight = weights[al][ap];
c16_t prec_weight = pmi_pdu->weights[al][ap];
precodatatx_F = c16maddShift(datatx_F_precoding[al][offset], prec_weight, precodatatx_F, 15);
}
return precodatatx_F;
@@ -804,15 +803,15 @@ static inline __attribute__((always_inline)) __m128i cmac_prec128(__m128i y, __m
#endif
#define load_consts(Type, Instruct, Rank) \
const Type w_c##Rank = Instruct(c16toI32(c16conj(weights[Rank][ant]))); \
const Type w_s##Rank = Instruct(c16toI32(c16swap(weights[Rank][ant]))); \
const Type w_c##Rank = Instruct(c16toI32(c16conj(pmi_pdu->weights[Rank][ant]))); \
const Type w_s##Rank = Instruct(c16toI32(c16swap(pmi_pdu->weights[Rank][ant]))); \
const Type *in##Rank = (Type *)(txdataF_res_mapped[Rank] + sc_offset + (out-beginning));
void nr_layer_precoder_simd(const int n_layers,
const int symSz,
const c16_t txdataF_res_mapped[n_layers][symSz],
const int ant,
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS],
const nfapi_nr_pm_pdu_t *pmi_pdu,
const int sc_offset,
const int re_cnt,
c16_t *txdataF_precoded)

View File

@@ -7,6 +7,7 @@
#include <stdint.h>
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#define DMRS_MOD_ORDER 2
/*Precoding matices: W[pmi][antenna_port][layer]*/
@@ -126,7 +127,7 @@ c16_t nr_layer_precoder_cm(int n_layers,
int symSz,
c16_t datatx_F_precoding[n_layers][symSz],
int ap,
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS],
nfapi_nr_pm_pdu_t *pmi_pdu,
int offset);
/*! \brief Precoding with SIMDe, txdataF_precoded[] = prec_matrix[] * txdataF_res_mapped[]
@@ -139,7 +140,7 @@ void nr_layer_precoder_simd(const int n_layers,
const int symSz,
const c16_t txdataF_res_mapped[n_layers][symSz],
const int ant,
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS],
const nfapi_nr_pm_pdu_t *pmi_pdu,
const int sc_offset,
const int re_cnt,
c16_t *txdataF_precoded);

View File

@@ -15,6 +15,7 @@ extern "C" {
#endif
#include "openair1/PHY/TOOLS/tools_defs.h" // c16_t
#include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h" // nfapi_nr_pm_pdu_t
#include "nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h" // fapi_nr_dl_config_dci_dl_pdu_rel15_t
//#include "openair1/PHY/MODULATION/nr_modulation.h" // nr_layer_precoder_simd_[cm, simd]
@@ -24,7 +25,7 @@ c16_t nr_layer_precoder_cm(int n_layers,
int symbol_size,
c16_t (*dataF_in)[/*symbol_size*/], // c16_t dataF_in[n_layers][symbol_size]
int ant,
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS],
nfapi_nr_pm_pdu_t *pmi_pdu,
int offset);
// Forward declare the function but hide the Variable-Length Array (VLA) feature from C not available in C++
@@ -32,7 +33,7 @@ void nr_layer_precoder_simd(int n_layers,
int symbol_size,
const c16_t (*dataF_in)[/*symbol_size*/], // c16_t dataF_in[n_layers][symbol_size]
int ant,
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS],
const nfapi_nr_pm_pdu_t *pmi_pdu,
int offset,
int re_cnt,
c16_t *dataF_out);
@@ -64,15 +65,15 @@ TEST(NrLayerPrecoderTest, Basic)
c16_t(*dataF_in)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_in.data());
c16_t(*dataF_out)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_out.data());
// Create and populate the weights
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS];
// Create and populate the pmi_pdu structure
nfapi_nr_pm_pdu_t pmi_pdu = {0};
for (int layer = 0; layer < n_layers; ++layer) {
weights[layer][ant] = (c16_t){-SHRT_MAX, 0};
pmi_pdu.weights[layer][ant] = (c16_t){-SHRT_MAX, 0};
}
// Call the C function
for (int symbol = 0; symbol < re_cnt; symbol++)
dataF_out[ant][symbol] = nr_layer_precoder_cm(n_layers, symbol_size, dataF_in, ant, weights, symbol);
dataF_out[ant][symbol] = nr_layer_precoder_cm(n_layers, symbol_size, dataF_in, ant, &pmi_pdu, symbol);
// You can calculate the expected value manually or test rough correctness
for (int symbol = 0; symbol < re_cnt; symbol++) {
@@ -109,14 +110,14 @@ TEST(NrLayerPrecoderTest, SIMD)
c16_t(*dataF_in)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_in.data());
c16_t(*dataF_out)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_out.data());
// Create and populate the weights
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS];
// Create and populate the pmi_pdu structure
nfapi_nr_pm_pdu_t pmi_pdu = {0};
for (int layer = 0; layer < n_layers; ++layer) {
weights[layer][ant] = (c16_t){-SHRT_MAX, 0};
pmi_pdu.weights[layer][ant] = (c16_t){-SHRT_MAX, 0};
}
// Call the C function
nr_layer_precoder_simd(n_layers, symbol_size, dataF_in, ant, weights, 0, re_cnt, dataF_out[ant]);
nr_layer_precoder_simd(n_layers, symbol_size, dataF_in, ant, &pmi_pdu, 0, re_cnt, dataF_out[ant]);
// You can calculate the expected value manually or test rough correctness
for (int symbol = 0; symbol < re_cnt; symbol++) {
@@ -155,14 +156,15 @@ TEST(NrLayerPrecoderTest, Compare_CM_SIMD)
c16_t(*dataF_out_cm)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_out_cm.data());
c16_t(*dataF_out_simd)[symbol_size] = reinterpret_cast<c16_t(*)[symbol_size]>(buffer_out_simd.data());
// Create and populate the weights
c16_t weights[NR_MAX_NB_LAYERS][NR_MAX_CSI_PORTS];
// Create and populate the pmi_pdu structure
nfapi_nr_pm_pdu_t pmi_pdu = {0};
pmi_pdu.pm_idx = 4;
for (int layer = 0; layer < n_layers; ++layer) {
// Could not use convert_precoder_weight() as complex.h could not be used in googletest
// Use the logic in convert_precoder_weight()
// precoder [1,j]
weights[layer][0] = (c16_t){-SHRT_MAX, 0};
weights[layer][1] = (c16_t){0, -SHRT_MAX};
pmi_pdu.weights[layer][0] = (c16_t){-SHRT_MAX, 0};
pmi_pdu.weights[layer][1] = (c16_t){0, -SHRT_MAX};
}
// Get the results for all the antenna
@@ -170,10 +172,10 @@ TEST(NrLayerPrecoderTest, Compare_CM_SIMD)
// Call the C function
for (int symbol = 0; symbol < re_cnt; symbol++)
dataF_out_cm[ant][symbol] = nr_layer_precoder_cm(n_layers, symbol_size, dataF_in, ant, weights, symbol);
dataF_out_cm[ant][symbol] = nr_layer_precoder_cm(n_layers, symbol_size, dataF_in, ant, &pmi_pdu, symbol);
// Call the C function
nr_layer_precoder_simd(n_layers, symbol_size, dataF_in, ant, weights, 0, re_cnt, dataF_out_simd[ant]);
nr_layer_precoder_simd(n_layers, symbol_size, dataF_in, ant, &pmi_pdu, 0, re_cnt, dataF_out_simd[ant]);
// Compare the result from both C function
for (int symbol = 0; symbol < re_cnt; symbol++) {

View File

@@ -2,6 +2,7 @@
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include "PHY/defs_eNB.h"
#include "PHY/sse_intrin.h"
#include "PHY/NR_ESTIMATION/nr_ul_estimation.h"

View File

@@ -123,12 +123,12 @@ void dump_nr_I0_stats(FILE *fd, PHY_VARS_gNB *gNB)
fprintf(fd, "\nPRACH I0 = %d.%d dB\n", gNB->measurements.prach_I0 / 10, gNB->measurements.prach_I0 % 10);
}
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][MAX_BWP_SIZE])
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9])
{
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
NR_gNB_COMMON *common_vars = &gNB->common_vars;
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
int nb_symb[MAX_BWP_SIZE] = {0};
int nb_symb[275]={0};
unsigned int tmp_n0_subband[frame_parms->nb_antennas_rx][frame_parms->N_RB_UL];
memset(tmp_n0_subband, 0, sizeof(tmp_n0_subband));
@@ -137,7 +137,7 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
for (int s = first_symb; s < first_symb + num_symb; s++) {
int offset0 = ((slot % RU_RX_SLOT_DEPTH) * frame_parms->symbols_per_slot + s) * frame_parms->ofdm_symbol_size;
for (int rb = 0; rb < frame_parms->N_RB_UL; rb++) {
if (rb_mask_ul[s][rb] == 0 && // check that rb was not used in this subframe
if ((rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0 && // check that rb was not used in this subframe
!(I0_SKIP_DC && rb == frame_parms->N_RB_UL >> 1)) { // skip middle PRB because of artificial noise possibly created by FFT
int offset = offset0 + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size;
nb_symb[rb]++;
@@ -162,7 +162,6 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
int32_t n0_subband_tot_perANT[frame_parms->nb_antennas_rx];
memset(n0_subband_tot_perANT, 0, sizeof(n0_subband_tot_perANT));
bool init_meas = measurements->n0_subband_power == NULL;
allocCast2D(n0_subband_power,
unsigned int,
measurements->n0_subband_power,
@@ -175,9 +174,6 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_sy
if (nb_symb[rb] > 0) {
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
tmp_n0_subband[aarx][rb] /= nb_symb[rb];
// Initialize n0_subband_power from the first measurement before EMA
if (init_meas)
n0_subband_power[aarx][rb] = tmp_n0_subband[aarx][rb];
// apply exponential moving average to smooth noise measurements
n0_subband_power[aarx][rb] = 0.9 * n0_subband_power[aarx][rb] + 0.1 * tmp_n0_subband[aarx][rb];
n0_subband_tot_perPRB += n0_subband_power[aarx][rb];

View File

@@ -34,7 +34,7 @@ typedef struct puschAntennaProc_s {
int aarx;
int beam_nb;
int numAntennas;
const nfapi_nr_pusch_pdu_t *pusch_pdu;
nfapi_nr_pusch_pdu_t *pusch_pdu;
int *max_ch;
c16_t *pilot;
int *nest_count;
@@ -82,7 +82,7 @@ static void nr_pusch_antenna_processing(void *arg)
int aarx = rdata->aarx;
int numAntennas = rdata->numAntennas;
unsigned short bwp_start_subcarrier = rdata->bwp_start_subcarrier;
const nfapi_nr_pusch_pdu_t *pusch_pdu = rdata->pusch_pdu;
nfapi_nr_pusch_pdu_t *pusch_pdu = rdata->pusch_pdu;
int *max_ch = rdata->max_ch;
c16_t *pilot = rdata->pilot;
uint64_t noise_amp2 = *(rdata->noise_amp2);
@@ -452,10 +452,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int nl,
unsigned short p,
unsigned char symbol,
NR_gNB_PUSCH *pusch_vars,
int ul_id,
int beam_nb,
unsigned short bwp_start_subcarrier,
const nfapi_nr_pusch_pdu_t *pusch_pdu,
nfapi_nr_pusch_pdu_t *pusch_pdu,
int *max_ch,
uint32_t *nvar,
c16_t *pusch_dmrs_slot_mem,
@@ -534,7 +534,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int nest_count = 0;
uint64_t noise_amp2 = 0;
delay_t *delay = &pusch_vars->delay;
delay_t *delay = &gNB->ulsch[ul_id].delay;
memset(delay, 0, sizeof(*delay));
int nb_antennas_rx = fp->nb_antennas_rx;
@@ -579,7 +579,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
rdata->delay = &delay_arr[rdata->aarx];
rdata->beam_nb = beam_nb;
rdata->frame_parms = fp;
rdata->pusch_vars = pusch_vars;
rdata->pusch_vars = &gNB->pusch_vars[ul_id];
rdata->chest_freq = gNB->chest_freq;
rdata->rxdataF = gNB->common_vars.rxdataF;
rdata->scope = gNB->scopeData;
@@ -628,7 +628,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
*
* PARAMETERS : gNB : gNB data structure
* rel15_ul : UL parameters
* pusch_vars : PUSCH data
* UE_id : UE ID
* nr_tti_rx : slot rx TTI
* dmrs_symbol_flag: DMRS Symbol Flag
* symbol : OFDM Symbol
@@ -646,22 +646,25 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
// #define DEBUG_UL_PTRS
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,
const nfapi_nr_pusch_pdu_t *rel15_ul,
NR_gNB_PUSCH *pusch_vars,
nfapi_nr_pusch_pdu_t *rel15_ul,
uint8_t ulsch_id,
uint8_t nr_tti_rx,
unsigned char symbol,
uint32_t nb_re_pusch)
{
NR_gNB_PUSCH *pusch_vars = &gNB->pusch_vars[ulsch_id];
int32_t *ptrs_re_symbol = NULL;
int8_t ret = 0;
uint8_t symbInSlot = rel15_ul->start_symbol_index + rel15_ul->nr_of_symbols;
uint8_t startSymbIndex = rel15_ul->start_symbol_index;
uint8_t nbSymb = rel15_ul->nr_of_symbols;
uint8_t L_ptrs = rel15_ul->pusch_ptrs.ptrs_time_density;
uint8_t K_ptrs = rel15_ul->pusch_ptrs.ptrs_freq_density;
uint16_t dmrsSymbPos = rel15_ul->ul_dmrs_symb_pos;
uint16_t nb_rb = rel15_ul->rb_size;
uint8_t ptrsReOffset = rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset;
uint8_t *startSymbIndex = &rel15_ul->start_symbol_index;
uint8_t *nbSymb = &rel15_ul->nr_of_symbols;
uint8_t *L_ptrs = &rel15_ul->pusch_ptrs.ptrs_time_density;
uint8_t *K_ptrs = &rel15_ul->pusch_ptrs.ptrs_freq_density;
uint16_t *dmrsSymbPos = &rel15_ul->ul_dmrs_symb_pos;
uint16_t *ptrsSymbPos = &pusch_vars->ptrs_symbols;
uint8_t *ptrsSymbIdx = &pusch_vars->ptrs_symbol_index;
uint16_t *nb_rb = &rel15_ul->rb_size;
uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset;
/* loop over antennas */
for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
@@ -670,7 +673,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
*ptrs_re_symbol = 0;
phase_per_symbol[symbol].i = 0;
/* set DMRS estimates to 0 angle with magnitude 1 */
if (is_dmrs_symbol(symbol, dmrsSymbPos)) {
if (is_dmrs_symbol(symbol, *dmrsSymbPos)) {
/* set DMRS real estimation to 32767 */
phase_per_symbol[symbol].r = INT16_MAX; // 32767
#ifdef DEBUG_UL_PTRS
@@ -680,13 +683,17 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
phase_per_symbol[symbol].r = 0;
}
if (symbol == startSymbIndex) {
pusch_vars->ptrs_symbols = 0;
set_ptrs_symb_idx(&pusch_vars->ptrs_symbols, nbSymb, startSymbIndex, 1 << L_ptrs, dmrsSymbPos);
if (symbol == *startSymbIndex) {
*ptrsSymbPos = 0;
set_ptrs_symb_idx(ptrsSymbPos, *nbSymb, *startSymbIndex, 1 << *L_ptrs, *dmrsSymbPos);
}
/* if not PTRS symbol set current ptrs symbol index to zero*/
*ptrsSymbIdx = 0;
/* Check if current symbol contains PTRS */
if (is_ptrs_symbol(symbol, pusch_vars->ptrs_symbols)) {
if (is_ptrs_symbol(symbol, *ptrsSymbPos)) {
*ptrsSymbIdx = symbol;
/*------------------------------------------------------------------------------------------------------- */
/* 1) Estimate common phase error per PTRS symbol */
/*------------------------------------------------------------------------------------------------------- */
@@ -696,9 +703,9 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
rel15_ul->scid,
nr_tti_rx,
symbol);
nr_ptrs_cpe_estimation(K_ptrs,
ptrsReOffset,
nb_rb,
nr_ptrs_cpe_estimation(*K_ptrs,
*ptrsReOffset,
*nb_rb,
rel15_ul->rnti,
frame_parms->ofdm_symbol_size,
&pusch_vars->rxdataF_comp[aarx][(symbol * nb_re_pusch)],
@@ -713,8 +720,8 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
/* 2) Interpolate PTRS estimated value in TD */
/*------------------------------------------------------------------------------------------------------- */
/* If L-PTRS is > 0 then we need interpolation */
if (L_ptrs > 0) {
ret = nr_ptrs_process_slot(dmrsSymbPos, pusch_vars->ptrs_symbols, (int16_t *)phase_per_symbol, startSymbIndex, nbSymb);
if (*L_ptrs > 0) {
ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t *)phase_per_symbol, *startSymbIndex, *nbSymb);
if (ret != 0) {
LOG_W(PHY, "[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n");
}
@@ -723,17 +730,17 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
/*------------------------------------------------------------------------------------------------------- */
/* 3) Compensated DMRS based estimated signal with PTRS estimation */
/*--------------------------------------------------------------------------------------------------------*/
for (uint8_t i = startSymbIndex; i < symbInSlot; i++) {
for (uint8_t i = *startSymbIndex; i < symbInSlot; i++) {
/* DMRS Symbol has 0 phase so no need to rotate the respective symbol */
/* Skip rotation if the slot processing is wrong */
if ((!is_dmrs_symbol(i, dmrsSymbPos)) && (ret == 0)) {
if ((!is_dmrs_symbol(i, *dmrsSymbPos)) && (ret == 0)) {
#ifdef DEBUG_UL_PTRS
printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r, phase_per_symbol[i].i);
#endif
rotate_cpx_vector(&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch],
&phase_per_symbol[i],
&pusch_vars->rxdataF_comp[aarx][i * nb_re_pusch],
(nb_rb * NR_NB_SC_PER_RB),
((*nb_rb) * NR_NB_SC_PER_RB),
15);
} // if not DMRS Symbol
} // symbol loop

View File

@@ -17,7 +17,7 @@
\param Ns slot number (0..19)
\param p
\param symbol symbol within slot
\param pusch_vars lower-phy PUSCH info
\param ul_id
\param bwp_start_subcarrier first allocated subcarrier
\param pusch_pdu
\param max_ch maximum value of estimated channel
@@ -29,10 +29,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
int nl,
unsigned short p,
unsigned char symbol,
NR_gNB_PUSCH *pusch_vars,
int ul_id,
int beam_nb,
unsigned short bwp_start_subcarrier,
const nfapi_nr_pusch_pdu_t *pusch_pdu,
nfapi_nr_pusch_pdu_t *pusch_pdu,
int *max_ch,
uint32_t *nvar,
c16_t *pusch_dmrs_slot_mem,
@@ -40,7 +40,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][MAX_BWP_SIZE]);
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]);
void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
@@ -52,8 +52,8 @@ void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,
const nfapi_nr_pusch_pdu_t *rel15_ul,
NR_gNB_PUSCH *pusch_vars,
nfapi_nr_pusch_pdu_t *rel15_ul,
uint8_t ulsch_id,
uint8_t nr_tti_rx,
unsigned char symbol,
uint32_t nb_re_pusch);

View File

@@ -438,7 +438,7 @@ static inline void do_txdataF(c16_t **txdataF,
symbol_sz,
txdataF_precoding,
ant,
pmi_pdu->weights,
pmi_pdu,
subCarrier,
re_cnt,
&txdataF[ant][txdataF_offset_per_symbol]);

View File

@@ -12,73 +12,72 @@
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "openair1/PHY/NR_TRANSPORT/nr_prach.h"
void init_nr_prach(PHY_VARS_gNB *gNB)
void init_prach_list(prach_list_t *l)
{
int num_prach = 8;
gNB->prach_ru_queue = spsc_q_alloc(num_prach, sizeof(prach_item_t));
gNB->prach_l1rx_queue = spsc_q_alloc(num_prach, sizeof(prach_item_t));
pthread_mutex_init(&l->prach_list_mutex, NULL);
memset(l->list, 0, sizeof(l->list));
}
void reset_nr_prach(PHY_VARS_gNB *gNB)
void free_nr_prach_entry(prach_list_t *l, prach_item_t *p)
{
spsc_q_free(&gNB->prach_ru_queue);
spsc_q_free(&gNB->prach_l1rx_queue);
pthread_mutex_lock(&l->prach_list_mutex);
if (p->frame == -1)
LOG_E(NR_PHY_RACH, "Freeing a not allocated prach entry\n");
*p = (prach_item_t){.frame = -1, .slot = -1, .num_slots = -1, .nb_rx = p->nb_rx, .prach_buf = (void *)(p + 1)};
pthread_mutex_unlock(&l->prach_list_mutex);
}
void free_nr_prach_entry(prach_item_t *p)
prach_item_t *find_nr_prach(prach_list_t *l, int frame, int slot, int nb_rx, nr_find_type_t type)
{
free(p->prach_buf);
pthread_mutex_lock(&l->prach_list_mutex);
AssertFatal(nb_rx, "Error! Number of antennas set to 0.\n");
prach_item_t **p = l->list;
prach_item_t **end = p + NUMBER_OF_NR_PRACH_MAX;
for (; p < end; p++)
if ((*p) && (*p)->frame == frame && ((*p)->slot + (*p)->num_slots - 1) == slot)
break;
if (p == end) {
if (type == NR_SEARCH_EXIST) {
pthread_mutex_unlock(&l->prach_list_mutex);
return NULL;
}
for (p = l->list; p < end; p++)
if (!(*p) || ((*p)->frame == -1 && (*p)->slot == -1))
break;
}
if (p == end) {
pthread_mutex_unlock(&l->prach_list_mutex);
return NULL;
}
// mark it used, it will be filled later
if (*p && (*p)->nb_rx != nb_rx) {
LOG_W(PHY, "rach procedure nb_rx ant changed from %d to %d\n", (*p)->nb_rx, nb_rx);
free(*p);
*p = NULL;
}
if (!(*p)) {
*p = calloc(1, sizeof(prach_item_t) + sizeof(c16_t) * nb_rx * NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX * NR_PRACH_SEQ_LEN_L);
(*p)->prach_buf = (void *)((*p) + 1);
}
(*p)->nb_rx = nb_rx;
(*p)->frame = frame;
pthread_mutex_unlock(&l->prach_list_mutex);
return (*p);
}
static bool drop_old_prach(const void *data, void *user)
{
const prach_item_t *p = data;
const fsn_t *now = user;
const fsn_t t = {p->frame, p->slot, now->mu};
bool drop = fsn_in_the_past(t, *now);
if (drop)
LOG_E(NR_PHY, "%4d.%2d PRACH job is in the past (%4d.%2d)\n", now->f, now->s, t.f, t.s);
return drop;
}
static bool get_current_prach(const void *data, void *user)
{
const prach_item_t *p = data;
const fsn_t *now = user;
const fsn_t t = {p->frame, p->slot, now->mu};
return fsn_equal(t, *now);
}
bool get_next_nr_prach(spsc_q_t *q, const fsn_t *now, prach_item_t *p)
{
spsc_q_drop_while(q, drop_old_prach, (void *)now);
return spsc_q_get_if(q, get_current_prach, (void *)now, p, sizeof(*p));
}
void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
prach_item_t *nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu)
{
prach_item_t *prach = find_nr_prach(&gNB->prach_list, SFN, Slot, gNB->frame_parms.nb_antennas_rx, NR_SEARCH_EXIST_OR_FREE);
if (!prach) {
LOG_W(PHY, "no free space for a new detected rach, discarding\n");
return NULL;
}
const int fmt = prach_pdu->prach_format;
const NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
const nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config;
const nfapi_nr_num_prach_fd_occasions_t *occ = &cfg->num_prach_fd_occasions_list[prach_pdu->num_ra];
prach_item_t prach = {
.frame = SFN,
.slot = Slot,
.num_slots = fmt < 4 ? get_long_prach_dur(fmt, fp->numerology_index) : 1,
.pdu = *prach_pdu,
.rootSequenceIndex = occ->prach_root_sequence_index.value,
.numrootSequenceIndex = occ->num_root_sequences.value,
.msg1_frequencystart = occ->k1.value,
.mu = cfg->prach_sub_c_spacing.value,
.prach_sequence_length = cfg->prach_sequence_length.value,
.restricted_set = cfg->restricted_set_config.value,
.numerology_index = fp->numerology_index,
.nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value,
.Xu = gNB->X_u,
.rx_prach = &gNB->rx_prach,
// TODO can be made permanently allocated?
.prach_buf = calloc_or_fail(1, sizeof(c16_t) * prach.nb_rx * NUMBER_OF_NR_RU_PRACH_OCCASIONS_MAX * NR_PRACH_SEQ_LEN_L),
};
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
// we set only elements as the whole structure has been cleaned when we release it
prach->frame = SFN;
prach->slot = Slot;
prach->num_slots = fmt < 4 ? get_long_prach_dur(fmt, fp->numerology_index) : 1;
if (gNB->common_vars.beam_id) {
int n_symb = get_nr_prach_duration(prach_pdu->prach_format);
AssertFatal(prach_pdu->beamforming.dig_bf_interface < NFAPI_MAX_NUM_BG_IF,
@@ -88,7 +87,7 @@ void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_p
int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[i].beam_idx;
int start_symb = prach_pdu->prach_start_symbol + i * n_symb;
int bitmap = SL_to_bitmap(start_symb, n_symb);
prach.beams[i] = beam_index_allocation(gNB->enable_analog_das,
prach->beams[i] = beam_index_allocation(gNB->enable_analog_das,
fapi_beam_idx,
&gNB->common_vars,
Slot,
@@ -96,9 +95,20 @@ void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_p
bitmap);
}
}
bool found = spsc_q_put(&gNB->prach_ru_queue, &prach, sizeof(prach));
if (!found)
LOG_W(NR_PHY, "%4d.%2d PRACH occ queue is full: dropping PRACH request\n", SFN, Slot);
prach->pdu = *prach_pdu;
nfapi_nr_prach_config_t *cfg = &gNB->gNB_config.prach_config;
nfapi_nr_num_prach_fd_occasions_t *occ = &cfg->num_prach_fd_occasions_list[prach_pdu->num_ra];
prach->rootSequenceIndex = occ->prach_root_sequence_index.value;
prach->numrootSequenceIndex = occ->num_root_sequences.value;
prach->msg1_frequencystart = occ->k1.value;
prach->mu = cfg->prach_sub_c_spacing.value;
prach->prach_sequence_length = cfg->prach_sequence_length.value;
prach->restricted_set = cfg->restricted_set_config.value;
prach->numerology_index = fp->numerology_index;
prach->nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value;
prach->Xu = gNB->X_u;
prach->rx_prach = &gNB->rx_prach;
return prach;
}
static void rx_nr_prach_ru_internal(prach_item_t *p,

View File

@@ -11,7 +11,6 @@
#include "PHY/defs_nr_common.h"
#include "PHY/defs_gNB.h"
#include "common/utils/fsn.h"
#define NR_PBCH_PDU_BITS 24
@@ -86,19 +85,11 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t *dlsch, uint16_t N_RB, const NR_DL_FRAME_PARM
- LLR computation
This function supports TM1, 2, 3, 5, and 6.
@param ue Pointer to PHY variables
@param pusch_vars ULSCH PUSCH data
@param rel15_ul FAPI message to process
@param unav_res unav_res result
@param UE_id id of current UE
@param frame Frame number
@param slot Slot number
*/
int nr_rx_pusch_tp(PHY_VARS_gNB *gNB,
NR_gNB_PUSCH *pusch_vars,
const nfapi_nr_pusch_pdu_t *rel15_ul,
uint32_t *ret_unav_res,
uint32_t frame,
uint8_t slot,
int beam_nb);
int nr_rx_pusch_tp(PHY_VARS_gNB *gNB, uint8_t ulsch_id, uint32_t frame, uint8_t slot, int beam_nb);
/*!
\brief This function implements the idft transform precoding in PUSCH
@@ -168,7 +159,7 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB,
int slot,
nfapi_nr_pusch_pdu_t *ulsch_pdu);
void nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu);
prach_item_t *nr_schedule_rx_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu);
typedef struct rx_prach_out {
uint16_t max_preamble;
@@ -179,6 +170,12 @@ rx_prach_out_t rx_nr_prach(const prach_item_t *, int occasion);
void rx_nr_prach_ru(prach_item_t *, int32_t **, NR_DL_FRAME_PARMS *frame_parms, int N_TA_offset);
typedef enum {
NR_SEARCH_EXIST = 0,
NR_SEARCH_EXIST_OR_FREE
} nr_find_type_t;
prach_item_t *find_nr_prach(prach_list_t *, int frame, int slot, int nb_rx, nr_find_type_t type);
void nr_fill_pucch(PHY_VARS_gNB *gNB,
int frame,
int slot,
@@ -192,32 +189,30 @@ void nr_fill_srs(PHY_VARS_gNB *gNB,
int nr_get_srs_signal(PHY_VARS_gNB *gNB,
c16_t **rxdataF,
slot_t slot,
const nfapi_nr_srs_pdu_t *srs_pdu,
nfapi_nr_srs_pdu_t *srs_pdu,
nr_srs_info_t *nr_srs_info,
c16_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)],
c16_t srs_received_noise[][gNB->frame_parms.ofdm_symbol_size * (1 << srs_pdu->num_symbols)]);
nr_srs_info_t nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
void nr_srs_rx_procedures(PHY_VARS_gNB *gNB,
int frame_rx,
int slot_rx,
uint8_t nb_antennas_rx,
uint8_t N_ap,
uint8_t N_symb_SRS,
uint16_t ofdm_symbol_size,
const NR_gNB_SRS_job_t *srs,
NR_gNB_SRS_t *srs,
nr_srs_info_t *nr_srs_info,
int *srs_est,
int8_t *snr,
c16_t srs_estimated_channel_freq[][N_ap][ofdm_symbol_size * N_symb_SRS],
c16_t srs_estimated_channel_time[][N_ap][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
int16_t *snr_per_rb,
uint16_t *timing_advance_offset,
int16_t *timing_advance_offset_nsec);
int get_nr_prach_duration(uint8_t prach_format);
void init_nr_prach(PHY_VARS_gNB *gNB);
void reset_nr_prach(PHY_VARS_gNB *gNB);
void free_nr_prach_entry(prach_item_t *);
bool get_next_nr_prach(spsc_q_t *q, const fsn_t *now, prach_item_t *p);
void free_nr_prach_entry(prach_list_t *, prach_item_t *);
void nr_decode_pucch1(PHY_VARS_gNB *gNB,
c16_t **rxdataF,
@@ -232,14 +227,14 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
int frame,
int slot,
nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu,
const nfapi_nr_pucch_pdu_t* pucch_pdu);
nfapi_nr_pucch_pdu_t* pucch_pdu);
void nr_decode_pucch0(PHY_VARS_gNB *gNB,
c16_t **rxdataF,
int frame,
int slot,
nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu,
const nfapi_nr_pucch_pdu_t* pucch_pdu);
nfapi_nr_pucch_pdu_t* pucch_pdu);
#endif /*__NR_TRANSPORT__H__*/

View File

@@ -11,6 +11,30 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "SCHED_NR/sched_nr.h"
static NR_gNB_ULSCH_t *find_nr_ulsch(PHY_VARS_gNB *gNB, uint16_t rnti, int pid)
{
int16_t first_free_index = -1;
AssertFatal(gNB != NULL, "gNB is null\n");
NR_gNB_ULSCH_t *ulsch = NULL;
for (int i = 0; i < gNB->max_nb_pusch; i++) {
ulsch = &gNB->ulsch[i];
AssertFatal(ulsch, "gNB->ulsch[%d] is null\n", i);
if (!ulsch->active) {
if (first_free_index == -1)
first_free_index = i;
} else {
// if there is already an active ULSCH for this RNTI and HARQ_PID
if ((ulsch->harq_pid == pid) && (ulsch->rnti == rnti))
return ulsch;
}
}
if (first_free_index != -1)
ulsch = &gNB->ulsch[first_free_index];
return ulsch;
}
static void dump_pusch_pdu(int instance, int frame, int slot, nfapi_nr_pusch_pdu_t *pusch_pdu)
{
LOG_D(PHY,
@@ -93,28 +117,49 @@ static void dump_pusch_pdu(int instance, int frame, int slot, nfapi_nr_pusch_pdu
void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t *ulsch_pdu)
{
dump_pusch_pdu(gNB->Mod_id, frame, slot, ulsch_pdu);
LOG_D(NR_PHY,
"%4d.%2d Programming ULSCH RNTI %04x HARQ PID %d new data indicator %d\n",
frame,
slot,
ulsch_pdu->rnti,
ulsch_pdu->pusch_data.harq_process_id,
ulsch_pdu->pusch_data.new_data_indicator);
int harq_pid = ulsch_pdu->pusch_data.harq_process_id;
NR_gNB_ULSCH_t *ulsch = find_nr_ulsch(gNB, ulsch_pdu->rnti, harq_pid);
if (ulsch == NULL) {
LOG_E(NR_PHY, "No ulsch_id found for rnti %04x\n", ulsch_pdu->rnti);
return;
}
NR_gNB_PUSCH_job_t pusch = {.frame = frame, .slot = slot, .pusch_pdu = *ulsch_pdu};
ulsch->rnti = ulsch_pdu->rnti;
ulsch->harq_pid = harq_pid;
ulsch->handled = 0;
ulsch->active = true;
ulsch->beam_nb = 0;
if (gNB->common_vars.beam_id) {
int fapi_beam_idx = ulsch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx;
int bitmap = SL_to_bitmap(ulsch_pdu->start_symbol_index, ulsch_pdu->nr_of_symbols);
pusch.beam_nb = beam_index_allocation(gNB->enable_analog_das,
ulsch->beam_nb = beam_index_allocation(gNB->enable_analog_das,
fapi_beam_idx,
&gNB->common_vars,
slot,
gNB->frame_parms.symbols_per_slot,
bitmap);
}
bool done = spsc_q_put(&gNB->pusch_queue, &pusch, sizeof(pusch));
if (!done)
LOG_W(NR_PHY, "PUSCH queue is full: dropping PUSCH UE %04x\n", ulsch_pdu->rnti);
ulsch->frame = frame;
ulsch->slot = slot;
NR_UL_gNB_HARQ_t *harq = ulsch->harq_process;
if (ulsch_pdu->pusch_data.new_data_indicator)
harq->harq_to_be_cleared = true;
LOG_D(NR_PHY,
"NEW ULSCH %d.%d RNTI %x HARQ PID %d new data indicator %d\n",
frame,
slot,
ulsch_pdu->rnti,
harq_pid,
ulsch_pdu->pusch_data.new_data_indicator);
if (ulsch_pdu->pusch_data.new_data_indicator)
harq->round = 0;
else
harq->round++;
memcpy(&ulsch->harq_process->ulsch_pdu, ulsch_pdu, sizeof(ulsch->harq_process->ulsch_pdu));
LOG_D(PHY, "Initializing nFAPI for ULSCH, harq_pid %d, layers %d\n", harq_pid, ulsch_pdu->nrOfLayers);
}
void reset_active_ulsch(PHY_VARS_gNB *gNB, int frame)

View File

@@ -23,6 +23,7 @@ NR_gNB_ULSCH_t new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL);
@param frame_parms, Pointer to frame descriptor structure
@param frame, current received frame
@param nr_tti_rx, current received TTI
@param G
@param ULSCH_ids, array of ULSCH ids
@param nb_pusch, number of uplink shared channels
*/
@@ -31,7 +32,8 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint8_t nr_tti_rx,
int *ULSCH_ids,
uint32_t *G,
uint8_t *ULSCH_ids,
int nb_pusch);
/*! \brief Perform PUSCH unscrambling. TS 38.211 V15.4.0 subclause 6.3.1.1

View File

@@ -93,7 +93,8 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
NR_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint8_t nr_tti_rx,
int *ULSCH_ids,
uint32_t *G,
uint8_t *ULSCH_ids,
int nb_pusch)
{
nrLDPC_TB_decoding_parameters_t TBs[nb_pusch];
@@ -111,29 +112,17 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
NR_gNB_PUSCH *pusch = &phy_vars_gNB->pusch_vars[ULSCH_id];
NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
const nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
nfapi_nr_pusch_pdu_t *pusch_pdu = &harq_process->ulsch_pdu;
nrLDPC_TB_decoding_parameters_t *TB_parameters = &TBs[pusch_id];
TB_parameters->G = G[pusch_id];
if (!harq_process) {
LOG_E(PHY, "ulsch_decoding.c: NULL harq_process pointer\n");
return -1;
}
uint8_t number_dmrs_symbols = count_bits64_with_mask(pusch_pdu->ul_dmrs_symb_pos, pusch_pdu->start_symbol_index, pusch_pdu->nr_of_symbols);
int factor = pusch_pdu->dmrs_config_type == pusch_dmrs_type1 ? 6 : 4;
int nb_re_dmrs = factor * pusch_pdu->num_dmrs_cdm_grps_no_data;
uint32_t G = nr_get_G(pusch_pdu->rb_size,
pusch_pdu->nr_of_symbols,
nb_re_dmrs,
number_dmrs_symbols, // number of dmrs symbols irrespective of single or double symbol dmrs
ulsch->unav_res,
pusch_pdu->qam_mod_order,
pusch_pdu->nrOfLayers);
DevAssert(G > 0);
TB_parameters->G = G;
// The harq_pid is not unique among the active HARQ processes in the instance so we use ULSCH_id instead
TB_parameters->harq_unique_pid = ULSCH_id;
@@ -145,9 +134,10 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
// ------------------------------------------------------------------
TB_parameters->processedSegments = &harq_process->processedSegments;
harq_process->TBS = pusch_pdu->pusch_data.tb_size;
TB_parameters->BG = pusch_pdu->maintenance_parms_v3.ldpcBaseGraph;
TB_parameters->A = pusch_pdu->pusch_data.tb_size << 3;
TB_parameters->A = (harq_process->TBS) << 3;
NR_gNB_PHY_STATS_t *stats = get_phy_stats(phy_vars_gNB, ulsch->rnti);
if (stats) {
stats->frame = frame;
@@ -159,7 +149,7 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
if (!harq_process->harq_to_be_cleared) {
stats->ulsch_stats.current_Qm = TB_parameters->Qm;
stats->ulsch_stats.current_RI = TB_parameters->nb_layers;
stats->ulsch_stats.total_bytes_tx += pusch_pdu->pusch_data.tb_size;
stats->ulsch_stats.total_bytes_tx += harq_process->TBS;
}
}

Some files were not shown because too many files have changed in this diff Show More