Compare commits

..

24 Commits

Author SHA1 Message Date
Teodora
307717ba78 Remove polling support for fronthaul interface 2026-04-16 17:25:00 +02:00
Teodora
88083df76b Revert "feat(FHI72): Fix lcore count on Arm targets"
This reverts commit 8d78c97513.

The DPDK version was upgraded to v24.11.4.
2026-04-16 17:25:00 +02:00
Teodora
e7e4e0562f Make debug logging for PRACH nRxPkt = 0
This commit was tested with MicroAmp FR2 with 2x2 MIMO,
where PRACH Rx antennas used is 1.

OAI L1 sets the number of PRACH antennas to be the same as for PUSCH.
Ideally, this should be properly fixed. In the meantime, I modified the
logging to debug to reduce noise.
2026-04-16 17:25:00 +02:00
Jaroslava Fiedlerova
ea12a351de Install libatomic in FHI72 gNB images
libatomic is required by DPDK 24.11.4
2026-04-16 17:25:00 +02:00
Teodora
0924f1e9fb Add support for the xran K release in the FHI README 2026-04-16 17:25:00 +02:00
Romain Beurdouche
f97a8758a0 feat(CI): Build FHI with K release
Update the dockerfiles for building FHI with xran K release
and DPDK 24.11.4.
2026-04-16 17:20:01 +02:00
Teodora
5ef21c6b82 Move the Tx/Rx counters logging in one function 2026-04-16 17:19:57 +02:00
Teodora Vladić
45cd9fb04e Reverse the Rx processing order
First process PUSCH and then PRACH because the PUSCH callback
is called before PRACH callback.
2026-04-16 17:18:25 +02:00
Teodora Vladić
e5f0f969e1 Separate PRACH and PUSCH packet processing
* rename read_prach_data() to xran_rx_prach_read_slot()
* in F release, there is no PRACH queue so `frame` and `slot` are
  passed as input; in K release, `frame` and `slot` are taken from the PRACH
queue

Note: since the PUSCH callback is the called before PRACH callback, this
commit is correct but the timing for PRACH processing is just a little
bit late. In previous state, PRACH processing was done inside the
function of PUSCH processing.
=> next commit will just reverse the order.
2026-04-16 17:18:25 +02:00
Teodora
f2e13bc166 Process PRACH packets
* Move PRACH callback in the oaioran.h/c since now used in K release.
* Reset the number of PRACH packets.
* Handle PRACH queue in the same manner as for PUSCH (95c8fa46).

Co-authored-by: Romain Beurdouche <romain.beurdouche@eurecom.fr>
2026-04-16 17:18:25 +02:00
Romain Beurdouche
1839fe4628 Process PUSCH packets
xran K release introduces a new parameter nRxPkt describing the
fragmentation of Rx symbols.

Co-authored-by: Teodora Vladić <teodora.vladic@openairinterface.org>
2026-04-16 17:18:25 +02:00
Romain Beurdouche
ae12e04e80 feat(oran_fhlib_5g): RX error counters
K releases added RX error counters
This commits adds a printing of these counters with LOG_I
2026-04-16 17:18:25 +02:00
Teodora
4a48d7ca0a feat(oran_fhlib_5g): Changes to run K release
* Initialize leak detector
* Fill IO config field holding the number of mbufs to be allocated
* Allocate and fill `activeMUs` in the FH config
* Start timing source, worker thread and activate CCs upon starting the FH
* Fill `mu_number[0]` in FH config
* Invert trx_oran end and stop
* Set `neAxcUl`
* Delete duplicated oran_eth_state_t struct definition
* gxran_handle is an array which length is equal to the number of RUs
2026-04-16 17:15:21 +02:00
Teodora
50c5e7ce0f feat(oran_fhlib_5g): Adapt oran_fhlib_5g for K release
Adapt the oran_fhlib_5g code to compile with xran K release.
Like previously E and F, uses preprocessor directives to separate codes for different xran releases.

Notes:
1. Release K of the FHI library supports many numerologies on one instance.
   As of now the integration supports only one numerology.
2. Several arrays in the xran interface are indexed by the numerology.
   It was ambiguous whether they were indexed by the actual numerology number or by the index of the relevant numerology within the numerology array.
   They are actually indexed by the numerology number so that when one is using only numerlogy 1 for example, he should only use perMu[1], fftSize[1], ...
2026-04-16 16:34:58 +02:00
Romain Beurdouche
b9e22d5fb2 feat(oran_fhlib_5g): update Findxran
Update the Cmake find script for xran to detect K release (11.1.1).
2026-04-14 16:21:05 +02:00
Teodora
e4c16fe050 [xran K] Enable PRACH eAxC ID offset to be 0 2026-04-14 16:21:05 +02:00
Teodora Vladić
8d34dafce5 [xran K] Fix Tx IQ buffer for fragmented packets 2026-04-14 16:21:05 +02:00
Teodora Vladić
ed39d42ada [xran K] Enable per symbol C-plane as for F
One C-plane packet containing 14 sections, one section per symbol.
If RU doesn't fill the expected section ID in a PUSCH packet, ignore it.

Please see the commit ID bbecfd5b03.
2026-04-14 16:21:05 +02:00
Teodora Vladić
42325045ba [xran K] Support large DU delay profile as for F
Please see the commit ID 003d72c859.
2026-04-14 16:21:05 +02:00
Teodora Vladić
9ad7032f3e [xran K] Update the XRAN_MAX_FRAGMENT as for F
Please see the commit ID b24fd337ba.
2026-04-14 16:21:05 +02:00
Romain Beurdouche
2f8c5c0883 [xran K] Correctly read PRACH beam index in K release
Co-authored-by: Mario Joa-Ng <mario.joa-ng@openairinterface.com>
2026-04-14 16:21:05 +02:00
Romain Beurdouche
fa5da04daa [xran K] Trim padding of UL U-Plane packets
Some RUs produce UL U-Plane packets with padding.
Packets with padding are considered erroneous by XRAN and are dropped.
Instead of dropping these packets, we trim their padding.
2026-04-14 16:21:05 +02:00
Romain Beurdouche
c9ea8a7ad3 [xran K] Fix build on Arm
Disable new AVX related additions
2026-04-14 16:21:05 +02:00
Romain Beurdouche
6f5fe48eff [xran K] Introduce a patch for the xran K release
Added a patch for K release inspired from the patch of F release.
xran K release compiles with DPDK v24.11.4 and custom DPDK install path.
2026-04-14 16:21:05 +02:00
198 changed files with 4750 additions and 4656 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

