Merge branch 'integration_2025_w40' into 'develop'
Integration: `2025.w40` * !3672 \[ci\] Fix MissingPropertyException - COTS-UE by binding OAI_Registry globally * !3609 BWP with no PRACH occasions * !3657 do not assert for mismatched TBS in phy-test mode * !3667 CI: Updates for HO and AW2S pipeline * !3674 NR UE: remove function get_nr_RSRP() and get_nr_rx_total_gain_dB() for cleanup * !3478 NR UE: add UCI (HARQ-ACK/NACK) on PUSCH support at PHY * !3664 modulation LUTs size was wrong, and remove inconsistent test of SSE2 enable * !3665 Make all targets compile * !3554 Handle failures in RRCReconfiguration encoding gracefully * !3655 Improvements to N2 handover * !3678 Add OAIUE longrun pipeline * !3628 Update documentation Closes #979, #726, #959, #967, and #930 See merge request oai/openairinterface5g!3676
@@ -19,8 +19,6 @@
|
||||
# * contact@openairinterface.org
|
||||
# */
|
||||
|
||||
# Author: laurent THOMAS, Lionel GAUTHIER
|
||||
|
||||
cmake_minimum_required (VERSION 3.16)
|
||||
project (OpenAirInterface LANGUAGES C CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
@@ -173,9 +171,6 @@ else ()
|
||||
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -march=armv8.2-a")
|
||||
endif()
|
||||
|
||||
# add autotools definitions that were maybe used!
|
||||
add_definitions(-DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FCNTL_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_STRERROR=1 -DHAVE_SOCKET=1 -DHAVE_MEMSET=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_LIBSCTP)
|
||||
|
||||
# we need -rdynamic to incorporate all symbols in shared objects, see man page
|
||||
set(commonOpts "-pipe -fPIC -Wall -fno-strict-aliasing -rdynamic")
|
||||
# GNU C/C++ Compiler might throw many warnings without packed-bitfield-compat, see man page
|
||||
@@ -469,9 +464,6 @@ target_include_directories(f1ap PUBLIC F1AP_DIR)
|
||||
target_link_libraries(f1ap PUBLIC asn1_f1ap GTPV1U)
|
||||
target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE f1ap_lib)
|
||||
target_include_directories(f1ap PRIVATE ${F1AP_DIR}/lib)
|
||||
if(E2_AGENT)
|
||||
target_compile_definitions(f1ap PRIVATE E2_AGENT)
|
||||
endif()
|
||||
|
||||
# LPP
|
||||
##############
|
||||
@@ -549,7 +541,6 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories("${OPENAIR_DIR}/executables")
|
||||
include_directories("${OPENAIR2_DIR}/COMMON")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/LOG")
|
||||
include_directories("${OPENAIR3_DIR}/COMMON")
|
||||
include_directories("${OPENAIR3_DIR}/UTILS")
|
||||
include_directories("${NFAPI_DIR}/nfapi/public_inc")
|
||||
@@ -590,12 +581,7 @@ include_directories("${OPENAIR3_DIR}/ocp-gtpu")
|
||||
include_directories("${OPENAIR3_DIR}/M3AP")
|
||||
include_directories("${OPENAIR3_DIR}/MME_APP")
|
||||
include_directories("${OPENAIR_DIR}/radio/COMMON")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/OSA")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/MEM")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/LISTS")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/FIFO")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/MATH")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/TIMER")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/OTG")
|
||||
include_directories("${OPENAIR2_DIR}/UTIL/OPT")
|
||||
include_directories("${OPENAIR_DIR}")
|
||||
@@ -623,11 +609,6 @@ add_library(UTIL
|
||||
${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c
|
||||
${OPENAIR2_DIR}/UTIL/OPT/probe.c
|
||||
)
|
||||
if (ENABLE_LTTNG)
|
||||
find_package(LTTngUST 2.3.8 EXACT REQUIRED)
|
||||
else()
|
||||
message(STATUS "LTTNG support disabled")
|
||||
endif()
|
||||
|
||||
pkg_check_modules(cap libcap)
|
||||
if (cap_FOUND)
|
||||
@@ -1318,12 +1299,6 @@ add_library(L2
|
||||
target_link_libraries(L2 PRIVATE x2ap s1ap lte_rrc m2ap)
|
||||
target_link_libraries(L2 PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(L2 PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
|
||||
target_compile_definitions(L2 PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
|
||||
endif()
|
||||
|
||||
|
||||
add_library(MAC_UE_NR ${MAC_NR_SRC_UE})
|
||||
target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures nr_ue_ra_procedures)
|
||||
|
||||
@@ -1350,10 +1325,6 @@ target_link_libraries(L2_NR PRIVATE f1ap x2ap s1ap ngap nr_rrc e1ap nr_rlc nr_co
|
||||
if(OAI_AERIAL)
|
||||
target_compile_definitions(L2_NR PRIVATE ENABLE_AERIAL)
|
||||
endif()
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(L2_NR PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
|
||||
target_compile_definitions(L2_NR PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
|
||||
endif()
|
||||
|
||||
add_library(L2_LTE_NR
|
||||
# temporary solution until 4G/5G code completely untangled (as evidenced by deletion of the following file)
|
||||
@@ -1683,13 +1654,6 @@ include_directories(${NAS_SRC}UE/EMM/SAP)
|
||||
include_directories(${NAS_SRC}UE/ESM)
|
||||
include_directories(${NAS_SRC}UE/ESM/SAP)
|
||||
|
||||
# nbiot
|
||||
add_definitions("-DNUMBER_OF_UE_MAX_NB_IoT=16")
|
||||
set (NBIOT_SOURCES
|
||||
${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c
|
||||
)
|
||||
add_library(NB_IoT MODULE ${NBIOT_SOURCES} )
|
||||
|
||||
# Simulation library
|
||||
##########################
|
||||
set (SIMUSRC
|
||||
@@ -1715,9 +1679,8 @@ include_directories("${NFAPI_DIR}/nfapi/inc")
|
||||
include_directories("${NFAPI_DIR}/sim_common/inc")
|
||||
include_directories("${NFAPI_DIR}/pnf_sim/inc")
|
||||
|
||||
add_library(oai_iqplayer MODULE
|
||||
${OPENAIR_DIR}/radio/iqplayer/iqplayer_lib.c
|
||||
)
|
||||
add_library(oai_iqplayer MODULE ${OPENAIR_DIR}/radio/iqplayer/iqplayer_lib.c)
|
||||
target_link_libraries(oai_iqplayer PRIVATE log_headers)
|
||||
|
||||
#################################
|
||||
# add executables for operation
|
||||
@@ -1727,10 +1690,6 @@ add_library(minimal_lib
|
||||
)
|
||||
target_link_libraries(minimal_lib PUBLIC pthread dl ${T_LIB} LOG)
|
||||
|
||||
add_executable(nfapi_test
|
||||
${OPENAIR_DIR}/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c
|
||||
)
|
||||
|
||||
add_executable(measurement_display
|
||||
${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c)
|
||||
target_link_libraries (measurement_display minimal_lib)
|
||||
@@ -1770,6 +1729,7 @@ target_link_libraries(lte-softmodem PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(lte-softmodem PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapacke_LIBRARIES} ${lapack_LIBRARIES})
|
||||
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(lte-softmodem PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
|
||||
target_compile_definitions(lte-softmodem PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
|
||||
endif()
|
||||
|
||||
@@ -1873,6 +1833,7 @@ if (OAI_AERIAL)
|
||||
target_link_libraries(nr-softmodem PUBLIC aerial_lib)
|
||||
endif()
|
||||
if(E2_AGENT)
|
||||
target_link_libraries(nr-softmodem PUBLIC e2_agent e2_agent_arg e2_ran_func_du_cucp_cuup)
|
||||
target_compile_definitions(nr-softmodem PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
|
||||
endif()
|
||||
|
||||
@@ -1947,14 +1908,14 @@ target_link_libraries(nr-uesoftmodem PRIVATE
|
||||
#####################################
|
||||
|
||||
#special case for dlim TM4, which uses its own version of phy_scope code
|
||||
add_executable(dlsim_tm4
|
||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/dlsim_tm4.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lte_phy_scope_tm4.c
|
||||
)
|
||||
target_link_libraries (dlsim_tm4
|
||||
-Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY ITTI -Wl,--end-group
|
||||
pthread m rt CONFIG_LIB ${T_LIB}
|
||||
)
|
||||
#add_executable(dlsim_tm4
|
||||
# ${OPENAIR1_DIR}/SIMULATION/LTE_PHY/dlsim_tm4.c
|
||||
# ${OPENAIR1_DIR}/PHY/TOOLS/lte_phy_scope_tm4.c
|
||||
# )
|
||||
#target_link_libraries (dlsim_tm4
|
||||
# -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY ITTI -Wl,--end-group
|
||||
# pthread m rt CONFIG_LIB ${T_LIB}
|
||||
# )
|
||||
|
||||
add_executable(rftest
|
||||
${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_test.c
|
||||
@@ -2079,7 +2040,9 @@ target_link_libraries(nr_ulsim PRIVATE
|
||||
)
|
||||
target_link_libraries(nr_ulsim PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
|
||||
foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim)
|
||||
# these simulators do not compile:
|
||||
# dlsim_tm7 pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim
|
||||
foreach(myExe dlsim ulsim)
|
||||
|
||||
add_executable(${myExe}
|
||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
|
||||
@@ -2099,22 +2062,23 @@ endforeach(myExe)
|
||||
|
||||
#unitary tests for Core NEtwork pieces
|
||||
#################################
|
||||
foreach(myExe s1ap
|
||||
secu_knas_encrypt_eia1
|
||||
secu_kenb
|
||||
aes128_ctr
|
||||
secu_knas_encrypt_eea2
|
||||
secu_knas secu_knas_encrypt_eea1
|
||||
kdf
|
||||
aes128_cmac_encrypt
|
||||
secu_knas_encrypt_eia2)
|
||||
add_executable(test_${myExe}
|
||||
${OPENAIR3_DIR}/TEST/test_${myExe}.c
|
||||
)
|
||||
target_link_libraries (test_${myExe}
|
||||
-Wl,--start-group SECURITY UTIL -Wl,--end-group m rt CONFIG_LIB
|
||||
)
|
||||
endforeach(myExe)
|
||||
#foreach(myExe
|
||||
# s1ap
|
||||
# secu_knas_encrypt_eia1
|
||||
# secu_kenb
|
||||
# aes128_ctr
|
||||
# secu_knas_encrypt_eea2
|
||||
# secu_knas secu_knas_encrypt_eea1
|
||||
# kdf
|
||||
# aes128_cmac_encrypt
|
||||
# secu_knas_encrypt_eia2)
|
||||
# add_executable(test_${myExe}
|
||||
# ${OPENAIR3_DIR}/TEST/test_${myExe}.c
|
||||
# )
|
||||
# target_link_libraries (test_${myExe}
|
||||
# -Wl,--start-group SECURITY UTIL -Wl,--end-group m rt CONFIG_LIB
|
||||
# )
|
||||
#endforeach(myExe)
|
||||
|
||||
#ensure that the T header files are generated before targets depending on them
|
||||
if (${T_TRACER})
|
||||
@@ -2124,17 +2088,17 @@ if (${T_TRACER})
|
||||
nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7
|
||||
ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim
|
||||
syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim
|
||||
nr_ulschsim ldpctest polartest smallblocktest cu_test du_test
|
||||
nr_ulschsim ldpctest polartest smallblocktest
|
||||
#all "add_library" definitions
|
||||
ITTI lte_rrc nr_rrc s1ap x2ap m2ap m3ap f1ap
|
||||
params_libconfig oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif oai_iqplayer
|
||||
oai_eth_transpro oai_mobipass HASHTABLE UTIL OMG_SUMO
|
||||
SECURITY SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL
|
||||
params_libconfig
|
||||
oai_eth_transpro HASHTABLE UTIL
|
||||
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 MISC_NFAPI_NR_LIB
|
||||
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
|
||||
CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU OPENAIR0_LIB
|
||||
GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE SIMU
|
||||
dfts config_internals nr_common crc_byte)
|
||||
if (TARGET ${i})
|
||||
add_dependencies(${i} generate_T)
|
||||
@@ -2142,8 +2106,6 @@ if (${T_TRACER})
|
||||
endforeach(i)
|
||||
endif (${T_TRACER})
|
||||
|
||||
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
|
||||
|
||||
set(ENABLE_TESTS OFF CACHE STRING "Activate build of tests")
|
||||
set_property(CACHE ENABLE_TESTS PROPERTY TYPE BOOL)
|
||||
set(ENABLE_PHYSIM_TESTS OFF CACHE STRING "Activate build of physim tests")
|
||||
|
||||
@@ -44,4 +44,4 @@ rf_driver: {
|
||||
#endif
|
||||
|
||||
tx_gain: 75.0, /* TX gain (in dB) */
|
||||
rx_gain: 55.0, /* RX gain (in dB) */
|
||||
rx_gain: 52.0, /* RX gain (in dB) */
|
||||
|
||||
@@ -26,11 +26,11 @@ gNBs =
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# 4.01 GHz
|
||||
absoluteFrequencySSB = 629376;
|
||||
dl_frequencyBand = 78;
|
||||
# 4 GHz
|
||||
dl_absoluteFrequencyPointA = 628720;
|
||||
# 4186.56 MHz
|
||||
absoluteFrequencySSB = 679104;
|
||||
dl_frequencyBand = 77;
|
||||
# 4175.82 MHz
|
||||
dl_absoluteFrequencyPointA = 678388;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
@@ -50,7 +50,7 @@ gNBs =
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
ul_frequencyBand = 77;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
@@ -188,7 +188,7 @@ RUs = (
|
||||
nb_rx = 1
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
bands = [77];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
|
||||
@@ -26,11 +26,11 @@ gNBs =
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# 4.01 GHz
|
||||
absoluteFrequencySSB = 629376;
|
||||
dl_frequencyBand = 78;
|
||||
# 4 GHz
|
||||
dl_absoluteFrequencyPointA = 628720;
|
||||
# 4186.56 MHz
|
||||
absoluteFrequencySSB = 679104;
|
||||
dl_frequencyBand = 77;
|
||||
# 4175.82 MHz
|
||||
dl_absoluteFrequencyPointA = 678388;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
@@ -50,7 +50,7 @@ gNBs =
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
ul_frequencyBand = 77;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
@@ -188,7 +188,7 @@ RUs = (
|
||||
nb_rx = 1
|
||||
att_tx = 0;
|
||||
att_rx = 0;
|
||||
bands = [78];
|
||||
bands = [77];
|
||||
max_pdschReferenceSignalPower = -27;
|
||||
max_rxgain = 114;
|
||||
eNB_instances = [0];
|
||||
|
||||
@@ -184,7 +184,7 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
prach_dtx_threshold = 130;
|
||||
prach_dtx_threshold = 150;
|
||||
#pucch0_dtx_threshold = 150;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -6,9 +6,9 @@ neighbour_list = (
|
||||
gNB_ID = 0xe01;
|
||||
nr_cellid = 11111111;
|
||||
physical_cellId = 1;
|
||||
absoluteFrequencySSB = 629376;
|
||||
absoluteFrequencySSB = 679104;
|
||||
subcarrierSpacing = 1; #30 KHz
|
||||
band = 78;
|
||||
band = 77;
|
||||
plmn = { mcc = 001; mnc = 03; mnc_length = 2};
|
||||
tracking_area_code = 1;
|
||||
}
|
||||
@@ -21,9 +21,9 @@ neighbour_list = (
|
||||
gNB_ID = 0xe00;
|
||||
nr_cellid = 12345678;
|
||||
physical_cellId = 0;
|
||||
absoluteFrequencySSB = 629376;
|
||||
absoluteFrequencySSB = 679104;
|
||||
subcarrierSpacing = 1; #30 KHz
|
||||
band = 78;
|
||||
band = 77;
|
||||
plmn = { mcc = 001; mnc = 03; mnc_length = 2};
|
||||
tracking_area_code = 1;
|
||||
}
|
||||
|
||||
@@ -22,5 +22,5 @@ git config user.name "OAI Jenkins"
|
||||
git config advice.detachedHead false
|
||||
mkdir -p cmake_targets/log
|
||||
git checkout -f ${ref}
|
||||
[ -n "${merge}" ] && git merge --ff ${merge} -m "Temporary merge for CI"
|
||||
[ -n "${merge}" ] && git fetch origin ${merge} && git merge --ff FETCH_HEAD -m "Temporary merge for CI"
|
||||
exit 0
|
||||
|
||||
@@ -15,7 +15,7 @@ oc project ${OC_NS} > /dev/null
|
||||
oc tag oaicicd-ran/oai-physim:${IMG_TAG} ${OC_NS}/oai-physim:${IMG_TAG}
|
||||
helm install ${OC_RELEASE} ${OAI_DIR}/charts/${OC_RELEASE} --set global.image.version=${IMG_TAG} --wait --timeout 120s
|
||||
POD_ID=$(oc get pods | grep oai-${OC_RELEASE} | awk '{print $1}')
|
||||
sleep 10
|
||||
sleep 30
|
||||
echo "Monitoring logs for 'FINISHED' in pod '$POD_ID'"
|
||||
oc logs -f -n ${OC_NS} "$POD_ID" | while read -r line; do
|
||||
if [[ "$line" == *"FINISHED"* ]]; then
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
000002
|
||||
000003
|
||||
020001
|
||||
020002
|
||||
030001
|
||||
030002
|
||||
000004
|
||||
040001
|
||||
050001
|
||||
@@ -110,7 +107,7 @@
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_ue</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 100 -i 0.25</ping_args>
|
||||
<ping_args>-c 50 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>5</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
@@ -121,7 +118,7 @@
|
||||
<nodes>acamas</nodes>
|
||||
<svr_id>rfsim5g_ext_dn</svr_id>
|
||||
<svr_node>acamas</svr_node>
|
||||
<ping_args>-c 100 -i 0.25</ping_args>
|
||||
<ping_args>-c 50 -i 0.25</ping_args>
|
||||
<ping_packetloss_threshold>10</ping_packetloss_threshold>
|
||||
</testCase>
|
||||
|
||||
|
||||
@@ -36,18 +36,6 @@
|
||||
102002
|
||||
302002
|
||||
102003
|
||||
102004
|
||||
102005
|
||||
102006
|
||||
102007
|
||||
102008
|
||||
102009
|
||||
102010
|
||||
102011
|
||||
102012
|
||||
102013
|
||||
102014
|
||||
102015
|
||||
100100
|
||||
100010
|
||||
100020
|
||||
@@ -118,80 +106,8 @@
|
||||
|
||||
<testCase id="102003">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE 3</desc>
|
||||
<id>amarisoft_ue_3</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102004">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE 4</desc>
|
||||
<id>amarisoft_ue_4</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102005">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach (RedCap) UE 5</desc>
|
||||
<id>amarisoft_ue_5</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102006">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach (RedCap) UE 6</desc>
|
||||
<id>amarisoft_ue_6</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102007">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE 7</desc>
|
||||
<id>amarisoft_ue_7</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102008">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE 8</desc>
|
||||
<id>amarisoft_ue_8</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102009">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE 9</desc>
|
||||
<id>amarisoft_ue_9</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102010">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach (RedCap) UE 10</desc>
|
||||
<id>amarisoft_ue_10</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102011">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach (RedCap) UE 11</desc>
|
||||
<id>amarisoft_ue_11</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102012">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach (RedCap) UE 12</desc>
|
||||
<id>amarisoft_ue_12</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102013">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE 13</desc>
|
||||
<id>amarisoft_ue_13</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102014">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach UE 14</desc>
|
||||
<id>amarisoft_ue_14</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="102015">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach (RedCap) UE 15</desc>
|
||||
<id>amarisoft_ue_15</id>
|
||||
<desc>Attach UE 3 - 15</desc>
|
||||
<id>amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="100010">
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
<!--
|
||||
|
||||
Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The OpenAirInterface Software Alliance licenses this file to You under
|
||||
the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.openairinterface.org/?page_id=698
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
contact@openairinterface.org
|
||||
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>LONGRUN-5G-NRUE</htmlTabRef>
|
||||
<htmlTabName>Longrun 40 MHz TDD SA</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
060000
|
||||
010000 010001
|
||||
800813
|
||||
020000
|
||||
800814
|
||||
020001
|
||||
000001
|
||||
001000
|
||||
000100
|
||||
001000
|
||||
000100
|
||||
001000
|
||||
000100
|
||||
001000
|
||||
000200
|
||||
001000
|
||||
000200
|
||||
001000
|
||||
000200
|
||||
040001 040000
|
||||
333333
|
||||
444444
|
||||
060001
|
||||
</TestCaseRequestedList>
|
||||
<TestCaseExclusionList></TestCaseExclusionList>
|
||||
|
||||
<testCase id="060000">
|
||||
<class>DeployCoreNetwork</class>
|
||||
<desc>Initialize 5G Core</desc>
|
||||
<cn_id>oc-cn5g</cn_id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="010000">
|
||||
<class>Pull_Cluster_Image</class>
|
||||
<desc>Pull Images from Cluster</desc>
|
||||
<images>oai-gnb</images>
|
||||
<node>avra</node>
|
||||
</testCase>
|
||||
|
||||
<testCase id="010001">
|
||||
<class>Pull_Cluster_Image</class>
|
||||
<desc>Pull Images from Cluster</desc>
|
||||
<images>oai-nr-ue</images>
|
||||
<node>caracal</node>
|
||||
</testCase>
|
||||
|
||||
<testCase id="800813">
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<node>avra</node>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020000">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy gNB (TDD/Band78/40MHz/N310) in a container</desc>
|
||||
<node>avra</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_gnb</yaml_path>
|
||||
<num_attempts>3</num_attempts>
|
||||
</testCase>
|
||||
|
||||
<testCase id="800814">
|
||||
<class>Create_Workspace</class>
|
||||
<desc>Create new Workspace</desc>
|
||||
<node>caracal</node>
|
||||
</testCase>
|
||||
|
||||
<testCase id="020001">
|
||||
<class>Deploy_Object</class>
|
||||
<desc>Deploy nrUE (TDD/Band78/40MHz/N310) in a container</desc>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_nrue</yaml_path>
|
||||
<node>caracal</node>
|
||||
<num_attempts>3</num_attempts>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000001">
|
||||
<class>Attach_UE</class>
|
||||
<desc>Attach OAIUE</desc>
|
||||
<id>oai_ue_caracal</id>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000100">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/10Mbps/UDP)(10 min)</desc>
|
||||
<iperf_args>-u -b 10M -t 600 -i 1 -R</iperf_args>
|
||||
<id>oai_ue_caracal</id>
|
||||
<svr_id>oc-cn5g</svr_id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="000200">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/2Mbps/UDP)(10 min)</desc>
|
||||
<iperf_args>-u -b 2M -t 600 -i 1 </iperf_args>
|
||||
<id>oai_ue_caracal</id>
|
||||
<svr_id>oc-cn5g</svr_id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>80</iperf_bitrate_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="001000">
|
||||
<class>Ping</class>
|
||||
<desc>Ping: 20pings in 20sec</desc>
|
||||
<id>oai_ue_caracal</id>
|
||||
<svr_id>oc-cn5g</svr_id>
|
||||
<ping_args>-c 20</ping_args>
|
||||
<ping_packetloss_threshold>1</ping_packetloss_threshold>
|
||||
<ping_rttavg_threshold>25</ping_rttavg_threshold>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040000">
|
||||
<class>Undeploy_Object</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Undeploy gNB</desc>
|
||||
<node>avra</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_gnb</yaml_path>
|
||||
<d_retx_th>20,100,100,100</d_retx_th>
|
||||
<u_retx_th>20,100,100,100</u_retx_th>
|
||||
</testCase>
|
||||
|
||||
<testCase id="040001">
|
||||
<class>Undeploy_Object</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Undeploy nr UE</desc>
|
||||
<node>caracal</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_nrue</yaml_path>
|
||||
</testCase>
|
||||
|
||||
<testCase id="333333">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<node>avra</node>
|
||||
<images>oai-gnb</images>
|
||||
</testCase>
|
||||
|
||||
<testCase id="444444">
|
||||
<class>Clean_Test_Server_Images</class>
|
||||
<always_exec>true</always_exec>
|
||||
<desc>Clean Test Images on Test Server</desc>
|
||||
<node>caracal</node>
|
||||
<images>oai-nr-ue</images>
|
||||
</testCase>
|
||||
|
||||
<testCase id="060001">
|
||||
<class>UndeployCoreNetwork</class>
|
||||
<desc>Terminate 5G Core</desc>
|
||||
<always_exec>true</always_exec>
|
||||
<cn_id>oc-cn5g</cn_id>
|
||||
</testCase>
|
||||
|
||||
</testCaseList>
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "common/config/config_paramdesc.h"
|
||||
#include "common/utils/T/T.h"
|
||||
#define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2...
|
||||
#define CONFIG_MAX_ALLOCATEDPTRS 32768 // maximum number of parameters that can be dynamicaly allocated in the config module
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ else()
|
||||
endif()
|
||||
|
||||
add_library(params_yaml_static config_yaml.cpp)
|
||||
target_link_libraries(params_yaml_static PUBLIC UTIL yaml-cpp::yaml-cpp)
|
||||
target_link_libraries(params_yaml_static PUBLIC yaml-cpp::yaml-cpp)
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
add_library(params_yaml MODULE config_yaml.cpp)
|
||||
target_link_libraries(params_yaml PUBLIC UTIL yaml-cpp::yaml-cpp)
|
||||
target_link_libraries(params_yaml PUBLIC yaml-cpp::yaml-cpp)
|
||||
set_target_properties(params_yaml PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
add_executable(test_yaml_config test_yaml_config.cpp)
|
||||
target_link_libraries(test_yaml_config PRIVATE params_yaml_static GTest::gtest)
|
||||
target_link_libraries(test_yaml_config PRIVATE params_yaml_static GTest::gtest CONFIG_LIB)
|
||||
add_dependencies(tests test_yaml_config)
|
||||
add_test(NAME test_yaml_config
|
||||
COMMAND ./test_yaml_config)
|
||||
|
||||
@@ -4,10 +4,12 @@ target_link_libraries(log_headers INTERFACE T_headers)
|
||||
|
||||
set(log_sources log.c)
|
||||
if (ENABLE_LTTNG)
|
||||
find_package(LTTngUST 2.3.8 EXACT REQUIRED)
|
||||
set(log_sources ${log_sources} lttng-tp.c)
|
||||
else()
|
||||
message(STATUS "LTTNG support disabled")
|
||||
endif()
|
||||
add_library(LOG ${log_sources})
|
||||
target_include_directories(LOG PUBLIC .)
|
||||
target_link_libraries(LOG PRIVATE CONFIG_LIB)
|
||||
target_link_libraries(LOG PUBLIC log_headers)
|
||||
if (ENABLE_LTTNG)
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <common/utils/utils.h>
|
||||
#include "common/utils/T/T.h"
|
||||
#if ENABLE_LTTNG
|
||||
#include "lttng-log.h"
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,7 @@ add_custom_target(generate_T DEPENDS T_IDs.h check_vcd)
|
||||
# even if T is off, we need the headers as many targets depend on it
|
||||
# for this, create an INTERFACE (header-only) library T_headers. To ensure the
|
||||
# headers have really been created, we make this headers library explicitly
|
||||
# depend on the generated headers.
|
||||
# depend on the generate_T target.
|
||||
add_library(T_headers INTERFACE)
|
||||
add_dependencies(T_headers T_IDs.h generate_T)
|
||||
target_include_directories(T_headers INTERFACE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
@@ -25,52 +25,6 @@
|
||||
#include "common/utils/mem/oai_memory.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
/****************************************************************************
|
||||
** **
|
||||
** Name: memory_get_path() **
|
||||
** **
|
||||
** Description: Gets the absolute path of the file where non-volatile **
|
||||
** data are located **
|
||||
** **
|
||||
** Inputs: dirname: The directory where data file is located **
|
||||
** filename: The name of the data file **
|
||||
** Others: None **
|
||||
** **
|
||||
** Outputs: None **
|
||||
** Return: The absolute path of the non-volatile data **
|
||||
** file. The returned value is a dynamically **
|
||||
** allocated octet string that needs to be **
|
||||
** freed after usage. **
|
||||
** Others: None **
|
||||
** **
|
||||
***************************************************************************/
|
||||
char* memory_get_path(const char* dirname, const char* filename)
|
||||
{
|
||||
/* Get non-volatile data directory */
|
||||
const char* path = getenv(dirname);
|
||||
|
||||
if (path == NULL) {
|
||||
path = getenv(DEFAULT_NAS_PATH);
|
||||
}
|
||||
|
||||
if (path == NULL) {
|
||||
path = ".";
|
||||
}
|
||||
|
||||
/* Append non-volatile data file name */
|
||||
size_t size = strlen(path) + strlen(filename) + 1;
|
||||
char* data_filename = (char*)malloc(size + 1);
|
||||
|
||||
if (data_filename != NULL) {
|
||||
if (size != sprintf(data_filename, "%s/%s", path, filename)) {
|
||||
free(data_filename);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return data_filename;
|
||||
}
|
||||
|
||||
char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid)
|
||||
{
|
||||
/* Get non-volatile data directory */
|
||||
|
||||
@@ -35,8 +35,6 @@ typedef unsigned char uint8_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
char* memory_get_path(const char* dirname, const char* filename);
|
||||
|
||||
char* memory_get_path_from_ueid(const char* dirname, const char* filename, int ueid);
|
||||
|
||||
int memory_read(const char* datafile, void* data, size_t size);
|
||||
|
||||
@@ -44,7 +44,7 @@ add_library(telnetsrv_enb MODULE
|
||||
telnetsrv_enb_phycmd.c
|
||||
)
|
||||
add_dependencies(telnetsrv telnetsrv_enb)
|
||||
target_link_libraries(telnetsrv_enb PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(telnetsrv_enb PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs log_headers)
|
||||
|
||||
message(STATUS "No specific telnet functions for gnb")
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
while ( 1 ) {
|
||||
if ( read(fd,&doneRequest, sizeof(doneRequest)) == sizeof(doneRequest)) {
|
||||
printf("%lu" SEP "%lu" SEP "%lu" SEP "%lu" "\n",
|
||||
printf("%lu" SEP "%llu" SEP "%llu" SEP "%llu" "\n",
|
||||
doneRequest.key,
|
||||
(doneRequest.startProcessingTime-doneRequest.creationTime)/cpuCyclesMicroSec,
|
||||
(doneRequest.endProcessingTime-doneRequest.startProcessingTime)/cpuCyclesMicroSec,
|
||||
|
||||
@@ -7,7 +7,7 @@ add_library(time_management_core OBJECT
|
||||
time_client.c)
|
||||
|
||||
target_link_libraries(time_management PUBLIC time_management_core)
|
||||
target_link_libraries(time_management_core PRIVATE ${T_LIB})
|
||||
target_link_libraries(time_management_core PRIVATE log_headers)
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
|
||||
@@ -51,7 +51,7 @@ PROJECT_BRIEF = "Full experimental OpenSource LTE and NR implementation
|
||||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||
# the logo to the output directory.
|
||||
|
||||
PROJECT_LOGO = @CMAKE_SOURCE_DIR@/doc/oai_logo.png
|
||||
PROJECT_LOGO = @CMAKE_SOURCE_DIR@/doc/images/oai_logo.png
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||
# into which the generated documentation will be written. If a relative path is
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[[_TOC_]]
|
||||
|
||||
# 1. Introduction
|
||||
## 1. Introduction
|
||||
|
||||
E1 is the interface that lies between the nodes CU Control Plane (CUCP) and CU User Plane (CUUP). Once the nodes are configured, all user plane traffic flows through CUUP.
|
||||
|
||||
@@ -77,11 +77,11 @@ sequenceDiagram
|
||||
```
|
||||
More details about the E1AP procedures in OAI are available in this document: [E1 Procedures](./e1ap_procedures.md).
|
||||
|
||||
# 2. Running the E1 Split
|
||||
## 2. Running the E1 Split
|
||||
|
||||
The setup is assuming that all modules are running on the same machine. The user can refer to the [F1 design document](./../F1AP/F1-design.md) for local deployment of the DU.
|
||||
|
||||
## 2.1 Configuration File
|
||||
### 2.1 Configuration File
|
||||
|
||||
The gNB is started based on the node type that is specified in the configuration file. The following parameters must be configured accordingly.
|
||||
|
||||
@@ -130,9 +130,9 @@ The CUUP uses the IP address specified in `gNBs.[0].local_s_address` for F1-U an
|
||||
|
||||
Alternatively, you can use the config files `ci-scripts/conf_files/gnb-cucp.sa.f1.conf` and `ci-scripts/conf_files/gnb-cuup.sa.f1.conf`.
|
||||
|
||||
## 2.2 Steps to Run the Split in rfsimulator with OAI UE
|
||||
### 2.2 Steps to Run the Split in rfsimulator with OAI UE
|
||||
|
||||
Note: A 5G core must be running at this point. Steps to start the OAI 5G core can be found [in the oai-cn5g-fed repository](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/docs/DEPLOY_HOME.md) or [here](NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md).
|
||||
Note: A 5G core must be running at this point. Steps to start the OAI 5G core can be found [in the oai-cn5g-fed repository](https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed/-/blob/master/docs/DEPLOY_HOME.md) or [here](../NR_SA_Tutorial_OAI_CN5G.md).
|
||||
|
||||
0. Open wireshark to capture the E1AP messages. You might set the capture filter
|
||||
to `sctp` to limit the number of captured packages.
|
||||
@@ -165,7 +165,7 @@ OAI UE:
|
||||
sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --rfsimulator.serveraddr 127.0.0.1
|
||||
```
|
||||
|
||||
# 3. Configuration file IP addresses of network functions
|
||||
## 3. Configuration file IP addresses of network functions
|
||||
|
||||
You can also run the nodes on different machines. If you do so please change the interface parameters accordingly and make sure the interfaces are reachable. Please refer to the following figure for an overview of all parameters.
|
||||
|
||||
@@ -173,7 +173,7 @@ You can also run the nodes on different machines. If you do so please change the
|
||||
|
||||
[PDF version](./images/e1-archi.pdf) | [LaTeX/TikZ version](./images/e1-archi.tex) if you want to modify to reflect your setup
|
||||
|
||||
# 4. Multiple CU-UP
|
||||
## 4. Multiple CU-UP
|
||||
|
||||
It is possible to connect multiple CU-UP to the same CU-CP. In the handler of
|
||||
the E1 Setup Request, the CU-CP verifies that the PLMN(s) (MCC, MNC) between
|
||||
@@ -195,6 +195,6 @@ that you have to restart the CU-CP if you want to connect the CU-UP again
|
||||
(e.g., after a crash). The CU-CP might also misfunction during attach if a
|
||||
CU-UP was connected, but disconnected in the meantime.
|
||||
|
||||
# 5. Abnormal conditions
|
||||
## 5. Abnormal conditions
|
||||
|
||||
* The CU-UP goes offline during normal operation (e.g. UEs have a valid PDU Session and are exchanging data on the UP): after restarting the CU-UP, the UP is not restored and the user will notice GTP errors. In this case the UEs have to reconnect.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
<img src="../images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# Introduction
|
||||
## Introduction
|
||||
|
||||
The F1 interface is the functional split of 3GPP between the CU (centralized
|
||||
unit: PDCP, RRC, SDAP) and the DU (distributed unit: RLC, MAC, PHY). It is
|
||||
@@ -33,17 +33,17 @@ F1-U:
|
||||
|
||||
No equivalent for 4G exists.
|
||||
|
||||
## Control plane (F1-C)
|
||||
### Control plane (F1-C)
|
||||
|
||||
The interface F1-C is designed for the exchange of signalling messages between the
|
||||
Radio Network Layer (RNL) and the Transport Network Layer (TNL). It
|
||||
consists of F1 Application Protocol messages (F1-AP) exchanged over SCTP.
|
||||
|
||||
## Data plane (F1-U)
|
||||
### Data plane (F1-U)
|
||||
|
||||
F1-U uses GTP-U for information exchange.
|
||||
|
||||
# OAI Implementation Status
|
||||
## OAI Implementation Status
|
||||
|
||||
The implementation of F1AP messages is seamlessly integrated into OAI, supporting both Monolithic SA
|
||||
and CU/DU functional split modes. The F1 code is therefore always compiled with nr-softmodem.
|
||||
@@ -63,13 +63,13 @@ This is the current status:
|
||||
- Not supported:
|
||||
* NSA
|
||||
|
||||
## F1-C
|
||||
### F1-C
|
||||
|
||||
### F1AP messages
|
||||
#### F1AP messages
|
||||
|
||||
Refer to [FEATURE_SET.md](FEATURE_SET.md#gNB-F1AP) to learn about the current F1AP implementation status.
|
||||
Refer to [FEATURE_SET.md](../FEATURE_SET.md#gnb-f1ap) to learn about the current F1AP implementation status.
|
||||
|
||||
### High-level F1-C code structure
|
||||
#### High-level F1-C code structure
|
||||
|
||||
The F1 interface is used internally between CU (mostly RRC) and DU (mostly MAC)
|
||||
to exchange information. In DL, the CU sends messages as defined by the
|
||||
@@ -170,7 +170,7 @@ sequenceDiagram
|
||||
TASK_MAC_GNB->>+TASK_RRC_GNB: raw F1AP message (ITTI)
|
||||
```
|
||||
|
||||
## F1-U
|
||||
### F1-U
|
||||
|
||||
Current status:
|
||||
|
||||
@@ -178,7 +178,7 @@ Current status:
|
||||
* Each packet is acknowledged individually
|
||||
* Support of multiple DUs per CU
|
||||
|
||||
# How to run
|
||||
## How to run
|
||||
|
||||
As mentioned earlier, OAI uses F1 internally. It is always compiled in.
|
||||
To start CU/DU, you use `./nr-softmodem` with the appropriate configuration
|
||||
@@ -190,7 +190,7 @@ sudo cmake_targets/ran_build/build/nr-softmodem -O ci-scripts/conf_files/gnb-du.
|
||||
```
|
||||
|
||||
These files are tested in the CI, and are configured for use in docker,
|
||||
see [this `docker-compose` file](../ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml).
|
||||
see [this `docker-compose` file](../../ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml).
|
||||
|
||||
The rules to decide if a config triggers a start of a DU, CU, or monolithic
|
||||
gNB, are, in order:
|
||||
@@ -200,7 +200,7 @@ gNB, are, in order:
|
||||
(`tr_s_preference`), it is a CU.
|
||||
3. It is a (monolithic) gNB.
|
||||
|
||||
## F1 IP configuration for Local network deployment of F1
|
||||
### F1 IP configuration for Local network deployment of F1
|
||||
|
||||
The following paragraphs explain the IP configuration for F1 in the OAI config
|
||||
files on the example of a a local deployment. We assume that the CU will bind
|
||||
@@ -242,7 +242,7 @@ the options `MACRLCs.[0].local_n_address` and
|
||||
`MACRLCs.[0].local_n_address_f1u`, respectively. Note that this is not foreseen
|
||||
for the CU; in the case of the CU, please use separate CU-UP and CU-CP.
|
||||
|
||||
## Configuration of multiple DUs
|
||||
### Configuration of multiple DUs
|
||||
|
||||
Upon F1 Setup Request of a new DU, the CU cross-checks that
|
||||
|
||||
@@ -260,9 +260,9 @@ You have to of course make sure that the local interface of the DU
|
||||
Assuming you use RFsim, you should make the RFsimulator server side (typically
|
||||
the gNB) bind on different hosts (`rfsimulator.serverport`).
|
||||
|
||||
# Code documentation
|
||||
## Code documentation
|
||||
|
||||
## Common multi-threading architecture
|
||||
### Common multi-threading architecture
|
||||
|
||||
The CU and DU interfaces are based on ITTI threads (see `common/utils/ocp_itti/itti.md`)
|
||||
adopted by all OAI upper layers to run isolated threads dedicated to one feature.
|
||||
@@ -301,7 +301,7 @@ All GTP-U tunnels are managed in a Linux Thread, that have partially ITTI design
|
||||
3. incoming packets are sent to the tunnel creator using a C callback (the callback function is given in tunnel creation order). The callback should not block
|
||||
|
||||
|
||||
## F1-C messages towards the CU
|
||||
### F1-C messages towards the CU
|
||||
|
||||
The CU thread starts when the CU starts. It opens listening socket on the
|
||||
configuration-specified IP/port by sending the appropriate message to
|
||||
@@ -332,7 +332,7 @@ You might also want to consult TS 38.401 regarding the message exchange.
|
||||
| UE Context Release Request | `F1AP_UE_CONTEXT_RELEASE_REQ` | `rrc_CU_process_ue_context_release_request()` | RRC will trigger UE release |
|
||||
| UE Context Release Complete | `F1AP_UE_CONTEXT_RELEASE_COMPLETE` | `rrc_CU_process_ue_context_release_complete()` | frees UE Context, signals to NGAP |
|
||||
|
||||
## F1-C Messages towards the DU
|
||||
### F1-C Messages towards the DU
|
||||
|
||||
The task "gNB app", after reading the configuration file, sends a message
|
||||
`F1AP_DU_REGISTER_REQ` to the DU task. This message contains network
|
||||
@@ -371,9 +371,9 @@ You might also want to consult TS 38.401 regarding the message exchange.
|
||||
a reconfiguration has to be triggered if the CU receives a CellGroupConfig,
|
||||
originating at the DU. See also flag `expect_reconfiguration`.
|
||||
|
||||
## F1-U messages
|
||||
### F1-U messages
|
||||
|
||||
### General
|
||||
#### General
|
||||
|
||||
In the DU in UL, RLC checks in `deliver_sdu()` if we are operating in split
|
||||
mode, and either (direct) calls `pdcp_data_ind` (DRB) or (f1ap) sends a GTP
|
||||
@@ -390,7 +390,7 @@ In the DU in DL, assuming the GTP-U tunnel exists, GTP decapsulates the packet
|
||||
and calls the reception call back `nr_rlc_data_req()`, which enqueues the
|
||||
packet into the UE's RLC buffer.
|
||||
|
||||
## Tunnel Setup
|
||||
### Tunnel Setup
|
||||
|
||||
In GTP-U, TS 29.281 specifies a optional header (NR RAN Container). This
|
||||
extension header may be transmitted in a G-PDU over the X2-U, Xn-U and F1-U user
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<tr style="border-collapse: collapse; border: none;">
|
||||
<td style="border-collapse: collapse; border: none;">
|
||||
<a href="http://www.openairinterface.org/">
|
||||
<img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
<img src="../images/oai_final_logo.png" alt="" border=3 height=50 width=150>
|
||||
</img>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
- FAPI (IF2) : specified by Small Cell Forum (open-nFAPI implementation)
|
||||
- IF1 : F1 in 3GPP Release 15
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
# OpenAirInterface Block Diagram #
|
||||
|
||||

|
||||

|
||||
|
||||
# OpenAirInterface 5G-NR Feature Set #
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
The following features are valid for the gNB and the 5G-NR UE.
|
||||
|
||||
* Static TDD
|
||||
- Multi TDD pattern supported refer [TDD Configuration](NR_SA_Multi_TDD_Pattern.md)
|
||||
- Multi TDD pattern supported refer [TDD Configuration](MAC/mac-usage.md)
|
||||
* Static FDD
|
||||
* Normal CP
|
||||
* Subcarrier spacings: 15 and 30kHz (FR1), 120kHz (FR2)
|
||||
|
||||
@@ -183,7 +183,7 @@ See [nFAPI documentation](../nfapi.md) or [Aerial
|
||||
tutorial](../Aerial_FAPI_Split_Tutorial.md) for information about the (n)FAPI
|
||||
split.
|
||||
|
||||
See [F1 documentation](../F1-design.md) for information about the F1 split.
|
||||
See [F1 documentation](../F1AP/F1-design.md) for information about the F1 split.
|
||||
|
||||
## MAC scheduler-related configuration options
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ There is some general information in the [OpenAirInterface Gitlab Wiki](https://
|
||||
* IF setups and arbitrary frequencies
|
||||
* MIMO
|
||||
- [How to run OAI with O-RAN 7.2 FHI](./ORAN_FHI7.2_Tutorial.md)
|
||||
- [How to run a 5G-NSA setup](./TESTING_GNB_W_COTS_UE.md)
|
||||
- [How to run a 5G-NSA setup](./TESTING_OAI_NSA_COTS_UE.md)
|
||||
- [How to run a 4G setup using L1 simulator](./L1SIM.md) _Note: we recommend the RFsimulator_
|
||||
- [How to use the L2 simulator](./L2NFAPI.md)
|
||||
- [How to use the OAI channel simulator](../openair1/SIMULATION/TOOLS/DOC/channel_simulation.md)
|
||||
@@ -60,7 +60,7 @@ There is some general information in the [OpenAirInterface Gitlab Wiki](https://
|
||||
- [How to run OAI-VNF and OAI-PNF](./nfapi.md): how to run the FAPI/nFAPI split,
|
||||
including some general remarks on FAPI/nFAPI.
|
||||
- [How to use the positioning reference signal (PRS)](./RUN_NR_PRS.md)
|
||||
- [How to use device-to-device communication (D2D, 4G)](./d2d_emulator_setup.txt)
|
||||
- [How to use device-to-device communication (D2D, 4G)](./d2d_emulator_setup.md)
|
||||
- [How to run with E2 agent](../openair2/E2AP/README.md)
|
||||
- [How to run the physical simulators](./physical-simulators.md)
|
||||
- [How to setup OAI with Nvidia Aerial and Foxconn](./Aerial_FAPI_Split_Tutorial.md)
|
||||
@@ -71,8 +71,6 @@ There is some general information in the [OpenAirInterface Gitlab Wiki](https://
|
||||
Legacy unmaintained files:
|
||||
- [`L2NFAPI_NOS1.md`](./L2NFAPI_NOS1.md), [`L2NFAPI_S1.md`](./L2NFAPI_S1.md):
|
||||
old L2simulator, not valid anymore
|
||||
- [`SystemX-tutorial-design.md`](./SystemX-tutorial-design.md): old, high-level
|
||||
documentation
|
||||
- [`UL_MIMO.txt`](./UL_MIMO.txt): UL-MIMO specific notes
|
||||
|
||||
# Designs
|
||||
|
||||
@@ -12,7 +12,7 @@ The RRC layer controls the basic connection setup of UEs as well as additional
|
||||
procedures. It is the fundamental building block of OAI's CU-CP, and interacts
|
||||
with lower layers (DU, basically MAC and RLC) through F1AP messages, and with
|
||||
the CU-UP through E1AP messages. More information can be found in the
|
||||
respective [F1AP page](../F1-design.md) and [E1AP page](../E1AP/E1-design.md).
|
||||
respective [F1AP page](../F1AP/F1-design.md) and [E1AP page](../E1AP/E1-design.md).
|
||||
|
||||
# Periodic output and interpretation
|
||||
|
||||
@@ -57,7 +57,7 @@ As of now, it does not print information about connected CU-UPs or AMFs.
|
||||
|
||||
## Split-related options (when running in a CU or CU-CP)
|
||||
|
||||
See [F1 documentation](../F1-design.md) for information about the F1 split.
|
||||
See [F1 documentation](../F1AP/F1-design.md) for information about the F1 split.
|
||||
See [E1 documentation](../E1AP/E1-design.md) for information about the E1 split.
|
||||
|
||||
## RRC-specific configuration options
|
||||
@@ -99,26 +99,43 @@ the [MAC configuration](../MAC/mac-usage.md) as well for SIB configuration.
|
||||
|
||||
### Neighbor-gNB configuration
|
||||
|
||||
#### What is a gNB neighbor?
|
||||
|
||||
Network continuity is a key aspect of 5G. In the 5G architecture, gNB neighbors play a central role in maintaining service continuity through mechanisms such as handover and load balancing. By definition, a gNB neighbor is another gNB that can be measured and linked by the UE. If the current serving gNB is no longer optimal, the UE may connect to a neighbor gNB.
|
||||
|
||||
To support this behavior, the network configuration specifies additional frequencies and cells that the UE should measure. The UE reports these measurements to the network, which then decides whether or not to initiate a handover.
|
||||
|
||||
Neighbor types include:
|
||||
- **Intra-gNB neighbors** - cells belonging to the same gNB
|
||||
- **Inter-gNB neighbors** - cells belonging to different gNBs
|
||||
- **Inter-RAT neighbors** - cells belonging to another RAT (e.g., LTE)
|
||||
Refer to the [handover tutorial](../handover-tutorial.md) for detailed information about gNB neighbors and handover procedures.
|
||||
|
||||
#### Required configuration parameters
|
||||
|
||||
To define a neighbor cell in the configuration file, the following parameters are typically needed:
|
||||
- **gNB ID** - unique identifier of the gNB
|
||||
- **Cell ID** - identifier of the cell within the gNB
|
||||
- **Physical Cell ID** - identifier of the cell’s synchronization signal (PCI)
|
||||
- **Absolute Frequency** - frequency used by the SSB (absoluteFrequencySSB)
|
||||
- **Subcarrier Spacing** - numerology (e.g., 15 kHz, 30 kHz)
|
||||
- **PLMN configuration** - MCC, MNC, and MNC length
|
||||
- **Tracking Area Code (TAC)** - identifier of the tracking area
|
||||
To define a neighbor cell in the configuration file, the following parameters are required:
|
||||
|
||||
Refer to the [handover tutorial](../handover-tutorial.md) for more information.
|
||||
- `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
|
||||
- `band` - 3GPP frequency band number (e.g., `78` for 3.5GHz)
|
||||
- `plmn` - PLMN configuration object with:
|
||||
- `mcc` - mobile country code (3 digits, e.g., `001`)
|
||||
- `mnc` - mobile network code (2-3 digits, e.g., `01`)
|
||||
- `mnc_length` - number of digits in MNC (must be `2` or `3`)
|
||||
- `tracking_area_code` - tracking area identifier (e.g., `1`)
|
||||
|
||||
Example configuration structure:
|
||||
```
|
||||
neighbour_list = (
|
||||
{
|
||||
nr_cellid = 12345678;
|
||||
neighbour_cell_configuration = (
|
||||
{
|
||||
gNB_ID = 0xe01;
|
||||
nr_cellid = 11111111;
|
||||
physical_cellId = 1;
|
||||
absoluteFrequencySSB = 643296;
|
||||
subcarrierSpacing = 1; # 30 kHz
|
||||
band = 78;
|
||||
plmn = { mcc = 001; mnc = 01; mnc_length = 2 };
|
||||
tracking_area_code = 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
Refer to the [handover tutorial](../handover-tutorial.md) for complete examples and detailed setup instructions.
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
# OpenAirInterface for SystemX
|
||||
|
||||
# Terminology
|
||||
|
||||
****This document use the 5G terminology****
|
||||
|
||||
**Central Unit (CU):** It is a logical node that includes the gNB
|
||||
functions like Transfer of user data, Mobility control, Radio access
|
||||
network sharing, Positioning, Session Management etc., except those
|
||||
functions allocated exclusively to the DU. CU controls the operation of
|
||||
DUs over front-haul (Fs) interface. A central unit (CU) may also be
|
||||
known as BBU/REC/RCC/C-RAN/V-RAN/VNF
|
||||
|
||||
**Distributed Unit (DU):** This logical node includes a subset of the
|
||||
gNB functions, depending on the functional split option. Its operation
|
||||
is controlled by the CU. Distributed Unit (DU) also known with other
|
||||
names like RRH/RRU/RE/RU/PNF.
|
||||
|
||||
In OpenAir code, the terminology is often RU and BBU.
|
||||
|
||||
# OpenAirUsage
|
||||
|
||||
## EPC and general environment
|
||||
|
||||
### OAI EPC
|
||||
|
||||
Use the stable OAI EPC, that can run in one machine (VM or standalone)
|
||||
|
||||
Draft description:
|
||||
<https://open-cells.com/index.php/2017/08/22/all-in-one-openairinterface-august-22nd/>
|
||||
|
||||
## Standalone 4G
|
||||
|
||||
EPC+eNB on one machine, the UE can be commercial or OAI UE.
|
||||
|
||||
### USRP B210
|
||||
|
||||
Main current issue: traffic is good only on coaxial link between UE and
|
||||
eNB (probably power management issue).
|
||||
|
||||
### Simulated RF
|
||||
|
||||
Running eNB+UE both OAI can be done over a virtual RF link.
|
||||
|
||||
The UE current status is that threads synchronization is implicit in
|
||||
some cases. As the RF simulator is very quick, a “sleep()” is required
|
||||
in the UE main loop
|
||||
|
||||
(line 1744, targets/RT/USER/lte-ue.c).
|
||||
|
||||
Running also the UE in the same machine is possible with simulated RF.
|
||||
|
||||
Running in same machine is simpler, offers about infinite speed for
|
||||
virtual RF samples transmission.
|
||||
|
||||
A specific configuration is required because the EPC Sgi interface has
|
||||
the same IP tunnel end point as the UE.
|
||||
|
||||
So, we have to create a network namespace for the UE and to route data
|
||||
in/out of the namespace.
|
||||
|
||||
```bash
|
||||
ip netns delete aNameSpace 2> /dev/null
|
||||
|
||||
ip link delete v-eth1 2> /dev/null
|
||||
|
||||
ip netns add aNameSpace
|
||||
|
||||
ip link add v-eth1 type veth peer name v-peer1
|
||||
|
||||
ip link set v-peer1 netns aNameSpace
|
||||
|
||||
ip addr add 10.200.1.1/24 dev v-eth1
|
||||
|
||||
ip link set v-eth1 up
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 10.200.1.0/255.255.255.0 -o enp0s31f6 \
|
||||
-j MASQUERADE
|
||||
|
||||
iptables -A FORWARD -i enp0s31f6 -o v-eth1 -j ACCEPT
|
||||
|
||||
iptables -A FORWARD -o enp0s31f6 -i v-eth1 -j ACCEPT
|
||||
|
||||
ip netns exec aNameSpace ip link set dev lo up
|
||||
|
||||
ip netns exec aNameSpace ip addr add 10.200.1.2/24 dev v-peer1
|
||||
|
||||
ip netns exec aNameSpace ip link set v-peer1 up
|
||||
|
||||
ip netns exec aNameSpace bash
|
||||
```
|
||||
|
||||
After the last command, the Linux shell is in the new namespace, ready
|
||||
to run the UE.
|
||||
|
||||
To make user plan traffic, the traffic generator has to run in the same
|
||||
namespace
|
||||
|
||||
```bash
|
||||
ip netns exec aNameSpace bash
|
||||
```
|
||||
|
||||
The traffic genenrator has to specify the interface:
|
||||
|
||||
```bash
|
||||
route add default oaitun_ue1
|
||||
```
|
||||
|
||||
or specify the outgoing route in the traffic generator (like option “-I”
|
||||
in ping command).
|
||||
|
||||
## 5G and F1
|
||||
|
||||
Today 5G achievement is limited to physical layer.
|
||||
|
||||
The available modulation is 40MHz, that require one X310 or N300 for the
|
||||
gNB and a X310 or N300 for the nrUE.
|
||||
|
||||
### Usage with X310
|
||||
|
||||
Linux configuration:
|
||||
<https://files.ettus.com/manual/page_usrp_x3x0_config.html>
|
||||
|
||||
We included most of this configuration included in OAI source code.
|
||||
|
||||
Remain to set the NIC (network interface card) MTU to 9000 (jumbo
|
||||
frames).
|
||||
|
||||
### Running 5G
|
||||
|
||||
Usage with RFsimulator:
|
||||
|
||||
**gNB**
|
||||
|
||||
```bash
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf
|
||||
```
|
||||
|
||||
**nrUE**
|
||||
|
||||
```bash
|
||||
sudo ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000 -d --rfsimulator.serveraddr 127.0.0.1
|
||||
```
|
||||
@@ -7,12 +7,12 @@ STATUS 2020/10/15 : added External Resources section and links
|
||||
## External Resources
|
||||
|
||||
Additional Resources to this page can be found here (special mention to Walter Maguire <wmaguire@live.com>) :
|
||||
https://docs.google.com/document/d/1pL8Szm0ocGxdl5ESVp12Ff71a4PbhCb9SpvbLZzwYbo/edit?usp=sharing
|
||||
[Additional Notes Supporting the OAI COTS NSA](https://docs.google.com/document/d/1pL8Szm0ocGxdl5ESVp12Ff71a4PbhCb9SpvbLZzwYbo/edit?usp=sharing)
|
||||
At time of writing, the openairinterface5G Commit Tag is 2020.w39
|
||||
|
||||
|
||||
Faraday Cages can be found here :
|
||||
http://www.saelig.com/MFR00066/ste2300.htm
|
||||
[Faraday Cage](http://www.saelig.com/MFR00066/ste2300.htm)
|
||||
|
||||
|
||||
## Configuration Overview
|
||||
@@ -37,32 +37,32 @@ Our code might not work with all 5G phones yet, but we are constantly improving
|
||||
* Simcom SIMCOM8200EA
|
||||
* Quectel RM500Q-GL
|
||||
|
||||
Note1: In the version we have at Eurecom, you need to set the PLMN to 50501, and you also need to change the firmware to "11.0.0 (RD1A.201105.003.B1, Nov 2020, EU carriers)" (see https://developers.google.com/android/images)
|
||||
Note1: In the version we have at Eurecom, you need to set the PLMN to 50501, and you also need to change the firmware to "11.0.0 (RD1A.201105.003.B1, Nov 2020, EU carriers)" (see [Factory Images for Nexus and Pixel Devices](https://developers.google.com/android/images))
|
||||
|
||||
## Repository
|
||||
|
||||
https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop
|
||||
[OAI](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop)
|
||||
|
||||
## Architecture Setup
|
||||
|
||||
The scheme below depicts our typical setup:
|
||||
|
||||

|
||||

|
||||
|
||||
The photo depicts the FR1 setup part of the scheme above:
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||
## Build and Install
|
||||
|
||||
General guidelines to build eNB and gNB :
|
||||
See https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/doc/BUILD.md#building-ues-enodeb-and-gnodeb-executables
|
||||
See [Building UE, eNB and gNb executables](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/doc/BUILD.md#building-ues-enodeb-and-gnodeb-executables)
|
||||
|
||||
|
||||
- **eNB**
|
||||
|
||||
```
|
||||
```bash
|
||||
cd <your oai installation directory>/openairinterface5g/
|
||||
source oaienv
|
||||
cd cmake_targets/
|
||||
@@ -72,7 +72,7 @@ cd cmake_targets/
|
||||
|
||||
- **gNB**
|
||||
|
||||
```
|
||||
```bash
|
||||
cd <your oai installation directory>/openairinterface5g/
|
||||
source oaienv
|
||||
cd cmake_targets/
|
||||
@@ -83,8 +83,7 @@ cd cmake_targets/
|
||||
- **EPC**
|
||||
|
||||
for reference:
|
||||
https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME.md
|
||||
|
||||
[DEPLOY_HOME_MAGMA_MME](https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME_MAGMA_MME.md)
|
||||
|
||||
|
||||
## Configuration Files
|
||||
@@ -93,15 +92,17 @@ Each component (EPC, eNB, gNB) has its own configuration file.
|
||||
These config files are passed as arguments of the run command line, using the option -O \<conf file\>
|
||||
|
||||
The **REFERENCE** files for eNB and gNB, **used by the CI**, can be found here:
|
||||
[enb conf file](../ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf)
|
||||
[gnb conf file](../ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf)
|
||||
* [enb conf file](../ci-scripts/conf_files/enb.band7.25prb.usrpb200.tm1.conf)
|
||||
* [gnb conf file](../ci-scripts/conf_files/gnb-du.sa.band78.106prb.usrpb200.conf)
|
||||
|
||||
These files have to be updated manually to set the IP addresses and frequency.
|
||||
|
||||
|
||||
**ATTENTION** : an **EXTERNAL** clock is used to sync the eNB and gNB,
|
||||
whether the clock is internal or external is defined in the configuration files (!! details needed !!)
|
||||
|
||||
---
|
||||
>**⚠️ ATTENTION ⚠️**
|
||||
>
|
||||
>An **EXTERNAL** clock is used to sync the eNB and gNB, whether the clock is internal or external is defined in the configuration files (!! details needed !!)
|
||||
>
|
||||
---
|
||||
|
||||
1- In the **eNB configuration file** :
|
||||
- look for MME IP address, and update the **ipv4 field** with the IP address of the **EPC** server
|
||||
@@ -198,14 +199,13 @@ The test takes typically a few seconds, max 10-15 seconds. If it takes more than
|
||||
- **EPC** (on EPC host):
|
||||
|
||||
for reference:
|
||||
https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME.md
|
||||
|
||||
[DEPLOY_HOME_MAGMA_MME](https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master/docs/DEPLOY_HOME_MAGMA_MME.md)
|
||||
|
||||
|
||||
- **eNB** (on the eNB host):
|
||||
|
||||
Execute:
|
||||
```
|
||||
```bash
|
||||
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./lte-softmodem -O **YOUR_ENB_CONF_FILE** | tee **YOUR_LOG_FILE**
|
||||
|
||||
```
|
||||
@@ -213,13 +213,16 @@ Execute:
|
||||
|
||||
- **gNB** (on the gNB host)
|
||||
|
||||
|
||||
**ATTENTION** : for the gNB execution,
|
||||
The **-E** option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP
|
||||
The **-E** option is **NOT supported** when using a a N300 USRP
|
||||
---
|
||||
>**⚠️ ATTENTION ⚠️**
|
||||
>
|
||||
> For the gNB execution:
|
||||
> - The **-E** option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP
|
||||
> - The **-E** option is **NOT supported** when using a a N300 USRP
|
||||
---
|
||||
|
||||
Execute:
|
||||
```
|
||||
```bash
|
||||
~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** -E --nsa | tee **YOUR_LOG_FILE**
|
||||
|
||||
```
|
||||
@@ -229,9 +232,9 @@ Execute:
|
||||
|
||||
The test case corresponds to the UE attachement, that is the UE connection and its initial access in 5G, as depicted below:
|
||||
|
||||
**Source** : https://www.sharetechnote.com/html/5G/5G_LTE_Interworking.html
|
||||
**Source** : [5G/LTE interworking](https://www.sharetechnote.com/html/5G/5G_LTE_Interworking.html )
|
||||
|
||||

|
||||

|
||||
|
||||
The test reaches step **12. E-RAB modifcation confirmation** , eventhough not all the messages will appear in the log file.
|
||||
|
||||
@@ -239,8 +242,8 @@ The test reaches step **12. E-RAB modifcation confirmation** , eventhough not al
|
||||
|
||||
From the log file that is generated, we can monitor several important steps, to assess that the test was successful.
|
||||
Log files examples can be found here:
|
||||
[enb log file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/oai_enb.log)
|
||||
[gnb log file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/oai_gnb.log)
|
||||
* [enb log file](./testing_oai_nsa_w_cots_ue_resources/oai_enb.log)
|
||||
* [gnb log file](./testing_oai_nsa_w_cots_ue_resources/oai_gnb.log)
|
||||
|
||||
|
||||
- eNB receives UE capabilities information, including its NR capabilites, and triggers sGNB Addition Request message:
|
||||
@@ -0,0 +1,88 @@
|
||||
# UpLink Multiple Input Multiple Output (UL MIMO)
|
||||
## What is UL MIMO ?
|
||||
|
||||
UpLink MIMO refers to the use of multiple antennas at both the UE (User Equipment) as transmitter and the base station as receiver. They are used to send multiple data streams simultaneously from the user to the network.
|
||||
|
||||
## How to use it ?
|
||||
|
||||
## Step 1: build phy sim
|
||||
|
||||
```bash
|
||||
cd cmake_targets/
|
||||
sudo ./build_oai --phy_simulators -c
|
||||
cd phy_simulators/build/
|
||||
```
|
||||
|
||||
## Step 2: Use the sim
|
||||
|
||||
### Option 1: launch ULSCH sim
|
||||
On UpLink Shared CHannel(ULSCH), multiple users share the same radio resources (time and frequency slots), the base station schedules and assigns the resources dynamically. The goal here is to simulate the sending of data from an UE to a base station.
|
||||
|
||||
Example:
|
||||
| Parameter | Value | Description |
|
||||
|--- |:-: |--: |
|
||||
| R | 106 | R_NB_UL=106|
|
||||
| m | 9 | MCS=9 |
|
||||
| s | 13 | Start SNR |
|
||||
| n | 100 | Will simulate 100 frames |
|
||||
| y | 4 | 4 antennas used in eNB |
|
||||
| z | 4 | 4 antennas used in UE |
|
||||
| W | 4 | Will use 4 layers |
|
||||
|
||||
|
||||
```bash
|
||||
sudo ./nr_ulschsim -R 106 -m9 -s13 -n100 -y4 -z4 -W4
|
||||
```
|
||||
|
||||
### Option 2: launch UL sim
|
||||
On UpLink Channel, a single user is dealing with a single base station. The goal is here to simulate the sending of the data from an UE to a base station.
|
||||
|
||||
It's focusing on:
|
||||
- UpLink chain validation
|
||||
- PUSCH (whole chain) on UE side and gNB side
|
||||
- No channel model on data domain signal, which means an ideal scenario is used
|
||||
- No cross-path connection, which means no signal leakage or interference are present
|
||||
- PMI = 0 is only unitary precoding matrix
|
||||
|
||||
The same parameters are used.
|
||||
|
||||
```bash
|
||||
sudo ./nr_ulsim -n100 -m9 -r106 -s13 -W4 -y4 -z4
|
||||
```
|
||||
### Option 3: Use RFSIM
|
||||
|
||||
#### Build
|
||||
|
||||
RF simulator allows to test OAI without an RF board. It replaces an actual RF board driver.
|
||||
|
||||
```bash
|
||||
sudo ./build_oai -c --gNB --nrUE -w SIMU
|
||||
```
|
||||
|
||||
#### Run
|
||||
##### 4x4 RANK 4
|
||||
|
||||
Example:
|
||||
| Parameter | Value | Description |
|
||||
|--- |:-: |--: |
|
||||
| O | [...] | Use a configuration file |
|
||||
| l | 2 | Set the number of layers for downlink to 2 for PHY test mode |
|
||||
| L | 4 | Set the number of layers for uplink to 4 for PHY test mode |
|
||||
| ue-nb-ant-rx | 4 | Set UE number of rx antennas to 4 |
|
||||
| ue-nb-ant-tx | 4 | Set UE number of tx antennas to 4 |
|
||||
|
||||
```bash
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 4
|
||||
sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4
|
||||
```
|
||||
|
||||
##### 4x4 RANK 2
|
||||
|
||||
The same parameters are used excepted uplink number of layers set to 2.
|
||||
|
||||
```bash
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 2
|
||||
sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4
|
||||
```
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# how to build phy sim
|
||||
cd cmake_targets/
|
||||
sudo ./build_oai --phy_simulators -c
|
||||
|
||||
cd phy_simulators/build/
|
||||
# ULSCH sim
|
||||
# bit level validation
|
||||
# PUSCH encoding and decoding for 4 layers 2 CMD without data
|
||||
sudo ./nr_ulschsim -R 106 -m9 -s13 -n100 -y4 -z4 -W4
|
||||
|
||||
# UL sim
|
||||
# Uplink chain validation
|
||||
# PUSCH on UE side and gNB side,whole chain for PUSCH
|
||||
# No channel model on data domain signal
|
||||
# No cross-path connection
|
||||
# PMI = 0 is only unitary prcoding matrix
|
||||
sudo ./nr_ulsim -n100 -m9 -r106 -s13 -W4 -y4 -z4
|
||||
|
||||
# How to build rfsim
|
||||
sudo ./build_oai -c --gNB --nrUE -w SIMU
|
||||
|
||||
# How to run with rfsim
|
||||
# 4x4 RANK 4
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 4
|
||||
sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4
|
||||
# 4x4 RANK 2
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf --rfsim --phy-test --l 2 --L 2
|
||||
sudo ./nr-uesoftmodem --rfsim --phy-test --ue-nb-ant-rx 4 --ue-nb-ant-tx 4
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
# How to use device-to-device communication (D2D, 4G)
|
||||
|
||||
---
|
||||
>**⚠️ ATTENTION ⚠️**
|
||||
>
|
||||
>D2D is currently unfinished, the following documentation steps are likely not enough to make it work.
|
||||
---
|
||||
|
||||
## Scenario 1 : **Off-network UE2UE link**
|
||||
SynchREF UE (UE1)
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
UE1[UE1<br/>eth0: 10.10.10.1] --- UE2[UE2<br/>eno1: 10.10.10.2]
|
||||
```
|
||||
|
||||
### Example of /etc/network/interfaces configuration for UE1
|
||||
```text
|
||||
auto eth0
|
||||
iface eth0 inet static
|
||||
address 10.10.10.1
|
||||
netmask 255.255.255.0
|
||||
gateway 10.10.10.1
|
||||
```
|
||||
|
||||
### Prepare the environment:
|
||||
```bash
|
||||
git clone https://gitlab.eurecom.fr/matzakos/LTE-D2D.git
|
||||
cd LTE-D2D
|
||||
git checkout master
|
||||
```
|
||||
|
||||
This branch contains all the current development for **DDPS**, including:
|
||||
- **UE MAC <-> UE MAC** for **Scenario 1** (off-network communication)
|
||||
- **eNB MAC <-> UE MAC** using **NFAPI Transport** (on-network communication)
|
||||
- **RRC Extensions** to support on-network cases
|
||||
|
||||
### NFAPI configuration (required even for Scenario 1 target)
|
||||
```bash
|
||||
git clone https://github.com/cisco/open-nFAPI.git
|
||||
cd open-nfapi
|
||||
patch -p1 --dry-run < $OPENAIR_HOME/open-nfapi.oai.patch
|
||||
```
|
||||
Validate that there are no errors:
|
||||
|
||||
```patch -p1 < $OPENAIR_HOME/open-nfapi.oai.patch```
|
||||
|
||||
### OAI build/execute
|
||||
```bash
|
||||
export NFAPI_DIR=XXX (place where NFAPI was installed)
|
||||
cd cmake_targets
|
||||
./build_oai --UE --ninja #If necessary, use ./build_oai -I --UE to install required packages
|
||||
cd ran_build/build/
|
||||
```
|
||||
|
||||
### UE1
|
||||
``` bash
|
||||
sudo ifconfig oip0 10.0.0.1
|
||||
sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3
|
||||
```
|
||||
---
|
||||
>**NOTE**
|
||||
>
|
||||
>If necessary, add a default gateway:
|
||||
>
|
||||
>```sudo route add default gw 10.10.10.1 eth0```
|
||||
---
|
||||
|
||||
|
||||
### UE2
|
||||
```bash
|
||||
sudo ifconfig oip0 10.0.0.2
|
||||
sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3
|
||||
```
|
||||
---
|
||||
>**NOTE**
|
||||
>
|
||||
>If necessary, add a default gateway:
|
||||
>
|
||||
>```sudo route add default gw 10.10.10.1 eno1```
|
||||
---
|
||||
|
||||
|
||||
### UE1 and UE2: Get and build `vencore_app` from `d2d-l3-stub` (branch: `l3_stub`)
|
||||
```bash
|
||||
gcc -I . vencore_app.c -o vencore_app -lpthread
|
||||
```
|
||||
|
||||
|
||||
## TEST ONE-TO-MANY
|
||||
|
||||
### Run UE1 then UE2, for example:
|
||||
- UE1:
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
```
|
||||
- UE2:
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
```
|
||||
|
||||
### Test with Ping
|
||||
- Sender - UE1:
|
||||
```bash
|
||||
ping -I oip0 224.0.0.3
|
||||
```
|
||||
- Receiver - UE2: *using wireshark*
|
||||
|
||||
### Test with Iperf
|
||||
- Sender - UE1:
|
||||
```bash
|
||||
iperf -c 224.0.0.3 -u -b 0.1M --bind 10.0.0.1 -t 100
|
||||
```
|
||||
|
||||
- Receiver - UE2:
|
||||
```bash
|
||||
sudo ./mcreceive 224.0.0.3 5001
|
||||
```
|
||||
|
||||
Filter the incoming packets according to GroupL2Id: receiver (one-to-many) can discard the packets if it doesn't belong to this group.
|
||||
For the moment, both sender and receiver use the same set of Ids (hardcoded)
|
||||
|
||||
- UE1 (sender):
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
./vencore_app #send the sourceL2Id, groupL2Id to OAI
|
||||
ping -I oip0 224.0.0.3
|
||||
```
|
||||
|
||||
- UE2(receiver)
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
#we can see the incomming packets from OAI log, however, cannot see from Wireshark -> they are discarded at MAC layer
|
||||
./vencore_app #we can see the packets appearing in Wireshark
|
||||
```
|
||||
|
||||
|
||||
## TEST PC5-S (UE1 -sender, UE2 - receiver) and PC5-U for ONE-TO-ONE scenario
|
||||
### Configure UE1/UE2
|
||||
|
||||
Configure ports and routing table for UE1 and UE2
|
||||
|
||||
**UE1:**
|
||||
```bash
|
||||
sudo ifconfig oip0 10.0.0.1
|
||||
sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.2 -j MARK --set-mark 3
|
||||
sudo route add default gw 10.10.10.1 eth0
|
||||
```
|
||||
**UE2:**
|
||||
```bash
|
||||
sudo ifconfig oip0 10.0.0.2
|
||||
sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.1 -j MARK --set-mark 3
|
||||
sudo route add default gw 10.10.10.1 eno1
|
||||
```
|
||||
|
||||
#### Step 1:
|
||||
Run the traffic emulated over Ethernet on UE1 using lte-softmodem-stub to test the behaviour without RF board.
|
||||
|
||||
**UE1:**
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
```
|
||||
|
||||
#### Step 2:
|
||||
Run the traffic emulated over Ethernet on UE2 and set it as listening to incoming messages from PC5-S
|
||||
|
||||
**UE2:**
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
./vencore_app -r #listen to incomming message from PC5-S
|
||||
```
|
||||
|
||||
#### Step 3:
|
||||
Send a message from UE1 to UE2
|
||||
|
||||
**UE1:**
|
||||
```bash
|
||||
./vencore_app -s #send a message via PC5-S (e.g., DirectCommunicationRequest)
|
||||
```
|
||||
|
||||
#### Generate unicast traffic
|
||||
**UE1:**
|
||||
```bash
|
||||
ping -I oip0 10.0.0.2
|
||||
```
|
||||
|
||||
|
||||
## TEST PC5-D
|
||||
|
||||
#### Step 1:
|
||||
Run the traffic emulated over Ethernet on UE1 and send a discovery message via PC5-D
|
||||
|
||||
**UE1:**
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
./vencore_app -d #send a PC5-Discovery-Announcement via PC5D
|
||||
```
|
||||
|
||||
#### Step 2:
|
||||
Run the traffic emulated over Ethernet on UE2 and send a discovery message via PC5-D
|
||||
|
||||
**UE2:**
|
||||
```bash
|
||||
sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
./vencore_app -d #send a PC5-Discovery-Announcement via PC5D
|
||||
```
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
Scenario 1 : Off-network UE2UE link
|
||||
SynchREF UE (UE1)
|
||||
|
||||
UE1(eth0 - 10.10.10.1)--------UE2(eno1 - 10.10.10.2)
|
||||
|
||||
Here's an example of /etc/network/interfaces configuration for UE1
|
||||
auto eth0
|
||||
iface eth0 inet static
|
||||
address 10.10.10.1
|
||||
netmask 255.255.255.0
|
||||
gateway 10.10.10.1
|
||||
|
||||
Prepare the environment:
|
||||
- git clone https://gitlab.eurecom.fr/matzakos/LTE-D2D.git #branch: master
|
||||
This branch contains all the current development for DDPS
|
||||
- UE MAC<-> UE MAC for Scenario 1
|
||||
- eNB MAC<->UE MAC (NFAPI Transport)
|
||||
- RRC Extensions for “on-network” cases
|
||||
|
||||
NFAPI configuration (required even for Scenario 1 target)
|
||||
- git clone https://github.com/cisco/open-nFAPI.git
|
||||
- cd open-nfapi
|
||||
- patch -p1 --dry-run < $OPENAIR_HOME/open-nfapi.oai.patch
|
||||
Validate that there are no errors
|
||||
- patch -p1 < $OPENAIR_HOME/open-nfapi.oai.patch
|
||||
|
||||
OAI build/execute
|
||||
- export NFAPI_DIR=XXX (place where NFAPI was installed)
|
||||
- cd cmake_targets
|
||||
- ./build_oai --UE --ninja
|
||||
(if necessary, use ./build_oai -I --UE to install required packages)
|
||||
- cd ran_build/build/
|
||||
|
||||
UE1:
|
||||
- sudo ifconfig oip0 10.0.0.1
|
||||
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3
|
||||
- (if necessary) sudo route add default gw 10.10.10.1 eth0
|
||||
UE2:
|
||||
- sudo ifconfig oip0 10.0.0.2
|
||||
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 224.0.0.3 -j MARK --set-mark 3
|
||||
- (if necessary) sudo route add default gw 10.10.10.1 eno1
|
||||
|
||||
UE1 and UE2: Get and build vencore_app from d2d-l3-stub (branch: l3_stub)
|
||||
- gcc -I . vencore_app.c -o vencore_app -lpthread
|
||||
|
||||
--------------------------------
|
||||
TEST ONE-TO-MANY
|
||||
Run UE1 then UE2, for example:
|
||||
UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
|
||||
Test with Ping
|
||||
- Sender - UE1: ping -I oip0 224.0.0.3
|
||||
- Receiver - UE2: using wireshark
|
||||
|
||||
Test with Iperf
|
||||
- Sender - UE1: iperf -c 224.0.0.3 -u -b 0.1M --bind 10.0.0.1 -t 100
|
||||
- Receiver - UE2: sudo ./mcreceive 224.0.0.3 5001
|
||||
|
||||
Filter the incomming packets according to GroupL2Id: receiver (one-to-many) can discard the packets if it doesn't belong to this group.
|
||||
For the moment, both sender and receiver use the same set of Ids (hardcoded)
|
||||
|
||||
UE1 (sender)
|
||||
- sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
- ./vencore_app #send the sourceL2Id, groupL2Id to OAI
|
||||
- ping -I oip0 224.0.0.3
|
||||
UE2(receiver)
|
||||
- sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
#we can see the incomming packets from OAI log, however, cannot see from Wireshark -> they are discarded at MAC layer
|
||||
- ./vencore_app #we can see the packets appearing in Wireshark
|
||||
|
||||
--------------------------------------
|
||||
TEST PC5-S (UE1 -sender, UE2 - receiver) and PC5-U for ONE-TO-ONE scenario
|
||||
Configure UE1/UE2
|
||||
UE1:
|
||||
- sudo ifconfig oip0 10.0.0.1
|
||||
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.2 -j MARK --set-mark 3
|
||||
- sudo route add default gw 10.10.10.1 eth0
|
||||
UE2:
|
||||
- sudo ifconfig oip0 10.0.0.2
|
||||
- sudo iptables -A POSTROUTING -t mangle -o oip0 -d 10.0.0.1 -j MARK --set-mark 3
|
||||
- sudo route add default gw 10.10.10.1 eno1
|
||||
|
||||
step 1:
|
||||
- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
step 2:
|
||||
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
- UE2: ./vencore_app -r #listen to incomming message from PC5-S
|
||||
step 3:
|
||||
- UE1: ./vencore_app -s #send a message via PC5-S (e.g., DirectCommunicationRequest)
|
||||
|
||||
Generate unicast traffic
|
||||
UE1: ping -I oip0 10.0.0.2
|
||||
|
||||
|
||||
--------------------------------------
|
||||
TEST PC5-D
|
||||
step 1:
|
||||
- UE1: sudo ./lte-softmodem-stub -U --emul-iface eth0
|
||||
- UE1: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D
|
||||
step 2:
|
||||
- UE2: sudo ./lte-softmodem-stub -U --emul-iface eno1
|
||||
- UE2: ./vencore_app -d #send a PC5-Discovery-Announcement via PC5D
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
OAI uses/supports a number of environment variables, documented in the following:
|
||||
|
||||
- `NFAPI_TRACE_LEVEL`: set the nfapi custom logging framework's log level; can be one of `error`, `warn`, `note`, `info`, `debug`. Default is `warn`.
|
||||
- `NR_AWGN_RESULTS_DIR`: directory containing BLER curves for L2simulator channel modelling in SISO case
|
||||
- `NR_MIMO2x2_AWGN_RESULTS_DIR`: directory containing BLER curves for L2simulator channel modelling in 2x2 MIMO case
|
||||
- `NR_AWGN_RESULTS_DIR`: directory containing BLER curves for NR L2simulator channel modelling in SISO case
|
||||
- `NR_MIMO2x2_AWGN_RESULTS_DIR`: directory containing BLER curves for NR L2simulator channel modelling in 2x2 MIMO case
|
||||
- `OPENAIR_DIR`: should point to the root directory of OpenAirInterface; BLER curves for LTE L2sim channel emulation
|
||||
- `NVRAM_DIR`: directory to read/write NVRAM data in (5G) `nvram` tool; if not defined, will use `PWD` (working directory)
|
||||
- `OAI_CONFIGMODULE`: can be used to pass the configuration file instead of `-O`
|
||||
- `OAI_GDBSTACKS`: if defined when hitting an assertion (`DevAssert()`, `AssertFatal()`, ...), OAI will load `gdb` and provide a backtrace for every thread
|
||||
- `OAI_RNGSEED`: overwrites any seed for random number generators (RNG) in simulators
|
||||
- `OAI_THREADPOOLMEASUREMENTS`: path to a file to store thread pool debugging information, see the [thread pool documentation](..common/utils/threadPool/thread-pool.md)
|
||||
- `OPENAIR_DIR`: should point to the root directory of OpenAirInterface; some code relies on this to get a filename, e.g., BLER curves for L2sim channel emulation
|
||||
- `USIM_DIR`: directory to read/write USIM data in (4G) `usim` tool; if not defined, will use `PWD` (working directory)
|
||||
|
||||
Furthermore, these variables appear in code that is not maintained and maybe not even compiled anywhere:
|
||||
@@ -19,3 +18,5 @@ Furthermore, these variables appear in code that is not maintained and maybe not
|
||||
- `SSH_CLIENT`: alternative host to connect to, for CLI, if `REMADDR` is not defined
|
||||
- `USER`: user name in the command-line interface
|
||||
- `rftestInputFile`: input file for the `calibration_test` tool
|
||||
- `OPENAIR2_DIR` : OMV and OMG modules, obsolete
|
||||
- `TITLE`: OTG module, obsolete
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
This tutorial explains how to perform handovers. For the moment, only F1
|
||||
handovers are supported.
|
||||
This tutorial explains how to perform handovers. It covers both F1 handovers
|
||||
(intra-gNB, within a single gNB between DUs) and N2 handovers (inter-gNB).
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
@@ -13,6 +13,23 @@ same.
|
||||
|
||||

|
||||
|
||||
# What is a gNB neighbor?
|
||||
|
||||
Network continuity is a key aspect of 5G. In the 5G architecture, gNB neighbors
|
||||
play a central role in maintaining service continuity through mechanisms such
|
||||
as handover and load balancing. By definition, a gNB neighbor is another gNB
|
||||
that can be measured and linked by the UE. If the current serving gNB is no
|
||||
longer optimal, the UE may connect to a neighbor gNB.
|
||||
|
||||
To support this behavior, the network configuration specifies additional frequencies
|
||||
and cells that the UE should measure. The UE reports these measurements to the
|
||||
network, which then decides whether or not to initiate a handover.
|
||||
|
||||
Neighbor types include:
|
||||
- **Intra-gNB neighbors** - cells belonging to the same gNB
|
||||
- **Inter-gNB neighbors** - cells belonging to different gNBs
|
||||
- **Inter-RAT neighbors** - cells belonging to another RAT (e.g., LTE)
|
||||
|
||||
# Steps to run F1 handover with OAI UE
|
||||
|
||||
Measurement reporting and processing of RRC Reconfiguration for Mobility are
|
||||
@@ -353,10 +370,16 @@ We assume:
|
||||
|
||||
* Two independent gNBs connected to the same 5GC via N2 interface.
|
||||
* A UE initially connected to gNB-PCI0, which will be handed over to gNB-PCI1.
|
||||
* Handover is triggered by either by decision based measurement event (e.g. A3) or telnet command.
|
||||
* Handover is triggered by either a decision based measurement event (e.g. A3) or telnet command.
|
||||
|
||||
## Steps to run N2 handover with OAI UE
|
||||
|
||||
**Note for same-machine setup:** When running both gNBs on the same machine, you need to assign a unique IP address to the second gNB to avoid network conflicts. For example:
|
||||
|
||||
```sh
|
||||
sudo ip addr add 192.168.71.180/24 dev rfsim5g-public
|
||||
```
|
||||
|
||||
1. Similarly to F1 handover, UE does not support any measurement reporting and handover is triggered by
|
||||
telnet command. Therefore, ensure that both gNBs and UE are built with telnet support:
|
||||
|
||||
@@ -380,10 +403,17 @@ sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --rfsim --ui
|
||||
|
||||
Ensure the UE successfully registers with the network.
|
||||
|
||||
4. Start the target gNB (gNB PCI1) e.g.
|
||||
4. Start the target gNB (gNB-PCI1) e.g.
|
||||
|
||||
```sh
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf --sa --rfsim --telnetsrv --telnetsrv.shrmod ci --gNBs.[0].min_rxtxtime 6 --rfsimulator.serveraddr 127.0.0.1
|
||||
sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.pci1.rfsim.conf --rfsim --telnetsrv --telnetsrv.shrmod ci --gNBs.[0].min_rxtxtime 6 --rfsimulator.serveraddr 127.0.0.1
|
||||
```
|
||||
|
||||
**Note for same-machine setup:** When running both gNBs on the same machine, add the following network interface options to the target gNB command, e.g.:
|
||||
|
||||
```sh
|
||||
--gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 192.168.71.180
|
||||
--gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 192.168.71.180
|
||||
```
|
||||
|
||||
5. Trigger the N2 handover, e.g.
|
||||
@@ -393,7 +423,7 @@ From gNB-PCI0, trigger handover on target gNB with PCI 1 for UE ID 1:
|
||||
```sh
|
||||
echo ci trigger_n2_ho 1,1 | nc 127.0.0.1 9090 && echo
|
||||
```
|
||||
where the input parameters correspond to the PCI of the neighbor call and the RRC ID of the UE.
|
||||
where the input parameters correspond to the PCI of the neighbor cell and the RRC ID of the UE.
|
||||
|
||||
This will initiate the N2 handover on the source gNB.
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 361 KiB After Width: | Height: | Size: 361 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 247 KiB After Width: | Height: | Size: 247 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
@@ -15,7 +15,7 @@ The UE exits when at any point in operation it gets out of synchronization. When
|
||||
|
||||
UE uses actors which are threads dedicated to particular activity. Sync Actor handles initial sync. DL Actors handle DLSCH PHY procedures. UL procedures are are run on the UL Actor
|
||||
|
||||

|
||||

|
||||
|
||||
## Initial Synchronization Block
|
||||
```mermaid
|
||||
|
||||
|
Before Width: | Height: | Size: 271 KiB |
@@ -36,9 +36,14 @@ RUN dnf install -y libasan libubsan
|
||||
|
||||
#run build_oai to build the target image
|
||||
RUN /bin/sh oaienv && \
|
||||
cd cmake_targets && \
|
||||
mkdir -p log && \
|
||||
./build_oai --phy_simulators --ninja --sanitize --build-tool-opt -k10 --noavx512 -c --cmake-opt -DCMAKE_C_FLAGS=-Werror --cmake-opt -DCMAKE_CXX_FLAGS=-Werror --cmake-opt -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/opt/oai-physim/bin
|
||||
mkdir -p cmake_targets/ran_build/build && \
|
||||
cd cmake_targets/ran_build/build && \
|
||||
cmake3 -GNinja ../../.. \
|
||||
-DAVX512=OFF -DCMAKE_C_FLAGS=-Werror -DCMAKE_CXX_FLAGS=-Werror \
|
||||
-DENABLE_PHYSIM_TESTS=ON \
|
||||
-DSANITIZE_ADDRESS=ON -DSANITIZE_UNDEFINED=ON \
|
||||
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=/opt/oai-physim/bin && \
|
||||
ninja -k10 -j36
|
||||
|
||||
#start from scratch for target executable
|
||||
FROM registry.access.redhat.com/ubi9/ubi:latest AS oai-physim
|
||||
|
||||
@@ -8,7 +8,6 @@ target_include_directories(nfapi_socket_lib PRIVATE include/)
|
||||
|
||||
target_compile_definitions(nfapi_socket_lib PUBLIC ENABLE_SOCKET)
|
||||
target_link_libraries(nfapi_socket_lib PRIVATE NFAPI_LIB NFAPI_USER_LIB)
|
||||
target_link_libraries(nfapi_socket_lib PRIVATE LOG)
|
||||
add_dependencies(nfapi_socket_lib generate_T)
|
||||
target_link_libraries(nfapi_socket_lib PRIVATE log_headers)
|
||||
target_link_libraries(nfapi_socket_lib PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
|
||||
target_link_libraries(nfapi_socket_lib PRIVATE nr_fapi_p5 nr_fapi_p7)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
//#define DEBUG_TURBO_ENCODER 1
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ add_library(coding MODULE
|
||||
3gpplte_turbo_decoder.c
|
||||
)
|
||||
set_target_properties(coding PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
#ensure that the T header files are generated before targets depending on them
|
||||
target_link_libraries(coding PRIVATE log_headers)
|
||||
|
||||
add_library(ldpc_orig MODULE
|
||||
@@ -68,3 +67,4 @@ if (ENABLE_LDPC_CUDA)
|
||||
endif()
|
||||
|
||||
add_subdirectory(nrLDPC_coding)
|
||||
add_subdirectory(nrLDPC_decoder)
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#define __CODING_DEFS__H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <PHY/defs_common.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define CRC24_A 0
|
||||
#define CRC24_B 1
|
||||
@@ -455,8 +455,5 @@ int32_t nr_segmentation(unsigned char *input_buffer,
|
||||
*/
|
||||
int nr_get_R_ldpc_decoder(int rvidx, int E, int BG, int Z, int *llrLen, int round);
|
||||
|
||||
decoder_if_t phy_threegpplte_turbo_decoder;
|
||||
decoder_if_t phy_threegpplte_turbo_decoder8;
|
||||
decoder_if_t phy_threegpplte_turbo_decoder16;
|
||||
/** @} */
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,4 @@ add_library(ldpc_segment OBJECT
|
||||
nrLDPC_coding_segment_decoder.c
|
||||
nrLDPC_coding_segment_encoder.c
|
||||
)
|
||||
|
||||
#ensure that the T header files are generated before targets depending on them
|
||||
if (${T_TRACER})
|
||||
add_dependencies(ldpc_segment generate_T)
|
||||
endif (${T_TRACER})
|
||||
target_link_libraries(ldpc_segment PUBLIC log_headers)
|
||||
|
||||
@@ -16,12 +16,7 @@ if (ENABLE_LDPC_XDMA)
|
||||
)
|
||||
target_include_directories(ldpc_xdma PRIVATE ../nrLDPC_coding_segment)
|
||||
|
||||
#ensure that the T header files are generated before targets depending on them
|
||||
if (${T_TRACER})
|
||||
add_dependencies(ldpc_xdma generate_T)
|
||||
endif (${T_TRACER})
|
||||
|
||||
target_link_libraries(ldpc_xdma PRIVATE ldpc_gen_HEADERS)
|
||||
target_link_libraries(ldpc_xdma PRIVATE ldpc_gen_HEADERS log_headers)
|
||||
set_target_properties(ldpc_xdma PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_dependencies(nr-softmodem ldpc_xdma)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
add_subdirectory(nrLDPC_tools)
|
||||
@@ -1,7 +1,7 @@
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_bnProc ldpc/generator_bnProc)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_bnProc_avx512 ldpc/generator_bnProc_avx512)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_cnProc ldpc/generator_cnProc)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/generator_cnProc_avx512 ldpc/generator_cnProc_avx512)
|
||||
add_subdirectory(generator_bnProc ldpc/generator_bnProc)
|
||||
add_subdirectory(generator_bnProc_avx512 ldpc/generator_bnProc_avx512)
|
||||
add_subdirectory(generator_cnProc ldpc/generator_cnProc)
|
||||
add_subdirectory(generator_cnProc_avx512 ldpc/generator_cnProc_avx512)
|
||||
|
||||
# custom target to build all generators
|
||||
add_custom_target(ldpc_generators)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||
#include "common/utils/utils.h"
|
||||
|
||||
// ----- Old implementation ----
|
||||
const uint8_t **crc24c_generator_matrix(uint16_t payloadSizeBits)
|
||||
|
||||
@@ -38,11 +38,13 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_dci_defs.h"
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_uci_defs.h"
|
||||
#include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/sse_intrin.h"
|
||||
// #include "SIMULATION/TOOLS/sim.h"
|
||||
|
||||
#define NR_POLAR_DECODER_LISTSIZE 8 // uint8_t
|
||||
|
||||
@@ -31,11 +31,14 @@
|
||||
*/
|
||||
|
||||
#include "PHY/CODING/nrSmallBlock/nr_small_block_defs.h"
|
||||
#include "common/utils/assertions.h"
|
||||
|
||||
//input = [0 ... 0 c_K-1 ... c_2 c_1 c_0]
|
||||
//output = [d_31 d_30 ... d_2 d_1 d_0]
|
||||
uint32_t encodeSmallBlock(int in, int len)
|
||||
{
|
||||
AssertFatal(len >= 3, "encodeSmallBlock only supports input lengths A >= 3, got A=%d", len);
|
||||
|
||||
uint32_t out = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
if ((in & (1 << i)) > 0)
|
||||
|
||||
@@ -119,49 +119,33 @@ const char nr_W_4l_4p[5][4][4] = {
|
||||
|
||||
void nr_modulation(const uint32_t *in, uint32_t length, uint16_t mod_order, int16_t *out)
|
||||
{
|
||||
uint16_t mask = ((1 << mod_order) - 1);
|
||||
int32_t *nr_mod_table32;
|
||||
const uint16_t mask = ((1 << mod_order) - 1);
|
||||
int32_t *out32 = (int32_t *)out;
|
||||
const uint8_t *in_bytes = (const uint8_t *)in;
|
||||
const uint64_t *in64 = (const uint64_t *)in;
|
||||
int64_t *out64 = (int64_t *)out;
|
||||
uint32_t i = 0;
|
||||
|
||||
#if defined(__SSE2__)
|
||||
simde__m128i *nr_mod_table128;
|
||||
simde__m128i *out128;
|
||||
#endif
|
||||
|
||||
LOG_D(PHY, "nr_modulation: length %d, mod_order %d\n", length, mod_order);
|
||||
|
||||
switch (mod_order) {
|
||||
#if defined(__SSE2__)
|
||||
case 2:
|
||||
nr_mod_table128 = (simde__m128i *)nr_qpsk_byte_mod_table;
|
||||
out128 = (simde__m128i *)out;
|
||||
case 2: {
|
||||
simde__m128i *nr_mod_table128 = (simde__m128i *)nr_qpsk_byte_mod_table;
|
||||
simde__m128i *out128 = (simde__m128i *)out;
|
||||
for (i = 0; i < length / 8; i++)
|
||||
out128[i] = nr_mod_table128[in_bytes[i]];
|
||||
// the bits that are left out
|
||||
i = i * 8 / 2;
|
||||
nr_mod_table32 = (int32_t *)nr_qpsk_mod_table;
|
||||
int32_t *nr_mod_table32 = (int32_t *)nr_qpsk_mod_table;
|
||||
while (i < length / 2) {
|
||||
const int idx = ((in_bytes[(i * 2) / 8] >> ((i * 2) & 0x7)) & mask);
|
||||
out32[i] = nr_mod_table32[idx];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
#else
|
||||
case 2:
|
||||
nr_mod_table32 = (int32_t *)nr_qpsk_mod_table;
|
||||
for (i = 0; i < length / mod_order; i++) {
|
||||
const int idx = ((in[i * 2 / 32] >> ((i * 2) & 0x1f)) & mask);
|
||||
out32[i] = nr_mod_table32[idx];
|
||||
}
|
||||
return;
|
||||
#endif
|
||||
|
||||
case 4:
|
||||
out64 = (int64_t *)out;
|
||||
for (i = 0; i < length / 8; i++)
|
||||
out64[i] = nr_16qam_byte_mod_table[in_bytes[i]];
|
||||
// the bits that are left out
|
||||
@@ -234,10 +218,11 @@ void nr_modulation(const uint32_t *in, uint32_t length, uint16_t mod_order, int1
|
||||
}
|
||||
return;
|
||||
|
||||
case 8:
|
||||
nr_mod_table32 = (int32_t *)nr_256qam_mod_table;
|
||||
case 8: {
|
||||
int32_t *nr_mod_table32 = (int32_t *)nr_256qam_mod_table;
|
||||
for (i = 0; i < length / 8; i++)
|
||||
out32[i] = nr_mod_table32[in_bytes[i]];
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
|
||||
@@ -306,6 +306,10 @@ int8_t get_next_dmrs_symbol_in_slot(uint16_t ul_dmrs_symb_pos, uint8_t counter,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t get_num_dmrs_re_per_rb(const uint8_t dmrs_type, const uint8_t num_cdm_grp_no_data)
|
||||
{
|
||||
return (dmrs_type == NFAPI_NR_DMRS_TYPE1 ? 6 * num_cdm_grp_no_data : 4 * num_cdm_grp_no_data);
|
||||
}
|
||||
|
||||
/* return the position of valid dmrs symbol in a slot for channel compensation */
|
||||
int8_t get_valid_dmrs_idx_for_channel_est(uint16_t dmrs_symb_pos, uint8_t counter)
|
||||
|
||||
@@ -71,6 +71,8 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
|
||||
uint16_t dmrs_bitmap,
|
||||
uint16_t num_rbs);
|
||||
|
||||
int8_t get_num_dmrs_re_per_rb(const uint8_t dmrs_type, const uint8_t num_cdm_grp_no_data);
|
||||
|
||||
static inline uint8_t is_dmrs_symbol(uint8_t l, uint16_t dmrsSymbMask)
|
||||
{
|
||||
DevAssert(l < 32);
|
||||
|
||||
@@ -22,15 +22,11 @@
|
||||
#include "nr_refsig.h"
|
||||
#include "nr_mod_table.h"
|
||||
c16_t nr_qpsk_mod_table[4];
|
||||
|
||||
simde__m128i nr_qpsk_byte_mod_table[256];
|
||||
int32_t nr_16qam_mod_table[16];
|
||||
simde__m128i nr_qpsk_byte_mod_table[2048];
|
||||
|
||||
int64_t nr_16qam_byte_mod_table[1024];
|
||||
|
||||
int64_t nr_16qam_byte_mod_table[256];
|
||||
int64_t nr_64qam_mod_table[4096];
|
||||
|
||||
int32_t nr_256qam_mod_table[512];
|
||||
int32_t nr_256qam_mod_table[256];
|
||||
|
||||
void nr_generate_modulation_table() {
|
||||
float sqrt2 = 0.70711;
|
||||
|
||||
@@ -29,15 +29,12 @@
|
||||
#define NR_MOD_TABLE_QAM256_OFFSET 87
|
||||
|
||||
extern c16_t nr_qpsk_mod_table[4];
|
||||
extern simde__m128i nr_qpsk_byte_mod_table[256];
|
||||
|
||||
extern int32_t nr_16qam_mod_table[16];
|
||||
#if defined(__SSE2__)
|
||||
extern simde__m128i nr_qpsk_byte_mod_table[2048];
|
||||
#endif
|
||||
|
||||
extern int64_t nr_16qam_byte_mod_table[1024];
|
||||
extern int64_t nr_16qam_byte_mod_table[256];
|
||||
|
||||
extern int64_t nr_64qam_mod_table[4096];
|
||||
|
||||
extern int32_t nr_256qam_mod_table[512];
|
||||
extern int32_t nr_256qam_mod_table[256];
|
||||
#endif
|
||||
|
||||
@@ -147,8 +147,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
|
||||
uint16_t rnti,
|
||||
NR_UE_DLSCH_t dlsch[2]);
|
||||
|
||||
float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
|
||||
|
||||
int nr_sl_psbch_rsrp_measurements(sl_nr_ue_phy_params_t *sl_phy_params,
|
||||
NR_DL_FRAME_PARMS *fp,
|
||||
c16_t rxdataF[][fp->samples_per_slot_wCP],
|
||||
|
||||
@@ -46,34 +46,6 @@
|
||||
//#define DEBUG_MEAS_UE
|
||||
//#define DEBUG_RANK_EST
|
||||
|
||||
uint32_t get_nr_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id)
|
||||
{
|
||||
|
||||
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
|
||||
|
||||
if (ue)
|
||||
return ue->rx_total_gain_dB;
|
||||
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
|
||||
float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index)
|
||||
{
|
||||
|
||||
AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is null\n");
|
||||
AssertFatal(PHY_vars_UE_g[Mod_id]!=NULL,"PHY_vars_UE_g[%d] is null\n",Mod_id);
|
||||
AssertFatal(PHY_vars_UE_g[Mod_id][CC_id]!=NULL,"PHY_vars_UE_g[%d][%d] is null\n",Mod_id,CC_id);
|
||||
|
||||
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
|
||||
|
||||
if (ue)
|
||||
return (10*log10(ue->measurements.rsrp[gNB_index])-
|
||||
get_nr_rx_total_gain_dB(Mod_id,0) -
|
||||
10*log10(20*12));
|
||||
return -140.0;
|
||||
}
|
||||
|
||||
void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
||||
const UE_nr_rxtx_proc_t *proc,
|
||||
NR_UE_DLSCH_t *dlsch,
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
#define NR_PUSCH_x 2 // UCI placeholder bit TS 38.212 V15.4.0 subclause 5.3.3.1
|
||||
#define NR_PUSCH_y 3 // UCI placeholder bit
|
||||
|
||||
typedef enum {
|
||||
BIT_TYPE_ULSCH = 0, // Default: UL-SCH data
|
||||
BIT_TYPE_ACK = 1, // HARQ-ACK bit
|
||||
BIT_TYPE_ACK_RESERVED = 2, // Reserved for HARQ-ACK (punctured)
|
||||
BIT_TYPE_ACK_ULSCH = 3,
|
||||
BIT_TYPE_CSI1 = 4, // CSI Part 1 bit
|
||||
BIT_TYPE_CSI2 = 5 // CSI Part 2 bit
|
||||
} uci_on_pusch_bit_type_t;
|
||||
|
||||
// Specifies the data that should be copied to the scope during PDSCH RX
|
||||
typedef struct pdsch_scope_req_s {
|
||||
bool copy_chanest_to_scope;
|
||||
@@ -86,6 +95,13 @@ void nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
|
||||
int nb_dlsch,
|
||||
uint8_t *DLSCH_ids);
|
||||
|
||||
int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
|
||||
const NR_UE_ULSCH_t *ulsch,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
const unsigned int *G,
|
||||
const int nb_ulsch,
|
||||
const uint8_t *ULSCH_ids);
|
||||
/** \brief This is the alternative top-level entry point for ULSCH encoding in UE.
|
||||
It handles all the HARQ processes in only one call. The routine first
|
||||
computes the segmentation information, followed by LDPC encoding algorithm of the
|
||||
@@ -121,8 +137,8 @@ void nr_pusch_codeword_scrambling(uint8_t *in,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI,
|
||||
bool uci_on_pusch,
|
||||
uint32_t* out);
|
||||
|
||||
const uci_on_pusch_bit_type_t *template,
|
||||
uint32_t *out);
|
||||
|
||||
/** \brief Alternative entry point to UE uplink shared channels procedures.
|
||||
It handles all the HARQ processes in only one call.
|
||||
@@ -154,7 +170,8 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT]);
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT],
|
||||
bool no_phase_pre_comp);
|
||||
|
||||
void clean_UE_harq(PHY_VARS_NR_UE *UE);
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ typedef struct {
|
||||
uint32_t C;
|
||||
/// Number of bits in code segments
|
||||
uint32_t K;
|
||||
///
|
||||
uint32_t Kb;
|
||||
/// Number of "Filler" bits
|
||||
uint32_t F;
|
||||
/// Number of soft channel bits
|
||||
@@ -135,4 +137,13 @@ typedef struct {
|
||||
// PTRS symbol index, to be updated every PTRS symbol within a slot.
|
||||
uint8_t ptrs_symbol_index;
|
||||
} NR_UE_DLSCH_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t Q_dash_ACK; // number of coded HARQ-ACK symbols
|
||||
uint16_t E_uci_ACK; // number of coded HARQ-ACK bits
|
||||
uint16_t Q_dash_ACK_rvd; // number of coded HARQ-ACK symbols reserved
|
||||
uint16_t E_uci_ACK_rvd; // number of coded HARQ-ACK bits reserved
|
||||
uint32_t G_ulsch; // bit capacity of ULSCH
|
||||
} rate_match_info_uci_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,56 +34,27 @@
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "PHY/log_tools.h"
|
||||
|
||||
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
NR_UE_ULSCH_t *ulsch,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
unsigned int *G,
|
||||
int nb_ulsch,
|
||||
uint8_t *ULSCH_ids,
|
||||
uint16_t number_dmrs_symbols)
|
||||
int nr_ulsch_pre_encoding(PHY_VARS_NR_UE *ue,
|
||||
const NR_UE_ULSCH_t *ulsch,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
const unsigned int *G,
|
||||
const int nb_ulsch,
|
||||
const uint8_t *ULSCH_ids)
|
||||
{
|
||||
start_meas_nr_ue_phy(ue, ULSCH_ENCODING_STATS);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
|
||||
|
||||
nrLDPC_TB_encoding_parameters_t TBs[nb_ulsch];
|
||||
memset(TBs, 0, sizeof(TBs));
|
||||
nrLDPC_slot_encoding_parameters_t slot_parameters = {
|
||||
.frame = frame,
|
||||
.slot = slot,
|
||||
.nb_TBs = nb_ulsch,
|
||||
.threadPool = &get_nrUE_params()->Tpool,
|
||||
.tinput = NULL,
|
||||
.tprep = NULL,
|
||||
.tparity = NULL,
|
||||
.toutput = NULL,
|
||||
.TBs = TBs
|
||||
};
|
||||
|
||||
int max_num_segments = 0;
|
||||
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
|
||||
uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
|
||||
|
||||
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[pusch_id];
|
||||
/* Neither harq_pid nor ULSCH_id are unique in the instance
|
||||
* but their combination is.
|
||||
* Since ULSCH_id < 2
|
||||
* then 2 * harq_pid + ULSCH_id is unique.
|
||||
*/
|
||||
TB_parameters->harq_unique_pid = 2 * harq_pid + ULSCH_id;
|
||||
for (uint_fast8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
|
||||
const uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
const uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
|
||||
|
||||
/////////////////////////parameters and variables initialization/////////////////////////
|
||||
|
||||
unsigned int crc = 1;
|
||||
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch->pusch_pdu;
|
||||
uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
uint32_t A = pusch_pdu->pusch_data.tb_size << 3;
|
||||
uint8_t Qm = pusch_pdu->qam_mod_order;
|
||||
const uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
const uint32_t A = pusch_pdu->pusch_data.tb_size << 3;
|
||||
const uint8_t Qm = pusch_pdu->qam_mod_order;
|
||||
// target_code_rate is in 0.1 units
|
||||
float Coderate = (float)pusch_pdu->target_code_rate / 10240.0f;
|
||||
const float Coderate = (float)pusch_pdu->target_code_rate / 10240.0f;
|
||||
|
||||
LOG_D(NR_PHY, "ulsch coding nb_rb %d, Nl = %d\n", nb_rb, pusch_pdu->nrOfLayers);
|
||||
LOG_D(NR_PHY, "ulsch coding A %d G %d mod_order %d Coderate %f\n", A, G[pusch_id], Qm, Coderate);
|
||||
@@ -91,11 +62,11 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
|
||||
///////////////////////// a---->| add CRC |---->b /////////////////////////
|
||||
|
||||
int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers * 1056;
|
||||
const int max_payload_bytes = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers * 1056;
|
||||
int B;
|
||||
if (A > NR_MAX_PDSCH_TBS) {
|
||||
// Add 24-bit crc (polynomial A) to payload
|
||||
crc = crc24a(harq_process->payload_AB, A) >> 8;
|
||||
const unsigned int crc = crc24a(harq_process->payload_AB, A) >> 8;
|
||||
harq_process->payload_AB[A >> 3] = ((uint8_t *)&crc)[2];
|
||||
harq_process->payload_AB[1 + (A >> 3)] = ((uint8_t *)&crc)[1];
|
||||
harq_process->payload_AB[2 + (A >> 3)] = ((uint8_t *)&crc)[0];
|
||||
@@ -103,7 +74,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
AssertFatal((A / 8) + 4 <= max_payload_bytes, "A %d is too big (A/8+4 = %d > %d)\n", A, (A / 8) + 4, max_payload_bytes);
|
||||
} else {
|
||||
// Add 16-bit crc (polynomial A) to payload
|
||||
crc = crc16(harq_process->payload_AB, A) >> 16;
|
||||
const unsigned int crc = crc16(harq_process->payload_AB, A) >> 16;
|
||||
harq_process->payload_AB[A >> 3] = ((uint8_t *)&crc)[1];
|
||||
harq_process->payload_AB[1 + (A >> 3)] = ((uint8_t *)&crc)[0];
|
||||
B = A + 16;
|
||||
@@ -151,7 +122,7 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
T_INT((int)ulsch->pusch_pdu.transform_precoding), // transformPrecoder_enabled = 0, transformPrecoder_disabled = 1
|
||||
T_INT((int)ulsch->pusch_pdu.dmrs_config_type), // dmrs_resource_map_config: pusch_dmrs_type1 = 0, pusch_dmrs_type2 = 1
|
||||
T_INT((int)ulsch->pusch_pdu.ul_dmrs_symb_pos), // used to derive the DMRS symbol positions
|
||||
T_INT((int)number_dmrs_symbols),
|
||||
T_INT((int)get_num_dmrs(ulsch->pusch_pdu.ul_dmrs_symb_pos)),
|
||||
// dmrs_start_ofdm_symbol
|
||||
// dmrs_duration_num_ofdm_symbols
|
||||
// dmrs_num_add_positions
|
||||
@@ -168,36 +139,55 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_IN);
|
||||
start_meas_nr_ue_phy(ue, ULSCH_SEGMENTATION_STATS);
|
||||
TB_parameters->Kb = nr_segmentation(harq_process->payload_AB,
|
||||
harq_process->c,
|
||||
B,
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
&harq_process->Z,
|
||||
&harq_process->F,
|
||||
harq_process->BG);
|
||||
TB_parameters->C = harq_process->C;
|
||||
TB_parameters->K = harq_process->K;
|
||||
TB_parameters->Z = harq_process->Z;
|
||||
TB_parameters->F = harq_process->F;
|
||||
TB_parameters->BG = harq_process->BG;
|
||||
if (TB_parameters->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", TB_parameters->C, B);
|
||||
harq_process->Kb = nr_segmentation(harq_process->payload_AB,
|
||||
harq_process->c,
|
||||
B,
|
||||
&harq_process->C,
|
||||
&harq_process->K,
|
||||
&harq_process->Z,
|
||||
&harq_process->F,
|
||||
harq_process->BG);
|
||||
if (harq_process->C > MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER * pusch_pdu->nrOfLayers) {
|
||||
LOG_E(PHY, "nr_segmentation.c: too many segments %d, B %d\n", harq_process->C, B);
|
||||
return (-1);
|
||||
}
|
||||
stop_meas_nr_ue_phy(ue, ULSCH_SEGMENTATION_STATS);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_SEGMENTATION, VCD_FUNCTION_OUT);
|
||||
max_num_segments = max(max_num_segments, TB_parameters->C);
|
||||
|
||||
TB_parameters->nb_rb = nb_rb;
|
||||
TB_parameters->Qm = Qm;
|
||||
TB_parameters->mcs = pusch_pdu->mcs_index;
|
||||
TB_parameters->nb_layers = pusch_pdu->nrOfLayers;
|
||||
TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index;
|
||||
TB_parameters->G = G[pusch_id];
|
||||
TB_parameters->tbslbrm = pusch_pdu->tbslbrm;
|
||||
TB_parameters->A = A;
|
||||
} // pusch_id
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
NR_UE_ULSCH_t *ulsch,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
unsigned int *G,
|
||||
int nb_ulsch,
|
||||
uint8_t *ULSCH_ids,
|
||||
uint16_t number_dmrs_symbols)
|
||||
{
|
||||
start_meas_nr_ue_phy(ue, ULSCH_ENCODING_STATS);
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_UE_ULSCH_ENCODING, VCD_FUNCTION_IN);
|
||||
|
||||
nrLDPC_TB_encoding_parameters_t TBs[nb_ulsch];
|
||||
memset(TBs, 0, sizeof(TBs));
|
||||
nrLDPC_slot_encoding_parameters_t slot_parameters = {.frame = frame,
|
||||
.slot = slot,
|
||||
.nb_TBs = nb_ulsch,
|
||||
.threadPool = &get_nrUE_params()->Tpool,
|
||||
.tinput = NULL,
|
||||
.tprep = NULL,
|
||||
.tparity = NULL,
|
||||
.toutput = NULL,
|
||||
.TBs = TBs};
|
||||
|
||||
int max_num_segments = 0;
|
||||
for (uint_fast8_t pusch_id = 0; pusch_id < nb_ulsch; pusch_id++) {
|
||||
const uint8_t ULSCH_id = ULSCH_ids[pusch_id];
|
||||
const uint8_t harq_pid = ulsch[ULSCH_id].pusch_pdu.pusch_data.harq_process_id;
|
||||
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
|
||||
max_num_segments = max(max_num_segments, harq_process->C);
|
||||
}
|
||||
|
||||
nrLDPC_segment_encoding_parameters_t segments[nb_ulsch][max_num_segments];
|
||||
memset(segments, 0, sizeof(segments));
|
||||
@@ -208,10 +198,25 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
|
||||
nrLDPC_TB_encoding_parameters_t *TB_parameters = &TBs[pusch_id];
|
||||
NR_UL_UE_HARQ_t *harq_process = &ue->ul_harq_processes[harq_pid];
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch[ULSCH_id].pusch_pdu;
|
||||
const uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
TB_parameters->harq_unique_pid = 2 * harq_pid + ULSCH_id;
|
||||
TB_parameters->C = harq_process->C;
|
||||
TB_parameters->K = harq_process->K;
|
||||
TB_parameters->Z = harq_process->Z;
|
||||
TB_parameters->F = harq_process->F;
|
||||
TB_parameters->BG = harq_process->BG;
|
||||
TB_parameters->Kb = harq_process->Kb;
|
||||
TB_parameters->nb_rb = nb_rb;
|
||||
TB_parameters->Qm = pusch_pdu->qam_mod_order;
|
||||
TB_parameters->mcs = pusch_pdu->mcs_index;
|
||||
TB_parameters->nb_layers = pusch_pdu->nrOfLayers;
|
||||
TB_parameters->rv_index = pusch_pdu->pusch_data.rv_index;
|
||||
TB_parameters->G = G[pusch_id];
|
||||
TB_parameters->tbslbrm = pusch_pdu->tbslbrm;
|
||||
TB_parameters->A = pusch_pdu->pusch_data.tb_size / 8;
|
||||
TB_parameters->segments = segments[pusch_id];
|
||||
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch->pusch_pdu;
|
||||
uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
memset(harq_process->f, 0, 14 * nb_rb * 12 * 16);
|
||||
TB_parameters->output = harq_process->f;
|
||||
|
||||
|
||||
@@ -49,6 +49,12 @@
|
||||
#include "PHY/NR_REFSIG/ul_ref_seq_nr.h"
|
||||
#include <openair2/UTIL/OPT/opt.h>
|
||||
#include "PHY/log_tools.h"
|
||||
#include "PHY/NR_UE_TRANSPORT/pucch_nr.h"
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_RE_PER_SYMBOL_IN_ALLOC (275 * 12)
|
||||
#define MAX_NLQM (4 * 8)
|
||||
#define MAX_UCI_CODED_BITS 1024
|
||||
|
||||
//#define DEBUG_PUSCH_MAPPING
|
||||
//#define DEBUG_MAC_PDU
|
||||
@@ -56,33 +62,72 @@
|
||||
|
||||
//extern int32_t uplink_counter;
|
||||
|
||||
void nr_pusch_codeword_scrambling_uci(uint8_t *in, uint32_t size, uint32_t Nid, uint32_t n_RNTI, uint32_t* out)
|
||||
static void nr_pusch_codeword_scrambling_uci(uint8_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI,
|
||||
const uci_on_pusch_bit_type_t *template,
|
||||
uint32_t *out)
|
||||
{
|
||||
uint32_t *seq = gold_cache((n_RNTI << 15) + Nid, (size + 31) / 32);
|
||||
for (int i=0; i<size; i++) {
|
||||
int idx = i / 32;
|
||||
int b_idx = i % 32;
|
||||
if (in[i]==NR_PUSCH_x)
|
||||
out[idx] ^= 1 << b_idx;
|
||||
else if (in[i]==NR_PUSCH_y){
|
||||
if (b_idx)
|
||||
out[idx] ^= (out[idx] & (1 << (b_idx - 1))) << 1;
|
||||
else{
|
||||
uint32_t temp_out = out[idx - 1];
|
||||
out[idx] ^= temp_out >> 31;
|
||||
uint32_t num_words = (size + 31) / 32;
|
||||
|
||||
// Step 1: Initial general scrambling
|
||||
// First convert unpacked input to bit-packed words
|
||||
uint32_t in_words[num_words];
|
||||
memset(in_words, 0, num_words * sizeof(uint32_t));
|
||||
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
uint32_t word_idx = i / 32;
|
||||
uint32_t bit_idx = i % 32;
|
||||
if (in[i] & 1) {
|
||||
in_words[word_idx] |= (1U << bit_idx);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_words; i++) {
|
||||
out[i] = in_words[i] ^ seq[i];
|
||||
}
|
||||
|
||||
// According to 38.211 6.3.1.1
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
if (template[i] == BIT_TYPE_ACK_ULSCH) {
|
||||
// Step 2: Overwrite/Correct positions for UCI bits including placeholders X, Y when O_ACK <= 2
|
||||
uint32_t pos = i;
|
||||
uint32_t idx = pos / 32;
|
||||
uint32_t b_idx = pos % 32;
|
||||
|
||||
if (in[pos] == NR_PUSCH_y) {
|
||||
// Clear bit
|
||||
out[idx] &= ~(1U << b_idx);
|
||||
if (b_idx > 0) {
|
||||
// Y depends on the final value of the previous bit in the same word.
|
||||
// This previous bit could be an ACK (already corrected) or ULSCH (from initial scramble).
|
||||
out[idx] |= ((out[idx] >> (b_idx - 1)) & 1) << b_idx;
|
||||
} else if (idx > 0) {
|
||||
// Y depends on the last bit of the previous word.
|
||||
out[idx] |= ((out[idx - 1] >> 31) & 1);
|
||||
}
|
||||
} else if (in[pos] == NR_PUSCH_x) {
|
||||
out[idx] |= (1U << b_idx);
|
||||
}
|
||||
}
|
||||
else
|
||||
out[idx] ^= (((in[i]) & 1) ^ ((seq[idx] >> b_idx) & 1)) << b_idx;
|
||||
//printf("i %d b_idx %d in %d s 0x%08x out 0x%08x\n", i, b_idx, in[i], s, *out);
|
||||
}
|
||||
}
|
||||
|
||||
void nr_pusch_codeword_scrambling(uint8_t *in, uint32_t size, uint32_t Nid, uint32_t n_RNTI, bool uci_on_pusch, uint32_t* out)
|
||||
void nr_pusch_codeword_scrambling(uint8_t *in,
|
||||
uint32_t size,
|
||||
uint32_t Nid,
|
||||
uint32_t n_RNTI,
|
||||
bool uci_on_pusch,
|
||||
const uci_on_pusch_bit_type_t *template,
|
||||
uint32_t *out)
|
||||
{
|
||||
if (uci_on_pusch)
|
||||
nr_pusch_codeword_scrambling_uci(in, size, Nid, n_RNTI, out);
|
||||
// in buffer is in byte-packed format
|
||||
nr_pusch_codeword_scrambling_uci(in, size, Nid, n_RNTI, template, out);
|
||||
else
|
||||
// in buffer is in bit-packed format
|
||||
nr_codeword_scrambling(in, size, 0, Nid, n_RNTI, out);
|
||||
}
|
||||
|
||||
@@ -472,6 +517,500 @@ static void map_symbols(const nr_phy_pxsch_params_t p,
|
||||
}
|
||||
}
|
||||
|
||||
// Function to lookup beta offset value from Table 9.3-1 in TS 38.213
|
||||
static double get_beta_offset_harq_ack(uint8_t beta_offset_index)
|
||||
{
|
||||
static const double beta_offset_values[21] = {
|
||||
1.000, // Index 0
|
||||
2.000, // Index 1
|
||||
2.500, // Index 2
|
||||
3.125, // Index 3
|
||||
4.000, // Index 4
|
||||
5.000, // Index 5
|
||||
6.250, // Index 6
|
||||
8.000, // Index 7
|
||||
10.000, // Index 8
|
||||
12.625, // Index 9
|
||||
15.875, // Index 10
|
||||
20.000, // Index 11
|
||||
31.000, // Index 12
|
||||
50.000, // Index 13
|
||||
80.000, // Index 14
|
||||
126.000, // Index 15
|
||||
0.6, // Index 16
|
||||
0.4, // Index 17
|
||||
0.2, // Index 18
|
||||
0.1, // Index 19
|
||||
0.05, // Index 20
|
||||
};
|
||||
|
||||
if (beta_offset_index > 20) {
|
||||
LOG_E(PHY, "Invalid beta_offset_index %d, using default value\n", beta_offset_index);
|
||||
return 20.000; // Default value using index 11
|
||||
}
|
||||
|
||||
return beta_offset_values[beta_offset_index];
|
||||
}
|
||||
|
||||
static double get_alpha_scaling_value(uint8_t alpha_scaling)
|
||||
{
|
||||
switch (alpha_scaling) {
|
||||
case 0:
|
||||
return 0.5;
|
||||
case 1:
|
||||
return 0.65;
|
||||
case 2:
|
||||
return 0.8;
|
||||
case 3:
|
||||
return 1.0;
|
||||
default:
|
||||
AssertFatal(false, "Invalid alpha_scaling value %d, valid range is 0-3", alpha_scaling);
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function gets the CRC size of UCI
|
||||
*/
|
||||
static int get_crc_uci(const uint16_t ouci)
|
||||
{
|
||||
int L = 0;
|
||||
if (ouci > 19) {
|
||||
L = 11;
|
||||
} else if (ouci > 11) {
|
||||
L = 6;
|
||||
} else {
|
||||
L = 0; // no ACK/NACK
|
||||
}
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
static uint16_t get_Qd(const uint16_t oack, double beta, double alpha, const uint32_t sumKr, const uint32_t s1, const uint32_t s2)
|
||||
{
|
||||
if (oack == 0)
|
||||
return 0;
|
||||
|
||||
uint16_t first_term = ceil(((double)oack + get_crc_uci(oack)) * (double)beta * s1 / sumKr);
|
||||
uint16_t second_term = ceil(alpha * s2);
|
||||
|
||||
return (first_term < second_term) ? first_term : second_term;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function calculates the rate matching information for UCI multiplexing with PUSCH
|
||||
*/
|
||||
static rate_match_info_uci_t calc_rate_match_info_uci(const nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
const NR_UL_UE_HARQ_t *harq_process_ul_ue,
|
||||
const uint8_t nlqm,
|
||||
unsigned int *G)
|
||||
{
|
||||
// get beta offset
|
||||
uint8_t beta_offset_index = pusch_pdu->pusch_uci.beta_offset_harq_ack;
|
||||
double beta = get_beta_offset_harq_ack(beta_offset_index);
|
||||
|
||||
// get alpha scaling value
|
||||
uint8_t alpha_scaling = pusch_pdu->pusch_uci.alpha_scaling;
|
||||
double alpha = get_alpha_scaling_value(alpha_scaling);
|
||||
|
||||
// Calculate sumKr (total bits in all code blocks)
|
||||
uint32_t sumKr = 0;
|
||||
if (harq_process_ul_ue->C == 0) {
|
||||
sumKr = 0;
|
||||
} else if (harq_process_ul_ue->C == 1) {
|
||||
sumKr = harq_process_ul_ue->K;
|
||||
} else {
|
||||
sumKr = harq_process_ul_ue->K * harq_process_ul_ue->C;
|
||||
}
|
||||
|
||||
// Calculate s1: total number of non-DMRS REs in allocation
|
||||
uint16_t nb_rb = pusch_pdu->rb_size;
|
||||
uint8_t start_symbol = pusch_pdu->start_symbol_index;
|
||||
uint8_t number_of_symbols = pusch_pdu->nr_of_symbols;
|
||||
uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
|
||||
uint32_t s1 = 0;
|
||||
for (int l = start_symbol; l < start_symbol + number_of_symbols; l++) {
|
||||
if (!((ul_dmrs_symb_pos >> l) & 0x01)) {
|
||||
s1 += nb_rb * NR_NB_SC_PER_RB;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate s2: number of non-DMRS REs after first DMRS symbol
|
||||
int first_dmrs_symbol = -1;
|
||||
for (int l = start_symbol; l < start_symbol + number_of_symbols; l++) {
|
||||
if ((ul_dmrs_symb_pos >> l) & 0x01) {
|
||||
first_dmrs_symbol = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int l0 = -1;
|
||||
if (first_dmrs_symbol >= 0 && first_dmrs_symbol < start_symbol + number_of_symbols - 1) {
|
||||
l0 = first_dmrs_symbol + 1;
|
||||
}
|
||||
uint32_t s2 = 0;
|
||||
for (int l = l0; l < start_symbol + number_of_symbols; l++) {
|
||||
if (!((ul_dmrs_symb_pos >> l) & 0x01)) {
|
||||
s2 += nb_rb * NR_NB_SC_PER_RB;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t oack = pusch_pdu->pusch_uci.harq_ack_bit_length;
|
||||
uint16_t oack_rvd = (oack <= 2) ? 2 : 0; // get the reserved bits when oACK <= 2 according to TS 38.212 section 6.2.7, step 1
|
||||
|
||||
rate_match_info_uci_t rminfo = {0};
|
||||
|
||||
// get the number of coded HARQ-ACK symbols and bits, TS 38.212 section 6.3.2.4.1.1
|
||||
rminfo.Q_dash_ACK = get_Qd(oack, beta, alpha, sumKr, s1, s2);
|
||||
rminfo.E_uci_ACK = rminfo.Q_dash_ACK * nlqm;
|
||||
|
||||
if (oack_rvd > 0) {
|
||||
rminfo.Q_dash_ACK_rvd = get_Qd(oack_rvd, beta, alpha, sumKr, s1, s2);
|
||||
rminfo.E_uci_ACK_rvd = rminfo.Q_dash_ACK_rvd * nlqm;
|
||||
}
|
||||
|
||||
if (oack_rvd == 0) {
|
||||
rminfo.G_ulsch = *G - rminfo.E_uci_ACK;
|
||||
} else {
|
||||
rminfo.G_ulsch = *G;
|
||||
}
|
||||
|
||||
*G = rminfo.G_ulsch;
|
||||
LOG_D(PHY, "[UCI_RATE_MATCH] sumKr=%u, s1=%u, s2=%u, Final G_ulsch (output G): %u\n", sumKr, s1, s2, *G);
|
||||
LOG_D(PHY,
|
||||
"[UCI_RATE_MATCH] rate matching info returned: E_uci_ACK=%u, E_uci_ACK_rvd=%u, G_ulsch=%u\n",
|
||||
rminfo.E_uci_ACK,
|
||||
rminfo.E_uci_ACK_rvd,
|
||||
rminfo.G_ulsch);
|
||||
|
||||
return rminfo;
|
||||
}
|
||||
|
||||
static int initialize_mapping_resources(const nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint32_t *m_ulsch_initial,
|
||||
uint32_t *m_uci_current)
|
||||
{
|
||||
if (!pusch_pdu || !m_ulsch_initial || !m_uci_current)
|
||||
return -1;
|
||||
|
||||
const uint8_t n_pusch_sym_all = pusch_pdu->nr_of_symbols;
|
||||
const uint16_t ul_dmrs_symb_pos = pusch_pdu->ul_dmrs_symb_pos;
|
||||
const uint8_t dmrs_type = pusch_pdu->dmrs_config_type;
|
||||
const uint8_t cdm_grps_no_data = pusch_pdu->num_dmrs_cdm_grps_no_data;
|
||||
const uint32_t res_per_symbol_non_dmrs = pusch_pdu->rb_size * NR_NB_SC_PER_RB;
|
||||
const uint32_t data_re_on_dmrs_sym_per_prb = NR_NB_SC_PER_RB - get_num_dmrs_re_per_rb(dmrs_type, cdm_grps_no_data);
|
||||
|
||||
// Initialize resources per symbol for ULSCH and UCI
|
||||
for (uint8_t i = 0; i < n_pusch_sym_all; i++) {
|
||||
uint8_t absolute_symbol_idx = pusch_pdu->start_symbol_index + i;
|
||||
|
||||
if ((ul_dmrs_symb_pos >> absolute_symbol_idx) & 0x01) {
|
||||
// Calculate available data REs on DMRS symbols based on DMRS configuration
|
||||
|
||||
m_ulsch_initial[i] = pusch_pdu->rb_size * data_re_on_dmrs_sym_per_prb;
|
||||
m_uci_current[i] = 0; // UCI is not mapped on DMRS symbols
|
||||
|
||||
} else { // Not a DMRS symbol
|
||||
|
||||
m_ulsch_initial[i] = res_per_symbol_non_dmrs;
|
||||
m_uci_current[i] = res_per_symbol_non_dmrs;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_first_uci_symbol(const uint8_t start_symbol,
|
||||
const uint8_t num_symbols,
|
||||
const uint16_t dmrs_map,
|
||||
uint8_t *first_non_dmrs_sym,
|
||||
uint8_t *dmrs_p1)
|
||||
{
|
||||
// First non-DMRS symbol
|
||||
const uint16_t last_sym = start_symbol + num_symbols;
|
||||
for (uint_fast8_t s = start_symbol; s < last_sym; s++) {
|
||||
if (!is_dmrs_symbol(s, dmrs_map)) {
|
||||
*first_non_dmrs_sym = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Symbol after first consequtive DMRS symbol
|
||||
const uint8_t first_dmrs_sym = get_next_dmrs_symbol_in_slot(dmrs_map, start_symbol, last_sym);
|
||||
*dmrs_p1 = first_dmrs_sym + 1;
|
||||
while (is_dmrs_symbol(*dmrs_p1, dmrs_map) && *dmrs_p1 < last_sym) {
|
||||
(*dmrs_p1)++;
|
||||
}
|
||||
|
||||
// Return relative symbol idx
|
||||
*first_non_dmrs_sym -= start_symbol;
|
||||
*dmrs_p1 -= start_symbol;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function builds the initial template by reserving positions for HARQ-ACK.
|
||||
*/
|
||||
static void build_template_reserve_ack(uci_on_pusch_bit_type_t *template,
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint32_t G_ack_rvd,
|
||||
uint8_t l1_c,
|
||||
const uint32_t *m_uci_current,
|
||||
const uint32_t *m_ulsch_initial,
|
||||
uint32_t positions_by_sym[][MAX_UCI_CODED_BITS],
|
||||
uint32_t *count_by_sym)
|
||||
{
|
||||
const uint8_t n_symbols = pusch_pdu->nr_of_symbols;
|
||||
const uint32_t nlqm = pusch_pdu->qam_mod_order * pusch_pdu->nrOfLayers;
|
||||
|
||||
memset(count_by_sym, 0, n_symbols * sizeof(uint32_t));
|
||||
|
||||
uint32_t symbol_start_bit_idx[14] = {0};
|
||||
for (uint8_t s = 1; s < n_symbols; s++) {
|
||||
symbol_start_bit_idx[s] = symbol_start_bit_idx[s - 1] + (m_ulsch_initial[s - 1] * nlqm);
|
||||
}
|
||||
|
||||
// Reserve Positions using RE-level D-Factor Distribution
|
||||
uint32_t total_reserved = 0;
|
||||
|
||||
for (uint8_t sym = l1_c; sym < n_symbols && total_reserved < G_ack_rvd; sym++) {
|
||||
const uint32_t uci_re_on_sym = m_uci_current[sym];
|
||||
|
||||
if (uci_re_on_sym > 0) {
|
||||
const uint32_t remaining_to_reserve = G_ack_rvd - total_reserved;
|
||||
uint32_t d_factor_re;
|
||||
const uint32_t num_re_to_select = ceil((double)remaining_to_reserve / nlqm);
|
||||
if (num_re_to_select >= uci_re_on_sym) {
|
||||
d_factor_re = 1;
|
||||
} else {
|
||||
d_factor_re = floor((double)uci_re_on_sym / num_re_to_select);
|
||||
if (d_factor_re == 0) {
|
||||
d_factor_re = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t re_offset = 0; re_offset < uci_re_on_sym && total_reserved < G_ack_rvd; re_offset += d_factor_re) {
|
||||
for (uint32_t bit_in_re = 0; bit_in_re < nlqm; bit_in_re++) {
|
||||
if (total_reserved >= G_ack_rvd) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t bit_offset_in_sym = (re_offset * nlqm) + bit_in_re;
|
||||
uint32_t cw_idx = symbol_start_bit_idx[sym] + bit_offset_in_sym;
|
||||
template[cw_idx] = BIT_TYPE_ACK_RESERVED;
|
||||
positions_by_sym[sym][count_by_sym[sym]] = cw_idx;
|
||||
count_by_sym[sym]++;
|
||||
|
||||
total_reserved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function maps the HARQ-ACK bits when O_ACK > 2
|
||||
*/
|
||||
static void map_non_overlapped_ack(uci_on_pusch_bit_type_t *template,
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uint16_t G_ack,
|
||||
uint8_t l1_c,
|
||||
const uint32_t *m_uci_current,
|
||||
const uint32_t *m_ulsch_initial)
|
||||
{
|
||||
const uint8_t n_symbols = pusch_pdu->nr_of_symbols;
|
||||
const uint32_t nlqm = pusch_pdu->qam_mod_order * pusch_pdu->nrOfLayers;
|
||||
|
||||
uint32_t symbol_start_bit_idx[14] = {0};
|
||||
for (uint8_t s = 1; s < n_symbols; s++) {
|
||||
symbol_start_bit_idx[s] = symbol_start_bit_idx[s - 1] + (m_ulsch_initial[s - 1] * nlqm);
|
||||
}
|
||||
|
||||
uint32_t total_placed = 0;
|
||||
for (uint8_t sym = l1_c; sym < n_symbols && total_placed < G_ack; sym++) {
|
||||
const uint32_t uci_re_on_sym = m_uci_current[sym];
|
||||
|
||||
if (uci_re_on_sym > 0) {
|
||||
const uint32_t remaining_to_place = G_ack - total_placed;
|
||||
uint32_t d_factor_re;
|
||||
const uint32_t num_re_to_select = ceil((double)remaining_to_place / nlqm);
|
||||
|
||||
if (num_re_to_select >= uci_re_on_sym) {
|
||||
d_factor_re = 1;
|
||||
} else {
|
||||
d_factor_re = floor((double)uci_re_on_sym / num_re_to_select);
|
||||
if (d_factor_re == 0) {
|
||||
d_factor_re = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t re_offset = 0; re_offset < uci_re_on_sym && total_placed < G_ack; re_offset += d_factor_re) {
|
||||
for (uint32_t bit_in_re = 0; bit_in_re < nlqm; bit_in_re++) {
|
||||
if (total_placed >= G_ack) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t bit_offset_in_sym = (re_offset * nlqm) + bit_in_re;
|
||||
uint32_t cw_idx = symbol_start_bit_idx[sym] + bit_offset_in_sym;
|
||||
template[cw_idx] = BIT_TYPE_ACK;
|
||||
|
||||
total_placed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function maps the HARQ-ACK bits when O_ACK <= 2
|
||||
*/
|
||||
static void map_overlapped_ack(uci_on_pusch_bit_type_t *template,
|
||||
uint16_t G_ack,
|
||||
uint8_t l1_c,
|
||||
uint8_t n_symbols,
|
||||
uint32_t positions_by_sym[][MAX_UCI_CODED_BITS],
|
||||
const uint32_t *count_by_sym)
|
||||
{
|
||||
uint32_t ack_bits_marked = 0;
|
||||
|
||||
for (uint8_t sym_iter = l1_c; sym_iter < n_symbols && ack_bits_marked < G_ack; sym_iter++) {
|
||||
const uint32_t num_reserved_bits_on_sym = count_by_sym[sym_iter];
|
||||
|
||||
if (num_reserved_bits_on_sym > 0) {
|
||||
const uint32_t num_ack_remaining = G_ack - ack_bits_marked;
|
||||
uint32_t d_factor;
|
||||
|
||||
// This d-factor is calculated for stepping through the list of *reserved bits*.
|
||||
if (num_ack_remaining >= num_reserved_bits_on_sym) {
|
||||
d_factor = 1;
|
||||
} else {
|
||||
d_factor = floor((double)num_reserved_bits_on_sym / num_ack_remaining);
|
||||
if (d_factor == 0) {
|
||||
d_factor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t *reserved_indices_on_this_sym = positions_by_sym[sym_iter];
|
||||
|
||||
for (uint32_t i = 0; i < num_reserved_bits_on_sym && ack_bits_marked < G_ack; i += d_factor) {
|
||||
uint32_t pos_to_mark = reserved_indices_on_this_sym[i];
|
||||
template[pos_to_mark] = BIT_TYPE_ACK_ULSCH;
|
||||
|
||||
ack_bits_marked++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Applies the template to build the final codeword
|
||||
*/
|
||||
static void apply_template_to_codeword(uint8_t *codeword,
|
||||
const uci_on_pusch_bit_type_t *template,
|
||||
uint32_t codeword_len,
|
||||
const uint8_t *ulsch_bits,
|
||||
const uint64_t *cack,
|
||||
uint16_t G_ack,
|
||||
uint32_t G_ulsch)
|
||||
{
|
||||
uint32_t ulsch_idx = 0;
|
||||
uint32_t ack_idx = 0;
|
||||
|
||||
for (uint32_t i = 0; i < codeword_len; i++) {
|
||||
switch (template[i]) {
|
||||
case BIT_TYPE_ACK:
|
||||
if (G_ack > 0 && ack_idx < G_ack) {
|
||||
uint32_t word_idx = ack_idx / 64;
|
||||
uint32_t bit_in_word_idx = ack_idx % 64;
|
||||
codeword[i] = (cack[word_idx] >> bit_in_word_idx) & 1;
|
||||
ack_idx++;
|
||||
}
|
||||
break;
|
||||
|
||||
case BIT_TYPE_ACK_ULSCH:
|
||||
if (G_ack > 0 && ack_idx < G_ack) {
|
||||
codeword[i] = ((const uint8_t *)cack)[ack_idx++];
|
||||
if (G_ulsch > 0 && ulsch_idx < G_ulsch) {
|
||||
ulsch_idx++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BIT_TYPE_ACK_RESERVED:
|
||||
case BIT_TYPE_ULSCH:
|
||||
default:
|
||||
if (G_ulsch > 0 && ulsch_idx < G_ulsch) {
|
||||
uint32_t byte_idx = ulsch_idx / 8;
|
||||
uint32_t bit_in_byte_idx = ulsch_idx % 8;
|
||||
codeword[i] = (ulsch_bits[byte_idx] >> bit_in_byte_idx) & 1;
|
||||
ulsch_idx++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function implements the UCI multiplexing on PUSCH according to TS 38.212 section 6.2.7.
|
||||
*/
|
||||
static uci_on_pusch_bit_type_t *nr_data_control_mapping(const nfapi_nr_ue_pusch_pdu_t *pusch_pdu,
|
||||
uci_on_pusch_bit_type_t *template,
|
||||
unsigned int G_ulsch,
|
||||
uint16_t G_ack,
|
||||
uint32_t G_ack_rvd,
|
||||
uint8_t *codeword,
|
||||
uint32_t codeword_len,
|
||||
const uint8_t *ulsch_bits,
|
||||
const uint64_t *cack)
|
||||
{
|
||||
if (!pusch_pdu || !codeword || codeword_len == 0 || !template)
|
||||
return NULL;
|
||||
const uint8_t n_symbols = pusch_pdu->nr_of_symbols;
|
||||
if (n_symbols == 0 || n_symbols > NR_NUMBER_OF_SYMBOLS_PER_SLOT)
|
||||
return NULL;
|
||||
|
||||
uint32_t m_ulsch_initial[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0};
|
||||
uint32_t m_uci_current[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0}; // This holds RE counts, not bit counts
|
||||
|
||||
if (initialize_mapping_resources(pusch_pdu, m_ulsch_initial, m_uci_current) != 0) {
|
||||
LOG_E(PHY, "Failed to initialize mapping resources\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t first_non_dmrs_sym = 0;
|
||||
uint8_t l1_c = 0;
|
||||
get_first_uci_symbol(pusch_pdu->start_symbol_index,
|
||||
pusch_pdu->nr_of_symbols,
|
||||
pusch_pdu->ul_dmrs_symb_pos,
|
||||
&first_non_dmrs_sym,
|
||||
&l1_c);
|
||||
|
||||
memset(template, 0, codeword_len * sizeof(uci_on_pusch_bit_type_t));
|
||||
|
||||
uint32_t positions_by_sym[NR_NUMBER_OF_SYMBOLS_PER_SLOT][MAX_UCI_CODED_BITS] = {0};
|
||||
uint32_t count_by_sym[NR_NUMBER_OF_SYMBOLS_PER_SLOT] = {0};
|
||||
|
||||
if (G_ack_rvd > 0) {
|
||||
build_template_reserve_ack(template,
|
||||
pusch_pdu,
|
||||
G_ack_rvd,
|
||||
l1_c,
|
||||
m_uci_current,
|
||||
m_ulsch_initial,
|
||||
positions_by_sym,
|
||||
count_by_sym);
|
||||
} else if (G_ack > 0) {
|
||||
map_non_overlapped_ack(template, pusch_pdu, G_ack, l1_c, m_uci_current, m_ulsch_initial);
|
||||
}
|
||||
|
||||
if (G_ack > 0 && G_ack_rvd > 0) {
|
||||
map_overlapped_ack(template, G_ack, l1_c, n_symbols, positions_by_sym, count_by_sym);
|
||||
}
|
||||
|
||||
apply_template_to_codeword(codeword, template, codeword_len, ulsch_bits, cack, G_ack, G_ulsch);
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
const uint32_t frame,
|
||||
const uint8_t slot,
|
||||
@@ -494,8 +1033,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
LOG_D(PHY, "nr_ue_ulsch_procedures_slot hard_id %d %d.%d prepare for coding\n", harq_pid, frame, slot);
|
||||
|
||||
NR_UE_ULSCH_t *ulsch_ue = &phy_data->ulsch;
|
||||
NR_UE_PUCCH *pucch_ue = &phy_data->pucch_vars;
|
||||
NR_UL_UE_HARQ_t *harq_process_ul_ue = &UE->ul_harq_processes[harq_pid];
|
||||
const nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch_ue->pusch_pdu;
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu = &pucch_ue->pucch_pdu[0];
|
||||
uci_on_pusch_bit_type_t *uci_mapping_template = NULL;
|
||||
|
||||
uint16_t number_dmrs_symbols = 0;
|
||||
|
||||
@@ -536,6 +1078,11 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
G[pusch_id] = nr_get_G(nb_rb, number_of_symbols, nb_dmrs_re_per_rb, number_dmrs_symbols, unav_res, mod_order, Nl);
|
||||
|
||||
// Capture the initial total PUSCH bits. This is the total_codeword_length for mapping.
|
||||
unsigned int G_initial_total_pusch_bits = G[pusch_id];
|
||||
|
||||
uci_on_pusch_bit_type_t template_buffer[G_initial_total_pusch_bits];
|
||||
|
||||
ws_trace_t tmp = {.nr = true,
|
||||
.direction = DIRECTION_UPLINK,
|
||||
.pdu_buffer = harq_process_ul_ue->payload_AB,
|
||||
@@ -552,6 +1099,17 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
/////////////////////////ULSCH coding/////////////////////////
|
||||
|
||||
rate_match_info_uci_t rm_info = {0};
|
||||
const uint8_t nl_qm = Nl * mod_order; // product of number of layers and modulation order
|
||||
if(nr_ulsch_pre_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids) != 0) {
|
||||
LOG_E(PHY, "Error pre-encoding\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pusch_pdu->pusch_uci.harq_ack_bit_length != 0) {
|
||||
rm_info = calc_rate_match_info_uci(pusch_pdu, harq_process_ul_ue, nl_qm, &G[pusch_id]);
|
||||
}
|
||||
|
||||
if (nr_ulsch_encoding(UE, &phy_data->ulsch, frame, slot, G, 1, ULSCH_ids, number_dmrs_symbols) == -1) {
|
||||
stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS);
|
||||
return;
|
||||
@@ -565,9 +1123,52 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
int N_PRB_oh = 0; // higher layer (RRC) parameter xOverhead in PUSCH-ServingCellConfig
|
||||
|
||||
AssertFatal(pusch_pdu->pusch_uci.harq_ack_bit_length == 0 && pusch_pdu->pusch_uci.csi_part1_bit_length == 0
|
||||
&& pusch_pdu->pusch_uci.csi_part2_bit_length == 0,
|
||||
"UCI on PUSCH not supported at PHY\n");
|
||||
if (pusch_pdu->pusch_uci.harq_ack_bit_length != 0) {
|
||||
LOG_D(PHY, "[UCI_ON_PUSCH] Original HARQ-ACK bit length: %u\n", pusch_pdu->pusch_uci.harq_ack_bit_length);
|
||||
LOG_D(PHY, "[UCI_ON_PUSCH] Initial G: %u\n", G_initial_total_pusch_bits);
|
||||
// b is the block of bits transmitted on the physical channel after payload coding
|
||||
uint64_t b[16] = {0}; // limit to 1024-bit encoded length
|
||||
|
||||
if (pucch_pdu == NULL) {
|
||||
LOG_E(PHY, "nr_ue_ulsch_procedures: pucch_pdu is NULL but HARQ-ACK is present. Cannot proceed with UCI encoding.\n");
|
||||
stop_meas_nr_ue_phy(UE, PUSCH_PROC_STATS);
|
||||
return;
|
||||
}
|
||||
|
||||
nr_uci_encoding(pusch_pdu->pusch_uci.harq_payload,
|
||||
pusch_pdu->pusch_uci.harq_ack_bit_length,
|
||||
pucch_pdu->prb_size,
|
||||
true,
|
||||
rm_info.E_uci_ACK,
|
||||
mod_order,
|
||||
&b[0]);
|
||||
|
||||
LOG_D(PHY,
|
||||
"[UCI_ON_PUSCH] G_ulsch=%u (updated G[pusch_id]), G_ack=%u (M_bit), G_ack_rvd=%u, total_len=%u "
|
||||
"(G_initial_total_pusch_bits).\n",
|
||||
G[pusch_id],
|
||||
rm_info.E_uci_ACK,
|
||||
rm_info.E_uci_ACK_rvd,
|
||||
G_initial_total_pusch_bits);
|
||||
|
||||
uint8_t temp_codeword[G_initial_total_pusch_bits];
|
||||
start_meas_nr_ue_phy(UE, UCI_ON_PUSCH_MAPPING);
|
||||
nr_data_control_mapping(pusch_pdu,
|
||||
template_buffer,
|
||||
G[pusch_id],
|
||||
rm_info.E_uci_ACK,
|
||||
rm_info.E_uci_ACK_rvd,
|
||||
temp_codeword,
|
||||
G_initial_total_pusch_bits,
|
||||
harq_process_ul_ue->f,
|
||||
b);
|
||||
stop_meas_nr_ue_phy(UE, UCI_ON_PUSCH_MAPPING);
|
||||
memcpy(harq_process_ul_ue->f, temp_codeword, G_initial_total_pusch_bits);
|
||||
uci_mapping_template = template_buffer;
|
||||
}
|
||||
|
||||
AssertFatal(pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0,
|
||||
"UCI (CSI) on PUSCH not supported at PHY\n");
|
||||
|
||||
uint16_t start_rb = pusch_pdu->rb_start;
|
||||
uint16_t start_sc = frame_parms->first_carrier_offset + (start_rb + pusch_pdu->bwp_start) * NR_NB_SC_PER_RB;
|
||||
@@ -600,17 +1201,32 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE,
|
||||
|
||||
/////////////////////////ULSCH scrambling/////////////////////////
|
||||
|
||||
uint32_t available_bits = G[pusch_id];
|
||||
// +1 because size can be not modulo 4
|
||||
uint32_t scrambled_output[available_bits / (8 * sizeof(uint32_t)) + 1];
|
||||
uint32_t available_bits;
|
||||
bool is_uci_on_pusch = (pusch_pdu->pusch_uci.harq_ack_bit_length != 0);
|
||||
|
||||
if (is_uci_on_pusch) {
|
||||
// UCI on PUSCH is present, so available bits are the total codeword length
|
||||
available_bits = G_initial_total_pusch_bits;
|
||||
} else {
|
||||
// No UCI on PUSCH, so available bits are the initial G value
|
||||
available_bits = G[pusch_id];
|
||||
}
|
||||
|
||||
// +1 because size can be not modulo 4 for the uint32_t array
|
||||
uint32_t scrambled_output_len_u32 = (available_bits + 31) / 32; // Round up to nearest uint32_t count
|
||||
uint32_t scrambled_output[scrambled_output_len_u32];
|
||||
memset(scrambled_output, 0, sizeof(scrambled_output));
|
||||
|
||||
nr_pusch_codeword_scrambling(harq_process_ul_ue->f,
|
||||
available_bits,
|
||||
pusch_pdu->data_scrambling_id,
|
||||
rnti,
|
||||
false,
|
||||
is_uci_on_pusch,
|
||||
uci_mapping_template,
|
||||
scrambled_output);
|
||||
if (UE->phy_sim_test_buf) {
|
||||
memcpy(UE->phy_sim_test_buf, scrambled_output, (available_bits + 7) / 8);
|
||||
}
|
||||
#if T_TRACER
|
||||
if (T_ACTIVE(T_UE_PHY_UL_SCRAMBLED_TX_BITS)) {
|
||||
// Get Time Stamp for T-tracer messages
|
||||
@@ -893,19 +1509,21 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE,
|
||||
c16_t **txdataF,
|
||||
c16_t **txdata,
|
||||
uint32_t linktype,
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT])
|
||||
bool was_symbol_used[NR_NUMBER_OF_SYMBOLS_PER_SLOT],
|
||||
bool no_phase_pre_comp)
|
||||
{
|
||||
int N_RB = (linktype == link_type_sl) ? frame_parms->N_RB_SL : frame_parms->N_RB_UL;
|
||||
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT; i++) {
|
||||
if (was_symbol_used[i] == false)
|
||||
continue;
|
||||
for (int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms, txdataF[ap], frame_parms->symbol_rotation[linktype], slot, N_RB, i, 1);
|
||||
if (!no_phase_pre_comp) {
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT; i++) {
|
||||
if (was_symbol_used[i] == false)
|
||||
continue;
|
||||
for (int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
apply_nr_rotation_TX(frame_parms, txdataF[ap], frame_parms->symbol_rotation[linktype], slot, N_RB, i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int ap = 0; ap < n_antenna_ports; ap++) {
|
||||
if (frame_parms->Ncp == 1) { // extended cyclic prefix
|
||||
for (int i = 0; i < NR_NUMBER_OF_SYMBOLS_PER_SLOT_EXTENDED_CP; i++) {
|
||||
|
||||
@@ -485,6 +485,45 @@ void nr_generate_pucch1(const PHY_VARS_NR_UE *ue,
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate number of DMRS symbols for PUCCH formats 3 and 4
|
||||
static uint8_t nr_pucch_get_dmrs_symbols(uint8_t nrofSymbols, uint8_t add_dmrs)
|
||||
{
|
||||
if (nrofSymbols == 4) {
|
||||
return 1;
|
||||
} else if (nrofSymbols > 4 && nrofSymbols <= 9) {
|
||||
return 2;
|
||||
} else if (nrofSymbols > 9) {
|
||||
return (add_dmrs == 0) ? 2 : 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate PUCCH format 2/3/4 rate matching output sequence length according to TS 38.212 Table 6.3.1.4-1
|
||||
static uint16_t nr_pucch_output_sequence_length(uint8_t format_type,
|
||||
uint8_t nrofSymbols,
|
||||
uint16_t nrofPRB,
|
||||
uint8_t n_SF_PUCCH_s,
|
||||
uint8_t is_pi_over_2_bpsk_enabled,
|
||||
uint8_t add_dmrs)
|
||||
{
|
||||
uint16_t M_bit = 0;
|
||||
|
||||
if (format_type == 2) {
|
||||
M_bit = 16 * nrofSymbols * nrofPRB;
|
||||
} else if (format_type == 3) {
|
||||
uint16_t E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24 : 12;
|
||||
uint8_t num_dmrs_symbols = nr_pucch_get_dmrs_symbols(nrofSymbols, add_dmrs);
|
||||
M_bit = E_init * (nrofSymbols - num_dmrs_symbols) * nrofPRB / n_SF_PUCCH_s;
|
||||
} else if (format_type == 4) {
|
||||
nrofPRB = 1;
|
||||
uint16_t E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24 : 12;
|
||||
uint8_t num_dmrs_symbols = nr_pucch_get_dmrs_symbols(nrofSymbols, add_dmrs);
|
||||
M_bit = E_init * (nrofSymbols - num_dmrs_symbols) * nrofPRB / n_SF_PUCCH_s;
|
||||
}
|
||||
|
||||
return M_bit;
|
||||
}
|
||||
|
||||
static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit, uint16_t rnti, uint16_t n_id, uint64_t *B64, uint8_t *btilde)
|
||||
{
|
||||
// c_init=nRNTI*2^15+n_id according to TS 38.211 Subclause 6.3.2.6.1
|
||||
@@ -520,101 +559,143 @@ static inline void nr_pucch2_3_4_scrambling(uint16_t M_bit, uint16_t rnti, uint1
|
||||
printf("\t\t [nr_pucch2_3_4_scrambling] scrambling M_bit=%d bits\n", M_bit);
|
||||
#endif
|
||||
}
|
||||
static void nr_uci_encoding(uint64_t payload,
|
||||
uint8_t nr_bit,
|
||||
int fmt,
|
||||
uint8_t is_pi_over_2_bpsk_enabled,
|
||||
uint8_t nrofSymbols,
|
||||
uint8_t nrofPRB,
|
||||
uint8_t n_SF_PUCCH_s,
|
||||
uint8_t intraSlotFrequencyHopping,
|
||||
uint8_t add_dmrs,
|
||||
uint64_t *b,
|
||||
uint16_t *M_bit) {
|
||||
|
||||
void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci_on_pusch, uint16_t E, uint8_t Qm, uint64_t *b)
|
||||
{
|
||||
/*
|
||||
* Implementing TS 38.212 Subclause 6.3.1.2
|
||||
* Implementing TS 38.212 Subclause 6.3.1.2 and 6.3.2
|
||||
*
|
||||
*/
|
||||
// A is the payload size, to be provided in function call
|
||||
uint8_t A = nr_bit;
|
||||
// L is the CRC size
|
||||
//uint8_t L;
|
||||
// uint8_t L;
|
||||
// E is the rate matching output sequence length as given in TS 38.212 subclause 6.3.1.4.1
|
||||
uint16_t E=0,E_init;
|
||||
|
||||
if (fmt == 2) E = 16*nrofSymbols*nrofPRB;
|
||||
|
||||
if (fmt == 3) {
|
||||
E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12;
|
||||
|
||||
if (nrofSymbols == 4) {
|
||||
E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)*nrofPRB):((E_init*(nrofSymbols-1)*nrofPRB));
|
||||
// int I_seg;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("format 3 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E);
|
||||
printf("\t\t [nr_uci_encoding] start function with encoding A=%d bits into M_bit=%d (where nrofPRB=%d)\n", A, E, nrofPRB);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (nrofSymbols > 4) {
|
||||
E = E_init*(nrofSymbols-2)*nrofPRB;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("format 3 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E);
|
||||
#endif
|
||||
}
|
||||
// For A=1 case (single bit UCI)
|
||||
if (A == 1) {
|
||||
uint8_t uci_bit_val = payload & 1; // Extract the single UCI bit
|
||||
uint64_t pattern_word;
|
||||
uint8_t *b_bytes = (uint8_t *)b; // Access b as bytes to set individual special values
|
||||
|
||||
if (nrofSymbols > 9) {
|
||||
E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)*nrofPRB):((E_init*(nrofSymbols-4)*nrofPRB));
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("format 3 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E);
|
||||
#endif
|
||||
if (Qm == 1) {
|
||||
// For BPSK, just repeat the input bit
|
||||
pattern_word = uci_bit_val ? 0xFFFFFFFFFFFFFFFFULL : 0x0000000000000000ULL;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
b[i] = pattern_word;
|
||||
}
|
||||
} else {
|
||||
// For higher order modulation (QPSK, etc.), use placeholder values
|
||||
memset(b, 0, 8 * sizeof(uint64_t));
|
||||
|
||||
// Fill the entire output with the pattern
|
||||
for (int i = 0; i < E; i++) {
|
||||
switch (i % Qm) {
|
||||
case 0:
|
||||
// First bit in each group is actual UCI bit
|
||||
b_bytes[i] = uci_bit_val;
|
||||
LOG_D(PHY,
|
||||
"[UCI_ENCODING_A1_QAM_LOOP] i=%d, i%%Qm=%d (case 0), writing uci_bit_val %d to b_bytes[%d]\n",
|
||||
i,
|
||||
i % Qm,
|
||||
uci_bit_val,
|
||||
i);
|
||||
break;
|
||||
case 1:
|
||||
b_bytes[i] = NR_PUSCH_y;
|
||||
LOG_D(PHY,
|
||||
"[UCI_ENCODING_A1_QAM_LOOP] i=%d, i%%Qm=%d (case 1), writing NR_PUSCH_y (0x%02X) to b_bytes[%d]\n",
|
||||
i,
|
||||
i % Qm,
|
||||
NR_PUSCH_y,
|
||||
i);
|
||||
break;
|
||||
default:
|
||||
b_bytes[i] = NR_PUSCH_x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// For A=2 case (two bits UCI)
|
||||
else if (A == 2) {
|
||||
uint8_t bit0 = (payload >> 0) & 1;
|
||||
uint8_t bit1 = (payload >> 1) & 1;
|
||||
uint8_t c2 = bit0 ^ bit1; // Parity bit (XOR of the two bits)
|
||||
uint8_t *b_bytes = (uint8_t *)b;
|
||||
|
||||
if (fmt == 4) {
|
||||
E_init = (is_pi_over_2_bpsk_enabled == 0) ? 24:12;
|
||||
if (Qm == 1) {
|
||||
// For BPSK, output is [bit0, bit1, c2]
|
||||
uint64_t pattern = (bit0) | (bit1 << 1) | (c2 << 2);
|
||||
// Repeat this 3-bit pattern to fill the output
|
||||
pattern |= pattern << 3;
|
||||
pattern |= pattern << 6;
|
||||
pattern |= pattern << 12;
|
||||
pattern |= pattern << 24;
|
||||
pattern |= pattern << 48;
|
||||
|
||||
if (nrofSymbols == 4) {
|
||||
E = (intraSlotFrequencyHopping == 0)?(E_init*(nrofSymbols-1)/n_SF_PUCCH_s):((E_init*(nrofSymbols-1)/n_SF_PUCCH_s));
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("format 4 nrofSymbols =4 and E_init=%d,E=%d\n",E_init,E);
|
||||
#endif
|
||||
for (int i = 0; i < 8; i++) {
|
||||
b[i] = pattern;
|
||||
}
|
||||
} else {
|
||||
// For higher order modulation (Qm>=2), using patterns from Table 5.3.3.2-1
|
||||
// Pattern: 3 groups of Qm bits each = 3*Qm total length
|
||||
memset(b, 0, 8 * sizeof(uint64_t));
|
||||
|
||||
for (int i = 0; i < E; i++) {
|
||||
int pos_in_pattern = i % (3 * Qm);
|
||||
int group = pos_in_pattern / Qm;
|
||||
int pos_in_group = pos_in_pattern % Qm;
|
||||
uint8_t val_to_write;
|
||||
|
||||
if (pos_in_group == 0) {
|
||||
if (group == 0)
|
||||
val_to_write = bit0;
|
||||
else if (group == 1)
|
||||
val_to_write = c2;
|
||||
else
|
||||
val_to_write = bit1;
|
||||
} else if (pos_in_group == 1) {
|
||||
if (group == 0)
|
||||
val_to_write = bit1;
|
||||
else if (group == 1)
|
||||
val_to_write = bit0;
|
||||
else
|
||||
val_to_write = c2;
|
||||
} else {
|
||||
// Positions 2 and beyond are x placeholders
|
||||
val_to_write = NR_PUSCH_x;
|
||||
}
|
||||
|
||||
b_bytes[i] = val_to_write;
|
||||
}
|
||||
}
|
||||
|
||||
if (nrofSymbols > 4) {
|
||||
E = E_init*(nrofSymbols-2)/n_SF_PUCCH_s;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("format 4 nrofSymbols >4 and E_init=%d,E = %d\n",E_init,E);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (nrofSymbols > 9) {
|
||||
E = (add_dmrs == 0)?(E_init*(nrofSymbols-2)/n_SF_PUCCH_s):((E_init*(nrofSymbols-4)/n_SF_PUCCH_s));
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("format 4 nrofSymbols >9 and E_init=%d,E = %d\n",E_init,E);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
*M_bit = E;
|
||||
//int I_seg;
|
||||
#ifdef DEBUG_NR_PUCCH_TX
|
||||
printf("\t\t [nr_uci_encoding] start function with fmt=%d, encoding A=%d bits into M_bit=%d (where nrofSymbols=%d,nrofPRB=%d)\n",fmt,A,*M_bit,nrofSymbols,nrofPRB);
|
||||
#endif
|
||||
|
||||
if (A<=11) {
|
||||
} else if (A <= 11) {
|
||||
// procedure in subclause 6.3.1.2.2 (UCI encoded by channel coding of small block lengths -> subclause 6.3.1.3.2)
|
||||
// CRC bits are not attached, and coding small block lengths (subclause 5.3.3)
|
||||
uint64_t b0 = encodeSmallBlock(payload, A);
|
||||
// repetition for rate-matching up to 16 PRB
|
||||
b[0] = b0 | (b0<<32);
|
||||
b[1] = b[0];
|
||||
b[2] = b[0];
|
||||
b[3] = b[0];
|
||||
b[4] = b[0];
|
||||
b[5] = b[0];
|
||||
b[6] = b[0];
|
||||
b[7] = b[0];
|
||||
AssertFatal(nrofPRB<=16,"Number of PRB >16\n");
|
||||
} else if (A>=12) {
|
||||
if (uci_on_pusch) {
|
||||
b[0] = b0;
|
||||
for (int i = 1; i < 8; i++) {
|
||||
b[i] = 0;
|
||||
}
|
||||
} else {
|
||||
// repetition for rate-matching up to 16 PRB
|
||||
b[0] = b0 | (b0<<32);
|
||||
b[1] = b[0];
|
||||
b[2] = b[0];
|
||||
b[3] = b[0];
|
||||
b[4] = b[0];
|
||||
b[5] = b[0];
|
||||
b[6] = b[0];
|
||||
b[7] = b[0];
|
||||
AssertFatal(nrofPRB<=16,"Number of PRB >16\n");
|
||||
}
|
||||
} else if (A >= 12) {
|
||||
// Encoder reversal
|
||||
payload = reverse_bits(payload, A);
|
||||
|
||||
@@ -623,7 +704,52 @@ static void nr_uci_encoding(uint64_t payload,
|
||||
A,
|
||||
nrofPRB);
|
||||
}
|
||||
|
||||
|
||||
if (uci_on_pusch) {
|
||||
// Rate matching for HARQ ACK following 38.212 section 5.4.3
|
||||
uint64_t output[8] = {0}; // Assuming max 512 bits (8 words of 64 bits)
|
||||
uint16_t N;
|
||||
if (nr_bit <= 2) {
|
||||
// For A=1 (BPSK), N=1. For A=2 (QPSK), N=3
|
||||
N = (nr_bit == 1) ? 1 : 3;
|
||||
} else if (nr_bit <= 11) {
|
||||
// For 3 <= A <= 11, the small block encoder produces a 32-bit codeword
|
||||
N = 32;
|
||||
} else {
|
||||
// For polar-coded UCI, output depends on nrofPRB
|
||||
N = 16 * nrofPRB;
|
||||
}
|
||||
|
||||
if ((nr_bit == 1 || nr_bit == 2) && Qm > 1) {
|
||||
LOG_D(PHY,
|
||||
"[UCI_ENCODING_RM] Bypassing bit-wise rate matching for A=%d, Qm=%d. 'b' (length %d bytes) is assumed to be already "
|
||||
"final.\n",
|
||||
nr_bit,
|
||||
Qm,
|
||||
E);
|
||||
} else {
|
||||
if (N == 0) {
|
||||
LOG_W(PHY, "HARQ-ACK rate matching with encoded_length=0 but E_uci_ack=%d\n", E);
|
||||
return;
|
||||
}
|
||||
|
||||
// Rate matching with single loop for both repetition and puncturing
|
||||
for (int i = 0; i < E; i++) {
|
||||
int src_bit = i % N; // Modulo for cyclic repetition
|
||||
int src_word = src_bit / 64;
|
||||
int src_bit_pos = src_bit % 64;
|
||||
int dst_word = i / 64;
|
||||
int dst_bit_pos = i % 64;
|
||||
|
||||
if ((b[src_word] >> src_bit_pos) & 1ULL)
|
||||
output[dst_word] |= (1ULL << dst_bit_pos);
|
||||
}
|
||||
|
||||
for (int i = 0; i < (E + 63) / 64; i++) {
|
||||
b[i] = output[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//#if 0
|
||||
void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
||||
@@ -639,13 +765,8 @@ void nr_generate_pucch2(const PHY_VARS_NR_UE *ue,
|
||||
// b is the block of bits transmitted on the physical channel after payload coding
|
||||
uint64_t b[16] = {0}; // limit to 1024-bit encoded length
|
||||
// M_bit is the number of bits of block b (payload after encoding)
|
||||
uint16_t M_bit = 0;
|
||||
nr_uci_encoding(pucch_pdu->payload,
|
||||
pucch_pdu->n_bit,
|
||||
2,0,
|
||||
pucch_pdu->nr_of_symbols,
|
||||
pucch_pdu->prb_size,
|
||||
1,0,0,&b[0],&M_bit);
|
||||
uint16_t M_bit = nr_pucch_output_sequence_length(pucch_pdu->format_type, pucch_pdu->nr_of_symbols, pucch_pdu->prb_size, 0, 0, 0);
|
||||
nr_uci_encoding(pucch_pdu->payload, pucch_pdu->n_bit, pucch_pdu->prb_size, false, M_bit, 0, &b[0]);
|
||||
/*
|
||||
* Implementing TS 38.211
|
||||
* Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2)
|
||||
@@ -829,7 +950,7 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
// b is the block of bits transmitted on the physical channel after payload coding
|
||||
uint64_t b[16];
|
||||
// M_bit is the number of bits of block b (payload after encoding)
|
||||
uint16_t M_bit;
|
||||
uint16_t M_bit = 0;
|
||||
// parameter PUCCH-F4-preDFT-OCC-length set of {2,4} -> to use table -1 or -2
|
||||
// in format 4, n_SF_PUCCH_s = {2,4}, provided by higher layer parameter PUCCH-F4-preDFT-OCC-length (in format 3 n_SF_PUCCH_s=1)
|
||||
uint8_t n_SF_PUCCH_s;
|
||||
@@ -856,17 +977,14 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
uint16_t startingPRB = pucch_pdu->prb_start + pucch_pdu->bwp_start;
|
||||
uint8_t add_dmrs = pucch_pdu->add_dmrs_flag;
|
||||
|
||||
nr_uci_encoding(pucch_pdu->payload,
|
||||
pucch_pdu->n_bit,
|
||||
pucch_pdu->format_type,
|
||||
is_pi_over_2_bpsk_enabled,
|
||||
nrofSymbols,
|
||||
nrofPRB,
|
||||
n_SF_PUCCH_s,
|
||||
intraSlotFrequencyHopping,
|
||||
add_dmrs,
|
||||
b,
|
||||
&M_bit);
|
||||
M_bit = nr_pucch_output_sequence_length(pucch_pdu->format_type,
|
||||
nrofSymbols,
|
||||
nrofPRB,
|
||||
n_SF_PUCCH_s,
|
||||
is_pi_over_2_bpsk_enabled,
|
||||
add_dmrs);
|
||||
|
||||
nr_uci_encoding(pucch_pdu->payload, pucch_pdu->n_bit, nrofPRB, false, M_bit, 0, b);
|
||||
/*
|
||||
* Implementing TS 38.211
|
||||
* Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4)
|
||||
|
||||
@@ -72,6 +72,8 @@ void nr_generate_pucch3_4(const PHY_VARS_NR_UE *ue,
|
||||
const int nr_slot_tx,
|
||||
const fapi_nr_ul_config_pucch_pdu *pucch_pdu);
|
||||
|
||||
void nr_uci_encoding(uint64_t payload, uint8_t nr_bit, uint8_t nrofPRB, bool uci_on_pusch, uint16_t E, uint8_t Qm, uint64_t *b);
|
||||
|
||||
static const uint8_t list_of_prime_numbers[46] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
|
||||
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
|
||||
73, 79, 83, 89, 97, 101,103,107,109,113,
|
||||
|
||||
@@ -45,6 +45,7 @@ if(ENABLE_UESCOPE OR ENABLE_ENBSCOPE OR ENABLE_NRSCOPE)
|
||||
lte_phy_scope.c
|
||||
../../../executables/stats.c)
|
||||
target_link_libraries(xforms_common PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
|
||||
target_link_libraries(xforms_common PRIVATE log_headers)
|
||||
|
||||
add_library(enbscope MODULE lte_enb_scope.c $<TARGET_OBJECTS:xforms_common>)
|
||||
target_link_libraries(enbscope PUBLIC forms PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
|
||||
|
||||
@@ -99,8 +99,9 @@ static void commonGraph(OAIgraph_t *graph, int type, FL_Coord x, FL_Coord y, FL_
|
||||
}
|
||||
|
||||
static OAIgraph_t calibrationCommonGraph( void (*funct) (OAIgraph_t *graph, calibData_t *context),
|
||||
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor) {
|
||||
OAIgraph_t graph;
|
||||
int type, FL_Coord x, FL_Coord y, FL_Coord w, FL_Coord h, const char *label, FL_COLOR pointColor)
|
||||
{
|
||||
OAIgraph_t graph = {0};
|
||||
commonGraph(&graph, type, x, y, w, h, label, pointColor);
|
||||
graph.funct=funct;
|
||||
return graph;
|
||||
@@ -236,7 +237,9 @@ static void genericWaterFall (OAIgraph_t *graph, scopeSample_t *values, const in
|
||||
graph->iteration++;
|
||||
}
|
||||
|
||||
static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len) {
|
||||
__attribute__((unused))
|
||||
static void genericPowerPerAntena(OAIgraph_t *graph, const int nb_ant, const scopeSample_t **data, const int len)
|
||||
{
|
||||
float *values, *time;
|
||||
oai_xygraph_getbuff(graph, &time, &values, len, 0);
|
||||
|
||||
@@ -263,7 +266,10 @@ static void gNBfreqWaterFall (OAIgraph_t *graph, calibData_t *context) {
|
||||
0, 0,
|
||||
"X axis:one frame in time");
|
||||
}
|
||||
static void timeResponse (OAIgraph_t *graph, calibData_t *context) {
|
||||
|
||||
__attribute__((unused))
|
||||
static void timeResponse (OAIgraph_t *graph, calibData_t *context)
|
||||
{
|
||||
#if 0
|
||||
const int len=2*phy_vars_gnb->frame_parms.ofdm_symbol_size;
|
||||
float *values, *time;
|
||||
|
||||
@@ -28,7 +28,6 @@ char *uecap_file;
|
||||
int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {return 0;}
|
||||
void nfapi_setmode(nfapi_mode_t nfapi_mode) {}
|
||||
void set_taus_seed(unsigned int seed_init){};
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
int main(int argc, char **argv) {
|
||||
///static configuration for NR at the moment
|
||||
if ((uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY)) == NULL) {
|
||||
@@ -60,8 +59,6 @@ int main(int argc, char **argv) {
|
||||
openair0_config_t openair0_cfg= {
|
||||
//! Module ID for this configuration
|
||||
.Mod_id=0,
|
||||
//! device log level
|
||||
.log_level=0,
|
||||
//! duplexing mode
|
||||
.duplex_mode=0,
|
||||
//! number of downlink resource blocks
|
||||
@@ -130,8 +127,6 @@ int main(int argc, char **argv) {
|
||||
.recplay_conf=NULL,
|
||||
//! number of samples per tti
|
||||
.samples_per_tti=0,
|
||||
//! check for threequarter sampling rate
|
||||
.threequarter_fs=0,
|
||||
};
|
||||
//-----------------------
|
||||
openair0_device rfdevice= {
|
||||
@@ -319,8 +314,13 @@ int main(int argc, char **argv) {
|
||||
rfdevice.trx_start_func(&rfdevice);
|
||||
|
||||
while(!oai_exit) {
|
||||
for (int i=0; i<antennas; i++)
|
||||
read(fd, samplesTx[i], DFT*sizeof(c16_t));
|
||||
for (int i=0; i<antennas; i++) {
|
||||
ssize_t len = read(fd, samplesTx[i], DFT*sizeof(c16_t));
|
||||
if (len < 0) {
|
||||
fprintf(stderr, "error during read(): errno %d, %s\n", errno, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
rfdevice.trx_read_func(&rfdevice, ×tamp, samplesRx, DFT, antennas);
|
||||
rfdevice.trx_write_func(&rfdevice, timestamp + TxAdvanceInDFTSize * DFT, samplesTx, DFT, antennas, 0);
|
||||
}
|
||||
|
||||
@@ -512,20 +512,20 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
|
||||
NB_IoT_DL_FRAME_PARMS frame_parms;
|
||||
PHY_MEASUREMENTS_eNB_NB_IoT measurements[NUMBER_OF_eNB_SECTORS_MAX_NB_IoT]; /// Measurement variables
|
||||
NB_IoT_eNB_COMMON common_vars;
|
||||
NB_IoT_eNB_SRS srs_vars[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
NB_IoT_eNB_SRS srs_vars[NUMBER_OF_UE_MAX];
|
||||
NB_IoT_eNB_PBCH pbch;
|
||||
NB_IoT_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
NB_IoT_eNB_PUSCH *pusch_vars[NUMBER_OF_UE_MAX];
|
||||
NB_IoT_eNB_PRACH prach_vars;
|
||||
//LTE_eNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX_NB_IoT][2]; // Nusers times two spatial streams
|
||||
NB_IoT_eNB_NULSCH_t *ulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; // Nusers + number of RA (the ulsch[0] contains RAR)
|
||||
//LTE_eNB_DLSCH_t *dlsch[NUMBER_OF_UE_MAX][2]; // Nusers times two spatial streams
|
||||
NB_IoT_eNB_NULSCH_t *ulsch[NUMBER_OF_UE_MAX+1]; // Nusers + number of RA (the ulsch[0] contains RAR)
|
||||
//LTE_eNB_DLSCH_t *dlsch_SI,*dlsch_ra;
|
||||
//LTE_eNB_DLSCH_t *dlsch_MCH;
|
||||
NB_IoT_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
//LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
NB_IoT_eNB_UE_stats UE_stats[NUMBER_OF_UE_MAX];
|
||||
//LTE_eNB_UE_stats *UE_stats_ptr[NUMBER_OF_UE_MAX];
|
||||
/// cell-specific reference symbols
|
||||
uint32_t lte_gold_table_NB_IoT[20][2][14];
|
||||
/// UE-specific reference symbols (p=5), TM 7
|
||||
uint32_t lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX_NB_IoT][20][38];
|
||||
uint32_t lte_gold_uespec_port5_table[NUMBER_OF_UE_MAX][20][38];
|
||||
/// UE-specific reference symbols (p=7...14), TM 8/9/10
|
||||
uint32_t lte_gold_uespec_table[2][20][2][21];
|
||||
/// mbsfn reference symbols
|
||||
@@ -539,7 +539,7 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
|
||||
///
|
||||
char eNB_generate_rar;
|
||||
/// Indicator set to 0 after first SR
|
||||
uint8_t first_sr[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
uint8_t first_sr[NUMBER_OF_UE_MAX];
|
||||
|
||||
uint32_t max_peak_val;
|
||||
///
|
||||
@@ -549,7 +549,7 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
|
||||
/// N0 (used for abstraction)
|
||||
double N0;
|
||||
///
|
||||
unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX];
|
||||
unsigned char first_run_I0_measurements;
|
||||
|
||||
unsigned char cooperation_flag; // for cooperative communication
|
||||
@@ -575,37 +575,37 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
|
||||
DCI_ALLOC_NB_IoT_t dci_alloc[2][NUM_DCI_MAX_NB_IoT]; // dci_alloc from even/odd subframes
|
||||
/////////////
|
||||
// PDSCH Variables
|
||||
PDSCH_CONFIG_DEDICATED_NB_IoT pdsch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
PDSCH_CONFIG_DEDICATED_NB_IoT pdsch_config_dedicated[NUMBER_OF_UE_MAX];
|
||||
// PUSCH Variables
|
||||
PUSCH_CONFIG_DEDICATED_NB_IoT pusch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
PUSCH_CONFIG_DEDICATED_NB_IoT pusch_config_dedicated[NUMBER_OF_UE_MAX];
|
||||
// PUCCH variables
|
||||
PUCCH_CONFIG_DEDICATED_NB_IoT pucch_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
PUCCH_CONFIG_DEDICATED_NB_IoT pucch_config_dedicated[NUMBER_OF_UE_MAX];
|
||||
// UL-POWER-Control
|
||||
UL_POWER_CONTROL_DEDICATED_NB_IoT ul_power_control_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
UL_POWER_CONTROL_DEDICATED_NB_IoT ul_power_control_dedicated[NUMBER_OF_UE_MAX];
|
||||
// TPC
|
||||
TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pucch[NUMBER_OF_UE_MAX];
|
||||
///
|
||||
TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
TPC_PDCCH_CONFIG_NB_IoT tpc_pdcch_config_pusch[NUMBER_OF_UE_MAX];
|
||||
// CQI reporting
|
||||
CQI_REPORT_CONFIG_NB_IoT cqi_report_config[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
CQI_REPORT_CONFIG_NB_IoT cqi_report_config[NUMBER_OF_UE_MAX];
|
||||
// SRS Variables
|
||||
SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
SOUNDINGRS_UL_CONFIG_DEDICATED_NB_IoT soundingrs_ul_config_dedicated[NUMBER_OF_UE_MAX];
|
||||
///
|
||||
uint8_t ncs_cell[20][7];
|
||||
// Scheduling Request Config
|
||||
SCHEDULING_REQUEST_CONFIG_NB_IoT scheduling_request_config[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
SCHEDULING_REQUEST_CONFIG_NB_IoT scheduling_request_config[NUMBER_OF_UE_MAX];
|
||||
// Transmission mode per UE
|
||||
uint8_t transmission_mode[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
uint8_t transmission_mode[NUMBER_OF_UE_MAX];
|
||||
/// cba_last successful reception for each group, used for collision detection
|
||||
uint8_t cba_last_reception[4];
|
||||
// Pointers for active physicalConfigDedicated to be applied in current subframe
|
||||
struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX];
|
||||
//Pointers for actve physicalConfigDedicated for NB-IoT to be applied in current subframe
|
||||
struct PhysicalConfigDedicated_NB_r13 *phy_config_dedicated_NB_IoT[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
struct PhysicalConfigDedicated_NB_r13 *phy_config_dedicated_NB_IoT[NUMBER_OF_UE_MAX];
|
||||
///
|
||||
uint32_t rb_mask_ul[4];
|
||||
/// Information regarding TM5
|
||||
MU_MIMO_mode_NB_IoT mu_mimo_mode[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
MU_MIMO_mode_NB_IoT mu_mimo_mode[NUMBER_OF_UE_MAX];
|
||||
/// target_ue_dl_mcs : only for debug purposes
|
||||
uint32_t target_ue_dl_mcs;
|
||||
/// target_ue_ul_mcs : only for debug purposes
|
||||
@@ -660,16 +660,16 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
|
||||
time_stats_t ulsch_tc_ext_stats;
|
||||
time_stats_t ulsch_tc_intl1_stats;
|
||||
time_stats_t ulsch_tc_intl2_stats;
|
||||
int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10];
|
||||
int32_t pucch1_stats[NUMBER_OF_UE_MAX_NB_IoT][10*1024];
|
||||
int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX_NB_IoT][10*1024];
|
||||
int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX_NB_IoT][10];
|
||||
int32_t pucch1ab_stats[NUMBER_OF_UE_MAX_NB_IoT][2*10*1024];
|
||||
int32_t pusch_stats_rb[NUMBER_OF_UE_MAX_NB_IoT][10240];
|
||||
int32_t pusch_stats_round[NUMBER_OF_UE_MAX_NB_IoT][10240];
|
||||
int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX_NB_IoT][10240];
|
||||
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX_NB_IoT][10240];
|
||||
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX_NB_IoT][10240];
|
||||
int32_t pucch1_stats_cnt[NUMBER_OF_UE_MAX][10];
|
||||
int32_t pucch1_stats[NUMBER_OF_UE_MAX][10*1024];
|
||||
int32_t pucch1_stats_thres[NUMBER_OF_UE_MAX][10*1024];
|
||||
int32_t pucch1ab_stats_cnt[NUMBER_OF_UE_MAX][10];
|
||||
int32_t pucch1ab_stats[NUMBER_OF_UE_MAX][2*10*1024];
|
||||
int32_t pusch_stats_rb[NUMBER_OF_UE_MAX][10240];
|
||||
int32_t pusch_stats_round[NUMBER_OF_UE_MAX][10240];
|
||||
int32_t pusch_stats_mcs[NUMBER_OF_UE_MAX][10240];
|
||||
int32_t pusch_stats_bsr[NUMBER_OF_UE_MAX][10240];
|
||||
int32_t pusch_stats_BO[NUMBER_OF_UE_MAX][10240];
|
||||
|
||||
/// RF and Interface devices per CC
|
||||
openair0_device rfdevice;
|
||||
@@ -682,7 +682,7 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
|
||||
//------------------------
|
||||
|
||||
/*
|
||||
* NUMBER_OF_UE_MAX_NB_IoT maybe in the future should be dynamic because could be very large and the memory may explode
|
||||
* NUMBER_OF_UE_MAX maybe in the future should be dynamic because could be very large and the memory may explode
|
||||
* (is almost the indication of the number of UE context that we are storing at PHY layer)
|
||||
*
|
||||
* reasoning: the following data structure (ndlsch, nulsch ecc..) are used to store the context that should be transmitted in at least n+4 subframe later
|
||||
@@ -710,11 +710,10 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
|
||||
*
|
||||
*/
|
||||
|
||||
//TODO: check what should be NUMBER_OF_UE_MAX_NB_IoT value
|
||||
NB_IoT_eNB_NPBCH_t *npbch;
|
||||
NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT][2];
|
||||
NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR
|
||||
NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX];
|
||||
NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX][2];
|
||||
NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX+1]; //nulsch[0] contains the RAR
|
||||
NB_IoT_eNB_NDLSCH_t *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1;
|
||||
|
||||
NB_IoT_DL_FRAME_PARMS frame_parms_NB_IoT;
|
||||
|
||||
@@ -499,6 +499,9 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
/// RF and Interface devices per CC
|
||||
openair0_device rfdevice;
|
||||
|
||||
/// Phase precompensation flag
|
||||
bool no_phase_pre_comp;
|
||||
|
||||
void* scopeData;
|
||||
// Pointers to hold PDSCH data only for phy simulators
|
||||
void *phy_sim_rxdataF;
|
||||
@@ -508,6 +511,7 @@ typedef struct PHY_VARS_NR_UE_s {
|
||||
void *phy_sim_pdsch_dl_ch_estimates;
|
||||
void *phy_sim_pdsch_dl_ch_estimates_ext;
|
||||
uint8_t *phy_sim_dlsch_b;
|
||||
uint8_t *phy_sim_test_buf;
|
||||
|
||||
dynamic_barrier_t process_slot_tx_barriers[NUM_PROCESS_SLOT_TX_BARRIERS];
|
||||
|
||||
|
||||
@@ -158,30 +158,30 @@ typedef struct {
|
||||
short n0_subband_power_tot_dBm[100];
|
||||
// eNB measurements (per user)
|
||||
//! estimated received spatial signal power (linear)
|
||||
unsigned int rx_spatial_power[NUMBER_OF_UE_MAX_NB_IoT][2][2];
|
||||
unsigned int rx_spatial_power[NUMBER_OF_UE_MAX][2][2];
|
||||
//! estimated received spatial signal power (dB)
|
||||
unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX_NB_IoT][2][2];
|
||||
unsigned short rx_spatial_power_dB[NUMBER_OF_UE_MAX][2][2];
|
||||
//! estimated rssi (dBm)
|
||||
short rx_rssi_dBm[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
short rx_rssi_dBm[NUMBER_OF_UE_MAX];
|
||||
//! estimated correlation (wideband linear) between spatial channels (computed in dlsch_demodulation)
|
||||
int rx_correlation[NUMBER_OF_UE_MAX_NB_IoT][2];
|
||||
int rx_correlation[NUMBER_OF_UE_MAX][2];
|
||||
//! estimated correlation (wideband dB) between spatial channels (computed in dlsch_demodulation)
|
||||
int rx_correlation_dB[NUMBER_OF_UE_MAX_NB_IoT][2];
|
||||
int rx_correlation_dB[NUMBER_OF_UE_MAX][2];
|
||||
|
||||
/// Wideband CQI (= SINR)
|
||||
int wideband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX];
|
||||
int wideband_cqi[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX];
|
||||
/// Wideband CQI in dB (= SINR dB)
|
||||
int wideband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX];
|
||||
int wideband_cqi_dB[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX];
|
||||
/// Wideband CQI (sum of all RX antennas, in dB)
|
||||
char wideband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT];
|
||||
char wideband_cqi_tot[NUMBER_OF_UE_MAX];
|
||||
/// Subband CQI per RX antenna and RB (= SINR)
|
||||
int subband_cqi[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100];
|
||||
int subband_cqi[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX][100];
|
||||
/// Total Subband CQI and RB (= SINR)
|
||||
int subband_cqi_tot[NUMBER_OF_UE_MAX_NB_IoT][100];
|
||||
int subband_cqi_tot[NUMBER_OF_UE_MAX][100];
|
||||
/// Subband CQI in dB and RB (= SINR dB)
|
||||
int subband_cqi_dB[NUMBER_OF_UE_MAX_NB_IoT][NB_ANTENNAS_RX][100];
|
||||
int subband_cqi_dB[NUMBER_OF_UE_MAX][NB_ANTENNAS_RX][100];
|
||||
/// Total Subband CQI and RB
|
||||
int subband_cqi_tot_dB[NUMBER_OF_UE_MAX_NB_IoT][100];
|
||||
int subband_cqi_tot_dB[NUMBER_OF_UE_MAX][100];
|
||||
|
||||
} PHY_MEASUREMENTS_eNB_NB_IoT;
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
FN(DLSCH_PROCEDURES_STATS),\
|
||||
FN(PHY_PROC_TX),\
|
||||
FN(PUSCH_PROC_STATS),\
|
||||
FN(UCI_ON_PUSCH_MAPPING),\
|
||||
FN(ULSCH_SEGMENTATION_STATS),\
|
||||
FN(ULSCH_LDPC_ENCODING_STATS),\
|
||||
FN(ULSCH_RATE_MATCHING_STATS),\
|
||||
|
||||
@@ -404,7 +404,8 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, n
|
||||
(c16_t **)txdataF,
|
||||
txp,
|
||||
link_type_ul,
|
||||
was_symbol_used);
|
||||
was_symbol_used,
|
||||
ue->no_phase_pre_comp);
|
||||
stop_meas_nr_ue_phy(ue, OFDM_MOD_STATS);
|
||||
}
|
||||
|
||||
@@ -1214,13 +1215,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT);
|
||||
|
||||
uint8_t nb_re_dmrs;
|
||||
if (dlsch_config->dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
|
||||
nb_re_dmrs = 6 * dlsch_config->n_dmrs_cdm_groups;
|
||||
}
|
||||
else {
|
||||
nb_re_dmrs = 4 * dlsch_config->n_dmrs_cdm_groups;
|
||||
}
|
||||
const uint8_t nb_re_dmrs = get_num_dmrs_re_per_rb(dlsch_config->dmrsConfigType, dlsch_config->n_dmrs_cdm_groups);
|
||||
uint16_t dmrs_len = get_num_dmrs(dlsch_config->dlDmrsSymbPos);
|
||||
uint32_t unav_res = 0;
|
||||
if(dlsch_config->pduBitmap & 0x1) {
|
||||
|
||||
@@ -313,7 +313,15 @@ void phy_procedures_nrUE_SL_TX(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc
|
||||
was_symbol_used[i] = true;
|
||||
if (tx_action) {
|
||||
LOG_D(NR_PHY, "Sending Uplink data \n");
|
||||
nr_ue_pusch_common_procedures(ue, proc->nr_slot_tx, fp, fp->nb_antennas_tx, txdataF, txp, link_type_sl, was_symbol_used);
|
||||
nr_ue_pusch_common_procedures(ue,
|
||||
proc->nr_slot_tx,
|
||||
fp,
|
||||
fp->nb_antennas_tx,
|
||||
txdataF,
|
||||
txp,
|
||||
link_type_sl,
|
||||
was_symbol_used,
|
||||
ue->no_phase_pre_comp);
|
||||
}
|
||||
|
||||
LOG_D(NR_PHY, "****** end Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nr_common.h"
|
||||
#include "time_meas.h"
|
||||
|
||||
#define NR_PRACH_DEBUG 1
|
||||
|
||||
@@ -513,6 +513,7 @@ int main(int argc, char **argv)
|
||||
|
||||
if (input_fd == NULL) {
|
||||
uint8_t ULSCH_ids[] = {0};
|
||||
nr_ulsch_pre_encoding(UE, ulsch_ue, 0, 0, &G, 1, ULSCH_ids);
|
||||
nr_ulsch_encoding(UE, ulsch_ue, 0, 0, &G, 1, ULSCH_ids, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,6 +160,108 @@ openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
channel_desc_t *UE2gNB[MAX_MOBILES_PER_GNB][NUMBER_OF_gNB_MAX];
|
||||
|
||||
static void copy_bytes_to_packed_bits(const uint8_t *in, const uint32_t num_bits, const bool is_ulsch, uint8_t *out)
|
||||
{
|
||||
if (is_ulsch) { // MATLAB computes CRC for input of MSB first
|
||||
for (uint_fast32_t b = 0; b < num_bits; b++) {
|
||||
out[b / 8] |= ((in[b] & 1) << (7 - (b % 8)));
|
||||
}
|
||||
} else {
|
||||
for (uint_fast32_t b = 0; b < num_bits; b++) {
|
||||
out[b / 8] |= (in[b] << (b % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void prepare_ue_pusch_pdu_from_matlab_vector(const bool uci_on_pusch,
|
||||
FILE *vect_file,
|
||||
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
|
||||
uint8_t *cw_buf)
|
||||
{
|
||||
if (!uci_on_pusch)
|
||||
return;
|
||||
|
||||
if (vect_file == NULL)
|
||||
return;
|
||||
|
||||
struct vect_vars {
|
||||
uint32_t A;
|
||||
uint32_t oack;
|
||||
uint32_t ocsi1;
|
||||
uint32_t ocsi2;
|
||||
uint32_t cwlen;
|
||||
uint32_t cwlen_scr;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct vect_vars var = {0};
|
||||
if (1 != fread(&var, sizeof(var), 1, vect_file)) {
|
||||
printf("Error reading from matlab vector file\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
const uint16_t buff_len = var.A + var.oack + var.ocsi1 + var.ocsi2;
|
||||
uint8_t vec_bits[buff_len];
|
||||
memset(vec_bits, 0, sizeof(vect_file));
|
||||
|
||||
uint8_t *p_vec_bits = vec_bits;
|
||||
if (var.A != fread(p_vec_bits, sizeof(uint8_t), var.A, vect_file)) {
|
||||
printf("Error reading ULSCH bits from file\n");
|
||||
exit(-1);
|
||||
}
|
||||
p_vec_bits += var.A;
|
||||
if (var.oack != fread(p_vec_bits, sizeof(uint8_t), var.oack, vect_file)) {
|
||||
printf("Error reading ACK bits from file\n");
|
||||
exit(-1);
|
||||
}
|
||||
p_vec_bits += var.oack;
|
||||
if (var.ocsi1 != fread(p_vec_bits, sizeof(uint8_t), var.ocsi1, vect_file)) {
|
||||
printf("Error reading CSI1 bits from file\n");
|
||||
exit(-1);
|
||||
}
|
||||
p_vec_bits += var.ocsi1;
|
||||
if (var.ocsi2 != fread(p_vec_bits, sizeof(uint8_t), var.ocsi2, vect_file)) {
|
||||
printf("Error reading CSI2 bits from file\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (var.cwlen != fread(cw_buf, sizeof(uint8_t), var.cwlen, vect_file)) {
|
||||
printf("Error reading cw bits from file\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
memset(cw_buf, 0, var.cwlen_scr);
|
||||
if (var.cwlen_scr != fread(cw_buf, sizeof(uint8_t), var.cwlen_scr, vect_file)) {
|
||||
printf("Error reading cw bits from file\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
uint16_t tb_buf_size = (var.A + 7) / 8;
|
||||
pusch_config_pdu->pusch_data.tb_size = tb_buf_size;
|
||||
pusch_config_pdu->tx_request_body.pdu_length = tb_buf_size;
|
||||
uint8_t *pb = pusch_config_pdu->tx_request_body.fapiTxPdu;
|
||||
memset(pb, 0, tb_buf_size);
|
||||
p_vec_bits = vec_bits;
|
||||
copy_bytes_to_packed_bits(p_vec_bits, var.A, true, pb);
|
||||
|
||||
pusch_config_pdu->pusch_uci.harq_ack_bit_length = var.oack;
|
||||
pb = (uint8_t *)&pusch_config_pdu->pusch_uci.harq_payload;
|
||||
memset(pb, 0, sizeof(pusch_config_pdu->pusch_uci.harq_payload));
|
||||
p_vec_bits += var.A;
|
||||
copy_bytes_to_packed_bits(p_vec_bits, var.oack, false, pb);
|
||||
|
||||
pusch_config_pdu->pusch_uci.csi_part1_bit_length = var.ocsi1;
|
||||
pb = (uint8_t *)&pusch_config_pdu->pusch_uci.csi_part1_payload;
|
||||
memset(pb, 0, sizeof(pusch_config_pdu->pusch_uci.csi_part1_payload));
|
||||
p_vec_bits += var.oack;
|
||||
copy_bytes_to_packed_bits(p_vec_bits, var.ocsi1, false, pb);
|
||||
|
||||
pusch_config_pdu->pusch_uci.csi_part2_bit_length = var.ocsi2;
|
||||
pb = (uint8_t *)&pusch_config_pdu->pusch_uci.csi_part2_payload;
|
||||
memset(pb, 0, sizeof(pusch_config_pdu->pusch_uci.csi_part2_payload));
|
||||
p_vec_bits += var.ocsi1;
|
||||
copy_bytes_to_packed_bits(p_vec_bits, var.ocsi2, false, pb);
|
||||
}
|
||||
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@@ -204,6 +306,8 @@ int main(int argc, char *argv[])
|
||||
int print_perf = 0;
|
||||
cpuf = get_cpu_freq_GHz();
|
||||
int msg3_flag = 0;
|
||||
bool uci_on_pusch = false;
|
||||
bool no_phase_pre_comp = false;
|
||||
int rv_index = 0;
|
||||
float roundStats;
|
||||
double effRate;
|
||||
@@ -227,6 +331,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
UE_nr_rxtx_proc_t UE_proc;
|
||||
FILE *scg_fd=NULL;
|
||||
FILE *uci_ulsch_matlab_vec = NULL;
|
||||
int file_offset = 0;
|
||||
|
||||
double DS_TDL = .03;
|
||||
@@ -252,7 +357,8 @@ int main(int argc, char *argv[])
|
||||
int c;
|
||||
bool setAffinity=false;
|
||||
char gNBthreads[128]="n";
|
||||
while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:jk:m:n:p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:Y:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "--:O:a:b:c:d:ef:g:h:i:jk:m:n:o::p:q:r:s:t:u:v:w:y:z:A:C:F:G:H:I:M:N:PR:S:T:U:L:ZW:E:X:Y:"))
|
||||
!= -1) {
|
||||
/* ignore long options starting with '--', option '-O' and their arguments that are handled by configmodule */
|
||||
/* with this opstring getopt returns 1 for non-option arguments, refer to 'man 3 getopt' */
|
||||
if (c == 1 || c == '-' || c == 'O')
|
||||
@@ -360,6 +466,20 @@ int main(int argc, char *argv[])
|
||||
Imcs = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
uci_on_pusch = true;
|
||||
// UCI on PUSCH is not implemented in OAI gNB yet.
|
||||
// So this flag is needed to verify in MATLAB
|
||||
no_phase_pre_comp = true;
|
||||
if (optarg) { // -o with file input: use matlab vector
|
||||
uci_ulsch_matlab_vec = fopen(optarg, "rb");
|
||||
if (uci_ulsch_matlab_vec == NULL) {
|
||||
printf("Error opening %s\n", optarg);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
precod_nbr_layers = atoi(optarg);
|
||||
break;
|
||||
@@ -539,6 +659,7 @@ int main(int argc, char *argv[])
|
||||
printf("-k 3/4 sampling\n");
|
||||
printf("-m MCS value\n");
|
||||
printf("-n Number of trials to simulate\n");
|
||||
printf("-o Enable UCI on PUSCH. Optionally accepts input file (without space). This feature is not yet available in gNB so only used to verify with MATLAB generated vector\n");
|
||||
printf("-p Use extended prefix mode\n");
|
||||
printf("-q MCS table\n");
|
||||
printf("-r Number of allocated resource blocks for PUSCH\n");
|
||||
@@ -786,7 +907,8 @@ int main(int argc, char *argv[])
|
||||
UE->if_inst->phy_config_request = nr_ue_phy_config_request;
|
||||
UE->if_inst->dl_indication = nr_ue_dl_indication;
|
||||
UE->if_inst->ul_indication = nr_ue_ul_indication;
|
||||
|
||||
UE->no_phase_pre_comp = no_phase_pre_comp;
|
||||
|
||||
UE_mac->if_module = nr_ue_if_module_init(0);
|
||||
|
||||
initFloatingCoresTpool(threadCnt, &nrUE_params.Tpool, false, "UE-tpool");
|
||||
@@ -924,6 +1046,9 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
unsigned int available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, number_dmrs_symbols, unav_res, mod_order, precod_nbr_layers);
|
||||
uint8_t cw_buf[available_bits];
|
||||
memset(cw_buf, 0, available_bits);
|
||||
UE->phy_sim_test_buf = calloc(1, (available_bits + 7) / 8);
|
||||
printf("[ULSIM]: VALUE OF G: %u, TBS: %u\n", available_bits, TBS);
|
||||
|
||||
int frame_length_complex_samples = gNB->frame_parms.samples_per_subframe * NR_NUMBER_OF_SUBFRAMES_PER_FRAME;
|
||||
@@ -1222,6 +1347,20 @@ int main(int argc, char *argv[])
|
||||
// pusch_config_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_DFTS_OFDM;
|
||||
pusch_config_pdu->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data;
|
||||
}
|
||||
if (uci_on_pusch) {
|
||||
const nfapi_nr_ue_pusch_uci_t pusch_uci = {
|
||||
.alpha_scaling = 3,
|
||||
.beta_offset_csi1 = 13,
|
||||
.beta_offset_csi2 = 13,
|
||||
.beta_offset_harq_ack = 11,
|
||||
.harq_ack_bit_length = 3,
|
||||
.harq_payload = 3,
|
||||
//.csi_part1_bit_length = 4,
|
||||
//.csi_part1_payload = 15
|
||||
};
|
||||
pusch_config_pdu->pusch_uci = pusch_uci;
|
||||
prepare_ue_pusch_pdu_from_matlab_vector(uci_on_pusch, uci_ulsch_matlab_vec, pusch_config_pdu, cw_buf);
|
||||
}
|
||||
|
||||
if (do_SRS == 1) {
|
||||
fapi_nr_ul_config_request_pdu_t *ul_config1 = &ul_config.ul_config_list[1];
|
||||
@@ -1457,7 +1596,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if ((ulsch_gNB->last_iteration_cnt >= ulsch_gNB->max_ldpc_iterations) || ul_proc_error == 1) {
|
||||
error_flag = 1;
|
||||
error_flag = uci_on_pusch ? 0 : 1;
|
||||
n_errors[round]++;
|
||||
crc_status = 1;
|
||||
} else
|
||||
@@ -1474,15 +1613,29 @@ int main(int argc, char *argv[])
|
||||
available_bits, (ptrsSymbPerSlot * ptrsRePerSymb * mod_order * precod_nbr_layers));
|
||||
}
|
||||
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
const uint8_t current_bit = (UE->ul_harq_processes[harq_pid].f[i / 8] >> (i & 7)) & 1;
|
||||
if (((current_bit == 0) && (pusch_vars->llr[i] <= 0)) || ((current_bit == 1) && (pusch_vars->llr[i] >= 0))) {
|
||||
/*if(errors_scrambling == 0)
|
||||
printf("\x1B[34m" "[frame %d][trial %d]\t1st bit in error in unscrambling = %d\n" "\x1B[0m", frame, trial, i);*/
|
||||
errors_scrambling[round]++;
|
||||
if (uci_on_pusch) {
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
const uint8_t current_bit = (UE->phy_sim_test_buf[i / 8] >> (i & 7)) & 1;
|
||||
const uint8_t test_vector_bit = cw_buf[i] & 1;
|
||||
if (current_bit != test_vector_bit)
|
||||
errors_scrambling[round]++;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < available_bits; i++) {
|
||||
const uint8_t current_bit = (UE->ul_harq_processes[harq_pid].f[i / 8] >> (i & 7)) & 1;
|
||||
if (((current_bit == 0) && (pusch_vars->llr[i] <= 0)) || ((current_bit == 1) && (pusch_vars->llr[i] >= 0))) {
|
||||
errors_scrambling[round]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
round++;
|
||||
if (uci_on_pusch && uci_ulsch_matlab_vec && (errors_scrambling[round] == 0)) {
|
||||
ret = 0;
|
||||
printf("*************\n");
|
||||
printf("UCI on PUSCH test OK against MATLAB generated codeword\n");
|
||||
printf("*************\n");
|
||||
break;
|
||||
}
|
||||
} // round
|
||||
|
||||
if (n_trials == 1 && errors_scrambling[0] > 0) {
|
||||
@@ -1655,5 +1808,10 @@ int main(int argc, char *argv[])
|
||||
free(filename_csv);
|
||||
}
|
||||
|
||||
if (uci_ulsch_matlab_vec)
|
||||
fclose(uci_ulsch_matlab_vec);
|
||||
|
||||
free_and_zero(UE->phy_sim_test_buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
% ULSIM command line
|
||||
% ./nr_ulsim -m 27 -u 1 -R 51 -r 51 -s 300 -L 4 -o
|
||||
|
||||
carrier = nrCarrierConfig;
|
||||
carrier.NSizeGrid = 51;
|
||||
carrier.NSlot = 8;
|
||||
carrier.SubcarrierSpacing = 30;
|
||||
carrier.CyclicPrefix = "normal";
|
||||
|
||||
pusch = nrPUSCHConfig;
|
||||
pusch.PRBSet = 0:carrier.NSizeGrid-1;
|
||||
pusch.SymbolAllocation = [0,12];
|
||||
pusch.MappingType = "B";
|
||||
pusch.NID = 0;
|
||||
pusch.RNTI = 4660;
|
||||
pusch.NumLayers = 1;
|
||||
pusch.TransformPrecoding = false;
|
||||
pusch.TransmissionScheme = "nonCodebook";
|
||||
pusch.NumAntennaPorts = 1;
|
||||
pusch.TPMI = 0;
|
||||
pusch.Modulation = "64QAM";
|
||||
|
||||
pusch.DMRS.DMRSConfigurationType = 1;
|
||||
pusch.DMRS.DMRSTypeAPosition = 2;
|
||||
pusch.DMRS.NumCDMGroupsWithoutData = 1;
|
||||
pusch.DMRS.DMRSAdditionalPosition = 0;
|
||||
pusch.DMRS.NIDNSCID = 0;
|
||||
pusch.DMRS.NRSID = 0;
|
||||
pusch.DMRS.NSCID = 0;
|
||||
pusch.DMRS.GroupHopping = 0;
|
||||
pusch.DMRS.SequenceHopping = 0;
|
||||
|
||||
pusch.BetaOffsetACK = 20;
|
||||
pusch.BetaOffsetCSI1 = 6.25;
|
||||
pusch.BetaOffsetCSI2 = 1;
|
||||
pusch.UCIScaling = 1;
|
||||
|
||||
[puschIndices,puschIndicesInfo] = nrPUSCHIndices(carrier,pusch);
|
||||
|
||||
dmrsLayerSymbols = nrPUSCHDMRS(carrier,pusch);
|
||||
dmrsLayerIndices = nrPUSCHDMRSIndices(carrier,pusch);
|
||||
|
||||
run("../../../cmake_targets/ran_build/build/txsig0.m");
|
||||
rxGrid = nrOFDMDemodulate(carrier,txs0);
|
||||
[estChannelGrid,noiseEst] = nrChannelEstimate(carrier,rxGrid,dmrsLayerIndices,dmrsLayerSymbols);
|
||||
[puschRx,puschHest] = nrExtractResources(puschIndices,rxGrid,estChannelGrid);
|
||||
[puschEq,csi] = nrEqualizeMMSE(puschRx,puschHest,noiseEst);
|
||||
|
||||
decodeULSCH = nrULSCHDecoder;
|
||||
decodeULSCH.MultipleHARQProcesses = false;
|
||||
decodeULSCH.CBGTransmission = false;
|
||||
decodeULSCH.TargetCodeRate = 910 / 1024;
|
||||
decodeULSCH.LDPCDecodingAlgorithm = 'Normalized min-sum';
|
||||
decodeULSCH.MaximumLDPCIterationCount = 6;
|
||||
decodeULSCH.TransportBlockLength = 37896;
|
||||
|
||||
oack = 3;
|
||||
ocsi1 = 0;
|
||||
ocsi2 = 0;
|
||||
[ulschLLRs,rxSymbols] = nrPUSCHDecode(carrier,pusch,decodeULSCH.TargetCodeRate,...
|
||||
decodeULSCH.TransportBlockLength,oack,ocsi1,ocsi2,puschEq,noiseEst);
|
||||
rmInfo = nrULSCHInfo(pusch,decodeULSCH.TargetCodeRate,...
|
||||
decodeULSCH.TransportBlockLength,oack,ocsi1,ocsi2);
|
||||
[culsch,cack,ccsi1,ccsi2] = nrULSCHDemultiplex(pusch,decodeULSCH.TargetCodeRate,...
|
||||
decodeULSCH.TransportBlockLength,oack,ocsi1,ocsi2,ulschLLRs);
|
||||
|
||||
plot(rxSymbols,'*');
|
||||
|
||||
decodeULSCH.reset();
|
||||
rv = 0; % Redundancy version for decoding
|
||||
[decodedBits,blkerr] = decodeULSCH(culsch,pusch.Modulation,pusch.NumLayers,rv);
|
||||
% Display the decoded bits
|
||||
disp('Block error:');
|
||||
disp(blkerr);
|
||||
|
||||
ucibits = nrUCIDecode(cack,oack);
|
||||
% Display the decoded UCI bits
|
||||
disp('Decoded UCI bits:');
|
||||
disp(ucibits);
|
||||
@@ -0,0 +1,85 @@
|
||||
% ulsim command for same pusch config
|
||||
% ./nr_ulsim -m 27 -u 1 -R 51 -r 51 -s 300 -o uci_on_pusch_7.bin
|
||||
|
||||
carrier = nrCarrierConfig;
|
||||
carrier.NSizeGrid = 51;
|
||||
carrier.NSlot = 8;
|
||||
carrier.SubcarrierSpacing = 30;
|
||||
carrier.CyclicPrefix = "normal";
|
||||
|
||||
pusch = nrPUSCHConfig;
|
||||
pusch.PRBSet = 0:carrier.NSizeGrid-1;
|
||||
pusch.SymbolAllocation = [0,12];
|
||||
pusch.MappingType = "B";
|
||||
pusch.NID = 0;
|
||||
pusch.RNTI = 4660;
|
||||
pusch.NumLayers = 1;
|
||||
pusch.TransformPrecoding = false;
|
||||
pusch.TransmissionScheme = "nonCodebook";
|
||||
pusch.NumAntennaPorts = 1;
|
||||
pusch.TPMI = 0;
|
||||
pusch.Modulation = "64QAM";
|
||||
|
||||
pusch.DMRS.DMRSConfigurationType = 1;
|
||||
pusch.DMRS.DMRSTypeAPosition = 2;
|
||||
pusch.DMRS.NumCDMGroupsWithoutData = 1;
|
||||
pusch.DMRS.DMRSAdditionalPosition = 0;
|
||||
pusch.DMRS.NIDNSCID = 0;
|
||||
pusch.DMRS.NRSID = 0;
|
||||
pusch.DMRS.NSCID = 0;
|
||||
pusch.DMRS.GroupHopping = 0;
|
||||
pusch.DMRS.SequenceHopping = 0;
|
||||
|
||||
pusch.BetaOffsetACK = 20;
|
||||
pusch.BetaOffsetCSI1 = 6.25;
|
||||
pusch.BetaOffsetCSI2 = 1;
|
||||
pusch.UCIScaling = 1;
|
||||
|
||||
A = 37896;
|
||||
rate = 910 / 1024;
|
||||
rv = 0;
|
||||
modulation = pusch.Modulation;
|
||||
nlayers = pusch.NumLayers; % Number of layers for decoding
|
||||
|
||||
oack = 7;
|
||||
ocsi1 = 0;
|
||||
ocsi2 = 0;
|
||||
cbsInfo = nrULSCHInfo(pusch, rate, A, oack, ocsi1, ocsi2); % Get ULSCH information
|
||||
|
||||
ack = randi([0 1],oack,1);
|
||||
csi1 = randi([0 1],ocsi1,1);
|
||||
csi2 = randi([0 1],ocsi2,1);
|
||||
cack = nrUCIEncode(ack,cbsInfo.GACK,pusch.Modulation);
|
||||
ccsi1 = [];
|
||||
ccsi2 = [];
|
||||
|
||||
tb_data = randi([0 1],A,1);
|
||||
% Transport block CRC attachment
|
||||
tbIn = nrCRCEncode(tb_data,cbsInfo.CRC);
|
||||
|
||||
% Code block segmentation and CRC attachment
|
||||
cbsIn = nrCodeBlockSegmentLDPC(tbIn,cbsInfo.BGN);
|
||||
|
||||
% LDPC encoding
|
||||
enc = nrLDPCEncode(cbsIn,cbsInfo.BGN);
|
||||
|
||||
% Rate matching and code block concatenation
|
||||
chIn = nrRateMatchLDPC(enc,cbsInfo.GULSCH,rv,modulation,nlayers);
|
||||
culsch = chIn;
|
||||
|
||||
|
||||
% Get the codeword and locations of each type (data and UCI)
|
||||
[cw,indInfo] = nrULSCHMultiplex(pusch,rate,A,culsch,cack,ccsi1,ccsi2);
|
||||
cw_scr = nrPUSCHScramble(cw,pusch.NID,pusch.RNTI);
|
||||
|
||||
% Write to bin file
|
||||
fid = fopen('uci_on_pusch_7.bin', 'wb');
|
||||
to_write = [A,oack,ocsi1,ocsi2,length(cw),length(cw_scr)];
|
||||
fwrite(fid, to_write, 'uint32'); % Write the data to the binary file
|
||||
fwrite(fid, tb_data, "uint8");
|
||||
fwrite(fid, ack, "uint8");
|
||||
fwrite(fid, csi1, "uint8");
|
||||
fwrite(fid, csi2, "uint8");
|
||||
fwrite(fid, cw, "uint8");
|
||||
fwrite(fid, cw_scr, "uint8");
|
||||
fclose(fid); % Close the file after writing
|
||||
@@ -398,7 +398,6 @@ static bool eq_pdcp_info(const e1_pdcp_status_info_t *a, const e1_pdcp_status_in
|
||||
*/
|
||||
static bool eq_drb_to_setup(const DRB_nGRAN_to_setup_t *a, const DRB_nGRAN_to_setup_t *b)
|
||||
{
|
||||
bool result = true;
|
||||
_E1_EQ_CHECK_LONG(a->id, b->id);
|
||||
_E1_EQ_CHECK_INT(a->numCellGroups, b->numCellGroups);
|
||||
for (int i = 0; i < a->numCellGroups; i++) {
|
||||
@@ -406,11 +405,14 @@ static bool eq_drb_to_setup(const DRB_nGRAN_to_setup_t *a, const DRB_nGRAN_to_se
|
||||
}
|
||||
_E1_EQ_CHECK_INT(a->numQosFlow2Setup, b->numQosFlow2Setup);
|
||||
for (int i = 0; i < a->numQosFlow2Setup; i++) {
|
||||
result &= eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]);
|
||||
if (!eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]))
|
||||
return false;
|
||||
}
|
||||
result &= eq_pdcp_config(&a->pdcp_config, &b->pdcp_config);
|
||||
result &= eq_sdap_config(&a->sdap_config, &b->sdap_config);
|
||||
return result;
|
||||
if (!eq_pdcp_config(&a->pdcp_config, &b->pdcp_config))
|
||||
return false;
|
||||
if (!eq_sdap_config(&a->sdap_config, &b->sdap_config))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void free_drb_to_setup_item(const DRB_nGRAN_to_setup_t *msg)
|
||||
@@ -1939,32 +1941,42 @@ static bool eq_security_ind(security_indication_t *a, security_indication_t *b)
|
||||
*/
|
||||
static bool eq_drb_to_mod(const DRB_nGRAN_to_mod_t *a, const DRB_nGRAN_to_mod_t *b)
|
||||
{
|
||||
bool result = true;
|
||||
_E1_EQ_CHECK_LONG(a->id, b->id);
|
||||
_E1_EQ_CHECK_INT(a->numQosFlow2Setup, b->numQosFlow2Setup);
|
||||
for (int i = 0; i < a->numQosFlow2Setup; i++) {
|
||||
result &= eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]);
|
||||
if (!eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]))
|
||||
return false;
|
||||
}
|
||||
_E1_EQ_CHECK_INT(a->numDlUpParam, b->numDlUpParam);
|
||||
for (int i = 0; i < a->numDlUpParam; i++) {
|
||||
_E1_EQ_CHECK_INT(a->DlUpParamList[i].cell_group_id, b->DlUpParamList[i].cell_group_id);
|
||||
result &= eq_up_tl_info(&a->DlUpParamList[i].tl_info, &b->DlUpParamList[i].tl_info);
|
||||
if (!eq_up_tl_info(&a->DlUpParamList[i].tl_info, &b->DlUpParamList[i].tl_info))
|
||||
return false;
|
||||
}
|
||||
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, pdcp_config);
|
||||
if (a->pdcp_config && b->pdcp_config) {
|
||||
if (!eq_pdcp_config(a->pdcp_config, b->pdcp_config))
|
||||
return false;
|
||||
}
|
||||
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, sdap_config);
|
||||
if (a->sdap_config && b->sdap_config) {
|
||||
if (!eq_sdap_config(a->sdap_config, b->sdap_config))
|
||||
return false;
|
||||
}
|
||||
if (a->pdcp_config && b->pdcp_config)
|
||||
result &= eq_pdcp_config(a->pdcp_config, b->pdcp_config);
|
||||
if (a->sdap_config && b->sdap_config)
|
||||
result &= eq_sdap_config(a->sdap_config, b->sdap_config);
|
||||
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, pdcp_status);
|
||||
if (a->pdcp_status && b->pdcp_status)
|
||||
result &= eq_pdcp_info(a->pdcp_status, b->pdcp_status);
|
||||
return result;
|
||||
if (a->pdcp_status && b->pdcp_status) {
|
||||
if (!eq_pdcp_info(a->pdcp_status, b->pdcp_status))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @brief Equality check for PDU session item to modify */
|
||||
static bool eq_pdu_session_to_mod_item(const pdu_session_to_mod_t *a, const pdu_session_to_mod_t *b)
|
||||
{
|
||||
_E1_EQ_CHECK_LONG(a->sessionId, b->sessionId);
|
||||
if (a->UP_TL_information && a->UP_TL_information) {
|
||||
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, UP_TL_information);
|
||||
if (a->UP_TL_information && b->UP_TL_information) {
|
||||
if (!eq_up_tl_info(a->UP_TL_information, b->UP_TL_information))
|
||||
return false;
|
||||
}
|
||||
@@ -1978,8 +1990,10 @@ static bool eq_pdu_session_to_mod_item(const pdu_session_to_mod_t *a, const pdu_
|
||||
if (!eq_drb_to_mod(&a->DRBnGRanModList[i], &b->DRBnGRanModList[i]))
|
||||
return false;
|
||||
}
|
||||
_E1_EQ_CHECK_OPTIONAL_PTR(a, b, securityIndication);
|
||||
if (a->securityIndication && b->securityIndication) {
|
||||
eq_security_ind(a->securityIndication, b->securityIndication);
|
||||
if (!eq_security_ind(a->securityIndication, b->securityIndication))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2423,8 +2437,6 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
|
||||
{
|
||||
if (!a || !b) return false; // Null-check both inputs
|
||||
|
||||
bool result = true;
|
||||
|
||||
// Basic members
|
||||
_E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
|
||||
_E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
|
||||
@@ -2440,8 +2452,10 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
|
||||
_E1_EQ_CHECK_OPTIONAL_IE(pduA, pduB, integrityProtectionIndication, _E1_EQ_CHECK_INT);
|
||||
|
||||
_E1_EQ_CHECK_OPTIONAL_PTR(pduA, pduB, ng_DL_UP_TL_info);
|
||||
if (pduA->ng_DL_UP_TL_info && pduB->ng_DL_UP_TL_info)
|
||||
result &= eq_up_tl_info(pduA->ng_DL_UP_TL_info, pduB->ng_DL_UP_TL_info);
|
||||
if (pduA->ng_DL_UP_TL_info && pduB->ng_DL_UP_TL_info) {
|
||||
if (!eq_up_tl_info(pduA->ng_DL_UP_TL_info, pduB->ng_DL_UP_TL_info))
|
||||
return false;
|
||||
}
|
||||
|
||||
// DRB Modified List
|
||||
_E1_EQ_CHECK_INT(pduA->numDRBModified, pduB->numDRBModified);
|
||||
@@ -2455,7 +2469,8 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
|
||||
}
|
||||
_E1_EQ_CHECK_OPTIONAL_PTR(drbModA, drbModB, pdcp_status);
|
||||
if (drbModA->pdcp_status && drbModB->pdcp_status) {
|
||||
result &= eq_pdcp_info(drbModA->pdcp_status, drbModA->pdcp_status);
|
||||
if (!eq_pdcp_info(drbModA->pdcp_status, drbModB->pdcp_status))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2490,7 +2505,7 @@ bool eq_bearer_context_mod_response(const e1ap_bearer_modif_resp_t *a, const e1a
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -129,4 +129,4 @@ add_subdirectory(flexric/src/util)
|
||||
add_subdirectory(RAN_FUNCTION)
|
||||
|
||||
add_library(e2_agent_arg STATIC e2_agent_arg.c)
|
||||
add_dependencies(e2_agent_arg generate_T)
|
||||
target_link_libraries(e2_agent_arg PRIVATE CONFIG_LIB log_headers)
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
nbiot_config.c
|
||||
-------------------
|
||||
AUTHOR : Francois Taburet
|
||||
COMPANY : NOKIA
|
||||
EMAIL : francois.taburet@nokia-bell-labs.com
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "sctp_eNB_task.h"
|
||||
#include "SystemInformationBlockType2.h"
|
||||
|
||||
#include "PHY/phy_extern.h"
|
||||
#include "radio/ETHERNET/ethernet_lib.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
#include "RRC_config_tools.h"
|
||||
#include "RRC_paramsvalues.h"
|
||||
#include "NB_IoT_paramdef.h"
|
||||
#include "L1_paramdef.h"
|
||||
#include "MACRLC_paramdef.h"
|
||||
#include "LAYER2/MAC/proto_NB_IoT.h"
|
||||
|
||||
|
||||
void RCconfig_NbIoTL1(void) {
|
||||
paramdef_t NbIoT_L1_Params[] = L1PARAMS_DESC;
|
||||
paramlist_def_t NbIoT_L1_ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0};
|
||||
/* No component carrier for NbIoT, ignore number of CC */
|
||||
// NbIoT_L1_Params[L1_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD;
|
||||
config_getlist(&NbIoT_L1_ParamList, NbIoT_L1_Params, sizeofArray(NbIoT_L1_Params), NULL);
|
||||
|
||||
if (NbIoT_L1_ParamList.numelt > 0) {
|
||||
if (RC.L1_NB_IoT == NULL) {
|
||||
RC.L1_NB_IoT = (PHY_VARS_eNB_NB_IoT **)malloc(RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *));
|
||||
LOG_I(PHY,"RC.L1_NB_IoT = %p\n",RC.L1_NB_IoT);
|
||||
memset(RC.L1_NB_IoT,0,RC.nb_nb_iot_L1_inst*sizeof(PHY_VARS_eNB_NB_IoT *));
|
||||
}
|
||||
|
||||
for(int j = 0; j <NbIoT_L1_ParamList.numelt ; j++) {
|
||||
if (RC.L1_NB_IoT[j] == NULL) {
|
||||
RC.L1_NB_IoT[j] = (PHY_VARS_eNB_NB_IoT *)malloc(sizeof(PHY_VARS_eNB_NB_IoT));
|
||||
LOG_I(PHY,"RC.L1_NB_IoT[%d] = %p\n",j,RC.L1_NB_IoT[j]);
|
||||
memset(RC.L1_NB_IoT[j],0,sizeof(PHY_VARS_eNB_NB_IoT));
|
||||
}
|
||||
|
||||
if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
|
||||
} else if (strcmp(*(NbIoT_L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) {
|
||||
RC.L1_NB_IoT[j]->eth_params_n.local_if_name = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr));
|
||||
RC.L1_NB_IoT[j]->eth_params_n.my_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr));
|
||||
RC.L1_NB_IoT[j]->eth_params_n.remote_addr = strdup(*(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr));
|
||||
RC.L1_NB_IoT[j]->eth_params_n.my_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr);
|
||||
RC.L1_NB_IoT[j]->eth_params_n.remote_portc = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr);
|
||||
RC.L1_NB_IoT[j]->eth_params_n.my_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr);
|
||||
RC.L1_NB_IoT[j]->eth_params_n.remote_portd = *(NbIoT_L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr);
|
||||
RC.L1_NB_IoT[j]->eth_params_n.transp_preference = ETH_UDP_MODE;
|
||||
} else { // other midhaul
|
||||
}
|
||||
}// j=0..num_inst
|
||||
|
||||
printf("Initializing northbound interface for NB-IoT L1\n");
|
||||
l1_north_init_NB_IoT();
|
||||
} else {
|
||||
LOG_I(PHY,"No " NBIOT_L1LIST_CONFIG_STRING " configuration found");
|
||||
}
|
||||
}
|
||||
|
||||
void RCconfig_NbIoTmacrlc(void) {
|
||||
paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC;
|
||||
paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0};
|
||||
/* No component carrier for NbIoT, ignore number of CC */
|
||||
// NbIoT_MacRLC_Params[MACRLC_CC_IDX ].paramflags = PARAMFLAG_DONOTREAD;
|
||||
config_getlist(&NbIoT_MacRLC_ParamList, NbIoT_MacRLC_Params, sizeofArray(NbIoT_MacRLC_Params), NULL);
|
||||
|
||||
if ( NbIoT_MacRLC_ParamList.numelt > 0) {
|
||||
mac_top_init_eNB_NB_IoT();
|
||||
|
||||
for (int j=0; j<RC.nb_nb_iot_macrlc_inst; j++) {
|
||||
if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
|
||||
// check number of instances is same as RRC/PDCP
|
||||
} else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) {
|
||||
RC.nb_iot_mac[j]->eth_params_n.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
|
||||
RC.nb_iot_mac[j]->eth_params_n.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
|
||||
RC.nb_iot_mac[j]->eth_params_n.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
|
||||
RC.nb_iot_mac[j]->eth_params_n.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr);
|
||||
RC.nb_iot_mac[j]->eth_params_n.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
|
||||
RC.nb_iot_mac[j]->eth_params_n.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
|
||||
RC.nb_iot_mac[j]->eth_params_n.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);;
|
||||
RC.nb_iot_mac[j]->eth_params_n.transp_preference = ETH_UDP_MODE;
|
||||
} else { // other midhaul
|
||||
AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr));
|
||||
}
|
||||
|
||||
if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) {
|
||||
} else if (strcmp(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) {
|
||||
RC.nb_iot_mac[j]->eth_params_s.local_if_name = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr));
|
||||
RC.nb_iot_mac[j]->eth_params_s.my_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr));
|
||||
RC.nb_iot_mac[j]->eth_params_s.remote_addr = strdup(*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr));
|
||||
RC.nb_iot_mac[j]->eth_params_s.my_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr);
|
||||
RC.nb_iot_mac[j]->eth_params_s.remote_portc = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr);
|
||||
RC.nb_iot_mac[j]->eth_params_s.my_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr);
|
||||
RC.nb_iot_mac[j]->eth_params_s.remote_portd = *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr);
|
||||
RC.nb_iot_mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE;
|
||||
} else { // other midhaul
|
||||
AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
|
||||
}
|
||||
}// j=0..num_inst */
|
||||
} else {// MacRLC_ParamList.numelt > 0
|
||||
AssertFatal (0,
|
||||
"No " NBIOT_MACRLCLIST_CONFIG_STRING " configuration found");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc) {
|
||||
char instprefix[MAX_OPTNAME_SIZE*3 + 32];
|
||||
checkedparam_t NBIoTCheckParams[] = NBIOT_RRCPARAMS_CHECK_DESC_0_14;
|
||||
checkedparam_t NBIoTCheckParamsB[] = NBIOT_RRCPARAMS_CHECK_DESC_15_end;
|
||||
paramdef_t NBIoTParams[] = NBIOTRRCPARAMS_DESC;
|
||||
paramdef_t NBIoTPrachParams[] = NBIOTRRC_NPRACH_PARAMS_DESC;
|
||||
checkedparam_t NBIoTPrachCheckParams[] = NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC;
|
||||
paramdef_t NBIoTRRCRefParams[] = NBIOTRRCPARAMS_RRCREF_DESC;
|
||||
paramdef_t NBIoTLteCCParams[] = NBIOT_LTECCPARAMS_DESC;
|
||||
checkedparam_t NBIoTLteCCCheckParams[] = NBIOT_LTECCPARAMS_CHECK_DESC;
|
||||
|
||||
/* map parameter checking array instances to parameter definition array instances */
|
||||
for (int i = 0; i < sizeofArray(NBIoTParams) && i < sizeofArray(NBIoTCheckParams); i++) {
|
||||
NBIoTParams[i].chkPptr = &(NBIoTCheckParams[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeofArray(NBIoTParams) && i < sizeofArray(NBIoTCheckParamsB); i++) {
|
||||
NBIoTParams[i + 15].chkPptr = &(NBIoTCheckParamsB[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeofArray(NBIoTPrachParams) && i < sizeofArray(NBIoTPrachCheckParams); i++) {
|
||||
NBIoTPrachParams[i].chkPptr = &(NBIoTPrachCheckParams[i]);
|
||||
}
|
||||
|
||||
/* brut force itti message fields assignment, to be redesigned with itti replacement */
|
||||
NBIoTParams[NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_raResponseWindowSize_NB);
|
||||
NBIoTParams[NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_macContentionResolutionTimer_NB);
|
||||
NBIoTParams[NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_powerRampingStep_NB);
|
||||
NBIoTParams[NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleInitialReceivedTargetPower_NB);
|
||||
NBIoTParams[NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax_CE_NB);
|
||||
NBIoTParams[NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff_NB);
|
||||
NBIoTParams[NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle_NB);
|
||||
NBIoTParams[NBIOT_NPRACH_CP_LENGTH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_CP_Length);
|
||||
NBIoTParams[NBIOT_NPRACH_RSRP_RANGE_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_rsrp_range);
|
||||
NBIoTParams[NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).maxNumPreambleAttemptCE_NB);
|
||||
NBIoTParams[NBIOT_NPDSCH_NRS_POWER_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdsch_nrs_Power);
|
||||
NBIoTParams[NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_ack_nack_numRepetitions_NB);
|
||||
NBIoTParams[NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p). npusch_srs_SubframeConfig_NB);
|
||||
NBIoTParams[NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_threeTone_CyclicShift_r13);
|
||||
NBIoTParams[NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_sixTone_CyclicShift_r13);
|
||||
NBIoTParams[NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupAssignmentNPUSCH_r13);
|
||||
NBIoTParams[NBIOT_DL_GAPTHRESHOLD_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapThreshold_NB);
|
||||
NBIoTParams[NBIOT_DL_GAPPERIODICITY_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapPeriodicity_NB);
|
||||
NBIoTParams[NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_p0_NominalNPUSCH);
|
||||
NBIoTParams[NBIOT_DELTAPREAMBLEMSG3_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).deltaPreambleMsg3);
|
||||
NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t300_NB);
|
||||
NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t301_NB);
|
||||
NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t310_NB);
|
||||
NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_t311_NB);
|
||||
NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n310_NB);
|
||||
NBIoTParams[NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).ue_TimersAndConstants_n311_NB);
|
||||
sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]",nbiotrrc_id);
|
||||
config_get( NBIoTParams,sizeofArray(NBIoTParams),instprefix);
|
||||
NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierMSG3_RangeStart = config_get_processedint(config_get_if(), &(NBIoTParams[NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX]) );
|
||||
NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_groupHoppingEnabled = config_get_processedint(config_get_if(), &(NBIoTParams[NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX] ) );
|
||||
NBIOTRRC_CONFIGURATION_REQ (msg_p).dl_GapDurationCoeff_NB = config_get_processedint(config_get_if(), &(NBIoTParams[NBIOT_DL_GAPDURATIONCOEFF_NB_IDX] ) );
|
||||
NBIOTRRC_CONFIGURATION_REQ (msg_p).npusch_alpha = config_get_processedint(config_get_if(), &(NBIoTParams[NBIOT_NPUSCH_ALPHA_IDX] ) );
|
||||
|
||||
for (int i=0; i<MAX_NUM_NBIOT_CELEVELS; i++) {
|
||||
char *tmpptr=NULL;
|
||||
NBIoTPrachParams[NBIOT_NPRACH_PERIODICITY_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_Periodicity[i]);
|
||||
NBIoTPrachParams[NBIOT_NPRACH_STARTTIME_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_StartTime[i]);
|
||||
NBIoTPrachParams[NBIOT_NPRACH_SUBCARRIEROFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_SubcarrierOffset[i]);
|
||||
NBIoTPrachParams[NBIOT_NPRACH_NUMSUBCARRIERS_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).nprach_NumSubcarriers[i]);
|
||||
NBIoTPrachParams[NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).numRepetitionsPerPreambleAttempt_NB[i]);
|
||||
NBIoTParams[NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_NumRepetitions_RA[i]);
|
||||
NBIoTParams[NBIOT_NPDCCH_STARTSF_CSS_RA_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).npdcch_StartSF_CSS_RA[i]);
|
||||
NBIoTParams[NBIOT_NPDCCH_OFFSET_RA_IDX].strptr = &tmpptr;
|
||||
sprintf(instprefix, "%s.[%i].%s.[%i]",NBIOT_RRCLIST_CONFIG_STRING, nbiotrrc_id,NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING,i);
|
||||
config_get(NBIoTPrachParams, sizeofArray(NBIoTPrachParams), instprefix);
|
||||
NBIOTRRC_CONFIGURATION_REQ(msg_p).npdcch_Offset_RA[i] =
|
||||
config_get_processedint(config_get_if(), &(NBIoTPrachParams[NBIOT_NPDCCH_OFFSET_RA_IDX]));
|
||||
}
|
||||
|
||||
/* get the LTE RRC and CC this NB-IoT RRC instance is attached to */
|
||||
sprintf(instprefix, NBIOT_RRCLIST_CONFIG_STRING ".[%i]." NBIOT_LTERRCREF_CONFIG_STRING, nbiotrrc_id );
|
||||
config_get( NBIoTRRCRefParams,sizeofArray(NBIoTRRCRefParams),instprefix);
|
||||
/* read SIB1 parameters in the LTE RRC and CC sections */
|
||||
sprintf(instprefix, ENB_CONFIG_STRING_ENB_LIST ".[%i]." ENB_CONFIG_STRING_COMPONENT_CARRIERS ".[%i]",
|
||||
*(NBIoTRRCRefParams[NBIOT_RRCINST_IDX].uptr), *(NBIoTRRCRefParams[NBIOT_CCINST_IDX].uptr));
|
||||
NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config);
|
||||
NBIoTLteCCParams[LTECCPARAMS_TDD_CONFIG_S_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).tdd_config_s);
|
||||
NBIoTLteCCParams[LTECCPARAMS_EUTRA_BAND_IDX ].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).eutra_band);
|
||||
NBIoTLteCCParams[LTECCPARAMS_DOWNLINK_FREQUENCY_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).downlink_frequency);
|
||||
NBIoTLteCCParams[LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).uplink_frequency_offset);
|
||||
NBIoTLteCCParams[LTECCPARAMS_NID_CELL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).Nid_cell);
|
||||
NBIoTLteCCParams[LTECCPARAMS_N_RB_DL_IDX].uptr = (uint32_t *)&(NBIOTRRC_CONFIGURATION_REQ (msg_p).N_RB_DL);
|
||||
|
||||
for (int i=0;i<sizeofArray(NBIoTLteCCParams) && i<sizeofArray(NBIoTLteCCCheckParams); i++ ) {
|
||||
NBIoTLteCCParams[i].chkPptr = &(NBIoTLteCCCheckParams[i]);
|
||||
}
|
||||
|
||||
config_get( NBIoTLteCCParams,sizeofArray(NBIoTLteCCParams),instprefix);
|
||||
NBIOTRRC_CONFIGURATION_REQ (msg_p).frame_type = config_get_processedint(config_get_if(), &(NBIoTLteCCParams[LTECCPARAMS_FRAME_TYPE_IDX]) );
|
||||
NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint(config_get_if(), &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_IDX]) );
|
||||
NBIOTRRC_CONFIGURATION_REQ (msg_p).prefix_type = config_get_processedint(config_get_if(), &(NBIoTLteCCParams[LTECCPARAMS_PREFIX_TYPE_UL_IDX]) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RCConfig_NbIoT(RAN_CONTEXT_t *RC) {
|
||||
paramlist_def_t NbIoT_MACRLCParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0};
|
||||
paramlist_def_t NbIoT_L1ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0};
|
||||
paramlist_def_t NbIoT_ParamList = {NBIOT_RRCLIST_CONFIG_STRING,NULL,0};
|
||||
config_getlist( &NbIoT_ParamList,NULL,0,NULL);
|
||||
RC->nb_nb_iot_rrc_inst = NbIoT_ParamList.numelt;
|
||||
config_getlist( &NbIoT_MACRLCParamList,NULL,0, NULL);
|
||||
RC->nb_nb_iot_macrlc_inst = NbIoT_MACRLCParamList.numelt;
|
||||
// Get num L1 instances
|
||||
config_getlist( &NbIoT_L1ParamList,NULL,0, NULL);
|
||||
RC->nb_nb_iot_L1_inst = NbIoT_L1ParamList.numelt;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
nbiot_config.h
|
||||
-------------------
|
||||
AUTHOR : Francois Taburet
|
||||
COMPANY : NOKIA
|
||||
EMAIL : francois.taburet@nokia-bell-labs.com
|
||||
*/
|
||||
#ifndef INCLUDE_NBIOT_CONFIG_H
|
||||
#define INCLUDE_NBIOT_CONFIG_H
|
||||
|
||||
|
||||
extern void RCconfig_NbIoTL1(void) ;
|
||||
extern void RCconfig_NbIoTmacrlc(void);
|
||||
extern int RCconfig_NbIoTRRC(MessageDef *msg_p, int nbiotrrc_id,eNB_RRC_INST_NB_IoT *nbiotrrc);
|
||||
extern void RCConfig_NbIoT(RAN_CONTEXT_t *RC);
|
||||
#endif
|
||||
@@ -1,405 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file openair2/ENB_APP/enb_paramdef.f
|
||||
* \brief definition of configuration parameters for all eNodeB modules
|
||||
* \author Francois TABURET
|
||||
* \date 2017
|
||||
* \version 0.1
|
||||
* \company NOKIA BellLabs France
|
||||
* \email: francois.taburet@nokia-bell-labs.com
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef __ENB_APP_NB_IOT_PARAMDEF__H__
|
||||
#define __ENB_APP_NB_IOT_PARAMDEF__H__
|
||||
|
||||
#include "common/config/config_paramdesc.h"
|
||||
#include "SystemInformationBlockType2.h"
|
||||
#include "DL-GapConfig-NB-r13.h"
|
||||
#include "NPRACH-Parameters-NB-r13.h"
|
||||
#include "PowerRampingParameters.h"
|
||||
#include "BCCH-Config-NB-r13.h"
|
||||
#include "PCCH-Config-NB-r13.h"
|
||||
#include "ACK-NACK-NumRepetitions-NB-r13.h"
|
||||
#include "TDD-Config.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
int16_t eutra_band;
|
||||
uint32_t downlink_frequency;
|
||||
int32_t uplink_frequency_offset;
|
||||
int16_t Nid_cell;// for testing, change later
|
||||
int16_t N_RB_DL;// for testing, change later
|
||||
*/
|
||||
/*-------------------------------------------------------------------------------------------------------------------*/
|
||||
/* SIB1 parameters possibly coming from LTE RRC (in band deployment) */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* component carriers configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt checked_param */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define NBIOT_LTECCPARAMS_CHECK_DESC { \
|
||||
{ .s3a= { config_checkstr_assign_integer, FRAMETYPE_OKVALUES, FRAMETYPE_MODVALUES,2}} , \
|
||||
{ .s2= { config_check_intrange, TDDCONFIG_OKRANGE}}, \
|
||||
{ .s2= { config_check_intrange, TDDCONFIGS_OKRANGE}}, \
|
||||
{ .s3a= { config_checkstr_assign_integer, PREFIX_OKVALUES, PREFIX_MODVALUES,2}} , \
|
||||
{ .s3a= { config_checkstr_assign_integer, PREFIXUL_OKVALUES, PREFIXUL_MODVALUES,2}} , \
|
||||
{ .s5= {NULL }} , \
|
||||
{ .s5= {NULL }} , \
|
||||
{ .s5= {NULL }} , \
|
||||
{ .s5= {NULL }} , \
|
||||
{ .s1= { config_check_intval, NRBDL_OKVALUES,6}} , \
|
||||
}
|
||||
|
||||
|
||||
#define NBIOT_LTECCPARAMS_DESC { \
|
||||
{ENB_CONFIG_STRING_FRAME_TYPE, NULL, 0, strptr:NULL, defstrval:"FDD", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_TDD_CONFIG, NULL, 0, iptr:NULL, defintval:3, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_TDD_CONFIG_S, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_PREFIX_TYPE, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_PREFIX_TYPE_UL, NULL, 0, strptr:NULL, defstrval:"NORMAL", TYPE_STRING, 0}, \
|
||||
{ENB_CONFIG_STRING_EUTRA_BAND, NULL, 0, iptr:NULL, defintval:7, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, NULL, 0, i64ptr:NULL, defint64val:2680000000, TYPE_UINT64, 0}, \
|
||||
{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, NULL, 0, iptr:NULL, defintval:-120000000, TYPE_INT, 0}, \
|
||||
{ENB_CONFIG_STRING_NID_CELL, NULL, 0, iptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{ENB_CONFIG_STRING_N_RB_DL, NULL, 0, iptr:NULL, defintval:25, TYPE_UINT, 0}, \
|
||||
}
|
||||
#define LTECCPARAMS_FRAME_TYPE_IDX 0
|
||||
#define LTECCPARAMS_TDD_CONFIG_IDX 1
|
||||
#define LTECCPARAMS_TDD_CONFIG_S_IDX 2
|
||||
#define LTECCPARAMS_PREFIX_TYPE_IDX 3
|
||||
#define LTECCPARAMS_PREFIX_TYPE_UL_IDX 4
|
||||
#define LTECCPARAMS_EUTRA_BAND_IDX 5
|
||||
#define LTECCPARAMS_DOWNLINK_FREQUENCY_IDX 6
|
||||
#define LTECCPARAMS_UPLINK_FREQUENCY_OFFSET_IDX 7
|
||||
#define LTECCPARAMS_NID_CELL_IDX 8
|
||||
#define LTECCPARAMS_N_RB_DL_IDX 9
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* NB-Iot RRC list section name */
|
||||
#define NBIOT_RRCLIST_CONFIG_STRING "NB-IoT_RRCs"
|
||||
|
||||
|
||||
#define RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES {20,50,80,120,180,240,320,400}
|
||||
#define PREF1(A) RACH_CE_LevelInfo_r13__ra_ResponseWindowSize_r13_ ## A
|
||||
#define RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES { PREF1(sf20),PREF1(sf50),PREF1(sf80),PREF1(sf120), \
|
||||
PREF1(sf180),PREF1(sf240),PREF1(sf320),PREF1(sf400) }
|
||||
|
||||
|
||||
#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES {80,100,120,160,200,240,480,960}
|
||||
#define PREF2(A) RACH_CE_LevelInfo_r13__mac_ContentionResolutionTimer_r13_ ## A
|
||||
#define RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES { PREF2(sf80),PREF2(sf100),PREF2(sf120),PREF2(sf160), \
|
||||
PREF2(sf200),PREF2(sf240),PREF2(sf480),PREF2(sf960) }
|
||||
|
||||
|
||||
#define RACH_POWERRAMPINGSTEP_NB_OKVALUES {0,2,4,6}
|
||||
#define PREF3(A) PowerRampingParameters__powerRampingStep_ ## A
|
||||
#define RACH_POWERRAMPINGSTEP_NB_MODVALUES { PREF3(dB0),PREF3(dB2),PREF3(dB4),PREF3(dB6) }
|
||||
|
||||
|
||||
#define RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE {-120, -90}
|
||||
|
||||
#define RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES {3,4,5,6,7,8,10,20,50,100,200}
|
||||
#define PREF4(A) PreambleTransMax_ ## A
|
||||
#define RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES { PREF4(n3), PREF4(n4), PREF4(n5), PREF4(n6), PREF4(n7), PREF4(n8), \
|
||||
PREF4(n10),PREF4(n20),PREF4(n50),PREF4(n100),PREF4(n200) }
|
||||
|
||||
#define BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES {16,32,64,128}
|
||||
#define PREF5(A) BCCH_Config_NB_r13__modificationPeriodCoeff_r13_ ## A
|
||||
#define BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES { PREF5(n16), PREF5(n32), PREF5(n64),PREF5(n128) }
|
||||
|
||||
#define PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES {128,256,512,1024}
|
||||
#define PREF6(A) PCCH_Config_NB_r13__defaultPagingCycle_r13_ ## A
|
||||
#define PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES { PREF6(rf128), PREF6(rf256), PREF6(rf512), PREF6(rf1024) }
|
||||
|
||||
#define NPRACH_CP_LENGTH_OKVALUES {0,1}
|
||||
#define NPRACH_RSRP_RANGE_OKVALUES {0,96}
|
||||
|
||||
#define MSG3RANGESTART_OKVALUES {"zero","oneThird","twoThird","one"}
|
||||
#define MSG3RANGESTART_MODVALUES {NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_zero, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_oneThird, \
|
||||
NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_twoThird, NPRACH_Parameters_NB_r13__nprach_SubcarrierMSG3_RangeStart_r13_one}
|
||||
|
||||
|
||||
#define MAXNUMPREAMBLEATTEMPTCE_OKVALUES {3,4,5,6,7,8,10}
|
||||
#define MAXNUMPREAMBLEATTEMPTCE_MODVALUES { NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n3, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n4, \
|
||||
NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n5, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n6, \
|
||||
NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n7, NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n8, \
|
||||
NPRACH_Parameters_NB_r13__maxNumPreambleAttemptCE_r13_n10 }
|
||||
|
||||
#define NPDSCH_NRS_POWER_OKRANGE {-60,50}
|
||||
|
||||
#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES {1,2,4,8,16,32,64,128}
|
||||
#define PREF9(A) ACK_NACK_NumRepetitions_NB_r13_ ## A
|
||||
#define NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES { PREF9(r1), PREF9(r2), PREF9(r4), PREF9(r8), \
|
||||
PREF9(r16), PREF9(r32), PREF9(r64), PREF9(r128) }
|
||||
|
||||
#define NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE {0,15}
|
||||
#define NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE {0,2}
|
||||
#define NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE {0,3}
|
||||
|
||||
#define NPUSCH_GROUPHOPPINGENABLED_OKVALUES {"enable","disable"}
|
||||
#define NPUSCH_GROUPHOPPINGENABLED_MODVALUES {1,0}
|
||||
|
||||
#define NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE {0,29}
|
||||
|
||||
#define DLGAPTHRESHOLD_OKVALUES {32,64,128,256}
|
||||
#define DLGAPTHRESHOLD_MODVALUES { DL_GapConfig_NB_r13__dl_GapThreshold_r13_n32, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n64, \
|
||||
DL_GapConfig_NB_r13__dl_GapThreshold_r13_n128, DL_GapConfig_NB_r13__dl_GapThreshold_r13_n256} \
|
||||
|
||||
#define DLGAPPERIODICITY_OKVALUES {64,128,256,512}
|
||||
#define DLGAPPERIODICITY_MODVALUES { DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf64, DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf128, \
|
||||
DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf256,DL_GapConfig_NB_r13__dl_GapPeriodicity_r13_sf512}
|
||||
|
||||
#define DLGAPDURATION_OKVALUES {"oneEighth","oneFourth","threeEighth","oneHalf"}
|
||||
#define DLGAPDURATION_MODVALUES {DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneFourth, \
|
||||
DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_threeEighth, DL_GapConfig_NB_r13__dl_GapDurationCoeff_r13_oneHalf}
|
||||
|
||||
#define NPUSCH_P0_NOMINALNPUSCH_OKRANGE {-126,24}
|
||||
|
||||
#define NPUSCH_ALPHA_OKVALUES {"AL0","AL04","AL05","AL06","AL07","AL08","AL09","AL1"}
|
||||
#define NPUSCH_ALPHA_MODVALUES { Alpha_r12_al0, Alpha_r12_al04, Alpha_r12_al05, Alpha_r12_al06, \
|
||||
Alpha_r12_al07, Alpha_r12_al08, Alpha_r12_al09, Alpha_r12_al1}
|
||||
|
||||
#define DELTAPREAMBLEMSG3_OKRANGE {-1,6}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define NBIOT_RRCPARAMS_CHECK_DESC { \
|
||||
{ .s1a= { config_check_modify_integer, RACH_RARESPONSEWINDOWSIZE_NB_OKVALUES, RACH_RARESPONSEWINDOWSIZE_NB_MODVALUES, 8}}, \
|
||||
{ .s1a= { config_check_modify_integer, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_OKVALUES, RACH_MACCONTENTIONRESOLUTIONTIMER_NB_MODVALUES, 8}}, \
|
||||
{ .s1a= { config_check_modify_integer, RACH_POWERRAMPINGSTEP_NB_OKVALUES, RACH_POWERRAMPINGSTEP_NB_MODVALUES, 4}} , \
|
||||
{ .s2= { config_check_intrange, RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_OKRANGE}}, \
|
||||
{ .s1a= { config_check_modify_integer, RACH_PREAMBLETRANSMAX_CE_NB_OKVALUES, RACH_PREAMBLETRANSMAX_CE_NB_MODVALUES, 11}} , \
|
||||
{ .s1a= { config_check_modify_integer, BCCH_MODIFICATIONPERIODCOEFF_NB_OKVALUES, BCCH_MODIFICATIONPERIODCOEFF_NB_MODVALUES, 4}} , \
|
||||
{ .s1a= { config_check_modify_integer, PCCH_DEFAULTPAGINGCYCLE_NB_OKVALUES, PCCH_DEFAULTPAGINGCYCLE_NB_MODVALUES, 4}} , \
|
||||
{ .s1= { NULL, NPRACH_CP_LENGTH_OKVALUES ,4}} , \
|
||||
{ .s2= { config_check_intrange, NPRACH_RSRP_RANGE_OKVALUES}} , \
|
||||
{ .s3a= { config_checkstr_assign_integer, MSG3RANGESTART_OKVALUES, MSG3RANGESTART_MODVALUES, 4}} , \
|
||||
{ .s1a= { config_check_modify_integer, MAXNUMPREAMBLEATTEMPTCE_OKVALUES, MAXNUMPREAMBLEATTEMPTCE_MODVALUES, 7}} , \
|
||||
{ .s1= { config_check_intval, NPDSCH_NRS_POWER_OKRANGE,4}} , \
|
||||
{ .s1a= { config_check_modify_integer, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_OKVALUES, NPUSCH_ACK_NACK_NUMREPETITIONS_NB_MODVALUES, 8}} , \
|
||||
{ .s2= { config_check_intrange, NPUSCH_SRS_SUBFRAMECONFIG_NB_OKRANGE}} , \
|
||||
{ .s2= { config_check_intrange, NPUSCH_THREETONE_CYCLICSHIFT_R13_OKRANGE}} , \
|
||||
{ .s2= { config_check_intrange, NPUSCH_SIXTONE_CYCLICSHIFT_R13_OKRANGE}} , \
|
||||
{ .s3a= { config_checkstr_assign_integer, NPUSCH_GROUPHOPPINGENABLED_OKVALUES, NPUSCH_GROUPHOPPINGENABLED_MODVALUES, 2}} , \
|
||||
{ .s2= { config_check_intrange, NPUSCH_GROUPASSIGNMENTNPUSCH_R13_OKRANGE}} , \
|
||||
{ .s1a= { config_check_modify_integer, DLGAPTHRESHOLD_OKVALUES, DLGAPTHRESHOLD_MODVALUES, 4}} , \
|
||||
{ .s1a= { config_check_modify_integer, DLGAPPERIODICITY_OKVALUES, DLGAPPERIODICITY_MODVALUES, 4}} , \
|
||||
{ .s3a= { config_checkstr_assign_integer, DLGAPDURATION_OKVALUES, DLGAPDURATION_MODVALUES , 4}} , \
|
||||
{ .s2= { config_check_intrange, NPUSCH_P0_NOMINALNPUSCH_OKRANGE}} , \
|
||||
{ .s3a= { config_checkstr_assign_integer, NPUSCH_ALPHA_OKVALUES, NPUSCH_ALPHA_MODVALUES, 8}} , \
|
||||
{ .s2= { config_check_intrange, DELTAPREAMBLEMSG3_OKRANGE}} , \
|
||||
{ .s1a= { config_check_modify_integer, UETIMER_T300_OKVALUES, UETIMER_T300_MODVALUES,8}} , \
|
||||
{ .s1a= { config_check_modify_integer, UETIMER_T301_OKVALUES, UETIMER_T301_MODVALUES,8}} , \
|
||||
{ .s1a= { config_check_modify_integer, UETIMER_T310_OKVALUES, UETIMER_T310_MODVALUES,7}} , \
|
||||
{ .s1a= { config_check_modify_integer, UETIMER_T311_OKVALUES, UETIMER_T311_MODVALUES,7}} , \
|
||||
{ .s1a= { config_check_modify_integer, UETIMER_N310_OKVALUES, UETIMER_N310_MODVALUES,8}} , \
|
||||
{ .s1a= { config_check_modify_integer, UETIMER_N311_OKVALUES, UETIMER_N311_MODVALUES,8}} , \
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* NB-IoT RRC configuration parameters */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define NBIOTRRCPARAMS_DESC { \
|
||||
{"rach_raResponseWindowSize_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \
|
||||
{"rach_macContentionResolutionTimer_NB", NULL, 0, uptr:NULL, defintval:80, TYPE_UINT, 0}, \
|
||||
{"rach_powerRampingStep_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"rach_preambleInitialReceivedTargetPower_NB", NULL, 0, iptr:NULL, defintval:-112, TYPE_INT32, 0}, \
|
||||
{"rach_preambleTransMax_CE_NB", NULL, 0, uptr:NULL, defintval:3, TYPE_UINT, 0}, \
|
||||
{"bcch_modificationPeriodCoeff_NB", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \
|
||||
{"pcch_defaultPagingCycle_NB", NULL, 0, uptr:NULL, defintval:256, TYPE_UINT, 0}, \
|
||||
{"nprach_CP_Length", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"nprach_rsrp_range", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"nprach_SubcarrierMSG3_RangeStart", NULL, 0, strptr:NULL, defstrval:"one", TYPE_STRING, 0}, \
|
||||
{"maxNumPreambleAttemptCE_NB", NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \
|
||||
{"npdsch_nrs_Power", NULL, 0, iptr:NULL, defintval:0, TYPE_INT, 0}, \
|
||||
{"npusch_ack_nack_numRepetitions_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \
|
||||
{"npusch_srs_SubframeConfig_NB", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"npusch_threeTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"npusch_sixTone_CyclicShift_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"npusch_groupHoppingEnabled", NULL, 0, strptr:NULL, defstrval:"disable", TYPE_STRING, 0}, \
|
||||
{"npusch_groupAssignmentNPUSCH_r13", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"dl_GapThreshold_NB", NULL, 0, uptr:NULL, defintval:32, TYPE_UINT, 0}, \
|
||||
{"dl_GapPeriodicity_NB", NULL, 0, uptr:NULL, defintval:64, TYPE_UINT, 0}, \
|
||||
{"dl_GapDurationCoeff_NB", NULL, 0, strptr:NULL, defstrval:"oneEighth", TYPE_STRING, 0}, \
|
||||
{"npusch_p0_NominalNPUSCH", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \
|
||||
{"npusch_alpha", NULL, 0, strptr:NULL, defstrval:"AL0", TYPE_STRING, 0}, \
|
||||
{"deltaPreambleMsg3", NULL, 0, iptr:NULL, defintval:0, TYPE_INT32, 0}, \
|
||||
{"ue_TimersAndConstants_t300_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \
|
||||
{"ue_TimersAndConstants_t301_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \
|
||||
{"ue_TimersAndConstants_t310_NB", NULL, 0, uptr:NULL, defintval:1000, TYPE_UINT, 0}, \
|
||||
{"ue_TimersAndConstants_t311_NB", NULL, 0, uptr:NULL, defintval:10000, TYPE_UINT, 0}, \
|
||||
{"ue_TimersAndConstants_n310_NB", NULL, 0, uptr:NULL, defintval:20, TYPE_UINT, 0}, \
|
||||
{"ue_TimersAndConstants_n311_NB", NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \
|
||||
}
|
||||
|
||||
#define NBIOT_RACH_RARESPONSEWINDOWSIZE_NB_IDX 0
|
||||
#define NBIOT_RACH_MACCONTENTIONRESOLUTIONTIMER_NB_IDX 1
|
||||
#define NBIOT_RACH_POWERRAMPINGSTEP_NB_IDX 2
|
||||
#define NBIOT_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER_NB_IDX 3
|
||||
#define NBIOT_RACH_PREAMBLETRANSMAX_CE_NB_IDX 4
|
||||
#define NBIOT_BCCH_MODIFICATIONPERIODCOEFF_NB_IDX 5
|
||||
#define NBIOT_PCCH_DEFAULTPAGINGCYCLE_NB_IDX 6
|
||||
#define NBIOT_NPRACH_CP_LENGTH_IDX 7
|
||||
#define NBIOT_NPRACH_RSRP_RANGE_IDX 8
|
||||
#define NBIOT_NPRACH_SUBCARRIERMSG3_RANGESTART_IDX 9
|
||||
#define NBIOT_MAXNUMPREAMBLEATTEMPTCE_NB_IDX 10
|
||||
#define NBIOT_NPDSCH_NRS_POWER_IDX 11
|
||||
#define NBIOT_NPUSCH_ACK_NACK_NUMREPETITIONS_NB_IDX 12
|
||||
#define NBIOT_NPUSCH_SRS_SUBFRAMECONFIG_NB_IDX 13
|
||||
#define NBIOT_NPUSCH_THREETONE_CYCLICSHIFT_R13_IDX 14
|
||||
#define NBIOT_NPUSCH_SIXTONE_CYCLICSHIFT_R13_IDX 15
|
||||
#define NBIOT_NPUSCH_GROUPHOPPINGENABLED_IDX 16
|
||||
#define NBIOT_NPUSCH_GROUPASSIGNMENTNPUSCH_R13_IDX 17
|
||||
#define NBIOT_DL_GAPTHRESHOLD_NB_IDX 18
|
||||
#define NBIOT_DL_GAPPERIODICITY_NB_IDX 19
|
||||
#define NBIOT_DL_GAPDURATIONCOEFF_NB_IDX 20
|
||||
#define NBIOT_NPUSCH_P0_NOMINALNPUSCH_IDX 21
|
||||
#define NBIOT_NPUSCH_ALPHA_IDX 22
|
||||
#define NBIOT_DELTAPREAMBLEMSG3_IDX 23
|
||||
#define NBIOT_UE_TIMERSANDCONSTANTS_T300_NB_IDX 24
|
||||
#define NBIOT_UE_TIMERSANDCONSTANTS_T301_NB_IDX 25
|
||||
#define NBIOT_UE_TIMERSANDCONSTANTS_T310_NB_IDX 26
|
||||
#define NBIOT_UE_TIMERSANDCONSTANTS_T311_NB_IDX 27
|
||||
#define NBIOT_UE_TIMERSANDCONSTANTS_N310_NB_IDX 28
|
||||
#define NBIOT_UE_TIMERSANDCONSTANTS_N311_NB_IDX 29
|
||||
|
||||
/* NB-Iot RRC: link to LTE RRC section name */
|
||||
#define NBIOT_LTERRCREF_CONFIG_STRING "LTERRC_Ref"
|
||||
/*---------------------------------------------------------------------------------------------------------------*/
|
||||
/* NB-IoT RRC configuration parameters to link to a LTE RRC instance (in-guard, in-band) */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------*/
|
||||
#define NBIOTRRCPARAMS_RRCREF_DESC { \
|
||||
{"RRC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"CC_inst", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
}
|
||||
/*--------------------------------------------------------------------------------------------------------------*/
|
||||
#define NBIOT_RRCINST_IDX 0
|
||||
#define NBIOT_CCINST_IDX 1
|
||||
|
||||
#define NBIOT_RRCLIST_NPRACHPARAMS_CONFIG_STRING "NPRACH-NB-r13"
|
||||
|
||||
|
||||
#define NPRACH_PERIODICITY_OKVALUES {40,80,160,240,320,640,1280,2560}
|
||||
#define NPRACH_PERIODICITY_MODVALUES { NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms40, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms80, \
|
||||
NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms160, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms240, \
|
||||
NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms320, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms640, \
|
||||
NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms1280, NPRACH_Parameters_NB_r13__nprach_Periodicity_r13_ms2560 }
|
||||
|
||||
#define NPRACH_STARTTIME_OKVALUES {8,16,32,64,128,256,512,1024}
|
||||
#define NPRACH_STARTTIME_MODVALUES { NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms8, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms16, \
|
||||
NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms32, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms64, \
|
||||
NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms128, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms256, \
|
||||
NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms512, NPRACH_Parameters_NB_r13__nprach_StartTime_r13_ms1024 }
|
||||
|
||||
#define NPRACH_SUBCARRIEROFFSET_OKVALUES {0,12,24,36,2,18,34}
|
||||
#define NPRACH_SUBCARRIEROFFSET_MODVALUES { NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n0, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n12, \
|
||||
NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n24, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n36, \
|
||||
NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n2, NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n18, \
|
||||
NPRACH_Parameters_NB_r13__nprach_SubcarrierOffset_r13_n34 }
|
||||
|
||||
#define NPRACH_NUMSUBCARRIERS_OKVALUES {12,24,36,48}
|
||||
#define NPRACH_NUMSUBCARRIERS_MODVALUES { NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n12, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n24, \
|
||||
NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n36, NPRACH_Parameters_NB_r13__nprach_NumSubcarriers_r13_n48 }
|
||||
|
||||
|
||||
#define NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES {1,2,4,8,16,32,64,128}
|
||||
#define NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES { NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n1, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n2, \
|
||||
NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n4, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n8, \
|
||||
NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n16, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n32, \
|
||||
NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n64, NPRACH_Parameters_NB_r13__numRepetitionsPerPreambleAttempt_r13_n128}
|
||||
|
||||
#define NPDCCHNUMREPETITIONSRA_OKVALUES {1,2,4,8,16,32,64,128,256,512,1024,2048}
|
||||
#define NPDCCHNUMREPETITIONSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r4, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r8, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r16, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r32, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r64, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r128, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r256, NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r512, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r1024,NPRACH_Parameters_NB_r13__npdcch_NumRepetitions_RA_r13_r2048}
|
||||
|
||||
#define NPDCCHSTARTSFCSSRA_OKVALUES {1,2,4,8,16,32,48,64}
|
||||
#define NPDCCHSTARTSFCSSRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v1dot5, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v2, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v4, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v8, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v16, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v32, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v48, NPRACH_Parameters_NB_r13__npdcch_StartSF_CSS_RA_r13_v64}
|
||||
|
||||
#define NPDCCHOFFSETRA_OKVALUES {"zero","oneEighth","oneFourth","threeEighth"}
|
||||
#define NPDCCHOFFSETRA_MODVALUES { NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_zero, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneEighth, \
|
||||
NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_oneFourth, NPRACH_Parameters_NB_r13__npdcch_Offset_RA_r13_threeEighth}
|
||||
|
||||
|
||||
|
||||
#define NBIOT_RRCLIST_NPRACHPARAMSCHECK_DESC { \
|
||||
{ .s1a= { config_check_modify_integer, NPRACH_PERIODICITY_OKVALUES, NPRACH_PERIODICITY_MODVALUES, 8 }}, \
|
||||
{ .s1a= { config_check_modify_integer, NPRACH_STARTTIME_OKVALUES, NPRACH_STARTTIME_MODVALUES, 8 }}, \
|
||||
{ .s1a= { config_check_modify_integer, NPRACH_SUBCARRIEROFFSET_OKVALUES, NPRACH_SUBCARRIEROFFSET_MODVALUES, 7 }}, \
|
||||
{ .s1a= { config_check_modify_integer, NPRACH_NUMSUBCARRIERS_OKVALUES, NPRACH_NUMSUBCARRIERS_MODVALUES, 4 }}, \
|
||||
{ .s1a= { config_check_modify_integer, NUMREPETITIONSPERPREAMBLEATTEMPT_OKVALUES, NUMREPETITIONSPERPREAMBLEATTEMPT_MODVALUES,8 }}, \
|
||||
{ .s1a= { config_check_modify_integer, NPDCCHNUMREPETITIONSRA_OKVALUES, NPDCCHNUMREPETITIONSRA_MODVALUES, 12}}, \
|
||||
{ .s1a= { config_check_modify_integer, NPDCCHSTARTSFCSSRA_OKVALUES, NPDCCHSTARTSFCSSRA_MODVALUES, 8 }}, \
|
||||
{ .s3a= { config_checkstr_assign_integer, NPDCCHOFFSETRA_OKVALUES, NPDCCHOFFSETRA_MODVALUES, 4 }}, \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* NB-IoT NPrach parameters, there will be three ocuurences of these parameters in each RRC instance */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define NBIOTRRC_NPRACH_PARAMS_DESC { \
|
||||
{"nprach_Periodicity", NULL, 0, uptr:NULL, defintval:320, TYPE_UINT, 0}, \
|
||||
{"nprach_StartTime", NULL, 0, uptr:NULL, defintval:8, TYPE_UINT, 0}, \
|
||||
{"nprach_SubcarrierOffset", NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
|
||||
{"nprach_NumSubcarriers", NULL, 0, uptr:NULL, defintval:12, TYPE_UINT, 0}, \
|
||||
{"numRepetitionsPerPreambleAttempt", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \
|
||||
{"npdcch_NumRepetitions_RA", NULL, 0, uptr:NULL, defintval:16, TYPE_UINT, 0}, \
|
||||
{"npdcch_StartSF_CSS_RA", NULL, 0, uptr:NULL, defintval:2, TYPE_UINT, 0}, \
|
||||
{"npdcch_Offset_RA", NULL, 0, strptr:NULL, defstrval:"zero", TYPE_STRING, 0}, \
|
||||
}
|
||||
|
||||
#define NBIOT_NPRACH_PERIODICITY_IDX 0
|
||||
#define NBIOT_NPRACH_STARTTIME_IDX 1
|
||||
#define NBIOT_NPRACH_SUBCARRIEROFFSET_IDX 2
|
||||
#define NBIOT_NPRACH_NUMSUBCARRIERS_IDX 3
|
||||
#define NBIOT_NUMREPETITIONSPERPREAMBLEATTEMPT_NB_IDX 4
|
||||
#define NBIOT_NPDCCH_NUMREPETITIONS_RA_IDX 5
|
||||
#define NBIOT_NPDCCH_STARTSF_CSS_RA_IDX 6
|
||||
#define NBIOT_NPDCCH_OFFSET_RA_IDX 7
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* NB IoT MACRLC configuration list section name */
|
||||
#define NBIOT_MACRLCLIST_CONFIG_STRING "NB-IoT_MACRLCs"
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* NB IoT L1 configuration list section name */
|
||||
#define NBIOT_L1LIST_CONFIG_STRING "NB-IoT_L1s"
|
||||
|
||||
#endif
|
||||
@@ -3,7 +3,7 @@ add_subdirectory(MESSAGES)
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
add_executable(f1ap_ids_test f1ap_ids_test.c f1ap_ids.c)
|
||||
target_link_libraries(f1ap_ids_test UTIL HASHTABLE minimal_lib)
|
||||
target_link_libraries(f1ap_ids_test HASHTABLE minimal_lib)
|
||||
add_dependencies(tests f1ap_ids_test)
|
||||
add_test(NAME F1AP_ID_test COMMAND f1ap_ids_test)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
add_library(nr_ue_power_procedures nr_ue_power_procedures.c)
|
||||
target_link_libraries(nr_ue_power_procedures PUBLIC asn1_nr_rrc ${T_LIB} MAC_NR_COMMON nr_common)
|
||||
target_link_libraries(nr_ue_power_procedures PUBLIC asn1_nr_rrc log_headers MAC_NR_COMMON nr_common)
|
||||
add_library(nr_ue_ra_procedures nr_ra_procedures.c)
|
||||
target_link_libraries(nr_ue_ra_procedures PUBLIC asn1_nr_rrc asn1_lte_rrc_hdrs ${T_LIB} MAC_NR_COMMON nr_common)
|
||||
target_link_libraries(nr_ue_ra_procedures PUBLIC asn1_nr_rrc asn1_lte_rrc_hdrs log_headers MAC_NR_COMMON nr_common)
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
@@ -879,23 +879,23 @@ bool init_RA(NR_UE_MAC_INST_t *mac, int frame)
|
||||
// set POWER_OFFSET_2STEP_RA to 0 dB
|
||||
prach_resources->power_offset_2step = 0;
|
||||
|
||||
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
||||
// perform the BWP operation as specified in clause 5.15
|
||||
// if PRACH occasions are not configured for the active UL BWP
|
||||
if (!current_UL_BWP->rach_ConfigCommon) {
|
||||
if (!mac->current_UL_BWP->rach_ConfigCommon) {
|
||||
// switch the active UL BWP to BWP indicated by initialUplinkBWP
|
||||
current_UL_BWP = get_ul_bwp_structure(mac, 0, false);
|
||||
mac->current_UL_BWP = get_ul_bwp_structure(mac, 0, false);
|
||||
// if the Serving Cell is an SpCell
|
||||
// switch the active DL BWP to BWP indicated by initialDownlinkBWP
|
||||
mac->current_DL_BWP = get_dl_bwp_structure(mac, 0, false);
|
||||
} else {
|
||||
// if the active DL BWP does not have the same bwp-Id as the active UL BWP
|
||||
if (current_UL_BWP->bwp_id != mac->current_DL_BWP->bwp_id) {
|
||||
if (mac->current_UL_BWP->bwp_id != mac->current_DL_BWP->bwp_id) {
|
||||
// switch the active DL BWP to the DL BWP with the same bwp-Id as the active UL BWP
|
||||
mac->current_DL_BWP = get_dl_bwp_structure(mac, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
const NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP;
|
||||
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = current_UL_BWP->rach_ConfigCommon;
|
||||
AssertFatal(nr_rach_ConfigCommon, "rach-ConfigCommon should be configured here\n");
|
||||
// stop the bwp-InactivityTimer associated with the active DL BWP of this Serving Cell, if running
|
||||
|
||||
@@ -1250,10 +1250,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
current_harq_pid,
|
||||
harq->round,
|
||||
harq->ndi);
|
||||
AssertFatal(harq->sched_pdsch.tb_size == TBS,
|
||||
"UE %04x mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
|
||||
UE->rnti,
|
||||
current_harq_pid);
|
||||
if (!get_softmodem_params()->phy_test)
|
||||
AssertFatal(harq->sched_pdsch.tb_size == TBS,
|
||||
"UE %04x mismatch between scheduled TBS and buffered TB for HARQ PID %d\n",
|
||||
UE->rnti,
|
||||
current_harq_pid);
|
||||
else if (harq->sched_pdsch.tb_size != TBS)
|
||||
LOG_E(NR_MAC,
|
||||
"Mismatch between scheduled TBS and buffered TB for HARQ PID %d. No RTX control in phy-test mode. "
|
||||
"Possible causes: presence of CSI-RS or DLSCH scheduled in the mixed slot.\n",
|
||||
current_harq_pid);
|
||||
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
|
||||
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock.buf, TBS));
|
||||
UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize;
|
||||
|
||||
@@ -2718,8 +2718,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
AssertFatal(dl_bwp_switch == ul_bwp_switch, "Different UL and DL BWP not supported\n");
|
||||
DL_BWP->bwp_id = dl_bwp_switch;
|
||||
UL_BWP->bwp_id = ul_bwp_switch;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// (re)configuring BWP
|
||||
// TODO BWP switching not via RRC reconfiguration
|
||||
// via RRC if firstActiveXlinkBWP_Id is NULL, MAC stays on the same BWP as before
|
||||
@@ -2768,8 +2767,7 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
UL_BWP->pusch_Config = ubwpd->pusch_Config->choice.setup;
|
||||
UL_BWP->pucch_Config = ubwpd->pucch_Config->choice.setup;
|
||||
UL_BWP->srs_Config = ubwpd->srs_Config->choice.setup;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
DL_BWP->bwp_id = 0;
|
||||
UL_BWP->bwp_id = 0;
|
||||
DL_BWP->pdsch_Config = NULL;
|
||||
@@ -2778,11 +2776,6 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
UL_BWP->configuredGrantConfig = NULL;
|
||||
}
|
||||
|
||||
if (old_dl_bwp_id != DL_BWP->bwp_id)
|
||||
LOG_I(NR_MAC, "Switching to DL-BWP %li\n", DL_BWP->bwp_id);
|
||||
if (old_ul_bwp_id != UL_BWP->bwp_id)
|
||||
LOG_I(NR_MAC, "Switching to UL-BWP %li\n", UL_BWP->bwp_id);
|
||||
|
||||
// TDA lists
|
||||
if (DL_BWP->bwp_id>0)
|
||||
DL_BWP->tdaList_Common = dl_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
@@ -2832,6 +2825,19 @@ void configure_UE_BWP(gNB_MAC_INST *nr_mac,
|
||||
UL_BWP->rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
||||
}
|
||||
|
||||
// if PRACH occasions are not configured for the active UL BWP
|
||||
// switch the active UL BWP to BWP indicated by initialUplinkBWP
|
||||
// as described in 5.15 of 38.321
|
||||
if (is_RA && !UL_BWP->rach_ConfigCommon) {
|
||||
LOG_I(NR_MAC, "Cannot perform RA in current BWP, switching to initial BWP\n");
|
||||
configure_UE_BWP(nr_mac, scc, UE, is_RA, target_ss, 0, 0);
|
||||
return;
|
||||
}
|
||||
if (old_dl_bwp_id != DL_BWP->bwp_id)
|
||||
LOG_I(NR_MAC, "Switching to DL-BWP %li\n", DL_BWP->bwp_id);
|
||||
if (old_ul_bwp_id != UL_BWP->bwp_id)
|
||||
LOG_I(NR_MAC, "Switching to UL-BWP %li\n", UL_BWP->bwp_id);
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
// Reset required fields in sched_ctrl (e.g. ul_ri and tpmi)
|
||||
reset_sched_ctrl(sched_ctrl);
|
||||
|
||||