Compare commits

..

3 Commits

Author SHA1 Message Date
francescomani
26fe404fde implementation of symbol level beam handling at L2 2026-04-10 19:00:19 +02:00
francescomani
2fb03fd59a remove unnecessary get_allocated_beam function 2026-04-10 18:38:35 +02:00
francescomani
f1180d09d4 remove slot level limitation when checking beam occupation at L1 2026-04-10 18:38:35 +02:00
167 changed files with 3005 additions and 4166 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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