@@ -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

@@ -4,9 +4,9 @@
# -------
#
# Finds the xran library. Note that the library number is as follows:
# - oran_bronze_release_v1.1 -> 2.1.1 (B = second letter)
# - oran_e_maintenance_release_v1.0 -> 5.1.0
# the version is currently hardcoded to 5.1.0
# - oran_e_maintenance_release_v1.5 -> 5.1.6
# - oran_f_release_v1.3 -> 6.1.4
# - oran_k_release_v1.1 -> 11.1.1
#
# Required options
# ^^^^^^^^^^^^^^^^
@@ -88,6 +88,8 @@ if (xran_VERSION_STRING MATCHES "^oran_e_maintenance_release_v")
string(REGEX REPLACE "oran_e_maintenance_release_v([0-9]+).([0-9]+)" "5.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
elseif(xran_VERSION_STRING MATCHES "^oran_f_release_v")
string(REGEX REPLACE "oran_f_release_v([0-9]+).([0-9]+)" "6.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
elseif(xran_VERSION_STRING MATCHES "^oran_k_release_v")
string(REGEX REPLACE "oran_k_release_v([0-9]+).([0-9]+)" "11.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
elseif(xran_VERSION_STRING MATCHES "^oran_bronze_release_v")
string(REGEX REPLACE "oran_bronze_release_v([0-9]+).([0-9]+)" "2.\\1.\\2" xran_VERSION ${xran_VERSION_STRING})
else()

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,6 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
| `PARAMFLAG_NOFREE` | The end_configmodule API won't free the memory which has been possibly allocated to store the value of the parameter.| I |
| `PARAMFLAG_BOOL` | Parameter is a boolean, it can be specified without a value to set it to true | I |
| `PARAMFLAG_CMDLINE_NOPREFIXENABLED` | parameter can be specified without the prefix on the command line. Must be used with care, carefuly checking unicity, especially for short parameter names | I |
| `PARAMFLAG_VALUE_OPTIONAL` | Parameter can be specified with a value or without a value to set it to 1 | I |
| `PARAMFLAG_MALLOCINCONFIG` | Memory for the parameter value has been allocated by the configuration module |O |
| `PARAMFLAG_PARAMSET` | Parameter value has been explicitely set, as the parameter was specified either on the command line or the config source | O |
| `PARAMFLAG_PARAMSETDEF` | Parameter value has been set to it's default | O |

View File

@@ -57,7 +57,7 @@ static int processoption(configmodule_interface_t *cfg, paramdef_t *cfgoptions,
char defbool[2]="1";
if ( value == NULL) {
if( (cfgoptions->paramflags & (PARAMFLAG_BOOL | PARAMFLAG_VALUE_OPTIONAL)) == 0 ) { /* not a boolean, argument required */
if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname);
AssertFatal(false, "[CONFIG] command line, requires an argument\n");
} else { /* boolean value option without argument, set value to true*/

View File

@@ -22,8 +22,7 @@
#define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function
#define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1
#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
#define PARAMFLAG_VALUE_OPTIONAL (1 << 7) // integer param is 1 if no value provided
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
/* Flags used by config modules to return info to calling modules and/or to for internal usage*/
#define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module
@@ -49,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

@@ -2,7 +2,6 @@
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#define _GNU_SOURCE
#define DICHOTOMY
#include <stdio.h>
#include "time_meas.h"
#include <math.h>
@@ -35,11 +34,6 @@ double get_cpu_freq_GHz(void)
}
static double StdDev(time_stats_t *ptr)
{
return sqrt((double)ptr->diff_square * 1e-6 / ptr->trials - pow((double)ptr->diff / ptr->trials / 1000, 2));
}
void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name)
{
@@ -98,45 +92,6 @@ void print_meas(time_stats_t *ts,
}
}
size_t print_meas_log_header(time_stats_t *total_exec_time,
time_stats_t *sf_exec_time,
char *output,
size_t outputlen)
{
const char *begin = output;
const char *end = output + outputlen;
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
output += snprintf(output,
end - output,
"%25s %18s %18s %18s %15s %18s %18s %18s %18s %18s %18s %9s %6f\n",
"Name",
"Total",
"Max",
"Std",
"Num Trials",
"min",
"d1",
"q1",
"median",
"q3",
"d9",
"CPU_F_GHz",
cpu_freq_GHz);
else
output += snprintf(output,
end - output,
"%25s %18s %18s %15s %9s %6f\n",
"Name",
"Total",
"Average/Frame",
"Trials",
"CPU_F_GHz",
cpu_freq_GHz);
return output - begin;
}
size_t print_meas_log(time_stats_t *ts,
const char *name,
time_stats_t *total_exec_time,
@@ -146,38 +101,46 @@ size_t print_meas_log(time_stats_t *ts,
{
const char *begin = output;
const char *end = output + outputlen;
static int first_time = 0;
static double cpu_freq_GHz = 0.0;
if (cpu_freq_GHz == 0.0)
cpu_freq_GHz = get_cpu_freq_GHz();
if (first_time == 0) {
first_time=1;
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
output += snprintf(output,
end - output,
"%25s %25s %25s %25s %25s %6f\n",
"Name",
"Total",
"Per Trials",
"Num Trials",
"CPU_F_GHz",
cpu_freq_GHz);
else
output += snprintf(output,
end - output,
"%25s %25s %25s %20s %15s %6f\n",
"Name",
"Total",
"Average/Frame",
"Trials",
"CPU_F_GHz",
cpu_freq_GHz);
}
if (ts->trials>0) {
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
if (is_enabled_time_stats_sorted_list(&ts->time_stats_sorted_list)) {
output += snprintf(output,
end - output,
"%25s: %15.3f us; %15.3f us; %15.3f us; %15d; %15.3f us; %15.3f us; %15.3f us; %15.3f us; %15.3f us; %15.3f us;\n",
name,
ts->diff / ts->trials / 1000.0,
ts->max / 1000.0,
StdDev(ts),
ts->trials,
get_min(&ts->time_stats_sorted_list) / 1000.0,
get_d1(&ts->time_stats_sorted_list) / 1000.0,
get_q1(&ts->time_stats_sorted_list) / 1000.0,
get_median(&ts->time_stats_sorted_list) / 1000.0,
get_q3(&ts->time_stats_sorted_list) / 1000.0,
get_d9(&ts->time_stats_sorted_list) / 1000.0);
} else {
output += snprintf(output,
end - output,
"%25s: %15.3f us; %15.3f us; %15.3f us; %15d;\n",
name,
ts->diff / ts->trials / 1000.0,
ts->max / 1000.0,
StdDev(ts),
ts->trials);
}
output += snprintf(output,
end - output,
"%25s: %15.3f us; %15d; %15.3f us;\n",
name,
ts->diff / ts->trials / cpu_freq_GHz / 1000.0,
ts->trials,
ts->max / cpu_freq_GHz / 1000.0);
} else {
output += snprintf(output,
end - output,
@@ -321,222 +284,3 @@ void end_meas(void) {
msg->msgid = TIMESTAT_MSGID_END ;
pushNotifiedFIFO(&measur_fifo, nfe);
}
/**
* \brief initializes sorted list
* if dst is already initialized then asserts
* \param time_stats_sorted_list sorted list to be initialized
* \param size size of the sorted list
*/
void init_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, unsigned int size)
{
if (time_stats_sorted_list->size == 0) {
time_stats_sorted_list->list = calloc(size, sizeof(oai_cputime_t));
time_stats_sorted_list->size = size;
time_stats_sorted_list->nb_elm = 0;
} else {
AssertFatal(time_stats_sorted_list->size == 0, "Calling init_time_stats_sorted_list on initialized sorted list\n");
}
}
/**
* \brief free sorted list
* if dst is already free then does nothing
* \param time_stats_sorted_list sorted list to be freed
*/
void free_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0) {
free(time_stats_sorted_list->list);
time_stats_sorted_list->size = 0;
}
}
/**
* \brief returns true if the sorted list is enabled and false otherwise
* \param time_stats_sorted_list sorted list to be tested
*/
int is_enabled_time_stats_sorted_list(const time_stats_sorted_list_t *time_stats_sorted_list)
{
return (time_stats_sorted_list->size > 0);
}
/**
* \brief empties sorted list
* if dst is not initialized then does nothing
* \param time_stats_sorted_list sorted list to be emptied
*/
void reset_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0) {
time_stats_sorted_list->nb_elm = 0;
}
}
/**
* \brief inserts value sorted list
* if dst is not initialized then does nothing
* if dst is full then does nothing
* \param time_stats_sorted_list sorted list to insert in
* \param time time value to insert
*/
void insert_in_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, oai_cputime_t time)
{
if (time_stats_sorted_list->size > 0) {
if (time_stats_sorted_list->nb_elm < time_stats_sorted_list->size) {
unsigned int i = 0;
#ifdef DICHOTOMY
unsigned int low = 0;
unsigned int high = time_stats_sorted_list->nb_elm;
bool converged = false;
while (!converged) {
i = (high + low) / 2;
if (i > 0 && time_stats_sorted_list->list[i - 1] > time) {
high = i - 1;
} else if (i < time_stats_sorted_list->nb_elm && time_stats_sorted_list->list[i] < time) {
low = i + 1;
} else {
converged = true;
}
}
#else
for (; i < time_stats_sorted_list->nb_elm && time_stats_sorted_list->list[i] < time; i++);
#endif
// dst and src may overlap => use memmove rather than memcpy
memmove(&time_stats_sorted_list->list[i+1], &time_stats_sorted_list->list[i], (time_stats_sorted_list->nb_elm - i) * sizeof(oai_cputime_t));
time_stats_sorted_list->list[i] = time;
time_stats_sorted_list->nb_elm++;
}
}
}
/**
* \brief copy sorted list src into dst, freeing and replacing dst
* dst and src should be initialized, otherwise does nothing
* \param dst destination sorted list
* should be intitialized even with a dummy size 1 buffer to make sure that copying the list there is expected by the caller
* \param src source sorted list
*/
void copy_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src)
{
if (dst->size > 0 && src->size > 0) {
if (dst->size != src->size) {
free_time_stats_sorted_list(dst);
init_time_stats_sorted_list(dst, src->size);
}
memcpy(dst->list, src->list, src->nb_elm * sizeof(oai_cputime_t));
dst->nb_elm = src->nb_elm;
}
}
/**
* \brief inserts the content of sorted list src into dst
* dst and src should be initialized, otherwise does nothing
* if dst is not large enough to copy src then does nothing
* \param dst destination sorted list
* \param src source sorted list
*/
void merge_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src)
{
if (dst->size > 0 && src->size > 0) {
if ((dst->size - dst->nb_elm) >= src->nb_elm) {
unsigned int j = 0;
for (unsigned int i = 0; i < src->nb_elm; i++) {
#ifdef DICHOTOMY
unsigned int low = j + 1;
unsigned int high = dst->nb_elm;
bool converged = false;
while (!converged) {
j = (high + low) / 2;
if (j > 0 && dst->list[j - 1] > src->list[i]) {
high = j - 1;
} else if (j < dst->nb_elm && dst->list[j] < src->list[i]) {
low = j + 1;
} else {
converged = true;
}
}
#else
for (; j < dst->nb_elm && dst->list[j] < src->list[i]; j++);
#endif
// dst and src may overlap => use memmove rather than memcpy
memmove(&dst->list[j+1], &dst->list[j], (dst->nb_elm - j) * sizeof(oai_cputime_t));
dst->list[j] = src->list[i];
dst->nb_elm++;
j++;
}
}
}
}
/**
* \brief get the minimum from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_min(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
return time_stats_sorted_list->list[0];
} else {
return -1;
}
}
/**
* \brief get the median from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_median(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 2];
} else {
return -1;
}
}
/**
* \brief get the first quartile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_q1(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 4];
} else {
return -1;
}
}
/**
* \brief get the third quartile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_q3(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
return time_stats_sorted_list->list[3 * time_stats_sorted_list->nb_elm / 4];
} else {
return -1;
}
}
/**
* \brief get the first decile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_d1(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 10];
} else {
return -1;
}
}
/**
* \brief get the nineth decile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_d9(time_stats_sorted_list_t *time_stats_sorted_list)
{
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
return time_stats_sorted_list->list[9 * time_stats_sorted_list->nb_elm / 10];
} else {
return -1;
}
}

View File

@@ -38,121 +38,20 @@ typedef struct {
meas_printfunc_t displayFunc; /*!< \brief function to call when DISPLAY message is received*/
} time_stats_msg_t;
/**
* \typedef time_stats_sorted_list_t
* \brief sorted list of time stats to get med, q1, q2
* it can be left disabled by leaving size equal to 0
* \var size allocated size of the list
* 0 is the sorted list is disabled
* \var nb_elm number of elements in the list
* \var list pointer to the list
*/
typedef struct {
unsigned int size;
unsigned int nb_elm;
oai_cputime_t *list;
} time_stats_sorted_list_t;
/**
* \brief initializes sorted list
* if dst is already initialized then asserts
* \param time_stats_sorted_list sorted list to be initialized
* \param size size of the sorted list
*/
void init_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, unsigned int size);
/**
* \brief free sorted list
* if dst is already free then does nothing
* \param time_stats_sorted_list sorted list to be freed
*/
void free_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief returns true if the sorted list is enabled and false otherwise
* \param time_stats_sorted_list sorted list to be tested
*/
int is_enabled_time_stats_sorted_list(const time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief empties sorted list
* if dst is not initialized then does nothing
* \param time_stats_sorted_list sorted list to be emptied
*/
void reset_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief inserts value sorted list
* if dst is not initialized then does nothing
* if dst is full then does nothing
* \param time_stats_sorted_list sorted list to insert in
* \param time time value to insert
*/
void insert_in_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, oai_cputime_t time);
/**
* \brief copy sorted list src into dst, freeing and replacing dst
* dst and src should be initialized, otherwise does nothing
* \param dst destination sorted list
* should be intitialized even with a dummy size 1 buffer to make sure that copying the list there is expected by the caller
* \param src source sorted list
*/
void copy_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src);
/**
* \brief inserts the content of sorted list src into dst
* dst and src should be initialized, otherwise does nothing
* if dst is not large enough to copy src then does nothing
* \param dst destination sorted list
* \param src source sorted list
*/
void merge_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src);
/**
* \brief get the minimum from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_min(time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief get the median from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_median(time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief get the first quartile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_q1(time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief get the third quartile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_q3(time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief get the first decile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_d1(time_stats_sorted_list_t *time_stats_sorted_list);
/**
* \brief get the nineth decile from a sorted list
* if the sorted list is not initialized or empty then returns -1
* \param time_stats_sorted_list sorted list to query
*/
oai_cputime_t get_d9(time_stats_sorted_list_t *time_stats_sorted_list);
struct notifiedFIFO_elt_s;
typedef struct time_stats {
oai_cputime_t in; /*!< \brief time at measure starting point */
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
oai_cputime_t p_time; /*!< \brief absolute process duration */
double diff_square; /*!< \brief process duration square */
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
int trials; /*!< \brief number of start point - end point iterations */
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
struct notifiedFIFO_elt_s *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations */
time_stats_sorted_list_t time_stats_sorted_list; /*!< \brief optional sorted list to get med, q1, q2 */
oai_cputime_t in; /*!< \brief time at measure starting point */
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
oai_cputime_t p_time; /*!< \brief absolute process duration */
double diff_square; /*!< \brief process duration square */
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
int trials; /*!< \brief number of start point - end point iterations */
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
struct notifiedFIFO_elt_s *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations*/
} time_stats_t;
#define MEASURE_ENABLED(X) (X->meas_enabled)
@@ -161,10 +60,6 @@ static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline));
void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name);
void print_meas(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time);
size_t print_meas_log_header(time_stats_t *total_exec_time,
time_stats_t *sf_exec_time,
char *output,
size_t outputlen);
size_t print_meas_log(time_stats_t *ts,
const char *name,
time_stats_t *total_exec_time,
@@ -206,19 +101,6 @@ static inline uint32_t rdtsc_oai(void) {
}
#endif
static inline long long clock_gettime_oai()
{
struct timespec time;
#ifdef CLOCK_MONOTONIC_RAW
// CLOCK_MONOTONIC_RAW only on linux
// See clock_getres(2)
clock_gettime(CLOCK_MONOTONIC_RAW, &time);
#else
clock_gettime(CLOCK_REALTIME, &time);
#endif
return 1e+9 * time.tv_sec + time.tv_nsec;
}
#define CPUMEAS_DISABLE 0
#define CPUMEAS_ENABLE 1
#define CPUMEAS_GETSTATE 2
@@ -244,10 +126,10 @@ static inline void start_meas(time_stats_t *ts) {
if (cpu_meas_enabled) {
if (ts->meas_flag==0) {
ts->trials++;
ts->in = clock_gettime_oai();
ts->in = rdtsc_oai();
ts->meas_flag=1;
} else {
ts->in = clock_gettime_oai();
ts->in = rdtsc_oai();
}
if ((ts->trials&16383)<10) ts->max=0;
}
@@ -255,7 +137,7 @@ static inline void start_meas(time_stats_t *ts) {
static inline void stop_meas(time_stats_t *ts) {
if (cpu_meas_enabled) {
long long out = clock_gettime_oai();
long long out = rdtsc_oai();
if (ts->in) {
ts->diff += (out - ts->in);
/// process duration is the difference between two clock points
@@ -265,7 +147,6 @@ static inline void stop_meas(time_stats_t *ts) {
if ((out - ts->in) > ts->max)
ts->max = out - ts->in;
insert_in_time_stats_sorted_list(&ts->time_stats_sorted_list, (out - ts->in));
ts->meas_flag = 0;
}
}
@@ -279,7 +160,6 @@ static inline void reset_meas(time_stats_t *ts) {
ts->max=0;
ts->trials=0;
ts->meas_flag=0;
reset_time_stats_sorted_list(&ts->time_stats_sorted_list);
}
static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
@@ -287,7 +167,6 @@ static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
dst_ts->trials=src_ts->trials;
dst_ts->diff=src_ts->diff;
dst_ts->max=src_ts->max;
copy_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, &src_ts->time_stats_sorted_list);
}
}
@@ -300,23 +179,6 @@ static inline void merge_meas(time_stats_t *dst_ts, const time_stats_t *src_ts)
dst_ts->diff_square += src_ts->diff_square;
if (src_ts->max > dst_ts->max)
dst_ts->max = src_ts->max;
if (is_enabled_time_stats_sorted_list(&src_ts->time_stats_sorted_list)) {
merge_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, &src_ts->time_stats_sorted_list);
} else if (src_ts->trials == 1) {
insert_in_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, src_ts->max);
}
}
#define TIME_STATS_ADVANCED_MODE 2
static inline void init_sorted_list_meas(time_stats_t *ts, unsigned int size)
{
init_time_stats_sorted_list(&ts->time_stats_sorted_list, size);
}
static inline void free_sorted_list_meas(time_stats_t *ts)
{
free_time_stats_sorted_list(&ts->time_stats_sorted_list);
}
#define CPUMEASUR_SECTION "cpumeasur"

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

@@ -72,9 +72,9 @@ Tested libxran releases:
| Vendor |
|-----------------------------------------|
| `oran_f_release_v1.0` |
| `oran_k_release_v1.0` |
**Note**: The libxran driver of OAI identifies the above F release version as "6.1.0" (F is the sixth letter, then 1.0).
**Note**: The libxran driver of OAI identifies the above F release version as "6.1.0" (F is the sixth letter, then 1.0), and the above K release as "11.1.0".
### Configure your server
@@ -274,7 +274,7 @@ timedatectl set-ntp false
### DPDK (Data Plane Development Kit)
Download DPDK version 20.11.9.
Download DPDK version 20.11.9 (F release) or 24.11.4 (K release).
```bash
# on debian
@@ -282,7 +282,8 @@ sudo apt install wget xz-utils libnuma-dev
# on Fedora/RHEL
sudo dnf install wget xz numactl-devel
cd
wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz
wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz # F release
wget http://fast.dpdk.org/rel/dpdk-24.11.4.tar.xz # K release
```
#### DPDK Compilation and Installation
@@ -293,7 +294,8 @@ wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz
sudo apt install meson
# on Fedora/RHEL
sudo dnf install meson
tar xvf dpdk-20.11.9.tar.xz && cd dpdk-stable-20.11.9
tar xvf dpdk-20.11.9.tar.xz && cd dpdk-stable-20.11.9 # F release
tar xvf dpdk-24.11.4.tar.xz && cd dpdk-stable-24.11.4 # K release
meson build
ninja -C build
@@ -359,7 +361,8 @@ pkg-config --libs libdpdk --static
Go back to the version folder you used to build and install
```
cd ~/dpdk-stable-20.11.9
cd ~/dpdk-stable-20.11.9 # F release
cd ~/dpdk-stable-24.11.4 # K release
sudo ninja deinstall -C build
```
@@ -384,6 +387,14 @@ git checkout oran_f_release_v1.0
git apply ~/openairinterface5g/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch
```
#### K release
```bash
git clone https://gerrit.o-ran-sc.org/r/o-du/phy.git ~/phy
cd ~/phy
git checkout oran_k_release_v1.0
git apply ~/openairinterface5g/cmake_targets/tools/oran_fhi_integration_patches/K/oaioran_K.patch
```
Compile the fronthaul interface library by calling `make` and the option
`XRAN_LIB_SO=1` to have it build a shared object. Note that we provide two
environment variables `RTE_SDK` for the path to the source tree of DPDK, and
@@ -398,6 +409,7 @@ This feature is intended to enable experiments and future improvements on Arm sy
cd ~/phy/fhi_lib/lib
make clean
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=~/dpdk-stable-20.11.9/ XRAN_DIR=~/phy/fhi_lib make XRAN_LIB_SO=1 # F release
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=~/dpdk-stable-24.11.4/ XRAN_DIR=~/phy/fhi_lib make XRAN_LIB_SO=1 # K release
...
[AR] build/libxran.so
./build/libxran.so
@@ -487,19 +499,6 @@ cmake .. -GNinja -DOAI_FHI72=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib
ninja nr-softmodem oran_fhlib_5g params_libconfig
```
Note that in tags 2025.w06 and prior, the FHI72 driver used polling to wait for
the next slot. This is inefficient as it burns CPU time, and has been replaced
with a more efficient mechanism. Nevertheless, if you experience problems that
did not occur previously, it is possible to re-enable polling, either with
`build_oai` like this
./build_oai --gNB --ninja -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=$HOME/phy/fhi_lib/lib --cmake-opt -DOAI_FHI72_USE_POLLING=ON
or with `cmake` like so
cmake .. -GNinja -DOAI_FHI72=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib -DOAI_FHI72_USE_POLLING=ON
ninja oran_fhlib_5g
## Configuration
RU and DU configurations have a circular dependency: you have to configure DU MAC address in the RU configuration and the RU MAC address, VLAN and Timing advance parameters in the DU configuration.

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

@@ -45,7 +45,9 @@ RUN rm -f /etc/rhsm-host && \
gcc-toolset-13-gcc-c++ \
# python3-pip and pyyaml are used for conf template generation
python3-pip && \
pip3 install --ignore-installed pyyaml && \
pip3 install --ignore-installed \
pyyaml \
pyelftools && \
echo "/usr/local/lib" > /etc/ld.so.conf.d/local-lib.conf && \
echo "/usr/local/lib64" >> /etc/ld.so.conf.d/local-lib.conf

View File

@@ -20,7 +20,8 @@ RUN apt-get update && \
wget \
xz-utils \
pkg-config \
libnuma-dev && \
libnuma-dev \
python3-pyelftools && \
rm -rf /var/lib/apt/lists/*
RUN rm -Rf /oai-ran
@@ -28,20 +29,20 @@ WORKDIR /oai-ran
COPY . .
## Download and build DPDK
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
tar -xvf dpdk-20.11.9.tar.xz && \
cd dpdk-stable-20.11.9 && \
meson setup -Dmachine=default build && \
RUN wget --no-verbose http://fast.dpdk.org/rel/dpdk-24.11.4.tar.xz && \
tar -xf dpdk-24.11.4.tar.xz && \
cd dpdk-stable-24.11.4 && \
meson build && \
ninja -C build && \
ninja install -C build
## Build Fronthaul library
RUN git clone https://github.com/openairinterface/o-du-phy.git /opt/phy && \
cd /opt/phy && \
git checkout oran_f_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
git checkout oran_k_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/K/oaioran_K.patch && \
cd /opt/phy/fhi_lib/lib && \
TARGET=armv8 WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
TARGET=armv8 WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-24.11.4/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
## Build Arm RAN Acceleration Library
RUN git clone https://git.gitlab.arm.com/networking/ral.git /opt/ral && \

View File

@@ -15,9 +15,9 @@ WORKDIR /oai-ran
COPY . .
## Download and build DPDK
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
tar -xvf dpdk-20.11.9.tar.xz && \
cd dpdk-stable-20.11.9 && \
RUN wget --no-verbose http://fast.dpdk.org/rel/dpdk-24.11.4.tar.xz && \
tar -xf dpdk-24.11.4.tar.xz && \
cd dpdk-stable-24.11.4 && \
meson build && \
ninja -C build && \
ninja install -C build
@@ -25,10 +25,10 @@ RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
## Build Fronthaul library
RUN git clone https://github.com/openairinterface/o-du-phy.git /opt/phy && \
cd /opt/phy && \
git checkout oran_f_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
git checkout oran_k_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/K/oaioran_K.patch && \
cd /opt/phy/fhi_lib/lib && \
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-24.11.4/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
FROM ran-base AS ran-build-fhi72
ARG E2AP_VERSION=E2AP_V3

View File

@@ -20,7 +20,8 @@ RUN apt-get update && \
wget \
xz-utils \
pkg-config \
libnuma-dev && \
libnuma-dev \
python3-pyelftools && \
rm -rf /var/lib/apt/lists/*
RUN rm -Rf /oai-ran
@@ -28,9 +29,9 @@ WORKDIR /oai-ran
COPY . .
## Download and build DPDK
RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
tar -xvf dpdk-20.11.9.tar.xz && \
cd dpdk-stable-20.11.9 && \
RUN wget --no-verbose http://fast.dpdk.org/rel/dpdk-24.11.4.tar.xz && \
tar -xf dpdk-24.11.4.tar.xz && \
cd dpdk-stable-24.11.4 && \
meson build && \
ninja -C build && \
ninja install -C build
@@ -38,10 +39,10 @@ RUN wget http://fast.dpdk.org/rel/dpdk-20.11.9.tar.xz && \
## Build Fronthaul library
RUN git clone https://github.com/openairinterface/o-du-phy.git /opt/phy && \
cd /opt/phy && \
git checkout oran_f_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/F/oaioran_F.patch && \
git checkout oran_k_release_v1.0 &&\
git apply /oai-ran/cmake_targets/tools/oran_fhi_integration_patches/K/oaioran_K.patch && \
cd /opt/phy/fhi_lib/lib && \
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-20.11.9/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
WIRELESS_SDK_TOOLCHAIN=gcc RTE_SDK=/oai-ran/dpdk-stable-24.11.4/ XRAN_DIR=/opt/phy/fhi_lib make XRAN_LIB_SO=1
FROM ran-base AS ran-build-fhi72
## Build and install OAI

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

@@ -41,6 +41,7 @@ RUN rm -f /etc/rhsm-host && \
python3-pip \
net-tools \
iputils \
libatomic \
yaml-cpp-devel && \
pip3 install six && \
pip3 install requests && \

View File

@@ -18,6 +18,7 @@ ENV TZ=Europe/Paris
RUN dnf update -y && \
dnf install -y \
procps-ng \
libatomic \
libXpm \
libX11 \
lksctp-tools \

View File

@@ -41,6 +41,7 @@ RUN apt-get update && \
python3 \
python3-six \
python3-requests \
libatomic1 \
libyaml-cpp-dev && \
# if the --sanitize option was used to build, additional packages are required
/bin/bash -c 'if [[ "$BUILD_OPTION" = "--sanitize" ]]; then DEBIAN_FRONTEND=noninteractive apt-get install --yes \

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) {
@@ -207,23 +202,14 @@ static void rx_func(processingData_L1_t *info)
static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
const char *begin = output;
const char *end = output + outputlen;
output += print_meas_log_header(NULL, NULL, output, end - output);
output += print_meas_log(&gNB->l1_tx_proc, "L1 Tx job", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->l1_rx_proc, "L1 Rx job", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->dlsch_segmentation_stats, "DL segment segmentation", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->tinput, "DL encoding input", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->tprep, "DL encoding preparation", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->tparity, "DL encoding parity", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->toutput, "DL encoding output", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->dlsch_rate_matching_stats, "DL rate matching", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->dlsch_interleaving_stats, "DL interleaving", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->dlsch_scrambling_stats, "DLSCH scrambling", NULL, NULL, output, end-output);
output += print_meas_log(&gNB->dlsch_modulation_stats, "DLSCH modulation", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->dlsch_pdsch_generation_stats, "PDSCH generation", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ulsch_decoding_stats, "ULSCH decoding", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ts_deinterleave, "UL segment deinterleaving", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ts_rate_unmatch, "UL segment rate recovery", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->ts_ldpc_decode, "UL segments decoding", NULL, NULL, output, end - output);
@@ -231,9 +217,8 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
output += print_meas_log(&gNB->slot_indication_stats, "Slot Indication", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output);
output += print_meas_log(&gNB->rx_prach, "PRACH RX", NULL, NULL, output, end - output);
if (ru->feprx) {
if (ru->feprx)
output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output);
}
bool full_slot = ru->half_slot_parallelization == 0;
if (ru->feptx_prec) {
@@ -257,9 +242,8 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
output += print_meas_log(&ru->txdataF_copy_stats, "txdataF_copy", NULL, NULL, output, end - output);
}
if (ru->fh_north_asynch_in) {
if (ru->fh_north_asynch_in)
output += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output, end - output);
}
output += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output, end - output);
@@ -267,26 +251,9 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
output += print_meas_log(&ru->compression,"compression",NULL,NULL, output, end - output);
output += print_meas_log(&ru->transport,"transport",NULL,NULL, output, end - output);
}
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
reset_meas(&gNB->l1_tx_proc);
reset_meas(&gNB->l1_rx_proc);
reset_meas(&gNB->phy_proc_tx);
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->dlsch_pdsch_generation_stats);
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->ulsch_decoding_stats);
reset_meas(&gNB->rx_pusch_stats);
reset_meas(&gNB->rx_prach);
if (ru->fh_north_asynch_in) {
reset_meas(&ru->rx_fhaul);
}
reset_meas(&ru->tx_fhaul);
}
return output - begin;
}
#define SORTED_LIST_SIZE 2048
void *nrL1_stats_thread(void *param) {
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
RU_t *ru = RC.ru[0];
@@ -299,66 +266,20 @@ void *nrL1_stats_thread(void *param) {
return NULL;
}
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
init_sorted_list_meas(&gNB->l1_tx_proc, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->l1_rx_proc, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->phy_proc_tx, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->dlsch_encoding_stats, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->dlsch_pdsch_generation_stats, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->phy_proc_rx, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->ulsch_decoding_stats, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->rx_pusch_stats, SORTED_LIST_SIZE);
init_sorted_list_meas(&gNB->rx_prach, SORTED_LIST_SIZE);
if (ru->fh_north_asynch_in) {
init_sorted_list_meas(&ru->rx_fhaul, SORTED_LIST_SIZE);
}
init_sorted_list_meas(&ru->tx_fhaul, SORTED_LIST_SIZE);
}
reset_meas(&gNB->l1_tx_proc);
reset_meas(&gNB->l1_rx_proc);
reset_meas(&gNB->phy_proc_tx);
reset_meas(&gNB->dlsch_encoding_stats);
reset_meas(&gNB->dlsch_segmentation_stats);
reset_meas(&gNB->tinput);
reset_meas(&gNB->tprep);
reset_meas(&gNB->tparity);
reset_meas(&gNB->toutput);
reset_meas(&gNB->dlsch_rate_matching_stats);
reset_meas(&gNB->dlsch_interleaving_stats);
reset_meas(&gNB->dlsch_scrambling_stats);
reset_meas(&gNB->dlsch_modulation_stats);
reset_meas(&gNB->dlsch_pdsch_generation_stats);
reset_meas(&gNB->phy_proc_rx);
reset_meas(&gNB->ulsch_decoding_stats);
reset_meas(&gNB->ts_deinterleave);
reset_meas(&gNB->ts_rate_unmatch);
reset_meas(&gNB->ts_ldpc_decode);
reset_meas(&gNB->ul_indication_stats);
reset_meas(&gNB->slot_indication_stats);
reset_meas(&gNB->rx_pusch_stats);
reset_meas(&gNB->rx_prach);
if (ru->feprx) {
reset_meas(&ru->ofdm_demod_stats);
}
if (ru->feptx_prec) {
reset_meas(&ru->precoding_stats);
}
if (ru->feptx_ofdm) {
reset_meas(&ru->txdataF_copy_stats);
reset_meas(&ru->ofdm_mod_stats);
reset_meas(&ru->ofdm_total_stats);
}
if (ru->fh_north_asynch_in) {
reset_meas(&ru->rx_fhaul);
}
reset_meas(&ru->tx_fhaul);
if (ru->fh_north_out) {
reset_meas(&ru->compression);
reset_meas(&ru->transport);
}
reset_meas(&gNB->dlsch_scrambling_stats);
reset_meas(&gNB->dlsch_modulation_stats);
reset_meas(&gNB->dlsch_pdsch_generation_stats);
while (!oai_exit) {
sleep(1);
if (ftruncate(fileno(fd), 0) != 0 || fseek(fd, 0, SEEK_SET) != 0) {
@@ -372,23 +293,6 @@ void *nrL1_stats_thread(void *param) {
fprintf(fd,"%s\n",output);
fflush(fd);
}
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
free_sorted_list_meas(&gNB->l1_tx_proc);
free_sorted_list_meas(&gNB->l1_rx_proc);
free_sorted_list_meas(&gNB->phy_proc_tx);
free_sorted_list_meas(&gNB->dlsch_encoding_stats);
free_sorted_list_meas(&gNB->dlsch_pdsch_generation_stats);
free_sorted_list_meas(&gNB->phy_proc_rx);
free_sorted_list_meas(&gNB->ulsch_decoding_stats);
free_sorted_list_meas(&gNB->rx_pusch_stats);
free_sorted_list_meas(&gNB->rx_prach);
if (ru->fh_north_asynch_in) {
free_sorted_list_meas(&ru->rx_fhaul);
}
free_sorted_list_meas(&ru->tx_fhaul);
}
fclose(fd);
return(NULL);
}

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

@@ -34,7 +34,6 @@
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
#define CONFIG_HLP_DLPMI_PHYTEST "Set the downlink Precoding Matrix Index for PHYTEST mode\n"
#define CONFIG_HLP_ULNL_PHYTEST "Set the uplink nrOfLayers for PHYTEST mode\n"
#define CONFIG_HLP_DLBW_PHYTEST "Set the number of PRBs used for DLSCH in PHYTEST mode\n"
#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n"

View File

@@ -358,9 +358,6 @@ int stop_L1(module_id_t gnb_id)
if (RC.nb_nr_L1_inst > 0)
stop_gNB(RC.nb_nr_L1_inst);
if (RC.nb_RU > 0)
stop_RU(RC.nb_RU);
/* stop trx devices, multiple carrier currently not supported by RU */
if (ru->rfdevice.trx_get_stats_func) {
ru->rfdevice.trx_get_stats_func(&ru->rfdevice);
@@ -378,6 +375,9 @@ int stop_L1(module_id_t gnb_id)
LOG_I(GNB_APP, "turned off RU ifdevice\n");
}
if (RC.nb_RU > 0)
stop_RU(RC.nb_RU);
/* release memory used by the RU/gNB threads (incomplete), after all
* threads have been stopped (they partially use the same memory) */
for (int inst = 0; inst < RC.nb_RU; inst++) {

View File

@@ -21,10 +21,9 @@
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
// clang-format off
#define CMDLINE_PARAMS_DESC_GNB { \
{"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \
{"l" , CONFIG_HLP_DLNL_PHYTEST, 0, .uptr=&target_dl_Nl, .defintval=0, TYPE_UINT, 0}, \
{"L" , CONFIG_HLP_ULNL_PHYTEST, 0, .uptr=&target_ul_Nl, .defintval=0, TYPE_UINT, 0}, \
{"p" , CONFIG_HLP_DLPMI_PHYTEST, 0, .uptr=&target_dl_pmi, .defintval=0, TYPE_UINT, 0}, \
{"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \
{"t" , CONFIG_HLP_ULMCS_PHYTEST, 0, .uptr=&target_ul_mcs, .defintval=0, TYPE_UINT, 0}, \
{"M" , CONFIG_HLP_DLBW_PHYTEST, 0, .uptr=&target_dl_bw, .defintval=0, TYPE_UINT, 0}, \
{"T" , CONFIG_HLP_ULBW_PHYTEST, 0, .uptr=&target_ul_bw, .defintval=0, TYPE_UINT, 0}, \
@@ -37,10 +36,9 @@
}
// clang-format on
extern uint32_t target_dl_mcs;
extern uint32_t target_dl_Nl;
extern uint32_t target_ul_Nl;
extern uint32_t target_dl_pmi;
extern uint32_t target_dl_mcs;
extern uint32_t target_ul_mcs;
extern uint32_t target_dl_bw;
extern uint32_t target_ul_bw;

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

@@ -118,7 +118,7 @@ extern int usrp_tx_thread;
{"CO" , CONFIG_HLP_ULF, 0, .i64ptr=&(uplink_frequency_offset[0][0]), .defintval=0, TYPE_INT64, 0}, \
{"a" , CONFIG_HLP_CHOFF, 0, .iptr=&CHAIN_OFFSET, .defintval=0, TYPE_INT, 0}, \
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, .uptr=&do_forms, .defintval=0, TYPE_UINT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_VALUE_OPTIONAL, .iptr=&cpu_meas_enabled, .defintval=0, TYPE_INT, 0}, \
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, .iptr=&cpu_meas_enabled, .defintval=0, TYPE_INT, 0}, \
{"numerology" , CONFIG_HLP_NUMEROLOGY, 0, .iptr=&NUMEROLOGY, .defintval=1, TYPE_INT, 0}, \
{"band" , CONFIG_HLP_BAND, 0, .iptr=&BAND, .defintval=78, TYPE_INT, 0}, \
{"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, .strptr=&parallel_config, .defstrval=NULL, TYPE_STRING, 0}, \

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

@@ -125,8 +125,7 @@ int main(int argc, char *argv[])
}
}
// Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
time_stats_t timeEncoder = {0};
time_stats_t timeDecoder = {0};
time_stats_t timeEncoder, timeDecoder;
cpu_meas_enabled = 1;
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);

View File

@@ -13,8 +13,7 @@
configmodule_interface_t *uniqCfg = NULL;
int main(int argc, char *argv[])
{
time_stats_t timeEncoder = {0};
time_stats_t timeDecoder = {0};
time_stats_t timeEncoder, timeDecoder;
cpu_meas_enabled = 1;
reset_meas(&timeEncoder);
reset_meas(&timeDecoder);

View File

@@ -899,8 +899,10 @@ static int pmd_lcore_ldpc_enc(void *arg)
AssertFatal(ret == 0, "Allocation failed for %d ops", num_segments);
set_ldpc_enc_op(ops_enq, bufs->inputs, bufs->hard_outputs, nrLDPC_slot_encoding_parameters);
stop_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tprep);
start_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tparity);
if (nrLDPC_slot_encoding_parameters->tprep != NULL)
stop_meas(nrLDPC_slot_encoding_parameters->tprep);
if (nrLDPC_slot_encoding_parameters->tparity != NULL)
start_meas(nrLDPC_slot_encoding_parameters->tparity);
uint16_t enq = 0, deq = 0;
while (enq < num_segments) {
@@ -914,11 +916,14 @@ static int pmd_lcore_ldpc_enc(void *arg)
time_out++;
DevAssert(time_out <= TIME_OUT_POLL);
}
stop_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tparity);
start_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].toutput);
if (nrLDPC_slot_encoding_parameters->tparity != NULL)
stop_meas(nrLDPC_slot_encoding_parameters->tparity);
if (nrLDPC_slot_encoding_parameters->toutput != NULL)
start_meas(nrLDPC_slot_encoding_parameters->toutput);
ret = retrieve_ldpc_enc_op(ops_deq, nrLDPC_slot_encoding_parameters);
AssertFatal(ret == 0, "Failed to retrieve LDPC encoding op!");
stop_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].toutput);
if (nrLDPC_slot_encoding_parameters->toutput != NULL)
stop_meas(nrLDPC_slot_encoding_parameters->toutput);
rte_bbdev_enc_op_free_bulk(ops_enq, num_segments);
return ret;
}
@@ -1333,7 +1338,8 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
int32_t nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters)
{
pthread_mutex_lock(&encode_mutex);
start_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tprep);
if (nrLDPC_slot_encoding_parameters->tprep != NULL)
start_meas(nrLDPC_slot_encoding_parameters->tprep);
const uint16_t num_segments = nb_segments_encoding(nrLDPC_slot_encoding_parameters);

View File

@@ -137,10 +137,6 @@ typedef struct nrLDPC_segment_encoding_parameters_s{
time_stats_t ts_interleave;
time_stats_t ts_rate_match;
time_stats_t ts_ldpc_encode;
time_stats_t tinput;
time_stats_t tprep;
time_stats_t tparity;
time_stats_t toutput;
} nrLDPC_segment_encoding_parameters_t;
/**
@@ -214,6 +210,10 @@ typedef struct nrLDPC_slot_encoding_parameters_s{
int slot;
int nb_TBs;
tpool_t *threadPool;
time_stats_t *tinput;
time_stats_t *tprep;
time_stats_t *tparity;
time_stats_t *toutput;
nrLDPC_TB_encoding_parameters_t *TBs;
} nrLDPC_slot_encoding_parameters_t;

View File

@@ -342,6 +342,10 @@ static int nrLDPC_launch_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_s
encoder_implemparams_t common_segment_params = {
.n_segments = nrLDPC_TB_encoding_parameters->C,
.tinput = nrLDPC_slot_encoding_parameters->tinput,
.tprep = nrLDPC_slot_encoding_parameters->tprep,
.tparity = nrLDPC_slot_encoding_parameters->tparity,
.toutput = nrLDPC_slot_encoding_parameters->toutput,
.Kb = nrLDPC_TB_encoding_parameters->Kb,
.Zc = nrLDPC_TB_encoding_parameters->Z,
.BG = nrLDPC_TB_encoding_parameters->BG,
@@ -430,6 +434,8 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
uint32_t C = nrLDPC_TB_encoding_parameters->C;
size_t n_seg = (C / 8 + ((C & 7) == 0 ? 0 : 1));
time_stats_t *toutput = nrLDPC_slot_encoding_parameters->toutput;
for (int j = 0; j < n_seg; j++) {
unsigned int macro_segment = j * 8;
unsigned int macro_segment_end = (C > macro_segment + 8) ? macro_segment + 8 : C;
@@ -448,8 +454,7 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
}
}
time_stats_t *toutput = &nrLDPC_TB_encoding_parameters->segments[macro_segment].toutput;
start_meas(toutput);
if(toutput != NULL) start_meas(toutput);
uint32_t Eoffset=0;
for (int s=0; s<macro_segment; s++)
@@ -465,7 +470,7 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
nrLDPC_TB_encoding_parameters->output,
Eoffset);
stop_meas(toutput);
if(toutput != NULL) stop_meas(toutput);
}
nbTasks += n_seg;
}

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);

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