diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index ef2637965fe383dba5134b63760a97837caf3ea4..72fa29aa393935a4c85beb949ff1d2a21cda21a2 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -68,11 +68,12 @@ function build_on_vm { then echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_CPU = $VM_CPU" + echo "VM_DISK = $VM_DISK GBytes" echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk 10 --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index b1d234639243733a675db231e7a957a336566df0..237a1a5d5e4521197c51a2f69433a38340f1c6e3 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -85,12 +85,13 @@ function create_vm { echo "VM_NAME = $VM_NAME" echo "VM_MEMORY = $VM_MEMORY MBytes" echo "VM_CPU = $VM_CPU" + echo "VM_DISK = $VM_DISK GBytes" echo "############################################################" echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" echo "############################################################" acquire_vm_create_lock - uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk 10 --unsafe-caching --template ci-scripts/template-host.xml + uvt-kvm create $VM_NAME release=$VM_OSREL --memory $VM_MEMORY --cpu $VM_CPU --disk $VM_DISK --unsafe-caching --template ci-scripts/template-host.xml echo "Waiting for VM to be started" uvt-kvm wait $VM_NAME --insecure diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index ce40134cec7f089939fe4871b8a299d12f71e237..fb9dc9ad7638f796a8f79e2cd205de2722022570 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -52,7 +52,7 @@ function variant_usage { if [ "$1" = "full" ] then printf " VM_NAME=%-15s ARCHIVES_LOC=%-15s\n" "$VM_NAME" "$ARCHIVES_LOC" - printf " VM_MEMORY=%-15s VM_CPU=%-15s\n" "$VM_MEMORY" "$VM_CPU" + printf " VM_MEMORY=%-15s VM_CPU=%-15s VM_DISK=%-15s\n" "$VM_MEMORY" "$VM_CPU" "$VM_DISK" printf " NB_PATTERN_FILES=%-15s BUILD_OPTIONS=%-15s\n" "$NB_PATTERN_FILES" "\"$BUILD_OPTIONS\"" printf " LOG_PATTERN=%-15s EXPERIMENTAL=%-15s\n\n\n" "$LOG_PATTERN" "$EXPERIMENTAL" fi @@ -185,6 +185,7 @@ function variant__v3__phy_sim { NB_PATTERN_FILES=12 BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 + VM_DISK=20 RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b" } @@ -272,6 +273,7 @@ function check_set_variant { ARCHIVES_LOC=${VARIANTS_LONG[$i]//"-"/"_"} VM_MEMORY=2048 VM_CPU=4 + VM_DISK=10 EXPERIMENTAL="" NBARGS=$[$NBARGS+$VARIANT_OPTID] variant__${VARIANTS_SHORT[$i]}__${VARIANTS_LONG[$i]//"-"/"_"} @@ -494,6 +496,7 @@ AUTHORIZED_VAR=("VM_OSREL RUN_EXPERIMENTAL OPTIONAL_APTCACHER TESTPLATFORM_OWNER # -V<xx> option. VM_NAME="" VM_MEMORY=0 +VM_DISK=0 VM_CPU=0 ARCHIVES_LOC="" LOG_PATTERN="" diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 9e69145a8f6ad90dc8bd35d20dd6c69c5184b087..ded67443bc8089a0d08cd31ef3c85903df190a9b 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -1149,6 +1149,11 @@ function run_test_on_vm { echo "cp /home/ubuntu/bc-install.txt log" >> $VM_CMDS echo "cd log" >> $VM_CMDS echo "zip -r -qq tmp.zip *.* 0*" >> $VM_CMDS + echo "echo \"############################################################\"" >> $VM_CMDS + echo "echo \"Evaluating remaining memory on disk!\"" >> $VM_CMDS + echo "echo \"############################################################\"" >> $VM_CMDS + echo "echo \"df -h\"" >> $VM_CMDS + echo "df -h" >> $VM_CMDS ssh -T -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 273aad0c20732e98b2ee70901d58184be170eb48..a0620d834548f6ec1ca75fef73cfd9ba9a3352c6 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1473,15 +1473,8 @@ set(RRC_DIR ${OPENAIR2_DIR}/RRC/LTE) set(NR_RRC_DIR ${OPENAIR2_DIR}/RRC/NR) set(NR_UE_RRC_DIR ${OPENAIR2_DIR}/RRC/NR_UE) set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0) -set(L2_SRC - ${OPENAIR2_DIR}/LAYER2/openair2_proc.c - ${PDCP_DIR}/pdcp.c - ${PDCP_DIR}/pdcp_fifo.c - ${PDCP_DIR}/pdcp_sequence_manager.c - ${PDCP_DIR}/pdcp_primitives.c - ${PDCP_DIR}/pdcp_util.c - ${PDCP_DIR}/pdcp_security.c - ${PDCP_DIR}/pdcp_netlink.c + +set(LTE_RLC_SRC ${RLC_AM_DIR}/rlc_am.c ${RLC_AM_DIR}/rlc_am_init.c ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c @@ -1509,6 +1502,29 @@ set(L2_SRC ${RLC_DIR}/rlc.c ${RLC_DIR}/rlc_rrc.c ${RLC_DIR}/rlc_mpls.c + ) + +set(NR_RLC_SRC + ${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_am.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_tm.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity_um.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_oai_api.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_pdu.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c + ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c + ) + +set(L2_SRC + ${OPENAIR2_DIR}/LAYER2/openair2_proc.c + ${PDCP_DIR}/pdcp.c + ${PDCP_DIR}/pdcp_fifo.c + ${PDCP_DIR}/pdcp_sequence_manager.c + ${PDCP_DIR}/pdcp_primitives.c + ${PDCP_DIR}/pdcp_util.c + ${PDCP_DIR}/pdcp_security.c + ${PDCP_DIR}/pdcp_netlink.c # ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_S1AP.c @@ -1519,7 +1535,12 @@ set(L2_SRC ${RRC_DIR}/L2_interface_ue.c ) +set(L2_LTE_SRC + ${LTE_RLC_SRC} + ) + set(L2_NR_SRC + ${NR_RLC_SRC} ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c @@ -1534,40 +1555,13 @@ set(L2_SRC_UE ${PDCP_DIR}/pdcp_util.c ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c - ${RLC_AM_DIR}/rlc_am.c - ${RLC_AM_DIR}/rlc_am_init.c - ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c - ${RLC_AM_DIR}/rlc_am_timer_reordering.c - ${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c - ${RLC_AM_DIR}/rlc_am_segment.c - ${RLC_AM_DIR}/rlc_am_segments_holes.c - ${RLC_AM_DIR}/rlc_am_in_sdu.c - ${RLC_AM_DIR}/rlc_am_receiver.c - ${RLC_AM_DIR}/rlc_am_retransmit.c - ${RLC_AM_DIR}/rlc_am_windows.c - ${RLC_AM_DIR}/rlc_am_rx_list.c - ${RLC_AM_DIR}/rlc_am_reassembly.c - ${RLC_AM_DIR}/rlc_am_status_report.c - ${RLC_TM_DIR}/rlc_tm.c - ${RLC_TM_DIR}/rlc_tm_init.c - ${RLC_UM_DIR}/rlc_um.c - ${RLC_UM_DIR}/rlc_um_fsm.c - ${RLC_UM_DIR}/rlc_um_control_primitives.c - ${RLC_UM_DIR}/rlc_um_segment.c - ${RLC_UM_DIR}/rlc_um_reassembly.c - ${RLC_UM_DIR}/rlc_um_receiver.c - ${RLC_UM_DIR}/rlc_um_dar.c - ${RLC_DIR}/rlc_mac.c - ${RLC_DIR}/rlc.c - ${RLC_DIR}/rlc_rrc.c - ${RLC_DIR}/rlc_mpls.c ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface_common.c ${RRC_DIR}/L2_interface_ue.c ) - set(LTE_NR_L2_SRC_UE +set(LTE_NR_L2_SRC_UE ${PDCP_DIR}/pdcp.c ${PDCP_DIR}/pdcp_fifo.c ${PDCP_DIR}/pdcp_sequence_manager.c @@ -1575,37 +1569,11 @@ set(L2_SRC_UE ${PDCP_DIR}/pdcp_util.c ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c - ${RLC_AM_DIR}/rlc_am.c - ${RLC_AM_DIR}/rlc_am_init.c - ${RLC_AM_DIR}/rlc_am_timer_poll_retransmit.c - ${RLC_AM_DIR}/rlc_am_timer_reordering.c - ${RLC_AM_DIR}/rlc_am_timer_status_prohibit.c - ${RLC_AM_DIR}/rlc_am_segment.c - ${RLC_AM_DIR}/rlc_am_segments_holes.c - ${RLC_AM_DIR}/rlc_am_in_sdu.c - ${RLC_AM_DIR}/rlc_am_receiver.c - ${RLC_AM_DIR}/rlc_am_retransmit.c - ${RLC_AM_DIR}/rlc_am_windows.c - ${RLC_AM_DIR}/rlc_am_rx_list.c - ${RLC_AM_DIR}/rlc_am_reassembly.c - ${RLC_AM_DIR}/rlc_am_status_report.c - ${RLC_TM_DIR}/rlc_tm.c - ${RLC_TM_DIR}/rlc_tm_init.c - ${RLC_UM_DIR}/rlc_um.c - ${RLC_UM_DIR}/rlc_um_fsm.c - ${RLC_UM_DIR}/rlc_um_control_primitives.c - ${RLC_UM_DIR}/rlc_um_segment.c - ${RLC_UM_DIR}/rlc_um_reassembly.c - ${RLC_UM_DIR}/rlc_um_receiver.c - ${RLC_UM_DIR}/rlc_um_dar.c - ${RLC_DIR}/rlc_mac.c - ${RLC_DIR}/rlc.c - ${RLC_DIR}/rlc_rrc.c - ${RLC_DIR}/rlc_mpls.c - ${RRC_DIR}/L2_interface_common.c + ${LTE_RLC_SRC} ) set(NR_L2_SRC_UE + ${NR_RLC_SRC} ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c @@ -1693,6 +1661,10 @@ add_library(MAC_UE_NR ${MAC_NR_SRC_UE} ) +add_library(L2_LTE + ${L2_LTE_SRC} + ) + add_library(L2_NR ${L2_NR_SRC} ${MAC_NR_SRC} @@ -2345,7 +2317,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-softmodem -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB - PHY_COMMON PHY PHY_RU LFDS L2 NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 + PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} -Wl,--end-group z dl) @@ -2417,7 +2389,7 @@ endif() target_link_libraries (lte-uesoftmodem -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON - PHY_UE PHY_RU LFDS L2_UE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} + PHY_UE PHY_RU LFDS L2_UE L2_LTE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -Wl,--end-group z dl) @@ -2745,7 +2717,7 @@ if (${T_TRACER}) SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_UE PHY_RU PHY_MEX - L2 L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U + L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U SCTP_CLIENT UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB) if (TARGET ${i}) add_dependencies(${i} generate_T) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index a407171d01dc455664f7fccd4f0e57aabcd5d8a8..6795f2d1fa490eaeae21477fa55059e105c82fa2 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1088,7 +1088,7 @@ (Test7: 106 PRB 51 PDSCH-Offset), (Test8: 217 PRB 100 PDSCH-PRBs), (Test9: 217 PRB 80 PDSCH-Offset), - (Test10: 217 PRB 100 PDSCH-PRBs 80 PDSCH-Offset), + (Test10: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset), (Test11: 106 PRBs 50 PDSCH-PRBs MCS Index 28</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> @@ -1105,7 +1105,7 @@ -n100 -R106 -a51 -n100 -R217 -b100 -n100 -R217 -a80 - -n100 -R217 -a80 -b100 + -n100 -R217 -a110 -b100 -n100 -e28</main_exec_args> <tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11</tags> diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index e14f28f8297383bfd22573d2b75f47f3c3f88705..56c3c0951fd493758c171e81ac62920297af03f7 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -81,7 +81,7 @@ char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { } if (*ptr == NULL) { - *ptr = malloc(length); + *ptr = malloc(length>40?length:40); // LTS: dummy fix, waiting Francois full fix in 4G branch if ( *ptr != NULL) { memset(*ptr,0,length); diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index 6bad041641cf626440d049af9662104ee9f471b9..7f177b90cee51c7c516ebe436fac181ff02d210c 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -324,7 +324,9 @@ void log_getconfig(log_t *g_log) config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1,CONFIG_STRING_LOG_PREFIX); - config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX); + + if (config_check_unknown_cmdlineopt(CONFIG_STRING_LOG_PREFIX) > 0) + exit(1); /* set the debug mask according to the debug parameters values */ for (int i=0; log_maskmap[i].name != NULL ; i++) { diff --git a/common/utils/LOG/vcd_signal_dumper.c b/common/utils/LOG/vcd_signal_dumper.c index 7ea15cf9dbe13897c7d0e245d9628fc37c330d18..63c5336bd88fc25751b623106a1417525f631588 100644 --- a/common/utils/LOG/vcd_signal_dumper.c +++ b/common/utils/LOG/vcd_signal_dumper.c @@ -247,7 +247,8 @@ const char* eurecomVariablesNames[] = { "slot_number_TX0_gNB", "slot_number_TX1_gNB", "slot_number_RX0_gNB", - "slot_number_RX1_gNB" + "slot_number_RX1_gNB", + "ru_tx_ofdm_mask" }; const char* eurecomFunctionsNames[] = { @@ -328,6 +329,13 @@ const char* eurecomFunctionsNames[] = { "phy_procedures_ru_feptx_ofdm7", "phy_procedures_ru_feptx_ofdm8", "phy_procedures_ru_feptx_ofdm9", + "phy_procedures_ru_feptx_ofdm10", + "phy_procedures_ru_feptx_ofdm11", + "phy_procedures_ru_feptx_ofdm12", + "phy_procedures_ru_feptx_ofdm13", + "phy_procedures_ru_feptx_ofdm14", + "phy_procedures_ru_feptx_ofdm15", + "phy_procedures_ru_feptx_ofdm16", "phy_procedures_ru_feptx_prec0", "phy_procedures_ru_feptx_prec1", "phy_procedures_ru_feptx_prec2", @@ -502,6 +510,7 @@ const char* eurecomFunctionsNames[] = { "pdcch_interleaving", "pdcch_tx", /*NR softmodem signal*/ + "wakeup_txfh", "gNB_thread_rxtx0", "gNB_thread_rxtx1" }; diff --git a/common/utils/LOG/vcd_signal_dumper.h b/common/utils/LOG/vcd_signal_dumper.h index a7c4c10fe31a6dc88859dfc450683d07151f6761..3a6fb6d6abb9f932b700efa1acb747ef6fd5a1ad 100644 --- a/common/utils/LOG/vcd_signal_dumper.h +++ b/common/utils/LOG/vcd_signal_dumper.h @@ -225,6 +225,7 @@ typedef enum { VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX0_GNB, VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX1_GNB, + VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, VCD_SIGNAL_DUMPER_VARIABLES_END @@ -309,6 +310,13 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM7, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM8, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM9, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM10, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM11, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM12, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM13, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM14, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM15, + VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM16, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC1, VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC2, @@ -494,6 +502,7 @@ typedef enum { VCD_SIGNAL_DUMPER_FUNCTIONS_PDCCH_TX, /*NR softmodem signal*/ + VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX0, VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h index 4f2b10c3ae152d08a2eedebcd65e0d54cf28c467..ab275d4d62d9cd7f03474e0a0521881b963adecb 100644 --- a/common/utils/T/T_defs.h +++ b/common/utils/T/T_defs.h @@ -73,10 +73,10 @@ typedef struct { } T_cache_t; /* number of VCD functions (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_FUNCTIONS (237)//(232) +#define VCD_NUM_FUNCTIONS (245) /* number of VCD variables (to be kept up to date! see in T_messages.txt) */ -#define VCD_NUM_VARIABLES (185) +#define VCD_NUM_VARIABLES (186) /* first VCD function (to be kept up to date! see in T_messages.txt) */ #define VCD_FIRST_FUNCTION ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 0b10b6e25ece1fd6199919df2cd012df24804a20..407bb66be17416fccb5345f58198da518fdf4357 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -2050,6 +2050,11 @@ ID = VCD_VARIABLE_SLOT_NUMBER_RX1_GNB GROUP = ALL:VCD:ENB:VCD_VARIABLE FORMAT = ulong,value VCD_NAME = slot_number_RX1_gNB +ID = VCD_VARIABLE_RU_TX_OFDM_MASK + DESC = VCD variable RU_TX_OFDM_MASK + GROUP = ALL:VCD:ENB:VCD_VARIABLE + FORMAT = ulong,value + VCD_NAME = ru_tx_ofdm_mask #functions @@ -2418,6 +2423,41 @@ ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM9 GROUP = ALL:VCD:ENB:VCD_FUNCTION FORMAT = int,value VCD_NAME = phy_procedures_ru_feptx_ofdm9 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM10 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM10 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm10 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM11 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM11 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm11 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM12 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM12 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm12 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM13 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM13 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm13 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM14 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM14 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm14 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM15 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM15 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm15 +ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_OFDM16 + DESC = VCD function PHY_PROCEDURES_RU_FEPTX_OFDM16 + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = phy_procedures_ru_feptx_ofdm16 ID = VCD_FUNCTION_PHY_PROCEDURES_RU_FEPTX_PREC DESC = VCD function PHY_PROCEDURES_RU_FEPTX_PREC GROUP = ALL:VCD:ENB:VCD_FUNCTION @@ -3230,6 +3270,11 @@ ID = VCD_FUNCTION_PDCCH_TX VCD_NAME = pdcch_tx #function for gNB +ID = VCD_FUNCTION_WAKEUP_TXFH + DESC = VCD function WAKEUP_TXFH + GROUP = ALL:VCD:ENB:VCD_FUNCTION + FORMAT = int,value + VCD_NAME = wakeup_txfh ID = VCD_FUNCTION_gNB_PROC_RXTX0 DESC = VCD function gNB_PROC_RXTX0 GROUP = ALL:VCD:ENB:VCD_FUNCTION diff --git a/common/utils/hashtable/hashtable.c b/common/utils/hashtable/hashtable.c index 50c2ec83245bd5dc5d7ce69e89103c5c96c1f2a1..e9641f8e0c06141eeeacd8442dbc518897b2e141 100644 --- a/common/utils/hashtable/hashtable.c +++ b/common/utils/hashtable/hashtable.c @@ -162,34 +162,6 @@ hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtblP, cons return HASH_TABLE_KEY_NOT_EXISTS; } //------------------------------------------------------------------------------------------------------------------------------- -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void functP(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP) -//------------------------------------------------------------------------------------------------------------------------------- -{ - hash_node_t *node = NULL; - unsigned int i = 0; - unsigned int num_elements = 0; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - - while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) { - if (hashtblP->nodes[i] != NULL) { - node=hashtblP->nodes[i]; - - while(node) { - num_elements += 1; - functP(node->key, node->data, parameterP); - node=node->next; - } - } - - i += 1; - } - - return HASH_TABLE_OK; -} -//------------------------------------------------------------------------------------------------------------------------------- hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ) //------------------------------------------------------------------------------------------------------------------------------- { @@ -266,7 +238,6 @@ hashtable_rc_t hashtable_insert(hash_table_t *const hashtblP, const hash_key_t k } hashtblP->nodes[hash]=node; - hashtblP->num_elements += 1; return HASH_TABLE_OK; } //------------------------------------------------------------------------------------------------------------------------------- @@ -295,7 +266,6 @@ hashtable_rc_t hashtable_remove(hash_table_t *const hashtblP, const hash_key_t k } free(node); - hashtblP->num_elements -= 1; return HASH_TABLE_OK; } @@ -335,47 +305,3 @@ hashtable_rc_t hashtable_get(const hash_table_t *const hashtblP, const hash_key_ *dataP = NULL; return HASH_TABLE_KEY_NOT_EXISTS; } -//------------------------------------------------------------------------------------------------------------------------------- -/* - * Resizing - * The number of elements in a hash table is not always known when creating the table. - * If the number of elements grows too large, it will seriously reduce the performance of most hash table operations. - * If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table. - * Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position. - * We create a temporary hash_table_t object (newtbl) to be used while building the new hashes. - * This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table. - * After that, we can just free the old table and copy the elements from newtbl to hashtbl. - */ - -hashtable_rc_t hashtable_resize(hash_table_t *const hashtblP, const hash_size_t sizeP) { - hash_table_t newtbl; - hash_size_t n; - hash_node_t *node,*next; - - if (hashtblP == NULL) { - return HASH_TABLE_BAD_PARAMETER_HASHTABLE; - } - - newtbl.size = sizeP; - newtbl.hashfunc = hashtblP->hashfunc; - newtbl.num_elements = 0; - - if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t *)))) return -1; - - for(n=0; n<hashtblP->size; ++n) { - for(node=hashtblP->nodes[n]; node; node=next) { - next = node->next; - hashtable_insert(&newtbl, node->key, node->data); - // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN - hashtable_remove(hashtblP, node->key); - } - } - - free(hashtblP->nodes); - hashtblP->size=newtbl.size; - hashtblP->nodes=newtbl.nodes; - return HASH_TABLE_OK; -} - - - diff --git a/common/utils/hashtable/hashtable.h b/common/utils/hashtable/hashtable.h index 3f770684fae9996f8973b4268f106a6526dafd0b..09f8623ce23af44ac608ed1f9e95102f2653e093 100644 --- a/common/utils/hashtable/hashtable.h +++ b/common/utils/hashtable/hashtable.h @@ -49,7 +49,6 @@ typedef struct hash_node_s { typedef struct hash_table_s { hash_size_t size; - hash_size_t num_elements; struct hash_node_s **nodes; hash_size_t (*hashfunc)(const hash_key_t); void (*freefunc)(void *); @@ -60,12 +59,10 @@ void hash_free_int_func(void *memoryP); hash_table_t *hashtable_create (const hash_size_t size, hash_size_t (*hashfunc)(const hash_key_t ), void (*freefunc)(void *)); hashtable_rc_t hashtable_destroy(hash_table_t **hashtbl); hashtable_rc_t hashtable_is_key_exists (const hash_table_t *const hashtbl, const uint64_t key); -hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *const hashtblP, void funct(hash_key_t keyP, void *dataP, void *parameterP), void *parameterP); hashtable_rc_t hashtable_dump_content (const hash_table_t *const hashtblP, char *const buffer_pP, int *const remaining_bytes_in_buffer_pP ); hashtable_rc_t hashtable_insert (hash_table_t *const hashtbl, const hash_key_t key, void *data); hashtable_rc_t hashtable_remove (hash_table_t *const hashtbl, const hash_key_t key); hashtable_rc_t hashtable_get (const hash_table_t *const hashtbl, const hash_key_t key, void **dataP); -hashtable_rc_t hashtable_resize (hash_table_t *const hashtbl, const hash_size_t size); diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index b4bf5efe81e834ad77228041d9fe98b6281be239..cb1d45adc2d3667ab337f345195f0ce7a237e638 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -290,6 +290,8 @@ static void *gNB_L1_thread_tx(void *param) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX1_GNB,slot_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_GNB,frame_tx); phy_procedures_gNB_TX(gNB, frame_tx,slot_tx, 1); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 1 ); pthread_mutex_lock( &L1_proc_tx->mutex ); L1_proc_tx->instance_cnt = -1; @@ -301,6 +303,7 @@ static void *gNB_L1_thread_tx(void *param) { pthread_mutex_unlock(&L1_proc_tx->mutex); wakeup_txfh(gNB,L1_proc_tx,frame_tx,slot_tx,timestamp_tx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_WAKEUP_TXFH, 0 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_gNB_PROC_RXTX1, 0 ); } @@ -420,10 +423,10 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot // note this should depend on the numerology used by the TX L1 thread, set here for 500us slot time VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,1); - waitret=timedwait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh",1000000); + waitret=wait_on_condition(&proc->mutex_RUs_tx,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh"); + AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL,0); - AssertFatal(release_thread(&proc->mutex_RUs_tx,&proc->instance_cnt_RUs,"wakeup_txfh")==0, "error releaseing gNB lock on RUs\n"); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,proc->instance_cnt_RUs); if (waitret == ETIMEDOUT) { @@ -448,7 +451,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot ru = gNB->RU_list[i]; ru_proc = &ru->proc; - AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); + //AssertFatal((ret = pthread_mutex_lock(&ru_proc->mutex_gNBs))==0,"ERROR pthread_mutex_lock failed on mutex_gNBs L1_thread_tx with ret=%d\n",ret); if (ru_proc->instance_cnt_gNBs == 0) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 1); @@ -456,7 +459,7 @@ int wakeup_txfh(PHY_VARS_gNB *gNB,gNB_L1_rxtx_proc_t *proc,int frame_tx,int slot AssertFatal((ret=pthread_mutex_lock(&gNB->proc.mutex_RU_tx))==0,"mutex_lock returns %d\n",ret); gNB->proc.RU_mask_tx = 0; AssertFatal((ret=pthread_mutex_unlock(&gNB->proc.mutex_RU_tx))==0,"mutex_unlock returns %d\n",ret); - AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); + //AssertFatal((ret=pthread_mutex_unlock( &ru_proc->mutex_gNBs ))==0,"mutex_unlock return %d\n",ret); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST_UE, 0); return(-1); @@ -522,6 +525,8 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { RU_proc_t *ru_proc=&ru->proc; int ret; int i; + struct timespec abstime; + int time_ns = 50000; AssertFatal((ret=pthread_mutex_lock(&proc->mutex_RU))==0,"mutex_lock returns %d\n",ret); for (i=0;i<gNB->num_RU;i++) { @@ -542,14 +547,22 @@ int wakeup_rxtx(PHY_VARS_gNB *gNB,RU_t *ru) { AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_RU))==0,"muex_unlock returns %d\n",ret); } + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_nsec = abstime.tv_nsec + time_ns; + + if (abstime.tv_nsec >= 1000*1000*1000) { + abstime.tv_nsec -= 1000*1000*1000; + abstime.tv_sec += 1; + } // wake up TX for subframe n+sl_ahead // lock the TX mutex and make sure the thread is ready - AssertFatal((ret=pthread_mutex_lock(&L1_proc->mutex)) == 0,"mutex_lock returns %d\n", ret); + AssertFatal((ret=pthread_mutex_timedlock(&L1_proc->mutex, &abstime)) == 0,"mutex_lock returns %d\n", ret); if (L1_proc->instance_cnt == 0) { // L1_thread is busy so abort the subframe AssertFatal((ret=pthread_mutex_unlock( &L1_proc->mutex))==0,"muex_unlock return %d\n",ret); LOG_W(PHY,"L1_thread isn't ready in %d.%d, aborting RX processing\n",ru_proc->frame_rx,ru_proc->tti_rx); + return(-1); } ++L1_proc->instance_cnt; diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 1abcd3b7a159669598ce48ec4f165f2fd3fe1dbf..b402110c4bb4cd08f0f33e7a4999cfdaf30fb9f9 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -91,7 +91,8 @@ unsigned short config_frames[4] = {2,9,11,13}; /* these variables have to be defined before including ENB_APP/enb_paramdef.h and GNB_APP/gnb_paramdef.h */ static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; - +static int DEFBFW[] = {0x00007fff}; + //static int DEFNRBANDS[] = {7}; //static int DEFGNBS[] = {0}; @@ -677,9 +678,6 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_slot*fp->slots_per_frame))&1023; proc->tti_rx = (proc->timestamp_rx / fp->samples_per_slot)%fp->slots_per_frame; // synchronize first reception to frame 0 subframe 0 - proc->timestamp_tx = proc->timestamp_rx+(sl_ahead*fp->samples_per_slot); - proc->tti_tx = (proc->tti_rx+sl_ahead)%fp->slots_per_frame; - proc->frame_tx = (proc->tti_rx>(fp->slots_per_frame-1-sl_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx; LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", ru->idx, 0, @@ -764,18 +762,22 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, frame ); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TTI_NUMBER_TX0_RU, slot ); - for (i=0; i<ru->nb_tx; i++) + for (i=0; i<ru->nb_tx; i++){ txp[i] = (void *)&ru->common.txdata[i][(slot*fp->samples_per_slot)-sf_extension]; + } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (timestamp-ru->openair0_cfg.tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); // prepare tx buffer pointers + start_meas(&ru->tx_fhaul); txs = ru->rfdevice.trx_write_func(&ru->rfdevice, timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, txp, siglen+sf_extension, ru->nb_tx, flags); + stop_meas(&ru->tx_fhaul); LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx, (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); @@ -784,6 +786,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { } + /*! * \brief The Asynchronous RX/TX FH thread of RAU/RCC/gNB/RRU. * This handles the RX FH for an asynchronous RRU/UE @@ -872,7 +875,7 @@ static void *ru_thread_prach( void *param ) { 0,0 ); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 ); */ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_RU_PRACH_RX, 0 );*/ if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"ru_prach_thread") < 0) break; } @@ -1209,14 +1212,20 @@ static void *ru_stats_thread(void *param) { sleep(1); if (opp_enabled == 1) { + if (ru->feprx) print_meas(&ru->ofdm_demod_stats,"feprx",NULL,NULL); - if (ru->feptx_ofdm) print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + if (ru->feptx_ofdm){ + print_meas(&ru->precoding_stats,"feptx_prec",NULL,NULL); + print_meas(&ru->txdataF_copy_stats,"txdataF_copy",NULL,NULL); + print_meas(&ru->ofdm_mod_stats,"feptx_ofdm",NULL,NULL); + print_meas(&ru->ofdm_total_stats,"feptx_total",NULL,NULL); + } if (ru->fh_north_asynch_in) print_meas(&ru->rx_fhaul,"rx_fhaul",NULL,NULL); - if (ru->fh_north_out) { print_meas(&ru->tx_fhaul,"tx_fhaul",NULL,NULL); + if (ru->fh_north_out) { print_meas(&ru->compression,"compression",NULL,NULL); print_meas(&ru->transport,"transport",NULL,NULL); } @@ -1273,7 +1282,7 @@ static void *ru_thread_tx( void *param ) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru,frame_tx,tti_tx); - // do OFDM if needed + // do OFDM with/without TX front-end processing if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,frame_tx,tti_tx); if(!emulate_rf) { @@ -1284,8 +1293,17 @@ static void *ru_thread_tx( void *param ) { } else { if(proc->frame_tx == print_frame) { for (i=0; i<ru->nb_tx; i++) { - sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); - LOG_M(filename,"txdataF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + + if(proc->tti_tx == 0) { + sprintf(filename,"gNBdataF_frame%d_sl%d.m", print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_frame",&ru->gNB_list[0]->common_vars.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_frame",&ru->common.txdataF[i][0],fp->samples_per_frame_wCP, 1, 1); + + sprintf(filename,"tx%ddataF_BF_frame%d_sl%d.m", i, print_frame, proc->tti_tx); + LOG_M(filename,"txdataF_BF_frame",&ru->common.txdataF_BF[i][0],fp->samples_per_subframe_wCP, 1, 1); + } if(proc->tti_tx == 9) { sprintf(filename,"tx%ddata_frame%d.m", i, print_frame); @@ -1338,14 +1356,14 @@ static void *ru_thread_tx( void *param ) { ret = pthread_mutex_lock(&L1_proc->mutex_RUs_tx); AssertFatal(ret == 0,"mutex_lock returns %d\n",ret); // the thread can now be woken up - if (L1_proc->instance_cnt_RUs==-1) { - AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, + //if (L1_proc->instance_cnt_RUs == -1) { + L1_proc->instance_cnt_RUs = 0; + AssertFatal(pthread_cond_signal(&L1_proc->cond_RUs) == 0, "ERROR pthread_cond_signal for gNB_L1_thread\n"); - } //else AssertFatal(1==0,"gNB TX thread is not ready\n"); - L1_proc->instance_cnt_RUs = 0; - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); + //} //else AssertFatal(1==0,"gNB TX thread is not ready\n"); ret = pthread_mutex_unlock(&L1_proc->mutex_RUs_tx); AssertFatal(ret == 0,"mutex_unlock returns %d\n",ret); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_UE,L1_proc->instance_cnt_RUs); } } } @@ -1507,7 +1525,7 @@ static void *ru_thread( void *param ) { // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); - // do OFDM if needed + // do OFDM with/without TX front-end processing if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru,proc->frame_tx,proc->tti_tx); if(!emulate_rf) { @@ -1646,6 +1664,7 @@ int stop_rf(RU_t *ru) { return 0; } + void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; @@ -1668,6 +1687,7 @@ void init_RU_proc(RU_t *ru) { proc->frame_offset = 0; proc->num_slaves = 0; proc->frame_tx_unwrap = 0; + proc->feptx_mask = 0; for (i=0; i<10; i++) proc->symbol_mask[i]=0; @@ -2025,9 +2045,9 @@ void set_function_spec_param(RU_t *ru) { malloc_IF4p5_buffer(ru); } else if (ru->function == gNodeB_3GPP) { ru->do_prach = 0; // no prach processing in RU - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs - ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding - ru->feptx_prec = NULL; // this is fep with idft and precoding + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // RX DFTs + ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // this is fep with idft and precoding + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // this is fep with idft and precoding ru->fh_north_in = NULL; // no incoming fronthaul from north ru->fh_north_out = NULL; // no outgoing fronthaul to north ru->nr_start_if = NULL; // no if interface @@ -2055,8 +2075,8 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF5: // the remote unit is IF5 RRU ru->do_prach = 0; - ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // this is frequency-shift + DFTs - ru->feptx_prec = feptx_prec; // need to do transmit Precoding + IDFTs + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_fep_full_2thread : nr_fep_full; // this is frequency-shift + DFTs + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // need to do transmit Precoding + IDFTs ru->feptx_ofdm = (get_thread_worker_conf() == WORKER_ENABLE) ? nr_feptx_ofdm_2thread : nr_feptx_ofdm; // need to do transmit Precoding + IDFTs ru->fh_south_in = fh_if5_south_in; // synchronous IF5 reception ru->fh_south_out = fh_if5_south_out; // synchronous IF5 transmission @@ -2080,7 +2100,7 @@ void set_function_spec_param(RU_t *ru) { case REMOTE_IF4p5: ru->do_prach = 0; ru->feprx = NULL; // DFTs - ru->feptx_prec = feptx_prec; // Precoding operation + ru->feptx_prec = (get_thread_worker_conf() == WORKER_ENABLE) ? NULL : nr_feptx_prec; // Precoding operation ru->feptx_ofdm = NULL; // no OFDM mod ru->fh_south_in = fh_if4p5_south_in; // synchronous IF4p5 reception ru->fh_south_out = fh_if4p5_south_out; // synchronous IF4p5 transmission @@ -2334,6 +2354,14 @@ void RCconfig_RU(void) RC.ru[j]->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); RC.ru[j]->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); RC.ru[j]->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); + + if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { + RC.ru[j]->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; + for (i=0; i<RC.ru[j]->num_gNB; i++) { + RC.ru[j]->bw_list[i] = (int32_t *)malloc16_clear((RC.ru[j]->nb_bfw)*sizeof(int32_t)); + for (int b=0; b<RC.ru[j]->nb_bfw; b++) RC.ru[j]->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; + } + } }// j=0..num_rus } else { RC.nb_RU = 0; diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 931e2c1cd4ca05329c61decaaf3080c88242e529..0a638f72655a2a6634b6d073e3c5ad61bd7fbe08 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -924,6 +924,10 @@ init_opt(); # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + + if(IS_SOFTMODEM_NOS1) + init_pdcp(); + #if defined(ENABLE_ITTI) if (RC.nb_nr_inst > 0) { @@ -942,9 +946,6 @@ init_opt(); flexran_agent_start(i); } - if(IS_SOFTMODEM_NOS1) - init_pdcp(); - // init UE_PF_PO and mutex lock pthread_mutex_init(&ue_pf_po_mutex, NULL); memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index fcbd659bbea7832b5b8f75c5394058fb5530a5f3..24288d76d38fe476325e77a886ea0d9b8a261ff2 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -419,7 +419,7 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE->Mod_id, ENB_FLAG_NO, 0x1234, proc->frame_rx, proc->nr_tti_rx, 0); - //pdcp_run(&ctxt); + pdcp_run(&ctxt); pdcp_fifo_flush_sdus(&ctxt); } } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index d8a916d13fba1c7fd61d2dc36ba0acefe8679aae..7e2ffebb35bde1b4324174f2dcc64d3c547374cf 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -664,7 +664,7 @@ int main( int argc, char **argv ) { logInit(); // get options and fill parameters from configuration file get_options (); //Command-line options, enb_properties - //get_common_options(); + get_common_options(); #if T_TRACER T_Config_Init(); #endif diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 206fcf3b6f3a65e2eab8d7748e3bcd9ec51d1a1b..e8828d805c9c5d5b96b7498b81deb1f15d3c4c60 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -74,6 +74,10 @@ int nr_phy_init_RU(RU_t *ru) { } + // allocate precoding input buffers (TX) + ru->common.txdataF = (int32_t **)malloc16(15*sizeof(int32_t*)); + for(i=0; i< 15; ++i) ru->common.txdataF[i] = (int32_t*)malloc16_clear(fp->samples_per_frame_wCP*sizeof(int32_t)); // [hna] samples_per_frame without CP + // allocate IFFT input buffers (TX) ru->common.txdataF_BF = (int32_t **)malloc16(ru->nb_tx*sizeof(int32_t*)); LOG_I(PHY,"[INIT] common.txdata_BF= %p (%lu bytes)\n",ru->common.txdataF_BF, @@ -105,37 +109,33 @@ int nr_phy_init_RU(RU_t *ru) { RC.nb_nr_L1_inst,NUMBER_OF_gNB_MAX); LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst); - - for (i=0; i<RC.nb_nr_L1_inst; i++) { - for (p=0;p<15;p++) { - if (p == 0|| p==5) { - ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); - for (j=0; j<ru->nb_tx; j++) { - ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); - // antenna ports 0-3 are mapped on antennas 0-3 - // antenna port 4 is mapped on antenna 0 - // antenna ports 5-14 are mapped on all antennas - if (((p<4) && (p==j)) || ((p==4) && (j==0))) { - for (re=0; re<fp->ofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff; - - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - else if (p>4) { - for (re=0; re<fp->ofdm_symbol_size; re++) - { - ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]); - } - } - //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); - } // for (j=0 - } // if (p<ru - } // for p - } //for i + + int beam_count = 0; + if (ru->nb_tx>1) { + for (p=0;p<fp->Lmax;p++) { + if ((fp->L_ssb >> p) & 0x01) + beam_count++; + } + AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); + + int l_ind = 0; + for (i=0; i<RC.nb_nr_L1_inst; i++) { + for (p=0;p<fp->Lmax;p++) { + if ((fp->L_ssb >> p) & 0x01) { + ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); + for (j=0; j<ru->nb_tx; j++) { + ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); + for (re=0; re<fp->ofdm_symbol_size; re++) + ru->beam_weights[i][p][j][re] = ru->bw_list[i][l_ind]; + //printf("Beam Weight %08x for beam %d and tx %d\n",ru->bw_list[i][l_ind],p,j); + l_ind++; + } // for j + } // for p + } + } //for i + } } // !=IF5 + ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP ); return(0); @@ -162,6 +162,10 @@ void nr_phy_free_RU(RU_t *ru) for (i = 0; i < ru->nb_rx; i++) free_and_zero(ru->common.rxdata_7_5kHz[i]); free_and_zero(ru->common.rxdata_7_5kHz); + // free beamforming input buffers (TX) + for (i = 0; i < 15; i++) free_and_zero(ru->common.txdataF[i]); + free_and_zero(ru->common.txdataF); + // free IFFT input buffers (TX) for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdataF_BF[i]); free_and_zero(ru->common.txdataF_BF); @@ -179,10 +183,8 @@ void nr_phy_free_RU(RU_t *ru) for (i = 0; i < RC.nb_nr_L1_inst; i++) { for (p = 0; p < 15; p++) { - if (p == 0 || p == 5) { for (j=0; j<ru->nb_tx; j++) free_and_zero(ru->beam_weights[i][p][j]); free_and_zero(ru->beam_weights[i][p]); - } } } } diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 6a13ac88a3eef98adc2514082d38d9d9da941bc9..a5475a1555535a7291978f66c1411566a8cebb34 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -93,7 +93,7 @@ int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot, int frame) p = cfg->sch_config.ssb_periodicity.value; n_hf = cfg->sch_config.half_frame_index.value; - // checking if the ssb is transmitted in given frame according to periodicity + // if SSB periodicity is 5ms, they are transmitted in both half frames if ( (p>10) && (frame%(p/10)) ) return 0; else { @@ -101,15 +101,15 @@ int nr_is_ssb_slot(nfapi_nr_config_request_t *cfg, int slot, int frame) // if SSB periodicity is 5ms, they are transmitted in both half frames if ( p == 5) { if (slot<hf_slots) - n_hf=0; - else - n_hf=1; - } + n_hf=0; + else + n_hf=1; + } - // to set a effective slot number between 0 to hf_slots-1 in the half frame where the SSB is supposed to be + // to set a effective slot number between 0 to 9 in the half frame where the SSB is supposed to be rel_slot = (n_hf)? (slot-hf_slots) : slot; - // there are two potential SSB per slot + return ( ((ssb_map >> rel_slot*2) & 0x01) || ((ssb_map >> (1+rel_slot*2)) & 0x01) ); } } @@ -273,15 +273,18 @@ int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; // definition of Lmax according to ts 38.213 section 4.1 - if (fp->dl_CarrierFreq < 6e9){ - if(fp->frame_type && (fp->ssb_type==2)) - fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8; - else - fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8; - } - else + if (fp->dl_CarrierFreq < 6e9) { + if(fp->frame_type && (fp->ssb_type==2)) + fp->Lmax = (fp->dl_CarrierFreq < 2.4e9)? 4 : 8; + else + fp->Lmax = (fp->dl_CarrierFreq < 3e9)? 4 : 8; + } else { fp->Lmax = 64; + } + fp->N_ssb = 0; + for (int p=0; p<fp->Lmax; p++) + fp->N_ssb += ((fp->L_ssb >> p) & 0x01); return 0; } diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index ab3271c61c87eed1046b6e2e2725f68d92e2605f..79e220ac37d2ecb8a7ef8873b4355e87c54da666 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -50,6 +50,7 @@ #include "PHY/CODING/lte_interleaver_inline.h" #include "PHY/LTE_TRANSPORT/transport_eNB.h" #include "modulation_eNB.h" +#include "nr_modulation.h" #include "common/utils/LOG/vcd_signal_dumper.h" int beam_precoding(int32_t **txdataF, @@ -135,3 +136,33 @@ int beam_precoding_one_eNB(int32_t **txdataF, } return 0; } + + +int nr_beam_precoding(int32_t **txdataF, + int32_t **txdataF_BF, + NR_DL_FRAME_PARMS *frame_parms, + int32_t ***beam_weights, + int slot, + int symbol, + int aa, + int nb_antenna_ports) +{ + + + uint8_t p; + + // clear txdata_BF[aa][re] for each call of ue_spec_beamforming + memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); + + for (p=0; p<nb_antenna_ports; p++) { + if ((frame_parms->L_ssb >> p) & 0x01) { + multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size], + (int16_t*)beam_weights[p][aa], + (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], + 0, + frame_parms->ofdm_symbol_size, + 15); + } + } + return 0; +} diff --git a/openair1/PHY/MODULATION/nr_modulation.h b/openair1/PHY/MODULATION/nr_modulation.h index 8a6abd5de5a93d5ee650528552c446d89294a201..706b4dc113bbb23b9a7390c820614ee72034cf6c 100644 --- a/openair1/PHY/MODULATION/nr_modulation.h +++ b/openair1/PHY/MODULATION/nr_modulation.h @@ -93,4 +93,14 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, */ void nr_dft(int32_t *z,int32_t *d, uint32_t Msc_PUSCH); +int nr_beam_precoding(int32_t **txdataF, + int32_t **txdataF_BF, + NR_DL_FRAME_PARMS *frame_parms, + int32_t ***beam_weights, + int slot, + int symbol, + int aa, + int nb_antenna_ports +); + #endif diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index b23fd2e2bfb8c9e53c12f43dba024e8756497e61..cbeeca13278f6147c0ce2657f95da5faef7e490d 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -86,6 +86,8 @@ void PHY_ofdm_mod(int *input, /// pointer to complex input ) { + if(nb_symbols == 0) return; + short temp[4096*4] __attribute__((aligned(32))); unsigned short i,j; short k; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 89321f637ba857beee15a541b44b2a27f4c0c9f2..16fc94a59fe3380db2a3d5c55492b97137091410 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -45,7 +45,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, int16_t *fl,*fm,*fr,*fml,*fmr,*fmm,*fdcl,*fdcr,*fdclh,*fdcrh; int ch_offset,symbol_offset, length_dmrs, UE_id = 0; unsigned short n_idDMRS[2] = {0,1}; //to update from pusch config - int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(16))); + int32_t temp_in_ifft_0[8192*2] __attribute__((aligned(32))); int32_t **ul_ch_estimates_time = gNB->pusch_vars[UE_id]->ul_ch_estimates_time; #ifdef DEBUG_CH @@ -267,7 +267,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, // check if PRB crosses DC and improve estimates around DC - if ((bwp_start_subcarrier >= gNB->frame_parms.ofdm_symbol_size/2) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { + if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); uint16_t idxPil = idxDC/2; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 665e9a690cfad491357cc4483347ca785275d8d9..7502d5d4a49d1a38439c75ae07447fec9cd93e9d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -90,6 +90,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, uint8_t Qm = rel15->modulation_order; uint32_t encoded_length = nb_symbols*Qm; + /// CRC, coding, interleaving and rate matching AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); start_meas(dlsch_encoding_stats); @@ -206,7 +207,6 @@ for (int i=0; i<n_dmrs>>4; i++) { printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n", start_sc, rel15->start_symbol, rel15->n_prb, rel15->nb_symbols); #endif - for (int ap=0; ap<rel15->nb_layers; ap++) { // DMRS params for this ap @@ -221,6 +221,7 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); #endif uint8_t k_prime=0; uint16_t m=0, n=0, dmrs_idx=0, k=0; + int txdataF_offset = (slot%2)*frame_parms->samples_per_slot_wCP; if (dmrs_type == NFAPI_NR_DMRS_TYPE1) // another if condition to be included to check pdsch config type (reference of k) dmrs_idx = rel15->start_prb*6; else @@ -230,12 +231,12 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); k = start_sc; for (int i=0; i<rel15->n_prb*NR_NB_SC_PER_RB; i++) { if ((l == dmrs_symbol) && (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_type))%(frame_parms->ofdm_symbol_size)))) { - ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[dmrs_idx<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (Wt[l_prime[0]]*Wf[k_prime]*amp*mod_dmrs[(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING printf("dmrs_idx %d\t l %d \t k %d \t k_prime %d \t n %d \t txdataF: %d %d\n", -dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], -((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); +dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], +((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif dmrs_idx++; k_prime++; @@ -245,12 +246,12 @@ dmrs_idx, l, k, k_prime, n, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_ else { - ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1] = (amp * tx_layers[ap][m<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", -m, l, k, ((int16_t*)txdataF[ap])[(l*frame_parms->ofdm_symbol_size + k)<<1], -((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1]); +m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], +((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif m++; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h index 4942ffe2f467eb2d22079b012ff8f9cd504bf858..dc7489ea512c9d3b988dc707961032d9eda60314 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.h @@ -79,4 +79,4 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int slot_rx, int UE_id, uint8_t harq_pid); - +int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 6e991faf37246a3a72bd4501fe5513b4086faf25..db0c601b2535317f7c82d43e2ee13369e5ef0439 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -48,7 +48,7 @@ #include "common/utils/LOG/log.h" #include <syscall.h> //#define DEBUG_ULSCH_DECODING -#define gNB_DEBUG_TRACE +//#define gNB_DEBUG_TRACE #define OAI_UL_LDPC_MAX_NUM_LLR 27000//26112 // NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX = 68*384 //#define PRINT_CRC_CHECK @@ -311,7 +311,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, int16_t z [68*384]; int8_t l [68*384]; - uint8_t kc; + uint8_t kc=255; uint8_t Ilbrm = 0; uint32_t Tbslbrm = 950984; double Coderate = 0.0; @@ -568,6 +568,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } + AssertFatal(kc!=255,""); for (i=Kr_bytes,j=K_bytes_F-((2*p_decParams->Z)>>3); i < ((kc*p_decParams->Z)>>3); i++, j++) { pv[i]= _mm_loadu_si128((__m128i*)(&harq_process->d[r][8*j])); } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 752d06fb21c766152a35a86110f0557a44bb61de..aaa304ec6373c1c194e41ddbc5a2fc735be928b4 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -205,10 +205,10 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue, unsigned int pilot_cnt; int16_t ch[2],*pil,*rxF,*dl_ch,*fl,*fm,*fr; int ch_offset,symbol_offset; - int slot_pbch; - fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; + //int slot_pbch; + //fapi_nr_pbch_config_t *pbch_config = &ue->nrUE_config.pbch_config; // initialized to 5ms in nr_init_ue for scenarios where UE is not configured (otherwise acquired by cell configuration from gNB or LTE) - uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; + //uint8_t ssb_periodicity = 10;// ue->ssb_periodicity; //uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1]; @@ -874,7 +874,7 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue, //} // check if PRB crosses DC and improve estimates around DC - if ((bwp_start_subcarrier >= ue->frame_parms.ofdm_symbol_size/2) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { + if ((bwp_start_subcarrier < ue->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pdsch*12 >= ue->frame_parms.ofdm_symbol_size)) { dl_ch = (int16_t *)&dl_ch_estimates[aarx][ch_offset]; uint16_t idxDC = 2*(ue->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); uint16_t idxPil = idxDC/2; diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index de88858c2da60ea4cf2365fe30d2651b5ddb2b63..3c6784be7e8f142a322bb7914406b434cd1a734a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -50,6 +50,15 @@ //#define NR_LTE_PDCCH_DCI_SWITCH #define NR_PDCCH_DCI_RUN // activates new nr functions //#define NR_PDCCH_DCI_DEBUG // activates NR_PDCCH_DCI_DEBUG logs +#ifdef NR_PDCCH_DCI_DEBUG +#define LOG_DNL(a, ...) printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#define LOG_DD(a, ...) printf("\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#define LOG_DDD(a, ...) printf("\t\t<-NR_PDCCH_DCI_DEBUG (%s)-> " a, __func__, ##__VA_ARGS__ ) +#else +#define LOG_DNL(a...) +#define LOG_DD(a...) +#define LOG_DDD(a...) +#endif #define NR_NBR_CORESET_ACT_BWP 3 // The number of CoreSets per BWP is limited to 3 (including initial CORESET: ControlResourceId 0) #define NR_NBR_SEARCHSPACE_ACT_BWP 10 // The number of SearSpaces per BWP is limited to 10 (including initial SEARCHSPACE: SearchSpaceId 0) #define PDCCH_TEST_POLAR_TEMP_FIX @@ -134,9 +143,7 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, if (coreset_interleaved==0) f_bundle_j=bundle_j; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j); -#endif + LOG_DNL("[r=%d,c=%d] bundle_j(%d) interleaved at f_bundle_j(%d)\n",r,c,bundle_j,f_bundle_j); } f_reg = (f_bundle_j*reg_bundle_size_L)+(reg%reg_bundle_size_L); @@ -145,11 +152,9 @@ void nr_pdcch_demapping_deinterleaving(uint32_t *llr, for (int i=0; i<9; i++) { z[index_z + i] = llr[index_llr + i]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_demapping_deinterleaving)-> [reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", + LOG_DDD("[reg=%d,bundle_j=%d] z[%d]=(%d,%d) <-> \t[f_reg=%d,fbundle_j=%d] llr[%d]=(%d,%d) \n", reg,bundle_j,(index_z + i),*(int16_t *) &z[index_z + i],*(1 + (int16_t *) &z[index_z + i]), f_reg,f_bundle_j,(index_llr + i),*(int16_t *) &llr[index_llr + i], *(1 + (int16_t *) &llr[index_llr + i])); -#endif } if ((reg%reg_bundle_size_L) == 0) r++; @@ -167,13 +172,11 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, pdcch_llrp = &pdcch_llr[2 * symbol * coreset_nbr_rb * 9]; if (!pdcch_llrp) { - printf("pdcch_qpsk_llr: llr is null, symbol %d\n", symbol); + LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n", symbol); return (-1); } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %d\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llrp-pdcch_llr); -#endif + LOG_DDD("llr logs: pdcch qpsk llr for symbol %d (pos %d), llr offset %ld\n",symbol,(symbol*frame_parms->N_RB_DL*12),pdcch_llrp-pdcch_llr); //for (i = 0; i < (frame_parms->N_RB_DL * ((symbol == 0) ? 16 : 24)); i++) { for (i = 0; i < (coreset_nbr_rb * ((symbol == 0) ? 18 : 18)); i++) { @@ -184,9 +187,7 @@ int32_t nr_pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, int32_t **rxdataF_comp, else *pdcch_llrp = (*rxF); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_llr)-> llr logs: rb=%d i=%d *rxF:%d => *pdcch_llrp:%d\n",i/18,i,*rxF,*pdcch_llrp); -#endif + LOG_DDD("llr logs: rb=%d i=%d *rxF:%d => *pdcch_llrp:%d\n",i/18,i,*rxF,*pdcch_llrp); rxF++; pdcch_llrp++; } @@ -207,7 +208,7 @@ int32_t pdcch_llr(NR_DL_FRAME_PARMS *frame_parms, pdcch_llr8 = &pdcch_llr[2*symbol*frame_parms->N_RB_DL*12]; if (!pdcch_llr8) { - printf("pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); + LOG_E(PHY,"pdcch_qpsk_llr: llr is null, symbol %d\n",symbol); return(-1); } @@ -330,43 +331,33 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //uint8_t rb_count_bit; uint8_t i, j, aarx, bitcnt_coreset_freq_dom=0; int32_t *dl_ch0, *dl_ch0_ext, *rxF, *rxF_ext; -#ifdef NR_PDCCH_DCI_DEBUG - int nushiftmod3 = frame_parms->nushift % 3; -#endif -#if defined(DEBUG_DCI_DECODING) || defined(NR_PDCCH_DCI_DEBUG) - uint8_t symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol; -#endif c_rb = n_BWP_start; // c_rb is the common resource block: RB within the BWP #ifdef DEBUG_DCI_DECODING + uint8_t symbol_mod = (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol; LOG_I(PHY, "extract_rbs_single: symbol_mod %d\n",symbol_mod); #endif for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { if (high_speed_flag == 1) { dl_ch0 = &dl_ch_estimates[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][ (symbol * (frame_parms->ofdm_symbol_size (%d))) = (%d)]\n", + LOG_DDD("dl_ch0 = &dl_ch_estimates[aarx = (%d)][ (symbol * (frame_parms->ofdm_symbol_size (%d))) = (%d)]\n", aarx,frame_parms->ofdm_symbol_size,(symbol * (frame_parms->ofdm_symbol_size))); -#endif } else { dl_ch0 = &dl_ch_estimates[aarx][0]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx); -#endif + LOG_DDD("dl_ch0 = &dl_ch_estimates[aarx = (%d)][0]\n",aarx); } dl_ch0_ext = &dl_ch_estimates_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", + LOG_DDD("dl_ch0_ext = &dl_ch_estimates_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)); -#endif rxF_ext = &rxdataF_ext[aarx][symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", + LOG_DDD("rxF_ext = &rxdataF_ext[aarx = (%d)][symbol * (frame_parms->N_RB_DL * 9) = (%d)]\n", aarx,symbol * (coreset_nbr_rb * NBR_RE_PER_RB_WITH_DMRS)); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> (for symbol=%d, aarx=%d), symbol_mod=%d, nushiftmod3=%d \n",symbol,aarx,symbol_mod,nushiftmod3); -#endif + LOG_DDD("(for symbol=%d, aarx=%d), symbol_mod=%d, nushiftmod3=%d \n", + symbol,aarx, + (symbol >= (7 - frame_parms->Ncp)) ? symbol - (7 - frame_parms->Ncp) : symbol, + frame_parms->nushift % 3); /* * The following for loop handles treatment of PDCCH contained in table rxdataF (in frequency domain) * In NR the PDCCH IQ symbols are contained within RBs in the CORESET defined by higher layers which is located within the BWP @@ -384,9 +375,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, * then the IQ symbol is going to be found at the position 0+c_rb-N_RB_DL/2 in rxdataF and * we have to point the pointer at (1+c_rb-N_RB_DL/2) in rxdataF */ -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb); -#endif + LOG_DDD("n_BWP_start=%d, coreset_nbr_rb=%d\n",n_BWP_start,coreset_nbr_rb); for (c_rb = n_BWP_start; c_rb < (n_BWP_start + coreset_nbr_rb + (BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN * offset_discontiguous)); c_rb++) { //c_rb_tmp = 0; @@ -399,40 +388,32 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, //c_rb_tmp = c_rb_tmp + 6; c_rb = c_rb + BIT_TO_NBR_RB_CORESET_FREQ_DOMAIN; offset_discontiguous ++; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> we entered here as coreset_freq_dom=%lx (bit %d) is 0, coreset_freq_domain is discontiguous\n",coreset_freq_dom, + LOG_DDD("we entered here as coreset_freq_dom=%lx (bit %d) is 0, coreset_freq_domain is discontiguous\n",coreset_freq_dom, (46 - bitcnt_coreset_freq_dom)); -#endif } } //c_rb = c_rb + c_rb_tmp; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> c_rb=%d\n",c_rb); -#endif + LOG_DDD("c_rb=%d\n",c_rb); rxF=NULL; // first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start) if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif } if ((c_rb >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) { // number of RBs is even and c_rb is higher than half system bandwidth (we don't skip DC) // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif //rxF = &rxdataF[aarx][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol //#ifdef NR_PDCCH_DCI_DEBUG - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + // LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", // c_rb,aarx,(1 + 12*(c_rb - (frame_parms->N_RB_DL>>1)) + (symbol * (frame_parms->ofdm_symbol_size)))); //#endif } @@ -440,30 +421,24 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, if ((c_rb < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif } if ((c_rb > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // number of RBs is odd and c_rb is higher than half system bandwidth + 1 // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC rxF = &rxdataF[aarx][(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][(12*(c_rb - frame_parms->N_RB_DL) - 5 + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(12*(c_rb - (frame_parms->N_RB_DL>>1)) - 6 + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif } if ((c_rb == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // treatment of RB containing the DC // if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC) // we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table) rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", + LOG_DDD("in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n", c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))); -#endif /*if (symbol_mod > 300) { // this if is going to be removed as DM-RS signals are present in all symbols of PDCCH for (i = 0; i < 6; i++) { dl_ch0_ext[i] = dl_ch0[i]; @@ -471,7 +446,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, } rxF = &rxdataF[aarx][(symbol * (frame_parms->ofdm_symbol_size))]; // we point at the 1st part of the rxdataF in symbol #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", + LOG_DDD("in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size))); #endif for (; i < 12; i++) { @@ -497,10 +472,8 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, // then we point at the begining of the symbol part of rxdataF do process second part of RB rxF = &rxdataF[aarx][((symbol * (frame_parms->ofdm_symbol_size)))]; // we point at the 1st part of the rxdataF in symbol -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", + LOG_DDD("in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][(symbol * (frame_parms->ofdm_symbol_size)) = (%d)]\n", c_rb,aarx,(symbol * (frame_parms->ofdm_symbol_size))); -#endif for (; i < 12; i++) { if ((i != 9)) { @@ -535,21 +508,17 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF, for (i = 0; i < 12; i++) { if ((i != 1) && (i != 5) && (i != 9)) { rxF_ext[j] = rxF[i]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n", + LOG_DDD("RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d)\n", c_rb, i, j, *(short *) &rxF_ext[j],*(1 + (short *) &rxF_ext[j]), i, *(short *) &rxF[i], *(1 + (short *) &rxF[i])); -#endif dl_ch0_ext[j] = dl_ch0[i]; - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); + //LOG_DDD("ch %d => dl_ch0(%d,%d)\n", i, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); //printf("\t-> dl_ch0[%d] => dl_ch0_ext[%d](%d,%d)\n", i,j, *(short *) &dl_ch0[i], *(1 + (short*) &dl_ch0[i])); j++; } else { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_extract_rbs_single)-> RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n", + LOG_DDD("RB[c_rb %d] \t RE[re %d] => rxF_ext[%d]=(%d,%d)\t rxF[%d]=(%d,%d) \t\t <==> DM-RS PDCCH, this is a pilot symbol\n", c_rb, i, j, *(short *) &rxF_ext[j], *(1 + (short *) &rxF_ext[j]), i, *(short *) &rxF[i], *(1 + (short *) &rxF[i])); -#endif } } @@ -658,15 +627,13 @@ void nr_pdcch_channel_compensation(int32_t **rxdataF_ext, //print_shorts("rx:",rxdataF128+2); //print_shorts("ch:",dl_ch128+2); //print_shorts("pack:",rxdataF_comp128+2); -#ifdef NR_PDCCH_DCI_DEBUG for (int i=0; i<12 ; i++) - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_channel_compensation)-> rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n", + LOG_DDD("rxdataF128[%d]=(%d,%d) X dlch[%d]=(%d,%d) rxdataF_comp128[%d]=(%d,%d)\n", (rb*12)+i, ((short *)rxdataF128)[i<<1],((short *)rxdataF128)[1+(i<<1)], (rb*12)+i, ((short *)dl_ch128)[i<<1],((short *)dl_ch128)[1+(i<<1)], (rb*12)+i, ((short *)rxdataF_comp128)[i<<1],((short *)rxdataF_comp128)[1+(i<<1)]); -#endif dl_ch128+=3; rxdataF128+=3; rxdataF_comp128+=3; @@ -795,11 +762,9 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", + LOG_DD("symbol_mon=(%d) and start_symbol=(%d)\n",symbol_mon,start_symbol); + LOG_DD("coreset_freq_dom=(%ld) n_rb_offset=(%d) coreset_time_dur=(%d) n_shift=(%d) reg_bundle_size_L=(%d) coreset_interleaver_size_R=(%d) scrambling_ID=(%d) \n", coreset_freq_dom,n_rb_offset,coreset_time_dur,n_shift,reg_bundle_size_L,coreset_interleaver_size_R,pdcch_DMRS_scrambling_id); -#endif // // according to 38.213 v15.1.0: a PDCCH monitoring pattern within a slot, // indicating first symbol(s) of the control resource set within a slot @@ -815,9 +780,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // for (int j=0; j < coreset_nbr_act; j++) { // for each active CORESET (max number of active CORESETs in a BWP is 3), // we calculate the number of RB for each CORESET bitmap -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld)\n",coreset_freq_dom); -#endif + LOG_DD("coreset_freq_dom=(%ld)\n",coreset_freq_dom); int i; //for each bit in the coreset_freq_dom bitmap for (i = 0; i < 45; i++) { @@ -826,22 +789,18 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, } coreset_nbr_rb = 6 * coreset_nbr_rb; // coreset_nbr_rb has to be multiplied by 6 to indicate the number of PRB or REG(=12 RE) within the CORESET -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - uint8_t coreset_nbr_reg = coreset_time_dur * coreset_nbr_rb; - uint32_t coreset_C = (uint32_t)(coreset_nbr_reg / (reg_bundle_size_L * coreset_interleaver_size_R)); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n", - coreset_nbr_rb, coreset_nbr_reg, coreset_nbr_reg, reg_bundle_size_L,coreset_interleaver_size_R, coreset_C); -#endif + LOG_DD("coreset_freq_dom=(%ld,%lx), coreset_nbr_rb=%d\n", coreset_freq_dom,coreset_freq_dom,coreset_nbr_rb); + LOG_DD("coreset_nbr_rb=%d, coreset_nbr_reg=%d, coreset_C=(%d/(%d*%d))=%d\n", + coreset_nbr_rb, + coreset_time_dur * coreset_nbr_rb, + coreset_time_dur * coreset_nbr_rb, + reg_bundle_size_L,coreset_interleaver_size_R, + (uint32_t)((coreset_time_dur * coreset_nbr_rb) / (reg_bundle_size_L * coreset_interleaver_size_R)) ); for (int s = start_symbol; s < (start_symbol + coreset_time_dur); s++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n", + LOG_DD("we enter nr_pdcch_extract_rbs_single(is_secondary_ue=%d) to remove DM-RS PDCCH\n", is_secondary_ue); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); -#endif + LOG_DD("in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n"); nr_pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].rxdataF, pdcch_vars[eNB_id]->dl_ch_estimates, pdcch_vars[eNB_id]->rxdataF_ext, @@ -852,10 +811,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, coreset_freq_dom, coreset_nbr_rb, n_rb_offset); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",avgP); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); -#endif + LOG_DD("we enter pdcch_channel_level(avgP=%d) => compute channel level based on ofdm symbol 0, pdcch_vars[eNB_id]->dl_ch_estimates_ext\n",*avgP); + LOG_DD("in pdcch_channel_level(dl_ch_estimates_ext -> dl_ch_estimates_ext)\n"); // compute channel level based on ofdm symbol 0 pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext, frame_parms, @@ -874,10 +831,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id), T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx), T_INT(avgP[0]), T_INT(avgP[1]), T_INT(avgP[2]), T_INT(avgP[3])); #endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); -#endif + LOG_DD("we enter nr_pdcch_channel_compensation(log2_maxh=%d)\n",log2_maxh); + LOG_DD("in nr_pdcch_channel_compensation(rxdataF_ext x dl_ch_estimates_ext -> rxdataF_comp)\n"); // compute LLRs for ofdm symbol 0 only nr_pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext, pdcch_vars[eNB_id]->dl_ch_estimates_ext, @@ -895,17 +850,13 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif if (frame_parms->nb_antennas_rx > 1) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", + LOG_DD("we enter pdcch_detection_mrc(frame_parms->nb_antennas_rx=%d)\n", frame_parms->nb_antennas_rx); -#endif pdcch_detection_mrc(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp,s); } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> in nr_pdcch_llr(rxdataF_comp -> llr)\n"); -#endif + LOG_DD("we enter nr_pdcch_llr(for symbol %d), pdcch_vars[eNB_id]->rxdataF_comp ---> pdcch_vars[eNB_id]->llr \n",s); + LOG_DD("in nr_pdcch_llr(rxdataF_comp -> llr)\n"); nr_pdcch_llr(frame_parms, pdcch_vars[eNB_id]->rxdataF_comp, pdcch_vars[eNB_id]->llr, @@ -923,9 +874,7 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, #endif } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we enter nr_pdcch_demapping_deinterleaving()\n"); -#endif + LOG_DD("we enter nr_pdcch_demapping_deinterleaving()\n"); nr_pdcch_demapping_deinterleaving((uint32_t *) pdcch_vars[eNB_id]->llr, (uint32_t *) pdcch_vars[eNB_id]->e_rx, frame_parms, @@ -942,12 +891,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue, // get_nCCE(n_pdcch_symbols, frame_parms, mi) * 72, pdcch_DMRS_scrambling_id, do_common); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> we end nr_pdcch_unscrambling()\n"); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_rx_pdcch)-> Ending nr_rx_pdcch() function\n"); -#endif + LOG_DD("we end nr_pdcch_unscrambling()\n"); + LOG_DD("Ending nr_rx_pdcch() function\n"); return (0); } #endif @@ -1006,22 +951,20 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 //uint32_t calc_x2=puissance_2_16%puissance_2_31; x2 = (((1<<16)*n_rnti)+n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3 // x2 = (nr_tti_rx << 9) + frame_parms->Nid_cell; //this is c_init in 36.211 Sec 6.8.2 -#ifdef NR_PDCCH_DCI_DEBUG - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> (c_init=%d, n_id=%d, n_rnti=%d, length=%d)\n",x2,n_id,n_rnti,length); -#endif + //LOG_DDD(" (c_init=%d, n_id=%d, n_rnti=%d, length=%d)\n",x2,n_id,n_rnti,length); for (i = 0; i < length; i++) { if ((i & 0x1f) == 0) { s = lte_gold_generic(&x1, &x2, reset); - //printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> lte_gold[%d]=%x\n",i,s); + //LOG_DDD("lte_gold[%d]=%x\n",i,s); reset = 0; } /* #ifdef NR_PDCCH_DCI_DEBUG - if (i%2 == 0) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", + if (i%2 == 0) LOG_DDD(" unscrambling %d : scrambled_z=%d, => ", i,*(char*) &z[(int)floor(i/2)]); - if (i%2 == 1) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", + if (i%2 == 1) LOG_DDD(" unscrambling %d : scrambled_z=%d, => ", i,*(1 + (char*) &z[(int)floor(i/2)])); #endif if (((s >> (i % 32)) & 1) == 1){ @@ -1035,16 +978,12 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 if (i%2 == 1) printf("unscrambled_z=%d\n",*(1 + (char*) &z[(int)floor(i/2)])); #endif */ -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_pdcch_unscrambling)-> unscrambling %d : scrambled_z=%d, => ", + LOG_DDD(" unscrambling %d : scrambled_z=%d, => ", i,z[i]); -#endif if (((s >> (i % 32)) & 1) == 1) z[i] = -z[i]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("unscrambled_z=%d\n",z[i]); -#endif + LOG_DDD("unscrambled_z=%d\n",z[i]); } } @@ -1090,19 +1029,15 @@ void nr_dci_decoding_procedure0(int s, //Table 10.1-3: Maximum number of non-overlapped CCEs per slot and per serving cell as a function of the subcarrier spacing value 2^mu*15 KHz, mu {0,1,2,3} //uint8_t cce_max_slot_pdcch_Table10_1_3 [4] = {56,56,48,32}; int coreset_nbr_cce_per_symbol=0; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found is %d \n", *format_found); -#endif + LOG_DDD("format_found is %d \n", *format_found); //if (mode == NO_DCI) { // #ifdef NR_PDCCH_DCI_DEBUG - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx); + // LOG_DDD("skip DCI decoding: expect no DCIs at nr_tti_rx %d in current searchSpace\n", nr_tti_rx); // #endif // return; //} -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> frequencyDomainResources=%lx, duration=%d\n", + LOG_DDD("frequencyDomainResources=%lx, duration=%d\n", pdcch_vars[eNB_id]->coreset[p].frequencyDomainResources, pdcch_vars[eNB_id]->coreset[p].duration); -#endif // nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols, frame_parms, mi); for (int i = 0; i < 45; i++) { @@ -1116,9 +1051,7 @@ void nr_dci_decoding_procedure0(int s, // the number of symbols in the CORESET (pdcch_vars[eNB_id]->coreset[p].duration) // multiplied by the number of bits set to '1' in the frequencyDomainResources bitmap // (1 bit set to '1' corresponds to 6 RB and 1 CCE = 6 RB) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> nCCE[%d]=%d\n",p,nCCE[p]); -#endif + LOG_DDD("nCCE[%d]=%d\n",p,nCCE[p]); /* if (nCCE > get_nCCE(3, frame_parms, 1)) { LOG_D(PHY, @@ -1172,9 +1105,7 @@ void nr_dci_decoding_procedure0(int s, nb_candidates = pdcch_vars[eNB_id]->searchSpace[s].searchSpaceType.srs_nrofCandidates; } else { nb_candidates = (L2 == 4) ? 4 : ((L2 == 8)? 2 : 1); // according to Table 10.1-1 (38.213 section 10.1) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> we are in common searchSpace and nb_candidates=%u for L2=%d\n", nb_candidates, L2); -#endif + LOG_DDD("we are in common searchSpace and nb_candidates=%u for L2=%d\n", nb_candidates, L2); } } else { switch (L2) { @@ -1211,9 +1142,7 @@ void nr_dci_decoding_procedure0(int s, Yk = (Yk * A[p%3]) % 65537; } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> L2(%d) | nCCE[%d](%d) | Yk(%u) | nb_candidates(%u)\n", L2, p, nCCE[p], Yk, nb_candidates); -#endif + LOG_DDD("L2(%d) | nCCE[%d](%d) | Yk(%u) | nb_candidates(%u)\n", L2, p, nCCE[p], Yk, nb_candidates); /* for (CCEind=0; CCEind<nCCE2; CCEind+=(1<<L)) {*/ @@ -1224,27 +1153,19 @@ void nr_dci_decoding_procedure0(int s, if (L==4) m_p_s_L_max=1; // Table 10.1-2 is not defined for L=4 -#ifdef NR_PDCCH_DCI_DEBUG - if(0 <= L && L < 4) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]); -#endif + if(0 <= L && L < 4) LOG_DDD("m_max_slot_pdcch_Table10_1_2(%d)=%d\n",L,m_max_slot_pdcch_Table10_1_2[L]); for (m = 0; m < nb_candidates; m++) { int n_ci = 0; if (nCCE[p] < L2) return; -#ifdef NR_PDCCH_DCI_DEBUG - int debug1 = nCCE[p] / L2; - int debug2 = L2*m_p_s_L_max; - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",debug1,p,nCCE[p],L2); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",debug2,L2,m_p_s_L_max); -#endif + LOG_DDD("debug1(%d)=nCCE[p]/L2 | nCCE[%d](%d) | L2(%d)\n",nCCE[p] / L2,p,nCCE[p],L2); + LOG_DDD("debug2(%d)=L2*m_p_s_L_max | L2(%d) | m_p_s_L_max(%d)\n",L2*m_p_s_L_max,L2,m_p_s_L_max); CCEind = (((Yk + (uint16_t)(floor((m*nCCE[p])/(L2*m_p_s_L_max))) + n_ci) % (uint16_t)(floor(nCCE[p] / L2))) * L2); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEind(%d) = (((Yk(%u) + ((m(%u)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) %% (nCCE[p] / L2)) * L2)\n", + LOG_DDD("CCEind(%d) = (((Yk(%u) + ((m(%u)*nCCE[p](%d))/(L2(%d)*m_p_s_L_max(%d)))) %% (nCCE[p] / L2)) * L2)\n", CCEind,Yk,m,nCCE[p],L2,m_p_s_L_max); - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> n_candidate(m)=%u | CCEind=%d |",m,CCEind); -#endif + LOG_DDD("n_candidate(m)=%u | CCEind=%d |",m,CCEind); if (CCEind < 32) CCEmap = CCEmap0; @@ -1283,9 +1204,7 @@ void nr_dci_decoding_procedure0(int s, CCEmap_cand = (*CCEmap) & CCEmap_mask; // CCE is not allocated yet -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> CCEmap_cand=%u \n",CCEmap_cand); -#endif + LOG_DDD("CCEmap_cand=%u \n",CCEmap_cand); if (CCEmap_cand == 0) { #ifdef DEBUG_DCI_DECODING @@ -1298,15 +1217,11 @@ void nr_dci_decoding_procedure0(int s, pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_uss); #endif -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n"); -#endif + LOG_DDD("... we enter function dci_decoding(sizeof_bits=%d L=%d) -----\n",sizeof_bits,L); + LOG_DDD("... we have to replace this part of the code by polar decoding\n"); // for (int m=0; m < (nCCE[p]*6*9*2); m++) -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n", + LOG_DDD("(polar decoding)-> polar intput (with coreset_time_dur=%d, coreset_nbr_rb=%d, p=%d, CCEind=%d): \n", coreset_time_dur,coreset_nbr_rb,p,CCEind); -#endif /* int reg_p=0,reg_e=0; for (int m=0; m < (L2*6); m++){ @@ -1331,7 +1246,7 @@ void nr_dci_decoding_procedure0(int s, //polar_hex[j] = (polar_hex[j]<<1) + ((polar_input[i]==-1)? 1:0); polar_hex[j] = polar_hex[j] + (((polar_input[i]==((-1)/sqrt(2)))?1:0)<<(i%32)); } - for (j=0;j<27;j++) printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: polar decoding input)-> polar_hex[%d]=%x\n",j,polar_hex[j]); + for (j=0;j<27;j++) LOG_DDD("polar_hex[%d]=%x\n",j,polar_hex[j]); #endif */ uint64_t dci_estimation[2]= {0}; @@ -1342,17 +1257,13 @@ void nr_dci_decoding_procedure0(int s, currentPtrDCI); crc = decoderState; //crc = (crc16(&dci_decoded_output[current_thread_id][0], sizeof_bits) >> 16) ^ extract_crc(&dci_decoded_output[current_thread_id][0], sizeof_bits); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we end function dci_decoding() with crc=%x\n",crc); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> ... we have to replace this part of the code by polar decoding\n"); -#endif + LOG_DDD("... we end function dci_decoding() with crc=%x\n",crc); + LOG_DDD("... we have to replace this part of the code by polar decoding\n"); #ifdef DEBUG_DCI_DECODING - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0: crc =>%d\n",crc); + LOG_DDD("(nr_dci_decoding_procedure0: crc =>%d\n",crc); #endif //uint16_t tc_rnti, uint16_t int_rnti, uint16_t sfi_rnti, uint16_t tpc_pusch_rnti, uint16_t tpc_pucch_rnti, uint16_t tpc_srs__rnti -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled); -#endif + LOG_DDD("format_found=%d\n",*format_found); + LOG_DDD("crc_scrambled=%d\n",*crc_scrambled); if (crc == crc_scrambled_values[_C_RNTI_]) { *crc_scrambled =_c_rnti; @@ -1420,10 +1331,8 @@ void nr_dci_decoding_procedure0(int s, } -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> format_found=%d\n",*format_found); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> crc_scrambled=%d\n",*crc_scrambled); -#endif + LOG_DDD("format_found=%d\n",*format_found); + LOG_DDD("crc_scrambled=%d\n",*crc_scrambled); if (*format_found!=255) { dci_alloc[*dci_cnt].dci_length = sizeof_bits; @@ -1432,31 +1341,29 @@ void nr_dci_decoding_procedure0(int s, dci_alloc[*dci_cnt].firstCCE = CCEind; memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_estimation,8); -#ifdef NR_PDCCH_DCI_DEBUG - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n", + LOG_DDD("rnti matches -> DCI FOUND !!! crc =>0x%x, sizeof_bits %d, sizeof_bytes %d \n", dci_alloc[*dci_cnt].rnti, dci_alloc[*dci_cnt].dci_length, sizeof_bytes); - printf ("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n", + LOG_DDD("dci_cnt %d (format_css %d crc_scrambled %d) L %d, firstCCE %d pdu[0] 0x%lx pdu[1] 0x%lx \n", *dci_cnt, format_css,*crc_scrambled,dci_alloc[*dci_cnt].L, dci_alloc[*dci_cnt].firstCCE,dci_alloc[*dci_cnt].dci_pdu[0],dci_alloc[*dci_cnt].dci_pdu[1]); -#endif if ((format_css == cformat0_0_and_1_0) || (format_uss == uformat0_0_and_1_0)) { if ((*crc_scrambled == _p_rnti) || (*crc_scrambled == _si_rnti) || (*crc_scrambled == _ra_rnti)) { dci_alloc[*dci_cnt].format = format1_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_1_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> a format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("a format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } else { if ((dci_estimation[0]&1) == 0) { dci_alloc[*dci_cnt].format = format0_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_0_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> b format0_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("b format0_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } if ((dci_estimation[0]&1) == 1) { dci_alloc[*dci_cnt].format = format1_0; *dci_cnt = *dci_cnt + 1; *format_found=_format_1_0_found; - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> c format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); + // LOG_DDD("c format1_0=%d and dci_cnt=%d\n",*format_found,*dci_cnt); } } } @@ -1584,9 +1491,7 @@ void nr_dci_decoding_procedure0(int s, */ } // candidate loop -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure0)-> end candidate loop\n"); -#endif + LOG_DDD("end candidate loop\n"); } #endif @@ -1628,7 +1533,7 @@ void nr_dci_decoding_procedure0(int s, unsigned int Yk,nb_candidates = 0,i,m; unsigned int CCEmap_cand; #ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (dci_decoding_procedure0)-> \n"); + LOG_DDD("\n"); #endif nCCE = get_nCCE(pdcch_vars[eNB_id]->num_pdcch_symbols,frame_parms,mi); @@ -2053,9 +1958,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, uint16_t n_RB_DLBWP, uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], uint8_t format) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size)-> crc_scrambled=%d, n_RB_ULBWP=%d, n_RB_DLBWP=%d\n",crc_scrambled,n_RB_ULBWP,n_RB_DLBWP); -#endif + LOG_DDD("crc_scrambled=%d, n_RB_ULBWP=%d, n_RB_DLBWP=%d\n",crc_scrambled,n_RB_ULBWP,n_RB_DLBWP); /* * function nr_dci_format_size calculates and returns the size in bits of a determined format * it also returns an bi-dimensional array 'dci_fields_sizes' with x rows and y columns, where: @@ -2524,7 +2427,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, for (int i=0 ; i<NBR_NR_FORMATS ; i++) { //#ifdef NR_PDCCH_DCI_DEBUG - // printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size)-> i=%d, j=%d\n", i, j); + // LOG_DDD("i=%d, j=%d\n", i, j); //#endif for (int j=0; j<NBR_NR_DCI_FIELDS; j++) { dci_size [i] = dci_size [i] + dci_field_size_table[j][i]; // dci_size[i] contains the size in bits of the dci pdu format i @@ -2533,15 +2436,13 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, //} } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_size[%d]=%d for n_RB_ULBWP=%d\n", + LOG_DDD("(nr_dci_format_size) dci_size[%d]=%d for n_RB_ULBWP=%d\n", i,dci_size[i],n_RB_ULBWP); -#endif } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_fields_sizes[][] = { \n"); + LOG_DDD("(nr_dci_format_size) dci_fields_sizes[][] = { \n"); +#ifdef NR_PDCCH_DCI_DEBUG for (int j=0; j<NBR_NR_DCI_FIELDS; j++) { printf("\t\t"); @@ -2552,9 +2453,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, printf(" }\n"); #endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\n\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_size[0_0]=%d, dci_size[0_1]=%d, dci_size[1_0]=%d, dci_size[1_1]=%d,\n",dci_size[0],dci_size[1],dci_size[2],dci_size[3]); -#endif + LOG_DNL("(nr_dci_format_size) dci_size[0_0]=%d, dci_size[0_1]=%d, dci_size[1_0]=%d, dci_size[1_1]=%d,\n",dci_size[0],dci_size[1],dci_size[2],dci_size[3]); //UL/SUL indicator format0_0 (TS 38.212 subclause 7.3.1.1.1) // - 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding is larger than the number of bits for DCI format 0_0 before padding; @@ -2574,9 +2473,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, //if (format == format0_0) { dci_fields_sizes[PADDING_NR_DCI][0] = dci_size[2] - dci_size[0]; dci_size[0] = dci_size[2]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); -#endif + LOG_DDD("(nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); //} } @@ -2588,9 +2485,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, //if (format == format0_0) { dci_fields_sizes[FREQ_DOM_RESOURCE_ASSIGNMENT_UL][0] -= (dci_size[0] - dci_size[2]); dci_size[0] = dci_size[2]; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); -#endif + LOG_DDD("(nr_dci_format_size) new dci_size[format0_0]=%d\n",dci_size[0]); //} } @@ -2606,9 +2501,9 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, * */ // } -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t\t<-NR_PDCCH_DCI_DEBUG (nr_dci_format_size) dci_fields_sizes[][] = { \n"); + LOG_DDD("(nr_dci_format_size) dci_fields_sizes[][] = { \n"); +#ifdef NR_PDCCH_DCI_DEBUG for (int j=0; j<NBR_NR_DCI_FIELDS; j++) { printf("\t\t"); @@ -2640,10 +2535,8 @@ uint8_t nr_dci_decoding_procedure(int s, format_found_t *format_found, uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]) { // uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure) nr_tti_rx=%d n_RB_ULBWP=%d n_RB_DLBWP=%d format_found=%d\n", + LOG_DD("(nr_dci_decoding_procedure) nr_tti_rx=%d n_RB_ULBWP=%d n_RB_DLBWP=%d format_found=%d\n", nr_tti_rx,n_RB_ULBWP,n_RB_DLBWP,*format_found); -#endif int do_common = (int)searchSpacetype; uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS]; crc_scrambled_t crc_scrambled_ = *crc_scrambled; @@ -2701,16 +2594,9 @@ uint8_t nr_dci_decoding_procedure(int s, * This can be implemented by setting variable 'mode = NO_DCI' when overlap occurs */ //dci_detect_mode_t mode = 3; //dci_detect_mode_select(&ue->frame_parms, nr_tti_rx); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> searSpaceType=%d\n",do_common); - - if (do_common==0) { - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> css_dci_format=%d\n",css_dci_format); - } else { - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> uss_dci_format=%d\n",uss_dci_format); - } + LOG_DD("searSpaceType=%d\n",do_common); + LOG_DD("%s_dci_format=%d\n",do_common?"uss":"css",css_dci_format); -#endif // A set of PDCCH candidates for a UE to monitor is defined in terms of PDCCH search spaces if (do_common==0) { // COMMON SearchSpaceType assigned to current SearchSpace/CORESET @@ -2739,18 +2625,14 @@ uint8_t nr_dci_decoding_procedure(int s, // for format0_0 and format1_0, first we calculate dci pdu size format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<<aggregationLevel)); -#endif old_dci_cnt = dci_cnt; nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2778,16 +2660,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_0, first we calculate dci pdu size format_2_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_sfi_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,4); format_2_0_size_bytes = (format_2_0_size_bits%8 == 0) ? (uint8_t)floor(format_2_0_size_bits/8) : (uint8_t)(floor(format_2_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_0_size_bits=%d, format2_0_size_bytes=%d\n", css_dci_format,format_2_0_size_bits,format_2_0_size_bytes); -#endif for (int aggregationLevelSFI = 0; aggregationLevelSFI<5 ; aggregationLevelSFI++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<<aggregationLevelSFI)); -#endif // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0 old_dci_cnt = dci_cnt; nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, @@ -2812,16 +2690,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_1, first we calculate dci pdu size format_2_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_int_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,5); format_2_1_size_bytes = (format_2_1_size_bits%8 == 0) ? (uint8_t)floor(format_2_1_size_bits/8) : (uint8_t)(floor(format_2_1_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_1_size_bits=%d, format2_1_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_1_size_bits=%d, format2_1_size_bytes=%d\n", css_dci_format,format_2_1_size_bits,format_2_1_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<<aggregationLevel)); -#endif // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0 old_dci_cnt = dci_cnt; nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, @@ -2846,16 +2720,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_2, first we calculate dci pdu size format_2_2_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_tpc_pucch_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,6); format_2_2_size_bytes = (format_2_2_size_bits%8 == 0) ? (uint8_t)floor(format_2_2_size_bits/8) : (uint8_t)(floor(format_2_2_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_2_size_bits=%d, format2_2_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_2_size_bits=%d, format2_2_size_bytes=%d\n", css_dci_format,format_2_2_size_bits,format_2_2_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<<aggregationLevel)); -#endif // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0 old_dci_cnt = dci_cnt; nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, @@ -2880,16 +2750,12 @@ uint8_t nr_dci_decoding_procedure(int s, // for format2_1, first we calculate dci pdu size format_2_3_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_tpc_srs_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,7); format_2_3_size_bytes = (format_2_3_size_bits%8 == 0) ? (uint8_t)floor(format_2_3_size_bits/8) : (uint8_t)(floor(format_2_3_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_3_size_bits=%d, format2_3_size_bytes=%d\n", + LOG_DD("calculating dci format size for common searchSpaces with format css_dci_format=%d, format2_3_size_bits=%d, format2_3_size_bytes=%d\n", css_dci_format,format_2_3_size_bits,format_2_3_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<<aggregationLevel)); -#endif // for aggregation level 'aggregationLevelSFI'. The number of candidates (nrofCandidates-SFI) will be calculated in function nr_dci_decoding_procedure0 old_dci_cnt = dci_cnt; nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 1, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, @@ -2915,18 +2781,14 @@ uint8_t nr_dci_decoding_procedure(int s, // for format0_0 and format1_0, first we calculate dci pdu size format_0_0_1_0_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,0); format_0_0_1_0_size_bytes = (format_0_0_1_0_size_bits%8 == 0) ? (uint8_t)floor(format_0_0_1_0_size_bits/8) : (uint8_t)(floor(format_0_0_1_0_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", + LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_0_1_0_size_bits=%d, format_0_0_1_0_size_bytes=%d\n", css_dci_format,format_0_0_1_0_size_bits,format_0_0_1_0_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<<aggregationLevel)); -#endif old_dci_cnt = dci_cnt; nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2950,18 +2812,14 @@ uint8_t nr_dci_decoding_procedure(int s, // for format0_0 and format1_0, first we calculate dci pdu size format_0_1_1_1_size_bits = nr_dci_format_size(ue,eNB_id,nr_tti_rx,p,_c_rnti,n_RB_ULBWP,n_RB_DLBWP,dci_fields_sizes,1); format_0_1_1_1_size_bytes = (format_0_1_1_1_size_bits%8 == 0) ? (uint8_t)floor(format_0_1_1_1_size_bits/8) : (uint8_t)(floor(format_0_1_1_1_size_bits/8) + 1); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_1_1_1_size_bits=%d, format_0_1_1_1_size_bytes=%d\n", + LOG_DD("calculating dci format size for UE-specific searchSpaces with format uss_dci_format=%d, format_0_1_1_1_size_bits=%d, format_0_1_1_1_size_bytes=%d\n", css_dci_format,format_0_1_1_1_size_bits,format_0_1_1_1_size_bytes); -#endif for (int aggregationLevel = 0; aggregationLevel<5 ; aggregationLevel++) { // We fix aggregationLevel to 3 for testing=> nbr of CCE=8 //for (int aggregationLevel = 2; aggregationLevel<5 ; aggregationLevel++) { // for aggregation level aggregationLevel. The number of candidates (for L2= 2^aggregationLevel) will be calculated in function nr_dci_decoding_procedure0 -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", + LOG_DD("common searchSpaces with format css_dci_format=%d and aggregation_level=%d\n", css_dci_format,(1<<aggregationLevel)); -#endif old_dci_cnt = dci_cnt; nr_dci_decoding_procedure0(s,p,coreset_time_dur,coreset_nbr_rb,pdcch_vars, 0, nr_tti_rx, dci_alloc, eNB_id, ue->current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2984,12 +2842,8 @@ uint8_t nr_dci_decoding_procedure(int s, *crc_scrambled = crc_scrambled_; *format_found = format_found_; -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> at the end crc_scrambled=%d and format_found=%d\n",*crc_scrambled,*format_found); -#endif -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> at the end dci_cnt=%d \n",dci_cnt); -#endif + LOG_DD("at the end crc_scrambled=%d and format_found=%d\n",*crc_scrambled,*format_found); + LOG_DD("at the end dci_cnt=%d \n",dci_cnt); return(dci_cnt); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c index 48125a01f83d2d7b9b6bea1c091dee17c6963b91..df79abefcdef6d2ce0decc771d8e77e216534581 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_tools_nr.c @@ -37,7 +37,7 @@ //#include "PHY/extern.h" //#include "SCHED/defs.h" #ifdef DEBUG_DCI_TOOLS -#include "PHY/vars.h" + #include "PHY/vars.h" #endif #include "assertions.h" @@ -53,6 +53,12 @@ //#define DEBUG_DCI #define NR_PDCCH_DCI_TOOLS //#define NR_PDCCH_DCI_TOOLS_DEBUG +#ifdef NR_PDCCH_DCI_TOOLS_DEBUG +#define LOG_DCI_D(a...) printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) ->" a) +#else +#define LOG_DCI_D(a...) +#endif +#define LOG_DCI_PARM(a...) LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci)" a) typedef unsigned __int128 uint128_t; @@ -66,18 +72,16 @@ int8_t *nr_delta_PUCCH_lut = nr_delta_PUSCH_acc; uint16_t nr_dci_field(uint64_t dci_pdu[2], uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS], - uint8_t dci_field) -{ + uint8_t dci_field) { int dci_size=0; - for (int i=0;i<NBR_NR_DCI_FIELDS;i++) dci_size+=dci_fields_sizes[i]; + for (int i=0; i<NBR_NR_DCI_FIELDS; i++) dci_size+=dci_fields_sizes[i]; AssertFatal(dci_size<65,"DCI has %d > 64 bits, not supported for now\n", - dci_size); - + dci_size); uint16_t first_bit_position = dci_size; - - for (int i=0; i<=dci_field ; i++){ + + for (int i=0; i<=dci_field ; i++) { first_bit_position = first_bit_position - dci_fields_sizes[i]; } @@ -85,928 +89,832 @@ uint16_t nr_dci_field(uint64_t dci_pdu[2], uint16_t tmp2 = 0; for (int i=0; i<dci_fields_sizes[dci_field]; i++) tmp2 |= ((tmp1>>i)&1)<<(dci_fields_sizes[dci_field]-i-1);*/ - return ((uint16_t)(*dci_pdu>>first_bit_position)&((1<<dci_fields_sizes[dci_field])-1)); } int nr_extract_dci_info(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - lte_frame_type_t frame_type, - uint8_t dci_length, - uint16_t rnti, - uint64_t dci_pdu[2], - fapi_nr_dci_pdu_rel15_t *nr_pdci_info_extracted, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - NR_DCI_format_t dci_format, - uint8_t nr_tti_rx, - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]) -{ - -/* - * This function will extract the different elements of the dci pdu and interpret the values extracted to update correctly the parameters in: - * NR_DL_UE_HARQ_t *pdlsch0_harq, - * NR_UE_DLSCH_t *pdlsch0, - * - * We need to know the dci length and the dci_fields_sizes (array containing each field size in number of bits) - * In order to get the value of a specific field we will proceed as follows (let's have a look to an example: - * If the length of the pdu is 38 bits and the content of the dci_pdu is 0x3A8900789A (pdu is 11 1010 1000 1001 0000 0000 0111 1000 1001 1010) - * If the dci_fields_sizes is {0 0 1 0 0 0 0 0 0 13 0 1 0 0 0 0 0 0 0 0 0 0 5 1 2 4 2 0 0 0 2 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...} - * This means: - * number bits for carrier_ind field is 0 - * number bits for sul_ind_0_1 field is 0 - * number bits for identifier_dci_formats field is 0 - * number bits for slot_format_ind field is 0 - * number bits for pre_emption_ind field is 0 - * ... - * number bits for freq_dom_resource_assignment_DL field is 13 - * ... - * number bits for padding is 0 - * In order to extract the information of (e.g.) freq_dom_resource_assignment_DL field, - * we will do a left-shift of 1 position (because previous to this field, and according to the dci_fields_sizes array, there is only one non-empty field of size 1 bit) -> (1 1010 1000 1001 0000 0000 0111 1000 1001 1010 0) - * then we will do a right-shit of dci_length-13 positions -> (1 1010 1000 1001). And this is the content of the freq_dom_resource_assignment_DL field - * - * - * At the moment we have implemented the following formats: - * - * Format 0_0, that contains the following fields according to Specification 38.212 V15.1.1 Section 7.3.1 - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 32 TPC_PUSCH: - * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - * 50 SUL_IND_0_0: - * - * Format 0_1, that contains the following fields - * with CRC scrambled by C-RNTI or CS-RNTI or SP-CSI-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 1 CARRIER_IND - * 2 SUL_IND_0_1 - * 7 BANDWIDTH_PART_IND - * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 29 FIRST_DAI - * 30 SECOND_DAI - * 32 TPC_PUSCH: - * 36 SRS_RESOURCE_IND: - * 37 PRECOD_NBR_LAYERS: - * 38 ANTENNA_PORTS: - * 40 SRS_REQUEST: - * 42 CSI_REQUEST: - * 43 CBGTI - * 45 PTRS_DMRS - * 46 BETA_OFFSET_IND - * 47 DMRS_SEQ_INI - * 48 UL_SCH_IND - * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space - * - * Format 1_0, that contains the following fields - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * 34 PUCCH_RESOURCE_IND: - * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - * 55 RESERVED_NR_DCI - * - * If the CRC of the DCI format 1_0 is scrambled by C-RNTI and the "Frequency domain resource assignment" field are of all ones, - * the DCI format 1_0 is for random access procedure initiated by a PDCCH order. - * This is not implemented, but the fields are already included: FIXME!!! - * - * with CRC scrambled by P-RNTI - * 8 SHORT_MESSAGE_IND - * 9 SHORT_MESSAGES - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 31 TB_SCALING - * 55 RESERVED_NR_DCI - * - * with CRC scrambled by SI-RNTI - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 26 RV: - * 55 RESERVED_NR_DCI - * - * with CRC scrambled by RA-RNTI - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 31 TB_SCALING - * 55 RESERVED_NR_DCI - * - * with CRC scrambled by TC-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 24 MCS: - * 25 NDI: - * 26 RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * - * Format 1_1, that contains the following fields - * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI - * 0 IDENTIFIER_DCI_FORMATS: - * 1 CARRIER_IND: - * 7 BANDWIDTH_PART_IND: - * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: - * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, - * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 - * 14 PRB_BUNDLING_SIZE_IND: - * 15 RATE_MATCHING_IND: - * 16 ZP_CSI_RS_TRIGGER: - * 18 TB1_MCS: - * 19 TB1_NDI: - * 20 TB1_RV: - * 21 TB2_MCS: - * 22 TB2_NDI: - * 23 TB2_RV: - * 27 HARQ_PROCESS_NUMBER: - * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - * 33 TPC_PUCCH: - * 34 PUCCH_RESOURCE_IND: - * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: - * 38 ANTENNA_PORTS: - * 39 TCI: - * 40 SRS_REQUEST: - * 43 CBGTI: - * 44 CBGFI: - * 47 DMRS_SEQ_INI: - * - * We have not implemented the following formats: - * - * Format 2_0 - * Used for notifying the slot format - * - * Format 2_1 - * Used for notifying the PRB(s) and OFDM symbol(s) where UE may assume no transmission is intended for the UE - * - * Format 2_2 - * This format supports power control commands for semi-persistent scheduling. - * As we can already support power control commands dynamically with formats 0_0/0_1 (TPC PUSCH) and 1_0/1_1 (TPC PUCCH) - * This format will be implemented in the future FIXME!!! - * - * Format 2_3 - * This format is used for power control of uplink sounding reference signals for devices which have not coupled SRS power control to the PUSCH power control - * either because independent control is desirable or because the device is configured without PUCCH and PUSCH - * This format will be implemented in the future FIXME!!! - * - */ + uint8_t eNB_id, + lte_frame_type_t frame_type, + uint8_t dci_length, + uint16_t rnti, + uint64_t dci_pdu[2], + fapi_nr_dci_pdu_rel15_t *nr_pdci_info_extracted, + uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], + NR_DCI_format_t dci_format, + uint8_t nr_tti_rx, + uint16_t n_RB_ULBWP, + uint16_t n_RB_DLBWP, + uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]) { + /* + * This function will extract the different elements of the dci pdu and interpret the values extracted to update correctly the parameters in: + * NR_DL_UE_HARQ_t *pdlsch0_harq, + * NR_UE_DLSCH_t *pdlsch0, + * + * We need to know the dci length and the dci_fields_sizes (array containing each field size in number of bits) + * In order to get the value of a specific field we will proceed as follows (let's have a look to an example: + * If the length of the pdu is 38 bits and the content of the dci_pdu is 0x3A8900789A (pdu is 11 1010 1000 1001 0000 0000 0111 1000 1001 1010) + * If the dci_fields_sizes is {0 0 1 0 0 0 0 0 0 13 0 1 0 0 0 0 0 0 0 0 0 0 5 1 2 4 2 0 0 0 2 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...} + * This means: + * number bits for carrier_ind field is 0 + * number bits for sul_ind_0_1 field is 0 + * number bits for identifier_dci_formats field is 0 + * number bits for slot_format_ind field is 0 + * number bits for pre_emption_ind field is 0 + * ... + * number bits for freq_dom_resource_assignment_DL field is 13 + * ... + * number bits for padding is 0 + * In order to extract the information of (e.g.) freq_dom_resource_assignment_DL field, + * we will do a left-shift of 1 position (because previous to this field, and according to the dci_fields_sizes array, there is only one non-empty field of size 1 bit) -> (1 1010 1000 1001 0000 0000 0111 1000 1001 1010 0) + * then we will do a right-shit of dci_length-13 positions -> (1 1010 1000 1001). And this is the content of the freq_dom_resource_assignment_DL field + * + * + * At the moment we have implemented the following formats: + * + * Format 0_0, that contains the following fields according to Specification 38.212 V15.1.1 Section 7.3.1 + * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 32 TPC_PUSCH: + * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space + * 50 SUL_IND_0_0: + * + * Format 0_1, that contains the following fields + * with CRC scrambled by C-RNTI or CS-RNTI or SP-CSI-RNTI or new-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 1 CARRIER_IND + * 2 SUL_IND_0_1 + * 7 BANDWIDTH_PART_IND + * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 29 FIRST_DAI + * 30 SECOND_DAI + * 32 TPC_PUSCH: + * 36 SRS_RESOURCE_IND: + * 37 PRECOD_NBR_LAYERS: + * 38 ANTENNA_PORTS: + * 40 SRS_REQUEST: + * 42 CSI_REQUEST: + * 43 CBGTI + * 45 PTRS_DMRS + * 46 BETA_OFFSET_IND + * 47 DMRS_SEQ_INI + * 48 UL_SCH_IND + * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space + * + * Format 1_0, that contains the following fields + * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + * 33 TPC_PUCCH: + * 34 PUCCH_RESOURCE_IND: + * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: + * 55 RESERVED_NR_DCI + * + * If the CRC of the DCI format 1_0 is scrambled by C-RNTI and the "Frequency domain resource assignment" field are of all ones, + * the DCI format 1_0 is for random access procedure initiated by a PDCCH order. + * This is not implemented, but the fields are already included: FIXME!!! + * + * with CRC scrambled by P-RNTI + * 8 SHORT_MESSAGE_IND + * 9 SHORT_MESSAGES + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 31 TB_SCALING + * 55 RESERVED_NR_DCI + * + * with CRC scrambled by SI-RNTI + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 26 RV: + * 55 RESERVED_NR_DCI + * + * with CRC scrambled by RA-RNTI + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 31 TB_SCALING + * 55 RESERVED_NR_DCI + * + * with CRC scrambled by TC-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 24 MCS: + * 25 NDI: + * 26 RV: + * 27 HARQ_PROCESS_NUMBER: + * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + * 33 TPC_PUCCH: + * + * Format 1_1, that contains the following fields + * with CRC scrambled by C-RNTI or CS-RNTI or new-RNTI + * 0 IDENTIFIER_DCI_FORMATS: + * 1 CARRIER_IND: + * 7 BANDWIDTH_PART_IND: + * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: + * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, + * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 + * 14 PRB_BUNDLING_SIZE_IND: + * 15 RATE_MATCHING_IND: + * 16 ZP_CSI_RS_TRIGGER: + * 18 TB1_MCS: + * 19 TB1_NDI: + * 20 TB1_RV: + * 21 TB2_MCS: + * 22 TB2_NDI: + * 23 TB2_RV: + * 27 HARQ_PROCESS_NUMBER: + * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + * 33 TPC_PUCCH: + * 34 PUCCH_RESOURCE_IND: + * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: + * 38 ANTENNA_PORTS: + * 39 TCI: + * 40 SRS_REQUEST: + * 43 CBGTI: + * 44 CBGFI: + * 47 DMRS_SEQ_INI: + * + * We have not implemented the following formats: + * + * Format 2_0 + * Used for notifying the slot format + * + * Format 2_1 + * Used for notifying the PRB(s) and OFDM symbol(s) where UE may assume no transmission is intended for the UE + * + * Format 2_2 + * This format supports power control commands for semi-persistent scheduling. + * As we can already support power control commands dynamically with formats 0_0/0_1 (TPC PUSCH) and 1_0/1_1 (TPC PUCCH) + * This format will be implemented in the future FIXME!!! + * + * Format 2_3 + * This format is used for power control of uplink sounding reference signals for devices which have not coupled SRS power control to the PUSCH power control + * either because independent control is desirable or because the device is configured without PUCCH and PUSCH + * This format will be implemented in the future FIXME!!! + * + */ uint8_t dci_fields_sizes_format[NBR_NR_DCI_FIELDS] = {0}; - for (int m=0; m<NBR_NR_DCI_FIELDS; m++) dci_fields_sizes_format[m]=dci_fields_sizes[m][dci_format]; + for (int m=0; m<NBR_NR_DCI_FIELDS; m++) dci_fields_sizes_format[m]=dci_fields_sizes[m][dci_format]; -// uint64_t pdu_bitmap = 0xFFFFFFFFFFFFFFFF; -// uint128_t pdu_bitmap = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; -//#define DCI_MAX_SIZE 128 -// pdu_bitmap = (pdu_bitmap << (DCI_MAX_SIZE - dci_length)) >> (DCI_MAX_SIZE - dci_length); // this variable will help to remove the bits of other fields when left-switching + // uint64_t pdu_bitmap = 0xFFFFFFFFFFFFFFFF; + // uint128_t pdu_bitmap = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + //#define DCI_MAX_SIZE 128 + // pdu_bitmap = (pdu_bitmap << (DCI_MAX_SIZE - dci_length)) >> (DCI_MAX_SIZE - dci_length); // this variable will help to remove the bits of other fields when left-switching uint8_t dci_field=0; -// uint8_t sizes_count=0; -// uint8_t left_shift=0; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Entering function nr_extract_dci_info() with dci_pdu=%lx %lx dci_length=%d\n", + // uint8_t sizes_count=0; + // uint8_t left_shift=0; + LOG_DCI_D("Entering function nr_extract_dci_info() with dci_pdu=%lx %lx dci_length=%d\n", dci_pdu[0],dci_pdu[1], dci_length); - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> for format %d, dci_fields_sizes {",dci_format); - for (int i=0; i<NBR_NR_DCI_FIELDS; i++) printf("%d ",dci_fields_sizes[i][dci_format]); - printf("}\n"); - #endif + LOG_DCI_D("for format %d, dci_fields_sizes {",dci_format); +#ifdef NR_PDCCH_DCI_TOOLS_DEBUG + + for (int i=0; i<NBR_NR_DCI_FIELDS; i++) printf("%d ",dci_fields_sizes[i][dci_format]); -// uint8_t prev_ndi = pdlsch0_harq->DCINdi; + printf("}\n"); +#endif + // uint8_t prev_ndi = pdlsch0_harq->DCINdi; - /* - * Some dci fields need to be interpreted before the others. - */ + /* + * Some dci fields need to be interpreted before the others. + */ if (dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format] != 0) { // E.g: 27 HARQ_PROCESS_NUMBER (27 is the position in dci_fields_sizes array for field HARQ_PROCESS_NUMBER) //for (int i=0; i<=HARQ_PROCESS_NUMBER; i++) left_shift = left_shift + dci_fields_sizes[i][dci_format]; nr_pdci_info_extracted->harq_process_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,HARQ_PROCESS_NUMBER); //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format])); //left_shift = 0; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); - #endif + LOG_DCI_D("nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); } -/* - if ((dci_format == format1_0) || (dci_format == format1_1)) { - if (rnti==crc_scrambled_values[_SI_RNTI_]) { - ue->dlsch_SI[eNB_id]->active = 1; - } else if (rnti==crc_scrambled_values[_P_RNTI_]) { - ue->dlsch_p[eNB_id]->active = 1; - } else if (rnti==crc_scrambled_values[_RA_RNTI_]) { - ue->dlsch_ra[eNB_id]->active = 1; - } else { - pdlsch0->active = 1; - } - pdlsch0->rnti = rnti; - pdlsch0_harq->codeword = 0; - pdlsch0_harq->Nl = 1; -// pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; - pdlsch0_harq->dl_power_off = 1; //no power offset - - if ((rnti==crc_scrambled_values[_SI_RNTI_]) || (rnti==crc_scrambled_values[_P_RNTI_]) || (rnti==crc_scrambled_values[_RA_RNTI_])) { - pdlsch0_harq->round = 0; - pdlsch0_harq->status = ACTIVE; - } else { + + /* + if ((dci_format == format1_0) || (dci_format == format1_1)) { + if (rnti==crc_scrambled_values[_SI_RNTI_]) { + ue->dlsch_SI[eNB_id]->active = 1; + } else if (rnti==crc_scrambled_values[_P_RNTI_]) { + ue->dlsch_p[eNB_id]->active = 1; + } else if (rnti==crc_scrambled_values[_RA_RNTI_]) { + ue->dlsch_ra[eNB_id]->active = 1; + } else { + pdlsch0->active = 1; + } + pdlsch0->rnti = rnti; + pdlsch0_harq->codeword = 0; + pdlsch0_harq->Nl = 1; + // pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; + pdlsch0_harq->dl_power_off = 1; //no power offset + + if ((rnti==crc_scrambled_values[_SI_RNTI_]) || (rnti==crc_scrambled_values[_P_RNTI_]) || (rnti==crc_scrambled_values[_RA_RNTI_])) { + pdlsch0_harq->round = 0; + pdlsch0_harq->status = ACTIVE; + } else { + } } - } -*/ + */ for (dci_field=0; dci_field<NBR_NR_DCI_FIELDS; dci_field++) { //left_shift = left_shift + dci_fields_sizes[dci_field][dci_format]; - if (dci_fields_sizes[dci_field][dci_format] != 0){ + if (dci_fields_sizes[dci_field][dci_format] != 0) { //sizes_count = dci_fields_sizes[dci_field][dci_format]; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> dci_fields_sizes[%d][%d] = %d\n",dci_field,dci_format,dci_fields_sizes[dci_field][dci_format]); - #endif - - switch (dci_field){ - case IDENTIFIER_DCI_FORMATS: // 0 IDENTIFIER_DCI_FORMATS: (field defined for format0_0,format0_1,format1_0,format1_1,format2_0,format2_1,format2_2,format2_3) - // if format 0_0: The value of this bit field is always set to 0, indicating an UL DCI format (TS38.212 Section 7.3.1.1.1) - // if format 1_0: The value of this bit field is always set to 1, indicating a DL DCI format (TS38.212 Section 7.3.1.2.1) - nr_pdci_info_extracted->identifier_dci_formats = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->identifier_dci_formats=%x\n",nr_pdci_info_extracted->identifier_dci_formats); - #endif - break; + LOG_DCI_D("dci_fields_sizes[%d][%d] = %d\n",dci_field,dci_format,dci_fields_sizes[dci_field][dci_format]); + + switch (dci_field) { + case IDENTIFIER_DCI_FORMATS: // 0 IDENTIFIER_DCI_FORMATS: (field defined for format0_0,format0_1,format1_0,format1_1,format2_0,format2_1,format2_2,format2_3) + // if format 0_0: The value of this bit field is always set to 0, indicating an UL DCI format (TS38.212 Section 7.3.1.1.1) + // if format 1_0: The value of this bit field is always set to 1, indicating a DL DCI format (TS38.212 Section 7.3.1.2.1) + nr_pdci_info_extracted->identifier_dci_formats = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->identifier_dci_formats=%x\n",nr_pdci_info_extracted->identifier_dci_formats); + break; - case CARRIER_IND: // 1 CARRIER_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) - // 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] - nr_pdci_info_extracted->carrier_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); -#ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->carrier_ind=%x\n",nr_pdci_info_extracted->carrier_ind); -#endif - break; - case SUL_IND_0_1: // 2 SUL_IND_0_1: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->sul_ind_0_1 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_1=%x\n",nr_pdci_info_extracted->sul_ind_0_1); - #endif - break; + case CARRIER_IND: // 1 CARRIER_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) + // 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] + nr_pdci_info_extracted->carrier_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->carrier_ind=%x\n",nr_pdci_info_extracted->carrier_ind); + break; - case SLOT_FORMAT_IND: // 3 SLOT_FORMAT_IND: (field defined for -,-,-,-,format2_0,-,-,-) - // size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] - nr_pdci_info_extracted->slot_format_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->slot_format_ind=%x\n",nr_pdci_info_extracted->slot_format_ind); - #endif - break; - case PRE_EMPTION_IND: // 4 PRE_EMPTION_IND: (field defined for -,-,-,-,-,format2_1,-,-) - // size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits - nr_pdci_info_extracted->pre_emption_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pre_emption_ind=%x\n",nr_pdci_info_extracted->pre_emption_ind); - #endif - break; - case BLOCK_NUMBER: // 5 BLOCK_NUMBER: (field defined for -,-,-,-,-,-,-,format2_3) - // starting position of a block is determined by the parameter startingBitOfFormat2_3 - nr_pdci_info_extracted->block_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->block_number=%x\n",nr_pdci_info_extracted->block_number); - #endif - break; - case CLOSE_LOOP_IND: // 6 CLOSE_LOOP_IND: (field defined for -,-,-,-,-,-,format2_2,-) - // The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits - nr_pdci_info_extracted->close_loop_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->close_loop_ind=%x\n",nr_pdci_info_extracted->close_loop_ind); - #endif - break; - case BANDWIDTH_PART_IND: // 7 BANDWIDTH_PART_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->bandwidth_part_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->bandwidth_part_ind=%x\n",nr_pdci_info_extracted->bandwidth_part_ind); - #endif - break; + case SUL_IND_0_1: // 2 SUL_IND_0_1: (field defined for -,format0_1,-,-,-,-,-,-) + nr_pdci_info_extracted->sul_ind_0_1 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->sul_ind_0_1=%x\n",nr_pdci_info_extracted->sul_ind_0_1); + break; - case SHORT_MESSAGE_IND: // 8 SHORT_MESSAGE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) - nr_pdci_info_extracted->short_message_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->short_message_ind=%x\n",nr_pdci_info_extracted->short_message_ind); - #endif - break; + case SLOT_FORMAT_IND: // 3 SLOT_FORMAT_IND: (field defined for -,-,-,-,format2_0,-,-,-) + // size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] + nr_pdci_info_extracted->slot_format_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->slot_format_ind=%x\n",nr_pdci_info_extracted->slot_format_ind); + break; - case SHORT_MESSAGES: // 9 SHORT_MESSAGES: (field defined for -,-,format1_0,format1_1,-,-,-,-) - nr_pdci_info_extracted->short_messages = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->short_messages=%x\n",nr_pdci_info_extracted->short_messages); - #endif - break; + case PRE_EMPTION_IND: // 4 PRE_EMPTION_IND: (field defined for -,-,-,-,-,format2_1,-,-) + // size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits + nr_pdci_info_extracted->pre_emption_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->pre_emption_ind=%x\n",nr_pdci_info_extracted->pre_emption_ind); + break; - case FREQ_DOM_RESOURCE_ASSIGNMENT_UL: // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: (field defined for format0_0,format0_1,-,-,-,-,-,-) - // PUSCH hopping with resource allocation type 1 not considered - // According to 38.214 V15.1.0 Section 6.1.2.2 Two uplink resource allocation schemes, type 0 and type 1, are supported. - // The UE shall assume that when the scheduling PDCCH is received with DCI format 0_0, then uplink resource allocation type 1 is used. - nr_pdci_info_extracted->freq_dom_resource_assignment_UL = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - /*if (dci_format == format0_1){ // uplink resource allocation type 0 or 1 can be used - } - if (dci_format == format0_0){ // only uplink resource allocation type 1 - // At the moment we are supporting only format 1_0 (and not format 1_1), so we only support resource allocation type 1 (and not type 0). - // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): - // RIV = n_RB_ULBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_ULBWP/2) - // RIV = n_RB_ULBWP * (n_RB_ULBWP - l_RB + 1) + (n_RB_ULBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_ULBWP/2) - // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_ULBWP/2) - l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_ULBWP) + 1; - start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_ULBWP; - // if (l_RB - 1) > floor (n_RB_ULBWP/2) we need to recalculate them using the following lines - tmp_RIV = n_RB_ULBWP * (l_RB - 1) + start_RB; - if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_ULBWP/2) and we need to recalculate l_RB and start_RB - l_RB = n_RB_ULBWP - l_RB + 2; - start_RB = n_RB_ULBWP - start_RB - 1; - } - ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_rb = start_RB; - ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->nb_rb = l_RB; - }*/ - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_UL=%x\n",nr_pdci_info_extracted->freq_dom_resource_assignment_UL); - //printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_ULBWP); - #endif - break; + case BLOCK_NUMBER: // 5 BLOCK_NUMBER: (field defined for -,-,-,-,-,-,-,format2_3) + // starting position of a block is determined by the parameter startingBitOfFormat2_3 + nr_pdci_info_extracted->block_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->block_number=%x\n",nr_pdci_info_extracted->block_number); + break; - case FREQ_DOM_RESOURCE_ASSIGNMENT_DL: // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // According to 38.214 V15.1.0 Section 5.1.2.2 Two downlink resource allocation schemes, type 0 and type 1, are supported. - // The UE shall assume that when the scheduling grant is received with DCI format 1_0, then downlink resource allocation type 1 is used. - nr_pdci_info_extracted->freq_dom_resource_assignment_DL = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - /*if (dci_format == format1_1){ // uplink resource allocation type 0 or 1 can be used - } - if (dci_format == format1_0){ // only uplink resource allocation type 1 - // At the moment we are supporting only format 0_0 (and not format 0_1), so we only support resource allocation type 1 (and not type 0). - // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): - // RIV = n_RB_DLBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_DLBWP/2) - // RIV = n_RB_DLBWP * (n_RB_DLBWP - l_RB + 1) + (n_RB_DLBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_DLBWP/2) - // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_DLBWP/2) - l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_DLBWP) + 1; - start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_DLBWP; - // if (l_RB - 1) > floor (n_RB_DLBWP/2) we need to recalculate them using the following lines - tmp_RIV = n_RB_DLBWP * (l_RB - 1) + start_RB; - if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_DLBWP/2) and we need to recalculate l_RB and start_RB - l_RB = n_RB_DLBWP - l_RB + 2; - start_RB = n_RB_DLBWP - start_RB - 1; + case CLOSE_LOOP_IND: // 6 CLOSE_LOOP_IND: (field defined for -,-,-,-,-,-,format2_2,-) + // The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits + nr_pdci_info_extracted->close_loop_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->close_loop_ind=%x\n",nr_pdci_info_extracted->close_loop_ind); + break; + + case BANDWIDTH_PART_IND: // 7 BANDWIDTH_PART_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->bandwidth_part_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->bandwidth_part_ind=%x\n",nr_pdci_info_extracted->bandwidth_part_ind); + break; + + case SHORT_MESSAGE_IND: // 8 SHORT_MESSAGE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) + nr_pdci_info_extracted->short_message_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->short_message_ind=%x\n",nr_pdci_info_extracted->short_message_ind); + break; + + case SHORT_MESSAGES: // 9 SHORT_MESSAGES: (field defined for -,-,format1_0,format1_1,-,-,-,-) + nr_pdci_info_extracted->short_messages = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->short_messages=%x\n",nr_pdci_info_extracted->short_messages); + break; + + case FREQ_DOM_RESOURCE_ASSIGNMENT_UL: // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: (field defined for format0_0,format0_1,-,-,-,-,-,-) + // PUSCH hopping with resource allocation type 1 not considered + // According to 38.214 V15.1.0 Section 6.1.2.2 Two uplink resource allocation schemes, type 0 and type 1, are supported. + // The UE shall assume that when the scheduling PDCCH is received with DCI format 0_0, then uplink resource allocation type 1 is used. + nr_pdci_info_extracted->freq_dom_resource_assignment_UL = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + /*if (dci_format == format0_1){ // uplink resource allocation type 0 or 1 can be used } - pdlsch0_harq->nb_rb = l_RB; - pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number; - pdlsch0->active = 1; - pdlsch0->rnti = rnti; - }*/ - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_DL=%x, RIV = %d\n",nr_pdci_info_extracted->freq_dom_resource_assignment_DL,nr_pdci_info_extracted->freq_dom_resource_assignment_DL); - //printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_DLBWP); - /* - * According to TC 38.212 Subclause 7.3.1.2.1 (V15.2.0) (not implemented FIXME!!!) - * If the CRC of the DCI format 1_0 is scrambled by C-RNTI - * and the "Frequency domain resource assignment" field are of all ones, - * the DCI format 1_0 is for random access procedure initiated by a PDCCH order, - * with all remaining fields set as follows: - * - Random Access Preamble index (6 bits) - * - UL/SUL indicator (1 bit) - * - SS/PBCH index (6 bits) - * - PRACH Mask index (4 bits) - * - Reserved bits (10 bits) - * - */ - /* - * The following commented code is used to verify that l_RB and start_RB are correctly calculated - * - * - printf("\ns_RB\t"); - n_RB_DLBWP = 20; - for (int k = 0 ; k < n_RB_DLBWP; k++) printf("%d\t",k); - printf("\nl_RB"); - for (int j = 1 ; j <= n_RB_DLBWP; j++){ // l_RB - printf("\n%d\t",j); - for (int i = 0 ; i < n_RB_DLBWP; i++) { // start_RB - if ((j-1) <= (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { - tmp_RIV = n_RB_DLBWP * (j - 1) + i; - l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; - start_RB = tmp_RIV%n_RB_DLBWP; - printf("%d(%d,%d) ",tmp_RIV,l_RB,start_RB); - } - if ((j-1) > (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { - tmp_RIV = n_RB_DLBWP * (n_RB_DLBWP - j + 1) + (n_RB_DLBWP - 1 - i); - //l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; - //start_RB = tmp_RIV%n_RB_DLBWP; - l_RB = n_RB_DLBWP - (floor(tmp_RIV/n_RB_DLBWP) + 1) + 2; - start_RB = n_RB_DLBWP - (tmp_RIV%n_RB_DLBWP) - 1; - printf("%d*(%d,%d) ",tmp_RIV,l_RB,start_RB); + if (dci_format == format0_0){ // only uplink resource allocation type 1 + // At the moment we are supporting only format 1_0 (and not format 1_1), so we only support resource allocation type 1 (and not type 0). + // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): + // RIV = n_RB_ULBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_ULBWP/2) + // RIV = n_RB_ULBWP * (n_RB_ULBWP - l_RB + 1) + (n_RB_ULBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_ULBWP/2) + // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_ULBWP/2) + l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_ULBWP) + 1; + start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_ULBWP; + // if (l_RB - 1) > floor (n_RB_ULBWP/2) we need to recalculate them using the following lines + tmp_RIV = n_RB_ULBWP * (l_RB - 1) + start_RB; + if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_ULBWP/2) and we need to recalculate l_RB and start_RB + l_RB = n_RB_ULBWP - l_RB + 2; + start_RB = n_RB_ULBWP - start_RB - 1; } + ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_rb = start_RB; + ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->nb_rb = l_RB; + }*/ + LOG_DCI_D("nr_pdci_info_extracted->freq_dom_resource_assignment_UL=%x\n",nr_pdci_info_extracted->freq_dom_resource_assignment_UL); + //LOG_DCI_D("l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_ULBWP); + break; + + case FREQ_DOM_RESOURCE_ASSIGNMENT_DL: // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: (field defined for -,-,format1_0,format1_1,-,-,-,-) + // According to 38.214 V15.1.0 Section 5.1.2.2 Two downlink resource allocation schemes, type 0 and type 1, are supported. + // The UE shall assume that when the scheduling grant is received with DCI format 1_0, then downlink resource allocation type 1 is used. + nr_pdci_info_extracted->freq_dom_resource_assignment_DL = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + /*if (dci_format == format1_1){ // uplink resource allocation type 0 or 1 can be used } - }*/ - #endif - break; + if (dci_format == format1_0){ // only uplink resource allocation type 1 + // At the moment we are supporting only format 0_0 (and not format 0_1), so we only support resource allocation type 1 (and not type 0). + // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): + // RIV = n_RB_DLBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_DLBWP/2) + // RIV = n_RB_DLBWP * (n_RB_DLBWP - l_RB + 1) + (n_RB_DLBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_DLBWP/2) + // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_DLBWP/2) + l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_DLBWP) + 1; + start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_DLBWP; + // if (l_RB - 1) > floor (n_RB_DLBWP/2) we need to recalculate them using the following lines + tmp_RIV = n_RB_DLBWP * (l_RB - 1) + start_RB; + if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_DLBWP/2) and we need to recalculate l_RB and start_RB + l_RB = n_RB_DLBWP - l_RB + 2; + start_RB = n_RB_DLBWP - start_RB - 1; + } + pdlsch0_harq->nb_rb = l_RB; + pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number; + pdlsch0->active = 1; + pdlsch0->rnti = rnti; + }*/ + LOG_DCI_D("nr_pdci_info_extracted->freq_dom_resource_assignment_DL=%x, RIV = %d\n",nr_pdci_info_extracted->freq_dom_resource_assignment_DL,nr_pdci_info_extracted->freq_dom_resource_assignment_DL); + //LOG_DCI_D("l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_DLBWP); + /* + * According to TC 38.212 Subclause 7.3.1.2.1 (V15.2.0) (not implemented FIXME!!!) + * If the CRC of the DCI format 1_0 is scrambled by C-RNTI + * and the "Frequency domain resource assignment" field are of all ones, + * the DCI format 1_0 is for random access procedure initiated by a PDCCH order, + * with all remaining fields set as follows: + * - Random Access Preamble index (6 bits) + * - UL/SUL indicator (1 bit) + * - SS/PBCH index (6 bits) + * - PRACH Mask index (4 bits) + * - Reserved bits (10 bits) + * + */ + /* + * The following commented code is used to verify that l_RB and start_RB are correctly calculated + * + * + printf("\ns_RB\t"); + n_RB_DLBWP = 20; + for (int k = 0 ; k < n_RB_DLBWP; k++) printf("%d\t",k); + printf("\nl_RB"); + for (int j = 1 ; j <= n_RB_DLBWP; j++){ // l_RB + printf("\n%d\t",j); + for (int i = 0 ; i < n_RB_DLBWP; i++) { // start_RB + if ((j-1) <= (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { + tmp_RIV = n_RB_DLBWP * (j - 1) + i; + l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; + start_RB = tmp_RIV%n_RB_DLBWP; + printf("%d(%d,%d) ",tmp_RIV,l_RB,start_RB); + } + if ((j-1) > (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { + tmp_RIV = n_RB_DLBWP * (n_RB_DLBWP - j + 1) + (n_RB_DLBWP - 1 - i); + //l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; + //start_RB = tmp_RIV%n_RB_DLBWP; + l_RB = n_RB_DLBWP - (floor(tmp_RIV/n_RB_DLBWP) + 1) + 2; + start_RB = n_RB_DLBWP - (tmp_RIV%n_RB_DLBWP) - 1; + printf("%d*(%d,%d) ",tmp_RIV,l_RB,start_RB); + } + } + }*/ + break; - case TIME_DOM_RESOURCE_ASSIGNMENT: // 12 TIME_DOM_RESOURCE_ASSIGNMENT: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) - // 0, 1, 2, 3, or 4 bits as defined in: - // Subclause 6.1.2.1 of [6, TS 38.214] for formats format0_0,format0_1 - // Subclause 5.1.2.1 of [6, TS 38.214] for formats format1_0,format1_1 - // The bitwidth for this field is determined as log2(I) bits, - // where I the number of entries in the higher layer parameter pusch-AllocationList - nr_pdci_info_extracted->time_dom_resource_assignment = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - /*if (dci_format == format0_0 || dci_format == format0_1){ // Subclause 6.1.2.1 of [6, TS 38.214] - k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + case TIME_DOM_RESOURCE_ASSIGNMENT: // 12 TIME_DOM_RESOURCE_ASSIGNMENT: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) + // 0, 1, 2, 3, or 4 bits as defined in: + // Subclause 6.1.2.1 of [6, TS 38.214] for formats format0_0,format0_1 + // Subclause 5.1.2.1 of [6, TS 38.214] for formats format1_0,format1_1 + // The bitwidth for this field is determined as log2(I) bits, + // where I the number of entries in the higher layer parameter pusch-AllocationList + nr_pdci_info_extracted->time_dom_resource_assignment = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + /*if (dci_format == format0_0 || dci_format == format0_1){ // Subclause 6.1.2.1 of [6, TS 38.214] + k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - } - if (dci_format == format1_0 || dci_format == format1_1){ // Subclause 5.1.2.1 of [6, TS 38.214] - // the Time domain resource assignment field of the DCI provides a row index of a higher layer configured table pdsch-symbolAllocation - // FIXME! To clarify which parameters to update after reception of row index - k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - // k_offset = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][0]; - // sliv_S = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][1]; - // sliv_L = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][2]; - }*/ - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->time_dom_resource_assignment=%x\n",nr_pdci_info_extracted->time_dom_resource_assignment); - #endif - break; + } + if (dci_format == format1_0 || dci_format == format1_1){ // Subclause 5.1.2.1 of [6, TS 38.214] + // the Time domain resource assignment field of the DCI provides a row index of a higher layer configured table pdsch-symbolAllocation + // FIXME! To clarify which parameters to update after reception of row index + k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + // k_offset = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + // k_offset = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][0]; + // sliv_S = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][1]; + // sliv_L = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][2]; + }*/ + LOG_DCI_D("nr_pdci_info_extracted->time_dom_resource_assignment=%x\n",nr_pdci_info_extracted->time_dom_resource_assignment); + break; - case VRB_TO_PRB_MAPPING: // 13 VRB_TO_PRB_MAPPING: (field defined for -,format0_1,format1_0,format1_1,-,-,-,-) - //0 bit if resource allocation type 0 - //1 bit if resource allocation type 1 - //Table 7.3.1.1.2-33: VRB-to-PRB mapping - // 0 Non-interleaved - // 1 Interleaved - nr_pdci_info_extracted->vrb_to_prb_mapping = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->vrb_to_prb_mapping == 0) { // Non-interleaved - //} else { // Interleaved - // format 0_1 defined in TS 38.211 Section 6.3.1.7 - // formats 1_0 and 1_1 not defined yet - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->vrb_to_prb_mapping=%x\n",nr_pdci_info_extracted->vrb_to_prb_mapping); - #endif - break; + case VRB_TO_PRB_MAPPING: // 13 VRB_TO_PRB_MAPPING: (field defined for -,format0_1,format1_0,format1_1,-,-,-,-) + //0 bit if resource allocation type 0 + //1 bit if resource allocation type 1 + //Table 7.3.1.1.2-33: VRB-to-PRB mapping + // 0 Non-interleaved + // 1 Interleaved + nr_pdci_info_extracted->vrb_to_prb_mapping = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //if (nr_pdci_info_extracted->vrb_to_prb_mapping == 0) { // Non-interleaved + //} else { // Interleaved + // format 0_1 defined in TS 38.211 Section 6.3.1.7 + // formats 1_0 and 1_1 not defined yet + //} + LOG_DCI_D("nr_pdci_info_extracted->vrb_to_prb_mapping=%x\n",nr_pdci_info_extracted->vrb_to_prb_mapping); + break; - case PRB_BUNDLING_SIZE_IND: // 14 PRB_BUNDLING_SIZE_IND: (field defined for -,-,-,format1_1,-,-,-,-) - // 0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] - nr_pdci_info_extracted->prb_bundling_size_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->prb_bundling_size_ind=%x\n",nr_pdci_info_extracted->prb_bundling_size_ind); - #endif - break; - case RATE_MATCHING_IND: // 15 RATE_MATCHING_IND: (field defined for -,-,-,format1_1,-,-,-,-) - // 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set - nr_pdci_info_extracted->rate_matching_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rate_matching_ind=%x\n",nr_pdci_info_extracted->rate_matching_ind); - #endif - break; - case ZP_CSI_RS_TRIGGER: // 16 ZP_CSI_RS_TRIGGER: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->zp_csi_rs_trigger = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->zp_csi_rs_trigger=%x\n",nr_pdci_info_extracted->zp_csi_rs_trigger); - #endif - break; + case PRB_BUNDLING_SIZE_IND: // 14 PRB_BUNDLING_SIZE_IND: (field defined for -,-,-,format1_1,-,-,-,-) + // 0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] + nr_pdci_info_extracted->prb_bundling_size_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->prb_bundling_size_ind=%x\n",nr_pdci_info_extracted->prb_bundling_size_ind); + break; - case FREQ_HOPPING_FLAG: // 17 FREQ_HOPPING_FLAG: (field defined for format0_0,format0_1,-,-,-,-,-,-) - // 0 bit if only resource allocation type 0 - // 1 bit otherwise, only applicable to resource allocation type 1, as defined in Subclause 6.3 of [6, TS 38.214] - nr_pdci_info_extracted->freq_hopping_flag = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->freq_hopping_flag != 0) { // PUSCH frequency hopping is performed (only resource allocation type 1) + case RATE_MATCHING_IND: // 15 RATE_MATCHING_IND: (field defined for -,-,-,format1_1,-,-,-,-) + // 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set + nr_pdci_info_extracted->rate_matching_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->rate_matching_ind=%x\n",nr_pdci_info_extracted->rate_matching_ind); + break; - //} else { // PUSCH frequency hopping is not performed (only resource allocation type 1) + case ZP_CSI_RS_TRIGGER: // 16 ZP_CSI_RS_TRIGGER: (field defined for -,-,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->zp_csi_rs_trigger = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->zp_csi_rs_trigger=%x\n",nr_pdci_info_extracted->zp_csi_rs_trigger); + break; + + case FREQ_HOPPING_FLAG: // 17 FREQ_HOPPING_FLAG: (field defined for format0_0,format0_1,-,-,-,-,-,-) + // 0 bit if only resource allocation type 0 + // 1 bit otherwise, only applicable to resource allocation type 1, as defined in Subclause 6.3 of [6, TS 38.214] + nr_pdci_info_extracted->freq_hopping_flag = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //if (nr_pdci_info_extracted->freq_hopping_flag != 0) { // PUSCH frequency hopping is performed (only resource allocation type 1) + //} else { // PUSCH frequency hopping is not performed (only resource allocation type 1) // At the moment PUSCH hopping is not implemented. We are considering that the bit is present and the value is '0' - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_hopping_flag=%x\n",nr_pdci_info_extracted->freq_hopping_flag); - #endif - break; + //} + LOG_DCI_D("nr_pdci_info_extracted->freq_hopping_flag=%x\n",nr_pdci_info_extracted->freq_hopping_flag); + break; - case TB1_MCS: // 18 TB1_MCS: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb1_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb1_mcs; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_mcs=%x\n",nr_pdci_info_extracted->tb1_mcs); - #endif - break; - case TB1_NDI: // 19 TB1_NDI: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb1_ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb1_ndi; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_ndi=%x\n",nr_pdci_info_extracted->tb1_ndi); - #endif - break; - case TB1_RV: // 20 TB1_RV: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb1_rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb1_rv; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_rv=%x\n",nr_pdci_info_extracted->tb1_rv); - #endif - break; - case TB2_MCS: // 21 TB2_MCS: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb2_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb2_mcs; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_mcs=%x\n",nr_pdci_info_extracted->tb2_mcs); - #endif - break; - case TB2_NDI: // 22 TB2_NDI: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb2_ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb2_ndi; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_ndi=%x\n",nr_pdci_info_extracted->tb2_ndi); - #endif - break; - case TB2_RV: // 23 TB2_RV: (field defined for -,-,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->tb2_rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb2_rv; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_rv=%x\n",nr_pdci_info_extracted->tb2_rv); - #endif - break; + case TB1_MCS: // 18 TB1_MCS: (field defined for -,-,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->tb1_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb1_mcs; + LOG_DCI_D("nr_pdci_info_extracted->tb1_mcs=%x\n",nr_pdci_info_extracted->tb1_mcs); + break; - case MCS: // 24 MCS: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (nr_pdci_info_extracted->mcs < 29) { - // if (dci_format == format0_0 || dci_format == format0_1) - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->mcs = nr_pdci_info_extracted->mcs; - // else - // pdlsch0_harq->mcs = nr_pdci_info_extracted->mcs; - //} else { - // return(0); - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->mcs=%x\n",nr_pdci_info_extracted->mcs); - #endif - break; + case TB1_NDI: // 19 TB1_NDI: (field defined for -,-,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->tb1_ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb1_ndi; + LOG_DCI_D("nr_pdci_info_extracted->tb1_ndi=%x\n",nr_pdci_info_extracted->tb1_ndi); + break; - case NDI: // 25 NDI: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (dci_format == format0_0 || dci_format == format0_1) { - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi = nr_pdci_info_extracted->ndi; - // if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx==1) { - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx=0; - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi; - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0; - // } else { - // if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi != nr_pdci_info_extracted->ndi) { // new SDU opportunity - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi; - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0; - // } - // } - //} else { - // if (rnti == crc_scrambled_values[_TC_RNTI_]) { //fix for standalone Contention Resolution Id - // pdlsch0_harq->DCINdi = (uint8_t)-1; - // } else { - // if ((prev_ndi != nr_pdci_info_extracted->ndi) || (pdlsch0_harq->first_tx==1)) { - // pdlsch0_harq->round = 0; - // pdlsch0_harq->first_tx = 0; - // pdlsch0_harq->status = ACTIVE; - // } - // pdlsch0_harq->DCINdi = nr_pdci_info_extracted->ndi; - // } - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ndi=%x\n",nr_pdci_info_extracted->ndi); - #endif - break; + case TB1_RV: // 20 TB1_RV: (field defined for -,-,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->tb1_rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb1_rv; + LOG_DCI_D("nr_pdci_info_extracted->tb1_rv=%x\n",nr_pdci_info_extracted->tb1_rv); + break; - case RV: // 26 RV: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //if (dci_format == format0_0 || dci_format == format0_1) - // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->rvidx = nr_pdci_info_extracted->rv; - //else - // pdlsch0_harq->rvidx = nr_pdci_info_extracted->rv; - //if ((prev_ndi == nr_pdci_info_extracted->ndi) && (pdlsch0_harq->rvidx != 0)) { // NDI has not been toggled but rv was increased by eNB: retransmission - // if (pdlsch0_harq->status == SCH_IDLE) { - // packet was actually decoded in previous transmission (ACK was missed by eNB) - // however, the round is not a good check as it might have been decoded in a retransmission prior to this one. - // skip pdsch decoding and report ack - - // pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.ack = 1; - // pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.send_harq_status; -#if 0 - // pdlsch0->active = 0; - // pdlsch0->harq_ack[nr_tti_rx].ack = 1; - // pdlsch0->harq_ack[nr_tti_rx].harq_id = nr_pdci_info_extracted->harq_process_number; - // pdlsch0->harq_ack[nr_tti_rx].send_harq_status = 1; -#endif - // } else { // normal retransmission, nothing special to do - // } - //} else { - // pdlsch0_harq->status = ACTIVE; - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rv=%x\n",nr_pdci_info_extracted->rv); - #endif - break; + case TB2_MCS: // 21 TB2_MCS: (field defined for -,-,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->tb2_mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb2_mcs; + LOG_DCI_D("nr_pdci_info_extracted->tb2_mcs=%x\n",nr_pdci_info_extracted->tb2_mcs); + break; - case HARQ_PROCESS_NUMBER: // 27 HARQ_PROCESS_NUMBER: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) - nr_pdci_info_extracted->harq_process_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); - #endif - break; + case TB2_NDI: // 22 TB2_NDI: (field defined for -,-,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->tb2_ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb2_ndi; + LOG_DCI_D("nr_pdci_info_extracted->tb2_ndi=%x\n",nr_pdci_info_extracted->tb2_ndi); + break; - case DAI_: // 28 DAI_: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // For format1_0: 2 bits as defined in Subclause 9.1.3 at TS 38.213 - // For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI - // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI - // 0 otherwise - nr_pdci_info_extracted->dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.vDAI_DL = nr_pdci_info_extracted->dai+1; - //pdlsch0->harq_ack[nr_tti_rx].vDAI_DL = nr_pdci_info_extracted->dai+1; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dai=%x\n",nr_pdci_info_extracted->dai); - #endif - break; + case TB2_RV: // 23 TB2_RV: (field defined for -,-,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->tb2_rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb2_rv; + LOG_DCI_D("nr_pdci_info_extracted->tb2_rv=%x\n",nr_pdci_info_extracted->tb2_rv); + break; - case FIRST_DAI: // 29 FIRST_DAI: (field defined for -,format0_1,-,-,-,-,-,-) - // (1 or 2 bits) 1 bit for semi-static HARQ-ACK - nr_pdci_info_extracted->first_dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->first_dai=%x\n",nr_pdci_info_extracted->first_dai); - #endif - break; - case SECOND_DAI: // 30 SECOND_DAI: (field defined for -,format0_1,-,-,-,-,-,-) - // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks - nr_pdci_info_extracted->second_dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->second_dai=%x\n",nr_pdci_info_extracted->second_dai); - #endif - break; + case MCS: // 24 MCS: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) + nr_pdci_info_extracted->mcs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //if (nr_pdci_info_extracted->mcs < 29) { + // if (dci_format == format0_0 || dci_format == format0_1) + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->mcs = nr_pdci_info_extracted->mcs; + // else + // pdlsch0_harq->mcs = nr_pdci_info_extracted->mcs; + //} else { + // return(0); + //} + LOG_DCI_D("nr_pdci_info_extracted->mcs=%x\n",nr_pdci_info_extracted->mcs); + break; - case TB_SCALING: // 31 TB_SCALING: (field defined for -,format0_1,-,-,-,-,-,-) - // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks - nr_pdci_info_extracted->tb_scaling = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb_scaling=%x\n",nr_pdci_info_extracted->tb_scaling); - #endif - break; + case NDI: // 25 NDI: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) + nr_pdci_info_extracted->ndi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //if (dci_format == format0_0 || dci_format == format0_1) { + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi = nr_pdci_info_extracted->ndi; + // if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx==1) { + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_tx=0; + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi; + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0; + // } else { + // if (ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi != nr_pdci_info_extracted->ndi) { // new SDU opportunity + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->DCINdi= nr_pdci_info_extracted->ndi; + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->round = 0; + // } + // } + //} else { + // if (rnti == crc_scrambled_values[_TC_RNTI_]) { //fix for standalone Contention Resolution Id + // pdlsch0_harq->DCINdi = (uint8_t)-1; + // } else { + // if ((prev_ndi != nr_pdci_info_extracted->ndi) || (pdlsch0_harq->first_tx==1)) { + // pdlsch0_harq->round = 0; + // pdlsch0_harq->first_tx = 0; + // pdlsch0_harq->status = ACTIVE; + // } + // pdlsch0_harq->DCINdi = nr_pdci_info_extracted->ndi; + // } + //} + LOG_DCI_D("nr_pdci_info_extracted->ndi=%x\n",nr_pdci_info_extracted->ndi); + break; - case TPC_PUSCH: // 32 TPC_PUSCH: (field defined for format0_0,format0_1,-,-,-,-,-,-) - // defined in Subclause 7.1.1 TS 38.213 - nr_pdci_info_extracted->tpc_pusch = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC = nr_pdci_info_extracted->tpc_pusch; - //if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { - // ulsch0->f_pusch += nr_delta_PUSCH_acc[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; - //} else { - // ulsch0->f_pusch = nr_delta_PUSCH_abs[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; - //} - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pusch=%x\n",nr_pdci_info_extracted->tpc_pusch); - #endif - break; + case RV: // 26 RV: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) + nr_pdci_info_extracted->rv = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //if (dci_format == format0_0 || dci_format == format0_1) + // ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->rvidx = nr_pdci_info_extracted->rv; + //else + // pdlsch0_harq->rvidx = nr_pdci_info_extracted->rv; + //if ((prev_ndi == nr_pdci_info_extracted->ndi) && (pdlsch0_harq->rvidx != 0)) { // NDI has not been toggled but rv was increased by eNB: retransmission + // if (pdlsch0_harq->status == SCH_IDLE) { + // packet was actually decoded in previous transmission (ACK was missed by eNB) + // however, the round is not a good check as it might have been decoded in a retransmission prior to this one. + // skip pdsch decoding and report ack + // pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.ack = 1; + // pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.send_harq_status; +#if 0 + // pdlsch0->active = 0; + // pdlsch0->harq_ack[nr_tti_rx].ack = 1; + // pdlsch0->harq_ack[nr_tti_rx].harq_id = nr_pdci_info_extracted->harq_process_number; + // pdlsch0->harq_ack[nr_tti_rx].send_harq_status = 1; +#endif + // } else { // normal retransmission, nothing special to do + // } + //} else { + // pdlsch0_harq->status = ACTIVE; + //} + LOG_DCI_D("nr_pdci_info_extracted->rv=%x\n",nr_pdci_info_extracted->rv); + break; - case TPC_PUCCH: // 33 TPC_PUCCH: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // defined in Subclause 7.2.1 TS 38.213 - nr_pdci_info_extracted->tpc_pucch = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - //pdlsch0_harq->delta_PUCCH = nr_delta_PUCCH_lut[nr_pdci_info_extracted->tpc_pucch &3]; - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pucch=%x\n",nr_pdci_info_extracted->tpc_pucch); - #endif - break; + case HARQ_PROCESS_NUMBER: // 27 HARQ_PROCESS_NUMBER: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) + nr_pdci_info_extracted->harq_process_number = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //pdlsch0->current_harq_pid = nr_pdci_info_extracted->harq_process_number; + LOG_DCI_D("nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); + break; - case PUCCH_RESOURCE_IND: // 34 PUCCH_RESOURCE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // defined in Subclause 9.2.3 TS 38.213 - // PUCCH_RESOURCE_IND points to PUCCH-ResourceId, but PUCCH-ResourceId is not defined yet - nr_pdci_info_extracted->pucch_resource_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pucch_resource_ind=%x\n",nr_pdci_info_extracted->pucch_resource_ind); - #endif - break; + case DAI_: // 28 DAI_: (field defined for -,-,format1_0,format1_1,-,-,-,-) + // For format1_0: 2 bits as defined in Subclause 9.1.3 at TS 38.213 + // For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI + // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI + // 0 otherwise + nr_pdci_info_extracted->dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //pdlsch0->harq_processes[pdlsch0->current_harq_pid]->harq_ack.vDAI_DL = nr_pdci_info_extracted->dai+1; + //pdlsch0->harq_ack[nr_tti_rx].vDAI_DL = nr_pdci_info_extracted->dai+1; + LOG_DCI_D("nr_pdci_info_extracted->dai=%x\n",nr_pdci_info_extracted->dai); + break; - case PDSCH_TO_HARQ_FEEDBACK_TIME_IND: // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) - // defined in Subclause 9.2.3 TS 38.213 - // PDSCH_TO_HARQ_FEEDBACK_TIME_IND points to DL-data-DL-acknowledgement, but DL-data-DL-acknowledgement is not defined yet - nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind=%x\n",nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind); - #endif - break; + case FIRST_DAI: // 29 FIRST_DAI: (field defined for -,format0_1,-,-,-,-,-,-) + // (1 or 2 bits) 1 bit for semi-static HARQ-ACK + nr_pdci_info_extracted->first_dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->first_dai=%x\n",nr_pdci_info_extracted->first_dai); + break; - case SRS_RESOURCE_IND: // 36 SRS_RESOURCE_IND: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->srs_resource_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_resource_ind=%x\n",nr_pdci_info_extracted->srs_resource_ind); - #endif - break; - case PRECOD_NBR_LAYERS: // 37 PRECOD_NBR_LAYERS: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->precod_nbr_layers = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->precod_nbr_layers=%x\n",nr_pdci_info_extracted->precod_nbr_layers); - #endif - break; - case ANTENNA_PORTS: // 38 ANTENNA_PORTS: (field defined for -,format0_1,-,format1_1,-,-,-,-) - nr_pdci_info_extracted->antenna_ports = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->antenna_ports=%x\n",nr_pdci_info_extracted->antenna_ports); - #endif - break; - case TCI: // 39 TCI: (field defined for -,-,-,format1_1,-,-,-,-) - // 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits - nr_pdci_info_extracted->tci = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tci=%x\n",nr_pdci_info_extracted->tci); - #endif - break; - case SRS_REQUEST: // 40 SRS_REQUEST: (field defined for -,format0_1,-,format1_1,-,-,-,format2_3) - nr_pdci_info_extracted->srs_request = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_request=%x\n",nr_pdci_info_extracted->srs_request); - #endif - break; - case TPC_CMD: // 41 TPC_CMD: (field defined for -,-,-,-,-,-,-,format2_3) - nr_pdci_info_extracted->tpc_cmd = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_cmd=%x\n",nr_pdci_info_extracted->tpc_cmd); - #endif - break; - case CSI_REQUEST: // 42 CSI_REQUEST: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->csi_request = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->csi_request=%x\n",nr_pdci_info_extracted->csi_request); - #endif - break; - case CBGTI: // 43 CBGTI: (field defined for -,format0_1,-,format1_1,-,-,-,-) - // 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH - nr_pdci_info_extracted->cbgti = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgti=%x\n",nr_pdci_info_extracted->cbgti); - #endif - break; - case CBGFI: // 44 CBGFI: (field defined for -,-,-,format1_1,-,-,-,-) - // 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator - nr_pdci_info_extracted->cbgfi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgfi=%x\n",nr_pdci_info_extracted->cbgfi); - #endif - break; - case PTRS_DMRS: // 45 PTRS_DMRS: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->ptrs_dmrs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ptrs_dmrs=%x\n",nr_pdci_info_extracted->ptrs_dmrs); - #endif - break; - case BETA_OFFSET_IND: // 46 BETA_OFFSET_IND: (field defined for -,format0_1,-,-,-,-,-,-) - nr_pdci_info_extracted->beta_offset_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->beta_offset_ind=%x\n",nr_pdci_info_extracted->beta_offset_ind); - #endif - break; - case DMRS_SEQ_INI: // 47 DMRS_SEQ_INI: (field defined for -,format0_1,-,format1_1,-,-,-,-) - // 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise - nr_pdci_info_extracted->dmrs_seq_ini = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->dmrs_seq_ini); - #endif - break; - case UL_SCH_IND: // 48 UL_SCH_IND: (field defined for -,format0_1,-,-,-,-,-,-) - // value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH - nr_pdci_info_extracted->ul_sch_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->ul_sch_ind); - #endif - break; + case SECOND_DAI: // 30 SECOND_DAI: (field defined for -,format0_1,-,-,-,-,-,-) + // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks + nr_pdci_info_extracted->second_dai = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->second_dai=%x\n",nr_pdci_info_extracted->second_dai); + break; - case PADDING_NR_DCI: // 49 PADDING_NR_DCI: (field defined for format0_0,-,format1_0,-,-,-,-,-) - // (Note 2) If DCI format 0_0 is monitored in common search space - nr_pdci_info_extracted->padding_nr_dci = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->padding=%x\n",nr_pdci_info_extracted->padding_nr_dci); - #endif - break; + case TB_SCALING: // 31 TB_SCALING: (field defined for -,format0_1,-,-,-,-,-,-) + // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks + nr_pdci_info_extracted->tb_scaling = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->tb_scaling=%x\n",nr_pdci_info_extracted->tb_scaling); + break; - case SUL_IND_0_0: // 50 SUL_IND_0_0: (field defined for format0_0,-,-,-,-,-,-,-) - nr_pdci_info_extracted->sul_ind_0_0 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_0=%x\n",nr_pdci_info_extracted->sul_ind_0_0); - #endif - break; + case TPC_PUSCH: // 32 TPC_PUSCH: (field defined for format0_0,format0_1,-,-,-,-,-,-) + // defined in Subclause 7.1.1 TS 38.213 + nr_pdci_info_extracted->tpc_pusch = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC = nr_pdci_info_extracted->tpc_pusch; + //if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { + // ulsch0->f_pusch += nr_delta_PUSCH_acc[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; + //} else { + // ulsch0->f_pusch = nr_delta_PUSCH_abs[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; + //} + LOG_DCI_D("nr_pdci_info_extracted->tpc_pusch=%x\n",nr_pdci_info_extracted->tpc_pusch); + break; - case RA_PREAMBLE_INDEX: // 51 RA_PREAMBLE_INDEX: (field defined for format0_0,-,-,-,-,-,-,-) - nr_pdci_info_extracted->ra_preamble_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ra_preamble_index=%x\n",nr_pdci_info_extracted->ra_preamble_index); - #endif - break; + case TPC_PUCCH: // 33 TPC_PUCCH: (field defined for -,-,format1_0,format1_1,-,-,-,-) + // defined in Subclause 7.2.1 TS 38.213 + nr_pdci_info_extracted->tpc_pucch = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + //pdlsch0_harq->delta_PUCCH = nr_delta_PUCCH_lut[nr_pdci_info_extracted->tpc_pucch &3]; + LOG_DCI_D("nr_pdci_info_extracted->tpc_pucch=%x\n",nr_pdci_info_extracted->tpc_pucch); + break; - case SUL_IND_1_0: // 52 SUL_IND_1_0: (field defined for -,-,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->sul_ind_1_0 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_1_0=%x\n",nr_pdci_info_extracted->sul_ind_1_0); - #endif - break; + case PUCCH_RESOURCE_IND: // 34 PUCCH_RESOURCE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) + // defined in Subclause 9.2.3 TS 38.213 + // PUCCH_RESOURCE_IND points to PUCCH-ResourceId, but PUCCH-ResourceId is not defined yet + nr_pdci_info_extracted->pucch_resource_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->pucch_resource_ind=%x\n",nr_pdci_info_extracted->pucch_resource_ind); + break; - case SS_PBCH_INDEX: // 53 SS_PBCH_INDEX: (field defined for -,-,format1_0,-,-,-,-,-) - nr_pdci_info_extracted->ss_pbch_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ss_pbch_index=%x\n",nr_pdci_info_extracted->ss_pbch_index); - #endif - break; + case PDSCH_TO_HARQ_FEEDBACK_TIME_IND: // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) + // defined in Subclause 9.2.3 TS 38.213 + // PDSCH_TO_HARQ_FEEDBACK_TIME_IND points to DL-data-DL-acknowledgement, but DL-data-DL-acknowledgement is not defined yet + nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind=%x\n",nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind); + break; - case PRACH_MASK_INDEX: // 54 PRACH_MASK_INDEX: (field defined for -,-,-,format1_0,-,-,-,-) - nr_pdci_info_extracted->prach_mask_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->prach_mask_index=%x\n",nr_pdci_info_extracted->prach_mask_index); - #endif - break; + case SRS_RESOURCE_IND: // 36 SRS_RESOURCE_IND: (field defined for -,format0_1,-,-,-,-,-,-) + nr_pdci_info_extracted->srs_resource_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->srs_resource_ind=%x\n",nr_pdci_info_extracted->srs_resource_ind); + break; - case RESERVED_NR_DCI: // 55 RESERVED_NR_DCI: (field defined for -,-,-,format1_0,-,-,-,-) - nr_pdci_info_extracted->reserved_nr_dci = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); - //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->reserved_nr_dci=%x\n",nr_pdci_info_extracted->reserved_nr_dci); - #endif - break; + case PRECOD_NBR_LAYERS: // 37 PRECOD_NBR_LAYERS: (field defined for -,format0_1,-,-,-,-,-,-) + nr_pdci_info_extracted->precod_nbr_layers = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->precod_nbr_layers=%x\n",nr_pdci_info_extracted->precod_nbr_layers); + break; + + case ANTENNA_PORTS: // 38 ANTENNA_PORTS: (field defined for -,format0_1,-,format1_1,-,-,-,-) + nr_pdci_info_extracted->antenna_ports = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->antenna_ports=%x\n",nr_pdci_info_extracted->antenna_ports); + break; + + case TCI: // 39 TCI: (field defined for -,-,-,format1_1,-,-,-,-) + // 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits + nr_pdci_info_extracted->tci = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->tci=%x\n",nr_pdci_info_extracted->tci); + break; + + case SRS_REQUEST: // 40 SRS_REQUEST: (field defined for -,format0_1,-,format1_1,-,-,-,format2_3) + nr_pdci_info_extracted->srs_request = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->srs_request=%x\n",nr_pdci_info_extracted->srs_request); + break; + + case TPC_CMD: // 41 TPC_CMD: (field defined for -,-,-,-,-,-,-,format2_3) + nr_pdci_info_extracted->tpc_cmd = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->tpc_cmd=%x\n",nr_pdci_info_extracted->tpc_cmd); + break; + + case CSI_REQUEST: // 42 CSI_REQUEST: (field defined for -,format0_1,-,-,-,-,-,-) + nr_pdci_info_extracted->csi_request = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->csi_request=%x\n",nr_pdci_info_extracted->csi_request); + break; + + case CBGTI: // 43 CBGTI: (field defined for -,format0_1,-,format1_1,-,-,-,-) + // 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH + nr_pdci_info_extracted->cbgti = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->cbgti=%x\n",nr_pdci_info_extracted->cbgti); + break; + + case CBGFI: // 44 CBGFI: (field defined for -,-,-,format1_1,-,-,-,-) + // 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator + nr_pdci_info_extracted->cbgfi = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->cbgfi=%x\n",nr_pdci_info_extracted->cbgfi); + break; + + case PTRS_DMRS: // 45 PTRS_DMRS: (field defined for -,format0_1,-,-,-,-,-,-) + nr_pdci_info_extracted->ptrs_dmrs = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->ptrs_dmrs=%x\n",nr_pdci_info_extracted->ptrs_dmrs); + break; + + case BETA_OFFSET_IND: // 46 BETA_OFFSET_IND: (field defined for -,format0_1,-,-,-,-,-,-) + nr_pdci_info_extracted->beta_offset_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->beta_offset_ind=%x\n",nr_pdci_info_extracted->beta_offset_ind); + break; + + case DMRS_SEQ_INI: // 47 DMRS_SEQ_INI: (field defined for -,format0_1,-,format1_1,-,-,-,-) + // 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise + nr_pdci_info_extracted->dmrs_seq_ini = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->dmrs_seq_ini); + break; + + case UL_SCH_IND: // 48 UL_SCH_IND: (field defined for -,format0_1,-,-,-,-,-,-) + // value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH + nr_pdci_info_extracted->ul_sch_ind = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->ul_sch_ind); + break; + + case PADDING_NR_DCI: // 49 PADDING_NR_DCI: (field defined for format0_0,-,format1_0,-,-,-,-,-) + // (Note 2) If DCI format 0_0 is monitored in common search space + nr_pdci_info_extracted->padding_nr_dci = (uint16_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->padding=%x\n",nr_pdci_info_extracted->padding_nr_dci); + break; + + case SUL_IND_0_0: // 50 SUL_IND_0_0: (field defined for format0_0,-,-,-,-,-,-,-) + nr_pdci_info_extracted->sul_ind_0_0 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->sul_ind_0_0=%x\n",nr_pdci_info_extracted->sul_ind_0_0); + break; + + case RA_PREAMBLE_INDEX: // 51 RA_PREAMBLE_INDEX: (field defined for format0_0,-,-,-,-,-,-,-) + nr_pdci_info_extracted->ra_preamble_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->ra_preamble_index=%x\n",nr_pdci_info_extracted->ra_preamble_index); + break; + + case SUL_IND_1_0: // 52 SUL_IND_1_0: (field defined for -,-,format1_0,-,-,-,-,-) + nr_pdci_info_extracted->sul_ind_1_0 = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->sul_ind_1_0=%x\n",nr_pdci_info_extracted->sul_ind_1_0); + break; + + case SS_PBCH_INDEX: // 53 SS_PBCH_INDEX: (field defined for -,-,format1_0,-,-,-,-,-) + nr_pdci_info_extracted->ss_pbch_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->ss_pbch_index=%x\n",nr_pdci_info_extracted->ss_pbch_index); + break; + case PRACH_MASK_INDEX: // 54 PRACH_MASK_INDEX: (field defined for -,-,-,format1_0,-,-,-,-) + nr_pdci_info_extracted->prach_mask_index = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->prach_mask_index=%x\n",nr_pdci_info_extracted->prach_mask_index); + break; + + case RESERVED_NR_DCI: // 55 RESERVED_NR_DCI: (field defined for -,-,-,format1_0,-,-,-,-) + nr_pdci_info_extracted->reserved_nr_dci = (uint8_t)nr_dci_field(dci_pdu,dci_fields_sizes_format,dci_field); + //(((((*(uint128_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format])); + LOG_DCI_D("nr_pdci_info_extracted->reserved_nr_dci=%x\n",nr_pdci_info_extracted->reserved_nr_dci); + break; } } } - #ifdef NR_PDCCH_DCI_TOOLS_DEBUG - printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Ending function nr_extract_dci_info()\n"); - #endif + + LOG_DCI_D("Ending function nr_extract_dci_info()\n"); return(1); } @@ -1015,34 +923,29 @@ int nr_extract_dci_info(PHY_VARS_NR_UE *ue, #ifdef NR_PDCCH_DCI_TOOLS int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, - uint8_t eNB_id, - int frame, - uint8_t nr_tti_rx, - uint64_t dci_pdu[2], - uint16_t rnti, - uint8_t dci_length, - NR_DCI_format_t dci_format, - NR_DL_FRAME_PARMS *frame_parms, - PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, - uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], - uint16_t n_RB_ULBWP, - uint16_t n_RB_DLBWP, - uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES], - fapi_nr_dci_pdu_rel15_t *nr_dci_info_extracted) -{ + uint8_t eNB_id, + int frame, + uint8_t nr_tti_rx, + uint64_t dci_pdu[2], + uint16_t rnti, + uint8_t dci_length, + NR_DCI_format_t dci_format, + NR_DL_FRAME_PARMS *frame_parms, + PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, + uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], + uint16_t n_RB_ULBWP, + uint16_t n_RB_DLBWP, + uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES], + fapi_nr_dci_pdu_rel15_t *nr_dci_info_extracted) { /* * Note only format0_0 and format1_0 are implemented */ - uint8_t frame_type=frame_parms->frame_type; uint8_t status=0; - - LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> dci_format=%d, rnti=%d, dci_length=%d, dci_pdu[0]=0x%lx, dci_pdu[1]=0x%lx\n",dci_format,rnti,dci_length,dci_pdu[0],dci_pdu[1]); - + LOG_DCI_PARM("dci_format=%d, rnti=%d, dci_length=%d, dci_pdu[0]=0x%lx, dci_pdu[1]=0x%lx\n",dci_format,rnti,dci_length,dci_pdu[0], + dci_pdu[1]); memset(nr_dci_info_extracted,0,sizeof(*nr_dci_info_extracted)); - - LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d) \n",dci_format); - + LOG_DCI_PARM("Entering function nr_extract_dci_info(dci_format=%d) \n",dci_format); status = nr_extract_dci_info(ue, eNB_id, frame_type, @@ -1058,21 +961,18 @@ int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, crc_scrambled_values); if(status == 0) { - LOG_W(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format); + LOG_DCI_PARM("bad DCI %d !!! \n",dci_format); return(-1); } - LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Ending function nr_extract_dci_info()\n"); - - //fill - + LOG_DCI_PARM("Ending function nr_extract_dci_info()\n"); + //fill return(0); } #endif -uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx) -{ +uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx) { /* #ifdef DEBUG_DCI if (frame_parms->frame_type == TDD) @@ -1081,81 +981,77 @@ uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8 printf("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe); #endif */ - uint8_t ret = 255; uint8_t subframe = nr_tti_rx>>((int)(log2 (frame_parms->ttis_per_subframe))); if (frame_parms->frame_type == FDD) { ret = (((frame<<1)+nr_tti_rx)&7); } else { - switch (frame_parms->tdd_config) { + case 1: + if ((subframe==2) || + (subframe==3) || + (subframe==7) || + (subframe==8)) + switch (subframe) { + case 2: + case 3: + ret = (subframe-2); + break; + + case 7: + case 8: + ret = (subframe-5); + break; + + default: + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + break; + } - case 1: - if ((subframe==2) || - (subframe==3) || - (subframe==7) || - (subframe==8)) - switch (subframe) { - case 2: - case 3: - ret = (subframe-2); - break; - - case 7: - case 8: - ret = (subframe-5); - break; + break; - default: + case 2: + if ((subframe!=2) && (subframe!=7)) { LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + //mac_xface->macphy_exit("subframe2_harq_pid, Illegal subframe"); ret = (255); - break; } - break; + ret = (subframe/7); + break; - case 2: - if ((subframe!=2) && (subframe!=7)) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - //mac_xface->macphy_exit("subframe2_harq_pid, Illegal subframe"); - ret = (255); - } + case 3: + if ((subframe<2) || (subframe>4)) { + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + } - ret = (subframe/7); - break; + ret = (subframe-2); + break; - case 3: - if ((subframe<2) || (subframe>4)) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - ret = (255); - } + case 4: + if ((subframe<2) || (subframe>3)) { + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + } - ret = (subframe-2); - break; + ret = (subframe-2); + break; - case 4: - if ((subframe<2) || (subframe>3)) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); - ret = (255); - } + case 5: + if (subframe!=2) { + LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + ret = (255); + } - ret = (subframe-2); - break; + ret = (subframe-2); + break; - case 5: - if (subframe!=2) { - LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); + default: + LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config); ret = (255); - } - - ret = (subframe-2); - break; - - default: - LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config); - ret = (255); - } } @@ -1163,12 +1059,12 @@ uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8 LOG_E(PHY, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", ret, frame, subframe); //mac_xface->macphy_exit("invalid harq_pid"); } + return ret; } -uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n) -{ +uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n) { uint8_t ul_subframe = 255; if ((frame_parms->frame_type == TDD) && @@ -1190,8 +1086,7 @@ uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n) return ul_subframe; } -uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n) -{ +uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n) { uint32_t ul_frame = 255; if ((frame_parms->frame_type == TDD) && @@ -1211,6 +1106,5 @@ uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame); return ul_frame; - } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 12aaebc91755ca214322d4e30f6b1dffa2e8c402..d2dbd6fef2869a3d4ff290767b7f95c6b942b72c 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -124,7 +124,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ulsch_ue->length_dmrs = length_dmrs; ulsch_ue->rnti = n_rnti; ulsch_ue->Nid_cell = Nid_cell; - ulsch_ue->nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4; + ulsch_ue->nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1?6:4); N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs - N_PRB_oh; diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 80d63cbdd9e307d56d8108f8cfd519def8b9bc62..0ec04dd5370ac200e8e12f68fc95c88484882d8a 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -104,6 +104,10 @@ typedef struct { /// - first index: tx antenna [0..nb_antennas_tx[ /// - second index: sample [0..] int32_t **txdataF_BF; + /// \brief holds the transmit data before beamforming in the frequency domain. + /// - first index: tx antenna [0..nb_antennas_tx[ + /// - second index: sample [0..] + int32_t **txdataF; /// \brief holds the transmit data before beamforming for epdcch/mpdcch /// - first index : tx antenna [0..nb_epdcch_antenna_ports[ /// - second index: sampl [0..] @@ -147,6 +151,44 @@ typedef struct { } RU_CALIBRATION; +typedef struct RU_prec_t_s{ + /// \internal This variable is protected by \ref mutex_feptx_prec + int instance_cnt_feptx_prec; + /// pthread struct for RU TX FEP PREC worker thread + pthread_t pthread_feptx_prec; + /// pthread attributes for worker feptx prec thread + pthread_attr_t attr_feptx_prec; + /// condition varible for RU TX FEP PREC thread + pthread_cond_t cond_feptx_prec; + /// mutex for fep PREC TX worker thread + pthread_mutex_t mutex_feptx_prec; + int symbol; + int p;//logical + int aa;//physical MAX nb_tx + struct RU_t_s *ru; + int index; +} RU_prec_t; + +typedef struct RU_feptx_t_s{ + /// \internal This variable is protected by \ref mutex_feptx_prec + int instance_cnt_feptx; + /// pthread struct for RU TX FEP PREC worker thread + pthread_t pthread_feptx; + /// pthread attributes for worker feptx prec thread + pthread_attr_t attr_feptx; + /// condition varible for RU TX FEP PREC thread + pthread_cond_t cond_feptx; + /// mutex for fep PREC TX worker thread + pthread_mutex_t mutex_feptx; + struct RU_t_s *ru; + int aa;//physical MAX nb_tx + int half_slot;//first or second half of a slot + int slot;//current slot + int symbol;//current symbol + int nb_antenna_ports;//number of logical port + int index; +}RU_feptx_t; + typedef struct RU_proc_t_s { /// Pointer to associated RU descriptor struct RU_t_s *ru; @@ -339,8 +381,14 @@ typedef struct RU_proc_t_s { int ru_rx_ready; int ru_tx_ready; int emulate_rf_busy; -} RU_proc_t; + /// structure for precoding thread + RU_prec_t prec[16]; + /// structure for feptx thread + RU_feptx_t feptx[16]; + /// mask for checking process finished + int feptx_mask; +} RU_proc_t; typedef enum { LOCAL_RF =0, @@ -495,10 +543,16 @@ typedef struct RU_t_s { void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string, struct RU_t_s *ru); void (*gNB_top)(struct PHY_VARS_gNB_s *gNB, int frame_rx, int slot_rx, char *string, struct RU_t_s *ru); + /// Timing data copy statistics (TX) + time_stats_t txdataF_copy_stats; + /// Timing statistics (TX) + time_stats_t precoding_stats; /// Timing statistics time_stats_t ofdm_demod_stats; /// Timing statistics (TX) time_stats_t ofdm_mod_stats; + /// Timing statistics (TX) + time_stats_t ofdm_total_stats; /// Timing wait statistics time_stats_t ofdm_demod_wait_stats; /// Timing wakeup statistics @@ -518,10 +572,12 @@ typedef struct RU_t_s { /// RX and TX buffers for precoder output RU_COMMON common; RU_CALIBRATION calibration; - /// beamforming weight vectors per eNB + /// beamforming weight list size + int nb_bfw; + /// beamforming weight list of values + int32_t *bw_list[NUMBER_OF_eNB_MAX+1]; + /// beamforming weight vectors int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; - /// beamforming weight vectors per gNB - int32_t **nrbeam_weights[NUMBER_OF_gNB_MAX+1][16]; /// received frequency-domain signal for PRACH (IF4p5 RRU) int16_t **prach_rxsigF; /// received frequency-domain signal for PRACH BR (IF4p5 RRU) diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 86d2a7531d2bb340067f643113db21e1fb04d797..048e48ae458569f2e0eb2e5104ed6f930b0892e5 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -319,6 +319,8 @@ typedef struct NR_DL_FRAME_PARMS { uint8_t Lmax; /// SS block pattern (max 64 ssb, each bit is on/off ssb) uint64_t L_ssb; + /// Total number of SSB transmitted + uint8_t N_ssb; /// PBCH polar encoder params t_nrPolar_params pbch_polar_params; diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h index 150b0c194fddaac0326b1b83a5379605c69623a5..e74b9a312fda7bc7ed76430b83a73b4b92d9fa15 100644 --- a/openair1/SCHED/sched_eNB.h +++ b/openair1/SCHED/sched_eNB.h @@ -218,6 +218,8 @@ int is_srs_occasion_common(LTE_DL_FRAME_PARMS *frame_parms,int frame_tx,int subf void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeriodicity,uint16_t *psrsOffset); void release_rnti_of_phy(module_id_t mod_id); + +void ru_fep_full_2thread(RU_t *ru, int subframe); /*@}*/ diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 793e26232f5c705c126a898da77d7242cc48a369..270ab5772cc3c0e0780ca726a34a16f4654463e4 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -139,7 +139,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB = RC.gNB[Mod_id][CC_id]; uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu; - uint8_t number_ul_pdu = UL_tti_req->n_pdus; + //uint8_t number_ul_pdu = UL_tti_req->n_pdus; nfapi_nr_dl_config_request_pdu_t *dl_config_pdu; diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index e726bdc71173e2fdf8c4abcddd0a3f14aee1a936..0ce3172bfd8ce4813159a09e89a03f868d738458 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -56,160 +56,236 @@ extern openair0_config_t openair0_cfg[MAX_CARDS]; extern int oai_exit; -void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols) { +void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - unsigned int aa,slot_offset,slot_offsetF; + unsigned int slot_offset,slot_offsetF; int slot = tti_tx; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0) , 1 ); slot_offset = slot*fp->samples_per_slot; slot_offsetF = first_symbol*fp->ofdm_symbol_size; + if (first_symbol>0) slot_offset += (fp->ofdm_symbol_size*first_symbol) + (fp->nb_prefix_samples0) + (fp->nb_prefix_samples*(first_symbol-1)); LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d (first_symbol %d num_symbols %d)\n",ru->proc.frame_tx, ru->proc.tti_tx,slot,first_symbol,num_symbols); - for (aa=0; aa<ru->nb_tx; aa++) { - if (fp->Ncp == 1) { + if (fp->Ncp == 1) { + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + num_symbols, + fp->nb_prefix_samples, + CYCLIC_PREFIX); + } + else { + if (first_symbol==0) { PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - num_symbols, - fp->nb_prefix_samples, - CYCLIC_PREFIX); + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + 1, + fp->nb_prefix_samples0, + CYCLIC_PREFIX); + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], + (int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size], + fp->ofdm_symbol_size, + num_symbols-1, + fp->nb_prefix_samples, + CYCLIC_PREFIX); } else { - if (first_symbol==0) { - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - 1, - fp->nb_prefix_samples0, - CYCLIC_PREFIX); - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF+fp->ofdm_symbol_size], - (int*)&ru->common.txdata[aa][slot_offset+fp->nb_prefix_samples0+fp->ofdm_symbol_size], - fp->ofdm_symbol_size, - num_symbols-1, - fp->nb_prefix_samples, - CYCLIC_PREFIX); - } - else { - PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], - (int*)&ru->common.txdata[aa][slot_offset], - fp->ofdm_symbol_size, - num_symbols, - fp->nb_prefix_samples, - CYCLIC_PREFIX); - } + PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot_offsetF], + (int*)&ru->common.txdata[aa][slot_offset], + fp->ofdm_symbol_size, + num_symbols, + fp->nb_prefix_samples, + CYCLIC_PREFIX); } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+(first_symbol!=0?1:0), 0); } void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx) { - NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; nfapi_nr_config_request_t *cfg = &ru->gNB_list[0]->gNB_config; - RU_proc_t *proc = &ru->proc; - struct timespec wait; - int slot = tti_tx; + RU_proc_t *proc = &ru->proc; + RU_feptx_t *feptx = proc->feptx; - wait.tv_sec=0; - wait.tv_nsec=5000000L; + PHY_VARS_gNB *gNB; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - start_meas(&ru->ofdm_mod_stats); + int slot = tti_tx; + int i = 0; + int j = 0; + int aa = 0; + int ret = 0; + int nb_antenna_ports = fp->N_ssb; + int ofdm_mask_full = (1<<(ru->nb_tx*2))-1; + int txdataF_offset = ((tti_tx%2)*fp->samples_per_slot_wCP); if (nr_slot_select(cfg,slot,frame_tx) == SF_UL) return; + for (aa=0; aa<fp->Lmax; aa++) { + memset(ru->common.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); + } - // this copy should be done in the precoding thread (currently inactive) - for (int aa=0;aa<ru->nb_tx;aa++) - memcpy((void*)ru->common.txdataF_BF[aa], + start_meas(&ru->ofdm_total_stats); - (void*)ru->gNB_list[0]->common_vars.txdataF[aa], fp->samples_per_slot_wCP*sizeof(int32_t)); + for(j=0; j<fp->symbols_per_slot; ++j){ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 1); + start_meas(&ru->txdataF_copy_stats); + if (ru->num_gNB == 1){ + gNB = ru->gNB_list[0]; + cfg = &gNB->gNB_config; - if (nr_slot_select(cfg,slot,frame_tx)==SF_DL) { - // If this is not an S-tti - if (pthread_mutex_timedlock(&proc->mutex_feptx,&wait) != 0) { - printf("[RU] ERROR pthread_mutex_lock for feptx thread (IC %d)\n", proc->instance_cnt_feptx); - exit_fun( "error locking mutex_feptx" ); - return; - } - - if (proc->instance_cnt_feptx==0) { - printf("[RU] FEPtx thread busy\n"); - exit_fun("FEPtx thread busy"); - pthread_mutex_unlock( &proc->mutex_feptx ); - return; - } - - ++proc->instance_cnt_feptx; - // slot to pass to worker thread - proc->slot_feptx = slot; - pthread_mutex_unlock( &proc->mutex_feptx ); - - - if (pthread_cond_signal(&proc->cond_feptx) != 0) { - printf("[RU] ERROR pthread_cond_signal for feptx thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return; + for(i=0; i<nb_antenna_ports; ++i){ + memcpy((void*)&ru->common.txdataF[i][j*fp->ofdm_symbol_size], + (void*)&gNB->common_vars.txdataF[i][j*fp->ofdm_symbol_size + txdataF_offset], + fp->ofdm_symbol_size*sizeof(int32_t)); + } + + }//num_gNB == 1 + stop_meas(&ru->txdataF_copy_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC+j , 0); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); + + if (nr_slot_select(cfg,slot,frame_tx)==SF_DL) { + // If this is not an S-tti + for(i=0; i<ru->nb_tx; ++i){ + if(j%2 == 0){ + while(feptx[i].instance_cnt_feptx != -1){ + usleep(5); + } + AssertFatal((ret=pthread_mutex_lock(&feptx[i].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i].aa = i; + feptx[i].index = i; + feptx[i].ru = ru; + feptx[i].symbol = j; + feptx[i].slot = slot; + feptx[i].nb_antenna_ports = nb_antenna_ports; + feptx[i].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } + else{ + while(feptx[i+ru->nb_tx].instance_cnt_feptx != -1){ + usleep(5); + } + AssertFatal((ret=pthread_mutex_lock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock return %d\n",ret); + feptx[i+ru->nb_tx].aa = i; + feptx[i+ru->nb_tx].index = i+ru->nb_tx; + feptx[i+ru->nb_tx].ru = ru; + feptx[i+ru->nb_tx].symbol = j; + feptx[i+ru->nb_tx].slot = slot; + feptx[i+ru->nb_tx].nb_antenna_ports = nb_antenna_ports; + feptx[i+ru->nb_tx].instance_cnt_feptx = 0; + AssertFatal(pthread_cond_signal(&feptx[i+ru->nb_tx].cond_feptx) == 0,"ERROR pthread_cond_signal for feptx_ofdm_thread\n"); + AssertFatal((ret=pthread_mutex_unlock(&feptx[i+ru->nb_tx].mutex_feptx))==0,"mutex_lock returns %d\n",ret); + } + } + + }//if == SF_DL + else { + proc->feptx_mask = ofdm_mask_full; } - + }//j<fp->symbols_per_slot + + // wait all process to finish + AssertFatal((ret=pthread_mutex_lock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret); + while (proc->feptx_mask != ofdm_mask_full) { + // most of the time the thread is waiting here + // proc->instance_cnt_rxtx is -1 + pthread_cond_wait(&proc->cond_feptx,&proc->mutex_feptx); // this unlocks mutex_rxtx while waiting and then locks it again } + proc->feptx_mask = 0; + AssertFatal((ret=pthread_mutex_unlock(&proc->mutex_feptx))==0,"mutex_lock return %d\n",ret); - // call first half-slot in this thread - nr_feptx0(ru,slot,0,fp->symbols_per_slot>>1); - wait_on_busy_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"NR feptx thread"); - + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, proc->feptx_mask ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); //write_output - stop_meas(&ru->ofdm_mod_stats); + stop_meas(&ru->ofdm_total_stats); } static void *nr_feptx_thread(void *param) { - RU_t *ru = (RU_t *)param; - RU_proc_t *proc = &ru->proc; + RU_feptx_t *feptx = (RU_feptx_t *)param; + RU_t *ru; + int aa, slot, start, l, nb_antenna_ports, ret; + int32_t ***bw; + NR_DL_FRAME_PARMS *fp; + int ofdm_mask_full; while (!oai_exit) { - if (wait_on_condition(&proc->mutex_feptx,&proc->cond_feptx,&proc->instance_cnt_feptx,"NR feptx thread")<0) break; - int slot=proc->slot_feptx; - if (release_thread(&proc->mutex_feptx,&proc->instance_cnt_feptx,"NR feptx thread")<0) break; + ret = 0; + if (wait_on_condition(&feptx->mutex_feptx,&feptx->cond_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 1 ); + + ru = feptx->ru; + slot = feptx->slot; + aa = feptx->aa; + l = feptx->symbol; + fp = ru->nr_frame_parms; + start = feptx->symbol; + nb_antenna_ports = feptx->nb_antenna_ports; + ofdm_mask_full = (1<<(ru->nb_tx*2))-1; + + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + start_meas(&ru->precoding_stats); + if (ru->nb_tx == 1) { + AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx); + for (int p=0; p<fp->Lmax; p++) { + if ((fp->L_ssb >> p) & 0x01){ + memcpy((void*)&ru->common.txdataF_BF[0][l*fp->ofdm_symbol_size], + (void*)&ru->common.txdataF[p][l*fp->ofdm_symbol_size], + fp->ofdm_symbol_size*sizeof(int32_t)); + } + } + } + else { + bw = ru->beam_weights[0]; + nr_beam_precoding(ru->common.txdataF, + ru->common.txdataF_BF, + fp, + bw, + slot, + l, + aa, + nb_antenna_ports); + } + stop_meas(&ru->precoding_stats); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); - nr_feptx0(ru,slot,ru->nr_frame_parms->symbols_per_slot>>1,ru->nr_frame_parms->symbols_per_slot>>1); - if (pthread_cond_signal(&proc->cond_feptx) != 0) { - LOG_E(PHY,"[gNB] ERROR pthread_cond_signal for NR feptx thread exit\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return NULL; + start_meas(&ru->ofdm_mod_stats); + nr_feptx0(ru,slot,start,1,aa); + stop_meas(&ru->ofdm_mod_stats); + + if (release_thread(&feptx->mutex_feptx,&feptx->instance_cnt_feptx,"NR feptx thread")<0) break; + + if(l >= fp->symbols_per_slot -2){ + AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_feptx))==0,"mutex_lock return %d\n",ret); + ru->proc.feptx_mask |= 1<<(feptx->index); + if(ru->proc.feptx_mask == ofdm_mask_full) + AssertFatal(pthread_cond_signal(&ru->proc.cond_feptx) == 0,"ERROR pthread_cond_signal for precoding and ofdm finish\n"); + AssertFatal((ret=pthread_mutex_unlock(&ru->proc.mutex_feptx))==0,"mutex_lock returns %d\n",ret); } + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_RU_TX_OFDM_MASK, ru->proc.feptx_mask ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+feptx->index+1 , 0 ); } return(NULL); } -void nr_init_feptx_thread(RU_t *ru) { - - RU_proc_t *proc = &ru->proc; - - proc->instance_cnt_feptx = -1; - - pthread_mutex_init( &proc->mutex_feptx, NULL); - pthread_cond_init( &proc->cond_feptx, NULL); - - threadCreate(&proc->pthread_feptx, nr_feptx_thread, (void*)ru, "feptx", -1, OAI_PRIORITY_RT); - - -} // is this supposed to generate a slot or a subframe??? // seems to be hardcoded to numerology 1 (2 slots=1 subframe) @@ -224,21 +300,14 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { int slot = tti_tx; int *txdata = &ru->common.txdata[aa][slot*fp->samples_per_slot]; + if (nr_slot_select(cfg,slot, frame_tx) == SF_UL) return; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); start_meas(&ru->ofdm_mod_stats); - // this copy should be done in the precoding thread (currently inactive) - for (int aa=0;aa<ru->nb_tx;aa++) - memcpy((void*)ru->common.txdataF_BF[aa], - (void*)ru->gNB_list[0]->common_vars.txdataF[aa], fp->samples_per_slot_wCP*sizeof(int32_t)); - - if ((nr_slot_select(cfg,slot,frame_tx)==SF_DL)|| - ((nr_slot_select(cfg,slot,frame_tx)==SF_S))) { // LOG_D(HW,"Frame %d: Generating slot %d\n",frame,next_slot); - nr_feptx0(ru,slot,0,fp->symbols_per_slot); - - } + nr_feptx0(ru,slot,0,fp->symbols_per_slot,aa); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 0 ); stop_meas(&ru->ofdm_mod_stats); @@ -249,6 +318,79 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { } +void nr_init_feptx_thread(RU_t *ru) { + + RU_proc_t *proc = &ru->proc; + RU_feptx_t *feptx = proc->feptx; + int i = 0; + + for(i=0; i<16; i++){ + feptx[i].instance_cnt_feptx = -1; + + pthread_mutex_init( &feptx[i].mutex_feptx, NULL); + pthread_cond_init( &feptx[i].cond_feptx, NULL); + + threadCreate(&feptx[i].pthread_feptx, nr_feptx_thread, (void*)&feptx[i], "feptx", -1, OAI_PRIORITY_RT); + LOG_I(PHY,"init feptx thread %d\n", i); + } + +} + + +void nr_feptx_prec(RU_t *ru,int frame,int tti_tx) { + + int l,aa; + PHY_VARS_gNB **gNB_list = ru->gNB_list,*gNB; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + nfapi_nr_config_request_t *cfg; + int32_t ***bw; + int i=0; + + start_meas(&ru->precoding_stats); + if (ru->num_gNB == 1){ + gNB = gNB_list[0]; + cfg = &gNB->gNB_config; + if (nr_slot_select(cfg,tti_tx,frame) == SF_UL) return; + + for(i=0; i<fp->Lmax; ++i) + memcpy((void*)ru->common.txdataF[i], + (void*)gNB->common_vars.txdataF[i], + fp->samples_per_slot_wCP*sizeof(int32_t)); + + if (ru->nb_tx == 1) { + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 1); + + AssertFatal(fp->N_ssb==ru->nb_tx,"Attempting to transmit %d SSB while Nb_tx = %d",fp->N_ssb,ru->nb_tx); + + for (int p=0; p<fp->Lmax; p++) { + if ((fp->L_ssb >> p) & 0x01){ + memcpy((void*)ru->common.txdataF_BF[0], + (void*)ru->common.txdataF[p], + fp->samples_per_slot_wCP*sizeof(int32_t)); + } + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_PREC , 0); + }// if (ru->nb_tx == 1) + else { + bw = ru->beam_weights[0]; + for (l=0;l<fp->symbols_per_slot;l++) { + for (aa=0;aa<ru->nb_tx;aa++) { + nr_beam_precoding(ru->common.txdataF, + ru->common.txdataF_BF, + fp, + bw, + tti_tx, + l, + aa, + fp->Lmax); + }// for (aa=0;aa<ru->nb_tx;aa++) + }// for (l=0;l<fp->symbols_per_slot;l++) + }// if (ru->nb_tx == 1) + }// if (ru->num_gNB == 1) + stop_meas(&ru->precoding_stats); +} void nr_fep0(RU_t *ru, int first_half) { diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index caf76528410f6b2bfc1c981c81d3a85dd65537c3..a665a14112bbdc007c8b4b2d5fc6061df0ef05e3 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -96,6 +96,7 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { uint8_t *pbch_pdu=&gNB->pbch_pdu[0]; uint8_t ssb_index, n_hf; int ssb_start_symbol, rel_slot; + int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; uint16_t slots_per_hf = fp->slots_per_frame / 2; n_hf = cfg->sch_config.half_frame_index.value; @@ -124,19 +125,20 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier + // it is supposed that each logical antenna port correspont to a different beam so each SSB is stored into its own index of txdataF LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); - nr_generate_pss(gNB->d_pss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); - nr_generate_sss(gNB->d_sss, txdataF[0], AMP, ssb_start_symbol, cfg, fp); + nr_generate_pss(gNB->d_pss, &txdataF[ssb_index][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); + nr_generate_sss(gNB->d_sss, &txdataF[ssb_index][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); if (fp->Lmax == 4) - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index],&txdataF[ssb_index][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); else - nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],txdataF[0], AMP, ssb_start_symbol, cfg, fp); + nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index],&txdataF[ssb_index][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); nr_generate_pbch(&gNB->pbch, pbch_pdu, gNB->nr_pbch_interleaver, - txdataF[0], + &txdataF[ssb_index][txdataF_offset], AMP, ssb_start_symbol, n_hf,fp->Lmax,ssb_index, @@ -155,6 +157,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, nfapi_nr_config_request_t *cfg = &gNB->gNB_config; int offset = gNB->CC_id; uint8_t ssb_frame_periodicity; // every how many frames SSB are generated + int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; if (cfg->sch_config.ssb_periodicity.value < 20) ssb_frame_periodicity = 1; @@ -168,8 +171,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, if (do_meas==1) start_meas(&gNB->phy_proc_tx); // clear the transmit data array for the current subframe - for (aa=0; aa<1/*15*/; aa++) { - memset(gNB->common_vars.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); + for (aa=0; aa<fp->Lmax; aa++) { + memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,1); @@ -187,10 +190,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, num_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,1); + nr_generate_dci_top(gNB->pdcch_vars.dci_alloc[i], - gNB->nr_gold_pdcch_dmrs[slot], - gNB->common_vars.txdataF[0], - AMP, *fp, *cfg); + gNB->nr_gold_pdcch_dmrs[slot], + &gNB->common_vars.txdataF[0][txdataF_offset], // hardcoded to beam 0 + AMP, *fp, *cfg); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); } @@ -361,7 +366,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) switch (UL_tti_req->pdus_list[i].pdu_type) { case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: { - LOG_I(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 91035854930a04839d6d86ab4453ded98a73a360..5b53aa919a588f0611aea286b66faff06d6aa542 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -42,8 +42,12 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); -void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols); +void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa); void nr_init_feptx_thread(RU_t *ru); +void fep_full(RU_t *ru,int slot); +void nr_feptx_prec(RU_t *ru,int frame_tx,int tti_tx); +void nr_init_feptx_prec_thread(RU_t *ru); +void nr_feptx_prec_control(RU_t *ru,int frame,int tti_tx); void nr_init_feprx_thread(RU_t *ru); void nr_fep_full(RU_t *ru, int slot); void nr_fep_full_2thread(RU_t *ru, int slot); diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index ced40c491aecffd2914d460b13101f1d949ca55a..1bd7071b9950cf10d8773905b98401ffbb577827 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -214,7 +214,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){ - fapi_nr_config_request_t nrUE_config = PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; + fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; if(phy_config != NULL){ if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_PBCH){ @@ -230,7 +230,7 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){ LOG_I(MAC,"half frame bit: %d\n", phy_config->config_req.pbch_config.half_frame_bit); LOG_I(MAC,"-------------------------------\n"); - memcpy(&nrUE_config.pbch_config,&phy_config->config_req.pbch_config,sizeof(fapi_nr_pbch_config_t)); + memcpy(&nrUE_config->pbch_config,&phy_config->config_req.pbch_config,sizeof(fapi_nr_pbch_config_t)); } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index bf350cea710fa00c995cb3a15e2df0bf9e49f6cc..8d8140e19254131f98a15ed72ac1554e0e437b61 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -68,7 +68,7 @@ uint16_t NB_UE_INST = 1; //Dummy Functions lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms, unsigned char subframe) {return(SF_DL);} -int rlc_module_init (void) {return(0);} +int rlc_module_init (int enb) {return(0);} void pdcp_layer_init (void) {} int rrc_init_nr_global_param (void) {return(0);} void config_common(int Mod_idP,int CC_idP,int Nid_cell,int nr_bandP,uint64_t SSB_positions,uint16_t ssb_periodicity,uint64_t dl_CarrierFreqP,uint32_t dl_BandwidthP); @@ -86,7 +86,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( const module_id_t module_idP, const tb_size_t tb_sizeP, const uint32_t sourceL2Id, const uint32_t destinationL2Id) -{mac_rlc_status_resp_t mac_rlc_status_resp; return mac_rlc_status_resp;} +{mac_rlc_status_resp_t mac_rlc_status_resp={0}; return mac_rlc_status_resp;} tbs_size_t mac_rlc_data_req( const module_id_t module_idP, const rnti_t rntiP, const eNB_index_t eNB_index, @@ -602,24 +602,26 @@ int main(int argc, char **argv) phy_procedures_gNB_TX(gNB,frame,slot,0); //nr_common_signal_procedures (gNB,frame,subframe); + int txdataF_offset = (slot%2) * frame_parms->samples_per_slot_wCP; LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1); if (gNB->frame_parms.nb_antennas_tx>1) LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1); int tx_offset = slot*frame_parms->samples_per_slot; + printf("samples_per_slot_wCP = %d\n", frame_parms->samples_per_slot_wCP); //TODO: loop over slots for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) { if (gNB_config->subframe_config.dl_cyclic_prefix_type.value == 1) { - PHY_ofdm_mod(gNB->common_vars.txdataF[aa], + PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], &txdata[aa][tx_offset], frame_parms->ofdm_symbol_size, 12, frame_parms->nb_prefix_samples, CYCLIC_PREFIX); } else { - nr_normal_prefix_mod(gNB->common_vars.txdataF[aa], + nr_normal_prefix_mod(&gNB->common_vars.txdataF[aa][txdataF_offset], &txdata[aa][tx_offset], 14, frame_parms); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 15e7d3ca0e2deeaa6fc92132455272a8955eec26..724faf1d7f86806a34524944420c34595347f3c6 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -115,7 +115,7 @@ int generate_dlsch_header(unsigned char *mac_header, unsigned char short_padding, unsigned short post_padding){return 0;} uint64_t get_softmodem_optmask(void) {return 0;} -int rlc_module_init (void) {return(0);} +int rlc_module_init (int enb) {return(0);} void pdcp_layer_init (void) {} void nr_ip_over_LTE_DRB_preconfiguration(void){} @@ -146,7 +146,7 @@ int main(int argc, char **argv) uint16_t N_RB_DL = 106, N_RB_UL = 106, mu = 1; //unsigned char frame_type = 0; int number_of_frames = 1; - int frame_length_complex_samples, frame_length_complex_samples_no_prefix ; + int frame_length_complex_samples; NR_DL_FRAME_PARMS *frame_parms; int loglvl = OAILOG_WARNING; uint64_t SSB_positions=0x01; @@ -409,7 +409,7 @@ int main(int argc, char **argv) //init_eNB_afterRU(); frame_length_complex_samples = frame_parms->samples_per_subframe; - frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; + //frame_length_complex_samples_no_prefix = frame_parms->samples_per_subframe_wCP; //configure UE UE = malloc(sizeof(PHY_VARS_NR_UE)); @@ -443,7 +443,7 @@ int main(int argc, char **argv) unsigned char harq_pid = 0; unsigned int TBS; unsigned int available_bits; - uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4; + uint8_t nb_re_dmrs = UE->dmrs_UplinkConfig.pusch_maxLength*(UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1?6:4); uint8_t length_dmrs = 1; unsigned char mod_order; uint16_t code_rate; diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 4f81c22fb0bee322e307222890e6ff51c456ddb8..054f3f37341477ed5b033531cad4869cf7f1cddd 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -133,7 +133,7 @@ typedef struct gtpv1u_enb_data_forwarding_req_s { typedef struct gtpv1u_enb_data_forwarding_ind_s { uint32_t frame; uint8_t enb_flag; - uint32_t rb_id; + rb_id_t rb_id; uint32_t muip; uint32_t confirmp; uint32_t sdu_size; @@ -155,7 +155,7 @@ typedef struct gtpv1u_enb_end_marker_req_s { typedef struct gtpv1u_enb_end_marker_ind_s { uint32_t frame; uint8_t enb_flag; - uint32_t rb_id; + rb_id_t rb_id; uint32_t muip; uint32_t confirmp; uint32_t sdu_size; diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h index c90490b0fd36077c99f1c023ec33655244b01ca0..1551e4283f38327be795b84d86d419ef9e0e8f6b 100644 --- a/openair2/COMMON/pdcp_messages_types.h +++ b/openair2/COMMON/pdcp_messages_types.h @@ -40,7 +40,7 @@ typedef struct RrcDcchDataReq_s { uint32_t frame; uint8_t enb_flag; - uint32_t rb_id; + rb_id_t rb_id; uint32_t muip; uint32_t confirmp; uint32_t sdu_size; diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 977f44a31050f387d778dd1b9728d83e1e6bf7bf..49c1b340a6994a70c22176c46c1ddcb52aa49833 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -71,8 +71,8 @@ typedef uint8_t slice_id_t; typedef uint8_t eNB_index_t; typedef uint16_t ue_id_t; typedef int16_t smodule_id_t; -typedef uint16_t rb_id_t; -typedef uint16_t srb_id_t; +typedef long rb_id_t; +typedef long srb_id_t; typedef boolean_t MBMS_flag_t; #define MBMS_FLAG_NO FALSE diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 106a9f297ee92f9516985093441ee2d5e079eaf9..0fedc04abd8404a547869093e28e342adcc1ac24 100644 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -93,6 +93,7 @@ typedef enum { #define CONFIG_STRING_RU_SF_EXTENSION "sf_extension" #define CONFIG_STRING_RU_END_OF_BURST_DELAY "end_of_burst_delay" #define CONFIG_STRING_RU_OTA_SYNC_ENABLE "ota_sync_enabled" +#define CONFIG_STRING_RU_BF_WEIGHTS_LIST "bf_weights" #define RU_LOCAL_IF_NAME_IDX 0 #define RU_LOCAL_ADDRESS_IDX 1 @@ -118,23 +119,22 @@ typedef enum { #define RU_SF_EXTENSION_IDX 21 #define RU_END_OF_BURST_DELAY_IDX 22 #define RU_OTA_SYNC_ENABLE_IDX 23 - - +#define RU_BF_WEIGHTS_LIST_IDX 24 /*-----------------------------------------------------------------------------------------------------------------------------------------*/ /* RU configuration parameters */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*-----------------------------------------------------------------------------------------------------------------------------------------*/ #define RUPARAMS_DESC { \ - {CONFIG_STRING_RU_LOCAL_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_LOCAL_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_REMOTE_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_LOCAL_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_LOCAL_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_REMOTE_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_LOCAL_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_REMOTE_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_LOCAL_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_REMOTE_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_TRANSPORT_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"udp_if5", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_LOCAL_RF, NULL, 0, strptr:NULL, defstrval:"yes", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_TRANSPORT_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"udp_if5", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_LOCAL_RF, NULL, 0, strptr:NULL, defstrval:"yes", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_NB_TX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_NB_RX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_MAX_RS_EPRE, NULL, 0, iptr:NULL, defintval:-29, TYPE_INT, 0}, \ @@ -143,13 +143,14 @@ typedef enum { {CONFIG_STRING_RU_ENB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ {CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_IS_SLAVE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ + {CONFIG_STRING_RU_IS_SLAVE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFENBS, TYPE_INTARRAY, 1}, \ {CONFIG_STRING_RU_SDR_ADDRS, NULL, 0, strptr:NULL, defstrval:"type=b200", TYPE_STRING, 0}, \ {CONFIG_STRING_RU_SDR_CLK_SRC, NULL, 0, strptr:NULL, defstrval:"internal", TYPE_STRING, 0}, \ - {CONFIG_STRING_RU_SF_EXTENSION, NULL, 0, uptr:NULL, defuintval:312, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_END_OF_BURST_DELAY, NULL, 0, uptr:NULL, defuintval:400, TYPE_UINT, 0}, \ - {CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_SF_EXTENSION, NULL, 0, uptr:NULL, defuintval:312, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_END_OF_BURST_DELAY, NULL, 0, uptr:NULL, defuintval:400, TYPE_UINT, 0}, \ + {CONFIG_STRING_RU_OTA_SYNC_ENABLE, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \ + {CONFIG_STRING_RU_BF_WEIGHTS_LIST, NULL, 0, iptr:NULL, defintarrayval:DEFBFW, TYPE_INTARRAY, 0}, \ } /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 1ca6f2d7ec6e3feb4e52cbd394fca6293bac1e25..8a55c61cd7f5d22a35dcd629d2e1b719a9ae07d1 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -67,83 +67,9 @@ typedef enum { #define CONFIG_STRING_ACTIVE_RUS "Active_RUs" /*------------------------------------------------------------------------------------------------------------------------------------------*/ -/* RUs configuration section name */ -#define CONFIG_STRING_RU_LIST "RUs" -#define CONFIG_STRING_RU_CONFIG "ru_config" - -/* RUs configuration parameters name */ -#define CONFIG_STRING_RU_LOCAL_IF_NAME "local_if_name" -#define CONFIG_STRING_RU_LOCAL_ADDRESS "local_address" -#define CONFIG_STRING_RU_REMOTE_ADDRESS "remote_address" -#define CONFIG_STRING_RU_LOCAL_PORTC "local_portc" -#define CONFIG_STRING_RU_REMOTE_PORTC "remote_portc" -#define CONFIG_STRING_RU_LOCAL_PORTD "local_portd" -#define CONFIG_STRING_RU_REMOTE_PORTD "remote_portd" -#define CONFIG_STRING_RU_LOCAL_RF "local_rf" -#define CONFIG_STRING_RU_TRANSPORT_PREFERENCE "tr_preference" -#define CONFIG_STRING_RU_BAND_LIST "bands" -#define CONFIG_STRING_RU_GNB_LIST "gNB_instances" -#define CONFIG_STRING_RU_NB_TX "nb_tx" -#define CONFIG_STRING_RU_NB_RX "nb_rx" -#define CONFIG_STRING_RU_ATT_TX "att_tx" -#define CONFIG_STRING_RU_ATT_RX "att_rx" -#define CONFIG_STRING_RU_MAX_RS_EPRE "max_pdschReferenceSignalPower" -#define CONFIG_STRING_RU_MAX_RXGAIN "max_rxgain" -#define CONFIG_STRING_RU_IF_COMPRESSION "if_compression" -#define CONFIG_STRING_RU_NBIOTRRC_LIST "NbIoT_RRC_instances" -#define CONFIG_STRING_RU_SDR_ADDRS "sdr_addrs" -#define CONFIG_STRING_RU_SDR_CLK_SRC "clock_src" - -#define RU_LOCAL_IF_NAME_IDX 0 -#define RU_LOCAL_ADDRESS_IDX 1 -#define RU_REMOTE_ADDRESS_IDX 2 -#define RU_LOCAL_PORTC_IDX 3 -#define RU_REMOTE_PORTC_IDX 4 -#define RU_LOCAL_PORTD_IDX 5 -#define RU_REMOTE_PORTD_IDX 6 -#define RU_TRANSPORT_PREFERENCE_IDX 7 -#define RU_LOCAL_RF_IDX 8 -#define RU_NB_TX_IDX 9 -#define RU_NB_RX_IDX 10 -#define RU_MAX_RS_EPRE_IDX 11 -#define RU_MAX_RXGAIN_IDX 12 -#define RU_BAND_LIST_IDX 13 -#define RU_GNB_LIST_IDX 14 -#define RU_ATT_TX_IDX 15 -#define RU_ATT_RX_IDX 16 -#define RU_IS_SLAVE_IDX 17 -#define RU_NBIOTRRC_LIST_IDX 18 -#define RU_SDR_ADDRS 19 -#define RU_SDR_CLK_SRC 20 -#define RU_SF_EXTENSION_IDX 21 -#define RU_END_OF_BURST_DELAY_IDX 22 - - -/*-----------------------------------------------------------------------------------------------------------------------------------------*/ -/* RU configuration parameters */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-----------------------------------------------------------------------------------------------------------------------------------------*/ -#define GNBRUPARAMS_DESC { \ -{CONFIG_STRING_RU_LOCAL_IF_NAME, NULL, 0, strptr:NULL, defstrval:"lo", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_LOCAL_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.2", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_REMOTE_ADDRESS, NULL, 0, strptr:NULL, defstrval:"127.0.0.1", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_LOCAL_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_REMOTE_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_LOCAL_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_REMOTE_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_TRANSPORT_PREFERENCE, NULL, 0, strptr:NULL, defstrval:"udp_if5", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_LOCAL_RF, NULL, 0, strptr:NULL, defstrval:"yes", TYPE_STRING, 0}, \ -{CONFIG_STRING_RU_NB_TX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_NB_RX, NULL, 0, uptr:NULL, defuintval:1, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_MAX_RS_EPRE, NULL, 0, iptr:NULL, defintval:-29, TYPE_INT, 0}, \ -{CONFIG_STRING_RU_MAX_RXGAIN, NULL, 0, iptr:NULL, defintval:120, TYPE_INT, 0}, \ -{CONFIG_STRING_RU_BAND_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFNRBANDS, TYPE_INTARRAY, 1}, \ -{CONFIG_STRING_RU_GNB_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFGNBS, TYPE_INTARRAY, 1}, \ -{CONFIG_STRING_RU_ATT_TX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_ATT_RX, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \ -{CONFIG_STRING_RU_NBIOTRRC_LIST, NULL, 0, uptr:NULL, defintarrayval:DEFGNBS, TYPE_INTARRAY, 1}, \ -} +/* RUs configuration for gNB is the same for eNB */ +/* Check file enb_paramdef.h */ /*---------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index b1e1fb5d73022fa83a545b933fce51885379971c..04757dab16275b09c7e8c6448ec6f06977a1eee0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -171,7 +171,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB], DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]) { eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; @@ -573,8 +573,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, uint8_t slice_allocation[MAX_NUM_CCs][N_RBG_MAX]; int UE_id, i; uint16_t j,c; - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; - uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; + uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0}; rnti_t rnti; @@ -617,7 +617,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, frameP, subframeP, min_rb_unit, - (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, + (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required, rballoc_sub, MIMO_mode_indicator, mbsfn_flag); @@ -631,7 +631,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, assign_rbs_required(Mod_id, 0, frameP, subframeP, nb_rbs_required, min_rb_unit); #else - memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use], sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use], sizeof(uint16_t)*MAX_NUM_CCs*MAX_MOBILES_PER_ENB); #endif dlsch_scheduler_pre_ue_select_fairRR(Mod_id,frameP,subframeP, mbsfn_flag,nb_rbs_required,dlsch_ue_select); @@ -701,8 +701,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, CC_id, N_RBG[CC_id], min_rb_unit[CC_id], - (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, - (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required_remaining, + (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required, + (uint16_t (*)[MAX_MOBILES_PER_ENB])nb_rbs_required_remaining, rballoc_sub, slice_allocation, MIMO_mode_indicator); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h index 8c901186098c24b1a861dd208c97f8212c638ef0..5355a614a6c8c14b8dc7e2e3a1cd95ff270957c3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h @@ -82,7 +82,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( frame_t frameP, sub_frame_t subframeP, int* mbsfn_flag, - uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX], + uint16_t nb_rbs_required[MAX_NUM_CCs][MAX_MOBILES_PER_ENB], DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]); void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 8fb8d44e0abc80301bb20f566162f7b206e45ac6..4e139dcf92682280a0453e808237a1a4b5f0d66b 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -146,7 +146,7 @@ void mac_top_init_eNB(void) RC.mac = mac; - AssertFatal(rlc_module_init() == 0, + AssertFatal(rlc_module_init(1) == 0, "Could not initialize RLC layer\n"); // These should be out of here later @@ -184,7 +184,7 @@ int rlcmac_init_global_param(void) LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n"); - if (rlc_module_init() != 0) { + if (rlc_module_init(1) != 0) { return (-1); } diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c index f482806e1d198ef7ed98a3e97f6cf6c1192e5ab2..e8b05937170a3026f70b972d11047f81e61a6dc2 100644 --- a/openair2/LAYER2/MAC/main_ue.c +++ b/openair2/LAYER2/MAC/main_ue.c @@ -110,7 +110,7 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer, int rlcmac_init_global_param_ue(void) { LOG_I(MAC, "[MAIN] CALLING RLC_MODULE_INIT...\n"); - if (rlc_module_init() != 0) { + if (rlc_module_init(0) != 0) { return (-1); } diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index f196293ea0890a44070c7c989b072cd4bb4ab984..a74615c3d3309236c193fa4dd7ec1e30b49205f1 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -63,7 +63,8 @@ typedef enum { SFN_C_MOD_2_EQ_0, - SFN_C_MOD_2_EQ_1 + SFN_C_MOD_2_EQ_1, + SFN_C_IMPOSSIBLE } SFN_C_TYPE; diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index c96acccf9b36cbbc224332a980e74e8fb0032a99..0478a6b7d51464fe885023ce0a81dc3b14f7fbce 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -47,7 +47,7 @@ nr_l2_init_ue(void) nr_ue_mac_inst = (NR_UE_MAC_INST_t *)malloc(sizeof(NR_UE_MAC_INST_t)*NB_NR_UE_MAC_INST); if (IS_SOFTMODEM_NOS1){ - if (rlc_module_init() != 0) { + if (rlc_module_init(0) != 0) { LOG_I(RLC, "Problem at RLC initiation \n"); } pdcp_layer_init(); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 6b9e79d51025cb9c41e88c899cf9b2aac9a5ee48..ef94d5db7e10f3c176f69dd5414833c0b996b886 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -441,10 +441,10 @@ int8_t nr_ue_decode_mib( float big_o; float big_m; uint32_t temp; - SFN_C_TYPE sfn_c; // only valid for mux=1 - uint32_t n_c; - uint32_t number_of_search_space_per_slot; - uint32_t first_symbol_index; + SFN_C_TYPE sfn_c=SFN_C_IMPOSSIBLE; // only valid for mux=1 + uint32_t n_c=UINT_MAX; + uint32_t number_of_search_space_per_slot=UINT_MAX; + uint32_t first_symbol_index=UINT_MAX; uint32_t search_space_duration; // element of search space uint32_t coreset_duration; // element of coreset @@ -582,6 +582,7 @@ int8_t nr_ue_decode_mib( search_space_duration = 1; } + AssertFatal(number_of_search_space_per_slot!=UINT_MAX,""); coreset_duration = num_symbols * number_of_search_space_per_slot; mac->type0_pdcch_dci_config.number_of_candidates[0] = table_38213_10_1_1_c2[0]; @@ -591,8 +592,11 @@ int8_t nr_ue_decode_mib( mac->type0_pdcch_dci_config.number_of_candidates[4] = table_38213_10_1_1_c2[4]; // CCE aggregation level = 16 mac->type0_pdcch_dci_config.duration = search_space_duration; mac->type0_pdcch_dci_config.coreset.duration = coreset_duration; // coreset + AssertFatal(first_symbol_index!=UINT_MAX,""); mac->type0_pdcch_dci_config.monitoring_symbols_within_slot = (0x3fff << first_symbol_index) & (0x3fff >> (14-coreset_duration-first_symbol_index)) & 0x3fff; + AssertFatal(sfn_c!=SFN_C_IMPOSSIBLE,""); + AssertFatal(n_c!=UINT_MAX,""); mac->type0_pdcch_ss_sfn_c = sfn_c; mac->type0_pdcch_ss_n_c = n_c; diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 88f6c387585a743432ac0659c944793936da1a63..c5dad59d98f9d7c27bdac79241de6e39bf77826f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -128,7 +128,7 @@ void mac_top_init_gNB(void) }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) - AssertFatal(rlc_module_init() == 0,"Could not initialize RLC layer\n"); + AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); // These should be out of here later pdcp_layer_init(); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index d7cbb33c9eea307b1c181fb02e7c02e8a7a412f5..f234e02c04b7086ca6e81c9552bbd00aeb47410d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -146,12 +146,12 @@ boolean_t pdcp_data_req( sdu_buffer_sizeP, MAX_IP_PACKET_SIZE); if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { - AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); } else { if (srb_flagP) { - AssertError (rb_idP < 3, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < 3, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); } else { - AssertError (rb_idP < LTE_maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); } } @@ -160,7 +160,7 @@ boolean_t pdcp_data_req( if (h_rc != HASH_TABLE_OK) { if (modeP != PDCP_TRANSMISSION_MODE_TRANSPARENT) { - LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %d Ignoring SDU...\n", + LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %ld Ignoring SDU...\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); ctxt_pP->configured=FALSE; @@ -190,7 +190,7 @@ boolean_t pdcp_data_req( rlc_util_print_hex_octets(PDCP, (unsigned char *)&pdcp_pdu_p->data[0], sdu_buffer_sizeP); - LOG_UI(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP); + LOG_UI(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %ld \n", srb_flagP, rb_idP); } rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)?MBMS_FLAG_NO:MBMS_FLAG_YES, rb_idP, muiP, @@ -338,7 +338,7 @@ boolean_t pdcp_data_req( stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); } - LOG_E(PDCP, "[FRAME %5u][%s][PDCP][MOD %u][RB %u] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", + LOG_E(PDCP, "[FRAME %5u][%s][PDCP][MOD %u][RB %ld] PDCP_DATA_REQ SDU DROPPED, OUT OF MEMORY \n", ctxt_pP->frame, (ctxt_pP->enb_flag) ? "eNB" : "UE", ctxt_pP->module_id, @@ -352,11 +352,11 @@ boolean_t pdcp_data_req( * to see if RLC succeeded */ LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size, - "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); + "[MSG] PDCP DL %s PDU on rb_id %ld\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); if ((pdcp_pdu_p!=NULL) && (srb_flagP == 0) && (ctxt_pP->enb_flag == 1)) { - LOG_D(PDCP, "pdcp data req on drb %d, size %d, rnti %x, node_type %d \n", - rb_idP, pdcp_pdu_size, ctxt_pP->rnti, RC.rrc[ctxt_pP->module_id]->node_type); + LOG_D(PDCP, "pdcp data req on drb %ld, size %d, rnti %x, node_type %d \n", + rb_idP, pdcp_pdu_size, ctxt_pP->rnti, RC.rrc ? RC.rrc[ctxt_pP->module_id]->node_type: -1); // The check on nos1 is done only for the use case of LTE stack running over 5g-nr PHY. This should be changed // before future merge of develop with develop-nr and instead of a check of IS_SOFTMODEM_NOS1, we should use a check @@ -374,7 +374,7 @@ boolean_t pdcp_data_req( rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p,sourceL2Id, destinationL2Id); - + ret=FALSE; switch (rlc_status) { case RLC_OP_STATUS_OK: LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); @@ -383,22 +383,18 @@ boolean_t pdcp_data_req( case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; break; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; break; case RLC_OP_STATUS_OUT_OF_RESSOURCES: LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; break; default: LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; break; } // switch case } /* end if node_type is not DU */ @@ -527,19 +523,11 @@ pdcp_data_ind( int security_ok; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_IN); LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP, - "[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); - - -#if T_TRACER - - if (ctxt_pP->enb_flag != ENB_FLAG_NO) - T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP)); - -#endif + "[MSG] PDCP UL %s PDU on rb_id %ld\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); if (MBMS_flagP) { AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, - "RB id is too high (%u/%d) %u rnti %x!\n", + "RB id is too high (%ld/%d) %u rnti %x!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, @@ -547,7 +535,7 @@ pdcp_data_ind( if (ctxt_pP->enb_flag == ENB_FLAG_NO) { LOG_D(PDCP, "e-MBMS Data indication notification for PDCP entity from eNB %u to UE %x " - "and radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n", + "and radio bearer ID %ld rlc sdu size %d ctxt_pP->enb_flag %d\n", ctxt_pP->module_id, ctxt_pP->rnti, rb_idP, @@ -555,7 +543,7 @@ pdcp_data_ind( ctxt_pP->enb_flag); } else { LOG_D(PDCP, "Data indication notification for PDCP entity from UE %x to eNB %u " - "and radio bearer ID %d rlc sdu size %d ctxt_pP->enb_flag %d\n", + "and radio bearer ID %ld rlc sdu size %d ctxt_pP->enb_flag %d\n", ctxt_pP->rnti, ctxt_pP->module_id, rb_idP, @@ -564,12 +552,12 @@ pdcp_data_ind( } } else { rb_id = rb_idP % LTE_maxDRB; - AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%u/%d) %u UE %x!\n", + AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); - AssertError (rb_id > 0, return FALSE, "RB id is too low (%u/%d) %u UE %x!\n", + AssertError (rb_id > 0, return FALSE, "RB id is too low (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, @@ -735,14 +723,6 @@ pdcp_data_ind( pdcp_p->rx_hfn++; } - //rrc_lite_data_ind(module_id, //Modified MW - L2 Interface - MSC_LOG_TX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_NO)? MSC_PDCP_UE:MSC_PDCP_ENB, - (ctxt_pP->enb_flag == ENB_FLAG_NO)? MSC_RRC_UE:MSC_RRC_ENB, - NULL,0, - PROTOCOL_PDCP_CTXT_FMT" DATA-IND len %u", - PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), - sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len); rrc_data_ind(ctxt_pP, rb_id, sdu_buffer_sizeP - pdcp_header_len - pdcp_tailer_len, @@ -945,7 +925,7 @@ pdcp_data_ind( if (LINK_ENB_PDCP_TO_GTPV1U) { if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) { - LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %u len %u\n", + LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %ld len %u\n", ctxt_pP->rnti, rb_id + 4, sdu_buffer_sizeP - payload_offset ); @@ -1186,7 +1166,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).frame, 0, RRC_DCCH_DATA_REQ (msg_p).eNB_index); - LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %ld, muiP %d, confirmP %d, mode %d\n", PROTOCOL_CTXT_ARGS(&ctxt), ITTI_MSG_NAME (msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), @@ -1195,7 +1175,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).muip, RRC_DCCH_DATA_REQ (msg_p).confirmp, RRC_DCCH_DATA_REQ (msg_p).mode); - LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); + LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %ld \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); result = pdcp_data_req (&ctxt, SRB_FLAG_YES, RRC_DCCH_DATA_REQ (msg_p).rb_id, @@ -1846,7 +1826,7 @@ pdcp_config_req_asn1 ( pdcp_pP->rx_hfn = 0; pdcp_pP->last_submitted_pdcp_rx_sn = 4095; pdcp_pP->first_missing_pdu = -1; - LOG_I(PDCP, PROTOCOL_PDCP_CTXT_FMT" Action ADD LCID %d (%s id %d) " + LOG_I(PDCP, PROTOCOL_PDCP_CTXT_FMT" Action ADD LCID %d (%s id %ld) " "configured with SN size %d bits and RLC %s\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), lc_idP, @@ -1898,7 +1878,7 @@ pdcp_config_req_asn1 ( } LOG_I(PDCP,PROTOCOL_PDCP_CTXT_FMT" Action MODIFY LCID %d " - "RB id %d reconfigured with SN size %d and RLC %s \n", + "RB id %ld reconfigured with SN size %d and RLC %s \n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), lc_idP, rb_idP, @@ -1910,7 +1890,7 @@ pdcp_config_req_asn1 ( DevAssert(pdcp_pP != NULL); //#warning "TODO pdcp_module_id_to_rnti" //pdcp_module_id_to_rnti[ctxt_pP.module_id ][dst_id] = NOT_A_RNTI; - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE LCID %d RBID %d configured\n", + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE LCID %d RBID %ld configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), lc_idP, rb_idP); @@ -1937,7 +1917,7 @@ pdcp_config_req_asn1 ( case CONFIG_ACTION_MBMS_ADD: case CONFIG_ACTION_MBMS_MODIFY: - LOG_D(PDCP," %s service_id/mch index %d, session_id/lcid %d, rbid %d configured\n", + LOG_D(PDCP," %s service_id/mch index %d, session_id/lcid %d, rbid %ld configured\n", //PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_pP), actionP == CONFIG_ACTION_MBMS_ADD ? "CONFIG_ACTION_MBMS_ADD" : "CONFIG_ACTION_MBMS_MODIFY", mch_idP, @@ -2063,7 +2043,7 @@ rrc_pdcp_config_req ( } pdcp_p->first_missing_pdu = -1; - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d (already added) configured\n", + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %ld (already added) configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), rb_idP); break; @@ -2072,7 +2052,7 @@ rrc_pdcp_config_req ( break; case CONFIG_ACTION_REMOVE: - LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE: radio bearer id %d configured\n", + LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_REMOVE: radio bearer id %ld configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), rb_idP); pdcp_p->next_pdcp_tx_sn = 0; @@ -2141,7 +2121,7 @@ rrc_pdcp_config_req ( pdcp_p->first_missing_pdu = -1; LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Inserting PDCP instance in collection key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), key); - LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %d configured\n", + LOG_D(PDCP,PROTOCOL_PDCP_CTXT_FMT" Config request : Action ADD: radio bearer id %ld configured\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p), rb_idP); } @@ -2323,10 +2303,8 @@ void nr_ip_over_LTE_DRB_preconfiguration(void){ DRB_configList, (LTE_DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL - //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL - //#endif - ,NULL); + , (LTE_PMCH_InfoList_r9_t *) NULL, + &DRB_config->drb_Identity); rrc_rlc_config_asn1_req(&ctxt, (LTE_SRB_ToAddModList_t*)NULL, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 14507f25894b08af00350400db24b955f423bf10..1d4c6127434e6b57d67601ab07edc321a02efa03 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -87,7 +87,7 @@ extern pthread_mutex_t pdcp_mutex; extern pthread_cond_t pdcp_cond; extern int pdcp_instance_cnt; -#define PROTOCOL_PDCP_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] " +#define PROTOCOL_PDCP_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld] " #define PROTOCOL_PDCP_CTXT_ARGS(CTXT_Pp, pDCP_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (pDCP_Pp->is_srb) ? "SRB" : "DRB",\ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index bc3474a369e59690cf8943cc29912724cfd7bc53..9e873379b135d598ddd027dbfd4b3fe7be3c9e5c 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -98,7 +98,7 @@ extern int gtpv1u_new_data_req( uint8_t enb_module_idP, rnti_t ue_rntiP, uint void debug_pdcp_pc5s_sdu(sidelink_pc5s_element *sl_pc5s_msg, char *title) { LOG_I(PDCP,"%s: \nPC5S message, header traffic_type: %d)\n", title, sl_pc5s_msg->pc5s_header.traffic_type); - LOG_I(PDCP,"PC5S message, header rb_id: %d)\n", sl_pc5s_msg->pc5s_header.rb_id); + LOG_I(PDCP,"PC5S message, header rb_id: %ld)\n", sl_pc5s_msg->pc5s_header.rb_id); LOG_I(PDCP,"PC5S message, header data_size: %d)\n", sl_pc5s_msg->pc5s_header.data_size); LOG_I(PDCP,"PC5S message, header inst: %d)\n", sl_pc5s_msg->pc5s_header.inst); LOG_I(PDCP,"PC5-S message, sourceL2Id: 0x%08x\n)\n", sl_pc5s_msg->pc5s_header.sourceL2Id); @@ -181,33 +181,19 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) { ctxt.module_id, ctxt.rnti, ctxt.enb_flag); if (h_rc == HASH_TABLE_OK) { - LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n", ctxt.frame, ctxt.instance, len, rab_id); - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %ld]\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id); - MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt.instance, rab_id, rab_id, len); pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf, PDCP_TRANSMISSION_MODE_DATA , NULL, NULL ); } else { - MSC_LOG_RX_DISCARDED_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt.instance, rab_id, rab_id, len); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %ld] TUN NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id, ctxt.rnti, rab_id, key); } @@ -253,7 +239,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx if (nas_nlh_rx->nlmsg_len == sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)) { pdcp_read_state_g = 1; //get memcpy((void *)&pdcp_read_header_g, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); - LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %u data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n", + LOG_D(PDCP, "[PDCP][NETLINK] RX pdcp_data_req_header_t inst %u, rb_id %ld data_size %d, source L2Id 0x%08x, destination L2Id 0x%08x\n", pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, pdcp_read_header_g.data_size,pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id ); } else { LOG_E(PDCP, "[PDCP][NETLINK] WRONG size %d should be sizeof (pdcp_data_req_header_t) + sizeof(struct nlmsghdr)\n", @@ -269,7 +255,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; - LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %d, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id, + LOG_D(PDCP, "[PDCP][NETLINK] pdcp_read_header_g.rb_id = %ld, source L2Id = 0x%08x, destination L2Id = 0x%08x \n", pdcp_read_header_g.rb_id, pdcp_read_header_g.sourceL2Id, pdcp_read_header_g.destinationL2Id); if (ctxt.enb_flag) { @@ -283,25 +269,14 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc == HASH_TABLE_OK) { - LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d for rnti: %d \n", + LOG_D(PDCP, "[FRAME %5u][eNB][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %ld for rnti: %d \n", ctxt.frame, pdcp_read_header_g.inst, len, nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), pdcp_read_header_g.rb_id, ctxt.rnti); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u]UE %u][RB %ld]\n", ctxt_cpy.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -320,7 +295,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ,NULL, NULL ); } else { - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE, DROPPED\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %ld] NON INSTANCIATED INSTANCE, DROPPED\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -335,7 +310,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx for (ue_id = 0; ue_id < NB_UE_INST; ue_id++) { if (oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id] != NOT_A_RNTI) { ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt_cpy.module_id][ue_id]; - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -377,27 +352,27 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ctxt.module_id, ctxt.rnti, ctxt.enb_flag); key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_D(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } else { rab_id = rab_id % LTE_maxDRB; - LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%ld, SRB_FLAG=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_D(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } if (h_rc == HASH_TABLE_OK) { rab_id = pdcp_p->rb_id; - LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %d \n", + LOG_D(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d (nlmsg_len = %zu) on Rab %ld \n", ctxt.frame, pdcp_read_header_g.inst, len, nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), pdcp_read_header_g.rb_id); - LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %ld]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -405,17 +380,6 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ctxt.module_id, ctxt.rnti, rab_id); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL, - 0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - rab_id, - pdcp_read_header_g.data_size); pdcp_data_req( &ctxt, SRB_FLAG_NO, @@ -441,7 +405,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx rab_id, pdcp_read_header_g.data_size); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %ld] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -453,7 +417,7 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx } /* h_rc != HASH_TABLE_OK */ } else {/* else of rab_id != 0 */ LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pdcp_read_header_g.inst, pdcp_read_header_g.rb_id, @@ -461,16 +425,6 @@ int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctx ctxt.module_id, ctxt.rnti, DEFAULT_RAB_ID); - MSC_LOG_RX_MESSAGE( - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, - (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE, - NULL,0, - MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u default rab %u size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - pdcp_read_header_g.inst, - pdcp_read_header_g.rb_id, - DEFAULT_RAB_ID, - pdcp_read_header_g.data_size); pdcp_data_req ( &ctxt, SRB_FLAG_NO, @@ -555,7 +509,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) //#warning "TO DO CORRCT VALUES FOR ue mod id, enb mod id" ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ctxt_cpy.enb_flag; - LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %d\n", pc5s_header->rb_id); + LOG_I(PDCP, "[PDCP] pc5s_header->rb_id = %ld\n", pc5s_header->rb_id); if (ctxt_cpy.enb_flag) { ctxt.module_id = 0; @@ -575,26 +529,26 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) ctxt.module_id, ctxt.rnti, ctxt.enb_flag); key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_D(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } else { rab_id = rab_id % LTE_maxDRB; - LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", + LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%ld, SRB_FLAG=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); - LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_I(PDCP,"request key %x : (%d,%x,%d,%ld)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } if (h_rc == HASH_TABLE_OK) { rab_id = pdcp_p->rb_id; - LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n", + LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %ld \n", ctxt.frame, pc5s_header->inst, bytes_received, pc5s_header->rb_id); - LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %u]\n", + LOG_I(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB %ld]\n", ctxt.frame, pc5s_header->inst, pc5s_header->rb_id, @@ -638,7 +592,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) rab_id, pc5s_header->data_size); LOG_D(PDCP, - "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", + "[FRAME %5u][UE][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %u][RB %ld] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n", ctxt.frame, pc5s_header->inst, pc5s_header->rb_id, @@ -650,7 +604,7 @@ void pdcp_fifo_read_input_sdus_frompc5s (const protocol_ctxt_t *const ctxt_pP) } } else { /* else of if (rab_id == 0) */ LOG_D(PDCP, "Forcing send on DEFAULT_RAB_ID\n"); - LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", + LOG_D(PDCP, "[FRAME %5u][eNB][IP][INSTANCE %u][RB %ld][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %u][RB DEFAULT_RAB_ID %u]\n", ctxt.frame, pc5s_header->inst, pc5s_header->rb_id, @@ -706,28 +660,6 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t *const ctxt_pP) { return 0; } - -void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t *const ctxt_pP) { - module_id_t dst_id; // dst for otg - protocol_ctxt_t ctxt; - - // we need to add conditions to avoid transmitting data when the UE is not RRC connected. - if ((otg_enabled==1) && (ctxt_pP->enb_flag == ENB_FLAG_YES)) { // generate DL traffic - PROTOCOL_CTXT_SET_BY_MODULE_ID( - &ctxt, - ctxt_pP->module_id, - ctxt_pP->enb_flag, - NOT_A_RNTI, - ctxt_pP->frame, - ctxt_pP->subframe, - ctxt_pP->module_id); - - for (dst_id = 0; dst_id<NUMBER_OF_UE_MAX; dst_id++) { - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id][dst_id]; - } - } -} - //TTN for D2D (PC5S) void diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c index 0bf3d86bae4f0db6549207de73e9c65a812e0e34..891c38209b5eda9637cc17fabb7c81c186d24eb0 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_netlink.c @@ -221,7 +221,7 @@ void *pdcp_netlink_thread_fct(void *arg) pdcp_thread_read_state = 1; memcpy((void *)&new_data_p->pdcp_read_header, (void *)NLMSG_DATA(nas_nlh_rx), sizeof(pdcp_data_req_header_t)); LOG_I(PDCP, "[NETLINK_THREAD] RX pdcp_data_req_header_t inst %u, " - "rb_id %u data_size %d\n", + "rb_id %ld data_size %d\n", new_data_p->pdcp_read_header.inst, new_data_p->pdcp_read_header.rb_id, new_data_p->pdcp_read_header.data_size); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index a18713fbb67a32c94a91a922e47f7e7f67657310..8f9ee0af188e93a7fdb9a15c21d0c3b0551ccf99 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -128,7 +128,7 @@ pdcp_apply_security( /* SRBs */ uint8_t *mac_i; - LOG_D(PDCP, "[OSA][RB %d] %s Applying control-plane security %d \n", + LOG_D(PDCP, "[OSA][RB %ld] %s Applying control-plane security %d \n", rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE", pdcp_pP->integrityProtAlgorithm); encrypt_params.message = pdcp_pdu_buffer; @@ -145,7 +145,7 @@ pdcp_apply_security( encrypt_params.key = pdcp_pP->kRRCenc; // + 128 // bit key } else { - LOG_D(PDCP, "[OSA][RB %d] %s Applying user-plane security\n", + LOG_D(PDCP, "[OSA][RB %ld] %s Applying user-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "UE -> eNB" : "eNB -> UE"); encrypt_params.key = pdcp_pP->kUPenc;// + 128; @@ -200,11 +200,11 @@ pdcp_validate_security( decrypt_params.key_length = 16; if (srb_flagP) { - LOG_D(PDCP, "[OSA][RB %d] %s Validating control-plane security\n", + LOG_D(PDCP, "[OSA][RB %ld] %s Validating control-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kRRCenc;// + 128; } else { - LOG_D(PDCP, "[OSA][RB %d] %s Validating user-plane security\n", + LOG_D(PDCP, "[OSA][RB %ld] %s Validating user-plane security\n", rb_id, (pdcp_pP->is_ue != 0) ? "eNB -> UE" : "UE -> eNB"); decrypt_params.key = pdcp_pP->kUPenc;// + 128; } @@ -228,7 +228,7 @@ pdcp_validate_security( " Security: failed MAC-I Algo %X UE %"PRIx16" ", pdcp_pP->integrityProtAlgorithm, ctxt_pP->rnti); - LOG_E(PDCP, "[OSA][RB %d] %s failed to validate MAC-I (key %llx) of incoming PDU\n", + LOG_E(PDCP, "[OSA][RB %ld] %s failed to validate MAC-I (key %llx) of incoming PDU\n", rb_id, (pdcp_pP->is_ue != 0) ? "UE" : "eNB",((long long unsigned int*)decrypt_params.key)[0]); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY, VCD_FUNCTION_OUT); return -1; diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c index 02e1b63129668e97eb6dae7a98ee0990be15f499..a11c029bd3637e022a8699562f65f3863f56b5b3 100644 --- a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c +++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c @@ -543,7 +543,7 @@ int proto_agent_pdcp_data_ind_process(mod_id_t mod_id, const void *params, Proto // if (xid == 1) // pdcp_data_ind_wifi((const protocol_ctxt_t*) ctxt_pP, (const srb_flag_t) srb_flagP, (const MBMS_flag_t) flag_MBMS, (const rb_id_t) rb_idP, pdcp_pdu_size, pdcp_pdu_p); // else if (xid == 0) // FIXME: USE a preprocessed definition - LOG_D(PROTO_AGENT, "[inst %d] Received PDCP PDU with size %d for UE RNTI %x RB %d, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP); + LOG_D(PROTO_AGENT, "[inst %d] Received PDCP PDU with size %d for UE RNTI %x RB %ld, Calling pdcp_data_ind\n", ctxt_pP.instance, pdcp_pdu_size,ctxt_pP.rnti,rb_idP); result = pdcp_data_ind(&ctxt_pP, srb_flagP, flag_MBMS, diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index ef40b186e001e01a3472ea00fb8ec63ff282b8df..865a81535946cd927d847a5e17d5c5c643982313 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -672,7 +672,7 @@ rlc_am_mac_data_request ( if ( LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -771,7 +771,7 @@ rlc_am_mac_data_request ( if ( LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "PDU type : RLC AM DATA REQ: STATUS PDU\n\n"); message_string_size += sprintf(&message_string[message_string_size], "Header :\n"); @@ -874,7 +874,7 @@ rlc_am_mac_data_indication ( } if ( LOG_DEBUGFLAG(DEBUG_RLC)) { - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -971,7 +971,7 @@ rlc_am_mac_data_indication ( if ( LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", ((struct mac_tb_ind *) (tb_p->data))->size); message_string_size += sprintf(&message_string[message_string_size], "PDU type : RLC AM DATA IND: STATUS PDU\n\n"); message_string_size += sprintf(&message_string[message_string_size], "Header :\n"); @@ -1039,7 +1039,7 @@ rlc_am_data_req ( mui); if (LOG_DEBUGFLAG(DEBUG_RLC)) { - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", data_size); message_string_size += sprintf(&message_string[message_string_size], "MUI : %u\n", mui); message_string_size += sprintf(&message_string[message_string_size], "CONF : %u\n", ((struct rlc_am_data_req *) (sdu_pP->data))->conf); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h index c6a5ca721320915ccda6dbd98c5dbfca4e65a742..f2cb456e8cfb94816d46d77cecbb4e260cec5990 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h @@ -60,12 +60,12 @@ //# include "rlc_am_test.h" -#define PROTOCOL_RLC_AM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u]" +#define PROTOCOL_RLC_AM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld]" #define PROTOCOL_RLC_AM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\ rLC_Pp->rb_id -#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]" +#define PROTOCOL_RLC_AM_MSC_FMT "[RNTI %" PRIx16 " %s %02ld]" #define PROTOCOL_RLC_AM_MSC_ARGS(CTXT_Pp, rLC_Pp) \ CTXT_Pp->rnti,\ (rLC_Pp->is_data_plane) ? "DRB AM" : "SRB AM",\ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index 369c7fd0da56576168243e6c8de429a2f557e773..793d0057ac99a149fb27c1011c23aa27e24f62f5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -111,7 +111,7 @@ rlc_am_send_sdu ( char message_string[7000]; size_t message_string_size = 0; int octet_index, index; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_pP->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", rlc_pP->rb_id); message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", rlc_pP->output_sdu_size_to_write); message_string_size += sprintf(&message_string[message_string_size], "\nPayload : \n"); message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n"); diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h index a5bd0b9ef59d4d077791498f75204750410e345c..1ea99887071397ebccb8c2b9f9c7d5ceaf92ff3d 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h @@ -42,7 +42,7 @@ # include "mem_block.h" # include "rlc_tm_init.h" -#define PROTOCOL_RLC_TM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u]" +#define PROTOCOL_RLC_TM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld]" #define PROTOCOL_RLC_TM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (rLC_Pp->is_data_plane) ? "DRB TM" : "SRB TM",\ rLC_Pp->rb_id diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c index 78d7cc515f4ae713991cd7ec51c964242a232c10..22e6f4d78d1a4d1b8d0dc4c855216bda7068caed 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c @@ -42,7 +42,7 @@ void config_req_rlc_tm ( if (h_rc == HASH_TABLE_OK) { rlc_p = &rlc_union_p->rlc.tm; - LOG_D(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ (is_uplink_downlink=%d) RB %u\n", + LOG_D(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ (is_uplink_downlink=%d) RB %ld\n", PROTOCOL_RLC_TM_CTXT_ARGS(ctxt_pP, rlc_p), config_tmP->is_uplink_downlink, rb_idP); @@ -52,7 +52,7 @@ void config_req_rlc_tm ( rlc_tm_set_debug_infos(ctxt_pP, rlc_p, srb_flagP, rb_idP, chan_idP); rlc_tm_configure(ctxt_pP, rlc_p, config_tmP->is_uplink_downlink); } else { - LOG_E(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ RB %u RLC NOT FOUND\n", + LOG_E(RLC, PROTOCOL_RLC_TM_CTXT_FMT" CONFIG_REQ RB %ld RLC NOT FOUND\n", PROTOCOL_RLC_TM_CTXT_ARGS(ctxt_pP, rlc_p), rb_idP); } diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c index 66a544f96287c20a875d69277780e7cb1d4f2940..c7dc11f51dc62dfe4d615d427b5d45ce2d3edbd5 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c @@ -279,7 +279,7 @@ rlc_um_rx (const protocol_ctxt_t *const ctxt_pP, void *argP, struct mac_data_ind if (LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -525,7 +525,7 @@ rlc_um_mac_data_request (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP,cons if(LOG_DEBUGFLAG(DEBUG_RLC)) { message_string_size = 0; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", l_rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", l_rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "PDU size : %u\n", tb_size_in_bytes); message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size); message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size); @@ -631,7 +631,7 @@ rlc_um_data_req (const protocol_ctxt_t *const ctxt_pP, void *rlc_pP, mem_block_t if (LOG_DEBUGFLAG(DEBUG_RLC) ) { data_offset = sizeof (struct rlc_um_data_req_alloc); data_size = ((struct rlc_um_tx_sdu_management *)(sdu_pP->data))->sdu_size; - message_string_size += sprintf(&message_string[message_string_size], "Bearer : %u\n", rlc_p->rb_id); + message_string_size += sprintf(&message_string[message_string_size], "Bearer : %ld\n", rlc_p->rb_id); message_string_size += sprintf(&message_string[message_string_size], "SDU size : %u\n", data_size); message_string_size += sprintf(&message_string[message_string_size], "\nPayload : \n"); message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n"); diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h index fc6e449acf7b7e38dfd1d8dd229c24af58181e90..8000196b32d7ec033d0a9af9099320e8d9db2b79 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.h @@ -50,13 +50,13 @@ # include "rlc_um_segment.h" # include "rlc_um_test.h" -#define PROTOCOL_RLC_UM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02u] %s()" +#define PROTOCOL_RLC_UM_CTXT_FMT PROTOCOL_CTXT_FMT"[%s %02ld] %s()" #define PROTOCOL_RLC_UM_CTXT_ARGS(CTXT_Pp, rLC_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp),\ (rLC_Pp->is_data_plane) ? "DRB UM" : "SRB UM",\ rLC_Pp->rb_id,\ __FUNCTION__ -#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %" PRIx16 " %s %02u]" +#define PROTOCOL_RLC_UM_MSC_FMT "[RNTI %" PRIx16 " %s %02ld]" #define PROTOCOL_RLC_UM_MSC_ARGS(CTXT_Pp, rLC_Pp) \ CTXT_Pp->rnti,\ (rLC_Pp->is_data_plane) ? "DRB UM" : "SRB UM",\ diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c index 77194f3a9e219712ae274c98e6d35383ff60f747..940740943e06b4da2125a9f88cd257f3e523ebf3 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c @@ -50,7 +50,7 @@ void config_req_rlc_um ( if (h_rc == HASH_TABLE_OK) { rlc_p = &rlc_union_p->rlc.um; - LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%d sn_field_length=%d is_mXch=%d RB %u\n", + LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%d sn_field_length=%d is_mXch=%d RB %ld\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), config_um_pP->timer_reordering, config_um_pP->sn_field_length, @@ -69,7 +69,7 @@ void config_req_rlc_um ( config_um_pP->is_mXch); } } else { - LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ RB %u RLC UM NOT FOUND\n", + LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ RB %ld RLC UM NOT FOUND\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rb_idP); } @@ -143,14 +143,14 @@ void config_req_rlc_um_asn1 ( // rb_idP, // srb_flagP); if(h_rc != HASH_TABLE_OK) { - LOG_E(RLC, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %u, srb flag %u\n", + LOG_E(RLC, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %ld, srb flag %u\n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); return; } rlc_p = &rlc_union_p->rlc.um; //----------------------------------------------------------------------------- - LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%dms sn_field_length= RB %u \n", + LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" CONFIG_REQ timer_reordering=%dms sn_field_length= RB %ld \n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), (dl_rlc_pP && dl_rlc_pP->t_Reordering<31)?t_Reordering_tab[dl_rlc_pP->t_Reordering]:-1, rb_idP); @@ -170,7 +170,7 @@ void config_req_rlc_um_asn1 ( break; default: - LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID UL sn_FieldLength %ld, RLC NOT CONFIGURED\n", + LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID UL sn_FieldLength %ld, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, ul_rlc_pP->sn_FieldLength); @@ -198,7 +198,7 @@ void config_req_rlc_um_asn1 ( break; default: - LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID DL sn_FieldLength %ld, RLC NOT CONFIGURED\n", + LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID DL sn_FieldLength %ld, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, dl_rlc_pP->sn_FieldLength); @@ -217,7 +217,7 @@ void config_req_rlc_um_asn1 ( if (dl_rlc_pP->t_Reordering<32) { t_Reordering = t_Reordering_tab[dl_rlc_pP->t_Reordering]; } else { - LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID T_Reordering %ld, RLC NOT CONFIGURED\n", + LOG_E(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID T_Reordering %ld, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_p), rlc_p->rb_id, dl_rlc_pP->t_Reordering); @@ -382,7 +382,7 @@ void rlc_um_configure( rlc_pP->rx_um_window_size = RLC_UM_WINDOW_SIZE_SN_5_BITS; rlc_pP->rx_header_min_length_in_bytes = 1; } else if (rx_sn_field_lengthP != 0) { - LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", + LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->rb_id, rx_sn_field_lengthP); @@ -400,7 +400,7 @@ void rlc_um_configure( rlc_pP->tx_um_window_size = RLC_UM_WINDOW_SIZE_SN_5_BITS; rlc_pP->tx_header_min_length_in_bytes = 1; } else if (tx_sn_field_lengthP != 0) { - LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %u INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", + LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [CONFIGURE] RB %ld INVALID RX SN LENGTH %d BITS NOT IMPLEMENTED YET, RLC NOT CONFIGURED\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->rb_id, tx_sn_field_lengthP); @@ -428,7 +428,7 @@ void rlc_um_set_debug_infos( const srb_flag_t srb_flagP, const rb_id_t rb_idP, const logical_chan_id_t chan_idP) { - LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [SET DEBUG INFOS] rb_id %d srb_flag %d\n", + LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" [SET DEBUG INFOS] rb_id %ld srb_flag %d\n", PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP), rb_idP, srb_flagP); diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c index b6ab367bc1a112318c0c68073bf1a6a47b4586b2..90e006cd1782bdacc9b78d8213fbf1fa16ea78dd 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_receiver.c @@ -50,7 +50,7 @@ rlc_um_display_rx_window( LOG_T(RLC, "\n"); sprintf(time_out_str, "%010d", rlc_pP->t_reordering.ms_duration); time_out_str[10] = 0; - LOG_T(RLC, "| RLC UM RB %02d VR(UR)=%03d VR(UX)=%03d VR(UH)=%03d t-Reordering: %s %s %s |", + LOG_T(RLC, "| RLC UM RB %02ld VR(UR)=%03d VR(UX)=%03d VR(UH)=%03d t-Reordering: %s %s %s |", rlc_pP->rb_id, rlc_pP->vr_ur, rlc_pP->vr_ux, rlc_pP->vr_uh, (rlc_pP->t_reordering.running)?" ON":"OFF", (rlc_pP->t_reordering.running)?"Time-out frameP:":" ", diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 1563a01de352a809ab698161d059754a7e7a6e3c..2fb844f05a8b5d567cc559896e19a71643a1fe56 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -137,7 +137,7 @@ rlc_op_status_t rlc_stat_req ( //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } @@ -332,7 +332,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t log_ch_id = 0; #ifdef DEBUG_RLC_DATA_REQ - LOG_D(RLC,PROTOCOL_CTXT_FMT"rlc_data_req: rb_id %u (MAX %d), muip %d, confirmP %d, sdu_sizeP %d, sdu_pP %p\n", + LOG_D(RLC,PROTOCOL_CTXT_FMT"rlc_data_req: rb_id %ld (MAX %d), muip %d, confirmP %d, sdu_sizeP %d, sdu_pP %p\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP, NB_RAB_MAX, @@ -351,13 +351,13 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, if (MBMS_flagP) { //AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX); if(rb_idP >= NB_RB_MBMS_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MBMS_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } } else { //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } } @@ -387,14 +387,14 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); } else if (sourceL2Id && destinationL2Id) { - LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, + LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%ld, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); //Thinh's line originally uncommented //key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP); //key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, *sourceL2Id, *destinationL2Id, srb_flagP); } else { - LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, + LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%ld, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); } @@ -411,7 +411,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, } if (MBMS_flagP == 0) { - LOG_D(RLC, PROTOCOL_CTXT_FMT"[RB %u] Display of rlc_data_req:\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[RB %ld] Display of rlc_data_req:\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); #if defined(TRACE_RLC_PAYLOAD) @@ -424,7 +424,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, switch (rlc_mode) { case RLC_MODE_NONE: free_mem_block(sdu_pP, __func__); - LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %u\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %ld\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT); @@ -558,7 +558,7 @@ void rlc_data_ind ( const sdu_size_t sdu_sizeP, mem_block_t *sdu_pP) { //----------------------------------------------------------------------------- - LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %ld] Display of rlc_data_ind: size %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -601,7 +601,8 @@ void rlc_data_conf (const protocol_ctxt_t *const ctxt_pP, } //----------------------------------------------------------------------------- int -rlc_module_init (void) { +rlc_module_init (int enb_flag) { /* enb_flag is unused, but needed for binary + * compatibility with rlc_v2 */ //----------------------------------------------------------------------------- int k; module_id_t module_id1; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index dddffed241a1ecc9efd281739056589990834246..dfdf527123536d125e2c64420ab796f0e78a6cf7 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -197,7 +197,7 @@ rlc_mbms_id_t rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_ #define rlc_mbms_ue_get_lcid_by_rb_id(uE_mOD,rB_iD) rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] #define rlc_mbms_ue_set_lcid_by_rb_id(uE_mOD,rB_iD,lOG_cH_iD) do { \ - AssertFatal(rB_iD<NB_RB_MBMS_MAX, "INVALID RB ID %u", rB_iD); \ + AssertFatal(rB_iD<NB_RB_MBMS_MAX, "INVALID RB ID %ld", rB_iD); \ rlc_mbms_rbid2lcid_ue[uE_mOD][rB_iD] = lOG_cH_iD; \ } while (0); @@ -620,10 +620,10 @@ rlc_op_status_t rlc_stat_req ( unsigned int *const stat_timer_poll_retransmit_timed_out, unsigned int *const stat_timer_status_prohibit_timed_out); -/*! \fn int rlc_module_init(void) +/*! \fn int rlc_module_init(int enb_flag) * \brief RAZ the memory of the RLC layer, initialize the memory pool manager (mem_block_t structures mainly used in RLC module). */ -int rlc_module_init(void); +int rlc_module_init(int enb_flag); /** @} */ diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 4c04b9f66208ef5ca353c03ed2ce3a2f2ff84308..49f7420216c1dde675249d62118d80e78c4532ac 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -81,7 +81,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP for (cnt=0; cnt<srb2add_listP->list.count; cnt++) { rb_id = srb2add_listP->list.array[cnt]->srb_Identity; lc_id = rb_id; - LOG_D(RLC, "Adding SRB %ld, rb_id %d\n",srb2add_listP->list.array[cnt]->srb_Identity,rb_id); + LOG_D(RLC, "Adding SRB %ld, rb_id %ld\n",srb2add_listP->list.array[cnt]->srb_Identity,rb_id); srb_toaddmod_p = srb2add_listP->list.array[cnt]; if (srb_toaddmod_p->rlc_Config) { @@ -102,7 +102,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am, rb_id, lc_id); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -122,7 +122,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP rb_id, lc_id,0, 0 ); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -142,7 +142,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP rb_id, lc_id,0, 0 ); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -162,7 +162,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP rb_id, lc_id,0, 0 ); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -196,7 +196,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am, rb_id,lc_id); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_E(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -213,7 +213,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP NULL, // TO DO DEFAULT CONFIG rb_id, lc_id); } else { - LOG_D(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %d \n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" ERROR IN ALLOCATING SRB %ld \n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_id); } @@ -379,7 +379,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP } } - LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %ld SESSION ID %u SERVICE ID %u\n", PROTOCOL_CTXT_ARGS(ctxt_pP), lc_id, rb_id, @@ -502,7 +502,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } @@ -524,7 +524,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( break; default: - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] RLC mode is unknown!\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld] RLC mode is unknown!\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP); @@ -539,20 +539,20 @@ rlc_op_status_t rrc_rlc_remove_rlc ( if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { h_lcid_rc = hashtable_remove(rlc_coll_p, key_lcid); h_rc = hashtable_remove(rlc_coll_p, key); - LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASED %s\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %ld LCID %d] RELEASED %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, lcid, (srb_flagP) ? "SRB" : "DRB"); } else if ((h_rc == HASH_TABLE_KEY_NOT_EXISTS) || (h_lcid_rc == HASH_TABLE_KEY_NOT_EXISTS)) { - LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASE : RLC NOT FOUND %s, by RB-ID=%d, by LC-ID=%d\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %ld LCID %d] RELEASE : RLC NOT FOUND %s, by RB-ID=%d, by LC-ID=%d\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, lcid, (srb_flagP) ? "SRB" : "DRB", h_rc, h_lcid_rc); } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u LCID %d] RELEASE : INTERNAL ERROR %s\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld LCID %d] RELEASE : INTERNAL ERROR %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, lcid, @@ -585,7 +585,7 @@ rlc_union_t *rrc_rlc_add_rlc ( //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); //AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return NULL; } @@ -624,7 +624,7 @@ rlc_union_t *rrc_rlc_add_rlc ( h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p); if (h_rc == HASH_TABLE_OK) { - LOG_W(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , already exist %s\n", + LOG_W(RLC, PROTOCOL_CTXT_FMT"[%s %ld] rrc_rlc_add_rlc , already exist %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -649,7 +649,7 @@ rlc_union_t *rrc_rlc_add_rlc ( mbms_id_p->service_id, mbms_id_p->session_id); } else { - LOG_I(RLC, PROTOCOL_CTXT_FMT" [%s %u] rrc_rlc_add_rlc %s\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT" [%s %ld] rrc_rlc_add_rlc %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -659,7 +659,7 @@ rlc_union_t *rrc_rlc_add_rlc ( rlc_union_p->mode = rlc_modeP; return rlc_union_p; } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc FAILED %s (add by RB_id=%d; add by LC_id=%d)\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld] rrc_rlc_add_rlc FAILED %s (add by RB_id=%d; add by LC_id=%d)\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -670,7 +670,7 @@ rlc_union_t *rrc_rlc_add_rlc ( return NULL; } } else { - LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %u] rrc_rlc_add_rlc , INTERNAL ERROR %s\n", + LOG_E(RLC, PROTOCOL_CTXT_FMT"[%s %ld] rrc_rlc_add_rlc , INTERNAL ERROR %s\n", PROTOCOL_CTXT_ARGS(ctxt_pP), (srb_flagP) ? "SRB" : "DRB", rb_idP, @@ -689,13 +689,13 @@ rlc_op_status_t rrc_rlc_config_req ( const rlc_info_t rlc_infoP) { //----------------------------------------------------------------------------- //rlc_op_status_t status; - LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG_REQ for RAB %u\n", + LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG_REQ for RAB %ld\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); if(rb_idP >= NB_RB_MAX) { - LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); + LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX); return RLC_OP_STATUS_BAD_PARAMETER; } @@ -709,7 +709,7 @@ rlc_op_status_t rrc_rlc_config_req ( case CONFIG_ACTION_MODIFY: switch (rlc_infoP.rlc_mode) { case RLC_MODE_AM: - LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB AM\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %ld] MODIFY RB AM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_am( @@ -720,7 +720,7 @@ rlc_op_status_t rrc_rlc_config_req ( break; case RLC_MODE_UM: - LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB UM\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %ld] MODIFY RB UM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_um( @@ -731,7 +731,7 @@ rlc_op_status_t rrc_rlc_config_req ( break; case RLC_MODE_TM: - LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %u] MODIFY RB TM\n", + LOG_I(RLC, PROTOCOL_CTXT_FMT"[RB %ld] MODIFY RB TM\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); config_req_rlc_tm( diff --git a/openair2/LAYER2/nr_rlc/Makefile b/openair2/LAYER2/nr_rlc/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..071930c4f4b6dc573a1be9f817e91edd369a111b --- /dev/null +++ b/openair2/LAYER2/nr_rlc/Makefile @@ -0,0 +1,15 @@ +CC=gcc +CFLAGS=-Wall -g -Itests + +OBJS=nr_rlc_entity.o nr_rlc_entity_am.o nr_rlc_entity_um.o \ + nr_rlc_entity_tm.o nr_rlc_sdu.o nr_rlc_pdu.o test.o +PROG=test + +$(PROG): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +clean: + rm -f test *.o diff --git a/openair2/LAYER2/nr_rlc/TODO b/openair2/LAYER2/nr_rlc/TODO new file mode 100644 index 0000000000000000000000000000000000000000..4e2d3147c983682871c5f014949e0d4a3389220f --- /dev/null +++ b/openair2/LAYER2/nr_rlc/TODO @@ -0,0 +1,10 @@ +RLC AM: + + - status reporting (38.322 5.3.4): implement this (not done because not + clearly understood): + + "delay triggering the STATUS report until x < RX_Highest_Status + or x >= RX_Next + AM_Window_Size." + + - send indication of successful delivery as soon as possible. Today we + signal successful delivery in order. Probably not a big issue though. diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.c b/openair2/LAYER2/nr_rlc/asn1_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..46f7d90da57d2cb7d15cee8c60614a49a832e955 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/asn1_utils.c @@ -0,0 +1,129 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "rlc.h" + +int decode_t_reordering(int v) +{ + static int tab[32] = { + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, + 90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 1600 + }; + + if (v < 0 || v > 31) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_t_status_prohibit(int v) +{ + static int tab[62] = { + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, + 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, + 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, + 245, 250, 300, 350, 400, 450, 500, 800, 1000, 1200, 1600, 2000, 2400 + }; + + if (v < 0 || v > 61) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_t_poll_retransmit(int v) +{ + static int tab[59] = { + 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, + 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, + 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, + 250, 300, 350, 400, 450, 500, 800, 1000, 2000, 4000 + }; + + if (v < 0 || v > 58) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_poll_pdu(int v) +{ + static int tab[8] = { + 4, 8, 16, 32, 64, 128, 256, -1 /* -1 means infinity */ + }; + + if (v < 0 || v > 7) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_poll_byte(int v) +{ + static int tab[15] = { + 25, 50, 75, 100, 125, 250, 375, 500, 750, 1000, 1250, 1500, 2000, 3000, + -1 /* -1 means infinity */ + }; + + if (v < 0 || v > 14) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (tab[v] == -1) return -1; + return tab[v] * 1024; +} + +int decode_max_retx_threshold(int v) +{ + static int tab[8] = { + 1, 2, 3, 4, 6, 8, 16, 32 + }; + + if (v < 0 || v > 7) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_sn_field_length(int v) +{ + static int tab[2] = { + 5, 10 + }; + + if (v < 0 || v > 1) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.h b/openair2/LAYER2/nr_rlc/asn1_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..61394c9c6991ccdc32722bfb039bfdac82a741ae --- /dev/null +++ b/openair2/LAYER2/nr_rlc/asn1_utils.h @@ -0,0 +1,33 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _ASN1_UTILS_H_ +#define _ASN1_UTILS_H_ + +int decode_t_reordering(int v); +int decode_t_status_prohibit(int v); +int decode_t_poll_retransmit(int v); +int decode_poll_pdu(int v); +int decode_poll_byte(int v); +int decode_max_retx_threshold(int v); +int decode_sn_field_length(int v); + +#endif /* _ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c new file mode 100644 index 0000000000000000000000000000000000000000..fefe2fc77d4bf6a4ca606343133579cd4f2ecc2c --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -0,0 +1,174 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity.h" + +#include <stdlib.h> + +#include "nr_rlc_entity_am.h" +#include "nr_rlc_entity_um.h" +#include "nr_rlc_entity_tm.h" + +#include "LOG/log.h" + +nr_rlc_entity_t *new_nr_rlc_entity_am( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + struct nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, + struct nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length) +{ + nr_rlc_entity_am_t *ret; + + ret = calloc(1, sizeof(nr_rlc_entity_am_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ret->tx_maxsize = tx_maxsize; + ret->rx_maxsize = rx_maxsize; + + ret->t_poll_retransmit = t_poll_retransmit; + ret->t_reassembly = t_reassembly; + ret->t_status_prohibit = t_status_prohibit; + ret->poll_pdu = poll_pdu; + ret->poll_byte = poll_byte; + ret->max_retx_threshold = max_retx_threshold; + ret->sn_field_length = sn_field_length; + + if (!(sn_field_length == 12 || sn_field_length == 18)) { + LOG_E(RLC, "%s:%d:%s: wrong SN field_lenght (%d), must be 12 or 18\n", + __FILE__, __LINE__, __FUNCTION__, sn_field_length); + exit(1); + } + ret->sn_modulus = 1 << ret->sn_field_length; + ret->window_size = ret->sn_modulus / 2; + + ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_am_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; + ret->common.set_time = nr_rlc_entity_am_set_time; + ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_am_reestablishment; + ret->common.delete = nr_rlc_entity_am_delete; + + ret->common.deliver_sdu = deliver_sdu; + ret->common.deliver_sdu_data = deliver_sdu_data; + ret->common.sdu_successful_delivery = sdu_successful_delivery; + ret->common.sdu_successful_delivery_data = sdu_successful_delivery_data; + ret->common.max_retx_reached = max_retx_reached; + ret->common.max_retx_reached_data = max_retx_reached_data; + + return (nr_rlc_entity_t *)ret; +} + +nr_rlc_entity_t *new_nr_rlc_entity_um( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length) +{ + nr_rlc_entity_um_t *ret; + + ret = calloc(1, sizeof(nr_rlc_entity_um_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ret->tx_maxsize = tx_maxsize; + ret->rx_maxsize = rx_maxsize; + + ret->t_reassembly = t_reassembly; + ret->sn_field_length = sn_field_length; + + if (!(sn_field_length == 6 || sn_field_length == 12)) { + LOG_E(RLC, "%s:%d:%s: wrong SN field_lenght (%d), must be 6 or 12\n", + __FILE__, __LINE__, __FUNCTION__, sn_field_length); + exit(1); + } + ret->sn_modulus = 1 << ret->sn_field_length; + ret->window_size = ret->sn_modulus / 2; + + ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_um_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; + ret->common.set_time = nr_rlc_entity_um_set_time; + ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_um_reestablishment; + ret->common.delete = nr_rlc_entity_um_delete; + + ret->common.deliver_sdu = deliver_sdu; + ret->common.deliver_sdu_data = deliver_sdu_data; + + return (nr_rlc_entity_t *)ret; +} + +nr_rlc_entity_t *new_nr_rlc_entity_tm( + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data) +{ + nr_rlc_entity_tm_t *ret; + + ret = calloc(1, sizeof(nr_rlc_entity_tm_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ret->tx_maxsize = tx_maxsize; + + ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; + ret->common.set_time = nr_rlc_entity_tm_set_time; + ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; + ret->common.delete = nr_rlc_entity_tm_delete; + + ret->common.deliver_sdu = deliver_sdu; + ret->common.deliver_sdu_data = deliver_sdu_data; + + return (nr_rlc_entity_t *)ret; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h new file mode 100644 index 0000000000000000000000000000000000000000..5b12a90cfd1daf04437a276d5258e0849e7d9ca1 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -0,0 +1,104 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_H_ +#define _NR_RLC_ENTITY_H_ + +#include <stdint.h> + +#define NR_SDU_MAX 16000 /* max NR PDCP SDU size is 9000, let's take more */ + +typedef struct { + int status_size; + int tx_size; + int retx_size; +} nr_rlc_entity_buffer_status_t; + +typedef struct nr_rlc_entity_t { + /* functions provided by the RLC module */ + void (*recv_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); + nr_rlc_entity_buffer_status_t (*buffer_status)( + struct nr_rlc_entity_t *entity, int maxsize); + int (*generate_pdu)(struct nr_rlc_entity_t *entity, char *buffer, int size); + + void (*recv_sdu)(struct nr_rlc_entity_t *entity, char *buffer, int size, + int sdu_id); + + void (*set_time)(struct nr_rlc_entity_t *entity, uint64_t now); + + void (*discard_sdu)(struct nr_rlc_entity_t *entity, int sdu_id); + + void (*reestablishment)(struct nr_rlc_entity_t *entity); + + void (*delete)(struct nr_rlc_entity_t *entity); + + /* callbacks provided to the RLC module */ + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size); + void *deliver_sdu_data; + + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + struct nr_rlc_entity_t *entity, + int sdu_id); + void *sdu_successful_delivery_data; + + void (*max_retx_reached)(void *max_retx_reached_data, + struct nr_rlc_entity_t *entity); + void *max_retx_reached_data; +} nr_rlc_entity_t; + +nr_rlc_entity_t *new_nr_rlc_entity_am( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*sdu_successful_delivery)(void *sdu_successful_delivery_data, + struct nr_rlc_entity_t *entity, + int sdu_id), + void *sdu_successful_delivery_data, + void (*max_retx_reached)(void *max_retx_reached_data, + struct nr_rlc_entity_t *entity), + void *max_retx_reached_data, + int t_poll_retransmit, + int t_reassembly, + int t_status_prohibit, + int poll_pdu, + int poll_byte, + int max_retx_threshold, + int sn_field_length); + +nr_rlc_entity_t *new_nr_rlc_entity_um( + int rx_maxsize, + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + int t_reassembly, + int sn_field_length); + +nr_rlc_entity_t *new_nr_rlc_entity_tm( + int tx_maxsize, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data); + +#endif /* _NR_RLC_ENTITY_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c new file mode 100644 index 0000000000000000000000000000000000000000..8f3d49d8c2391b98daf24f8d74ad7bb54a951905 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -0,0 +1,1844 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity_am.h" + +#include <stdlib.h> +#include <string.h> + +#include "nr_rlc_pdu.h" + +#include "LOG/log.h" + +/*************************************************************************/ +/* PDU RX functions */ +/*************************************************************************/ + +static int modulus_rx(nr_rlc_entity_am_t *entity, int a) +{ + /* as per 38.322 7.1, modulus base is rx_next */ + int r = a - entity->rx_next; + if (r < 0) r += entity->sn_modulus; + return r; +} + +static int modulus_tx(nr_rlc_entity_am_t *entity, int a) +{ + int r = a - entity->tx_next_ack; + if (r < 0) r += entity->sn_modulus; + return r; +} + +static int sn_in_recv_window(void *_entity, int sn) +{ + nr_rlc_entity_am_t *entity = _entity; + int mod_sn = modulus_rx(entity, sn); + /* we simplify rx_next <= sn < rx_next + am_window_size */ + return mod_sn < entity->window_size; +} + +static int sn_compare_rx(void *_entity, int a, int b) +{ + nr_rlc_entity_am_t *entity = _entity; + return modulus_rx(entity, a) - modulus_rx(entity, b); +} + +static int sn_compare_tx(void *_entity, int a, int b) +{ + nr_rlc_entity_am_t *entity = _entity; + return modulus_tx(entity, a) - modulus_tx(entity, b); +} + +static int segment_already_received(nr_rlc_entity_am_t *entity, + int sn, int so, int size) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int covered; + + while (l != NULL && size > 0) { + if (l->sn == sn) { + if (l->so <= so && so < l->so + l->size) { + covered = l->size - (so - l->so); + size -= covered; + so += covered; + } else if (l->so <= so+size-1 && so+size-1 < l->so + l->size) { + covered = size - (l->so - so); + size -= covered; + } + } + l = l->next; + } + + return size <= 0; +} + +static void consider_retransmission(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *cur, int update_retx) +{ + if (update_retx) + cur->sdu->retx_count++; + + /* let's report max RETX reached for all retx_count >= max_retx_threshold + * (specs say to report if retx_count == max_retx_threshold). + * Upper layers should react (radio link failure), so no big deal actually. + */ + if (update_retx && cur->sdu->retx_count >= entity->max_retx_threshold) { + entity->common.max_retx_reached(entity->common.max_retx_reached_data, + (nr_rlc_entity_t *)entity); + } + + /* let's put in retransmit list even if we are over max_retx_threshold. + * upper layers should deal with this condition, internally it's better + * for the RLC code to keep going with this segment (we only remove + * a segment that was ACKed) + */ + nr_rlc_sdu_segment_list_append(&entity->retransmit_list, + &entity->retransmit_end, + cur); +} + +/* checks that all the bytes of the SDU sn have been received (but SDU + * has not been already processed) + */ +static int sdu_full(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 0; + if (l->is_last) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +/* checks that an SDU has already been delivered */ +static int sdu_delivered(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + return l != NULL && l->data == NULL; +} + +/* check if there is some missing bytes before the last received of SDU sn */ +/* todo: be sure that when no byte was received or the SDU has already been + * processed then the SDU has no missing byte + */ +static int sdu_has_missing_bytes(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; /* data already processed: no missing byte */ + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +static void reassemble_and_deliver(nr_rlc_entity_am_t *entity, int sn) +{ + nr_rlc_pdu_t *pdu; + char sdu[NR_SDU_MAX]; + int so = 0; + int bad_sdu = 0; + + /* go to first segment of sn */ + pdu = entity->rx_list; + while (pdu->sn != sn) + pdu = pdu->next; + + /* reassemble - free 'data' of each segment after processing */ + while (pdu != NULL && pdu->sn == sn) { + int len = pdu->size - (so - pdu->so); + if (so + len > NR_SDU_MAX && !bad_sdu) { + LOG_E(RLC, "%s:%d:%s: bad SDU, too big, discarding\n", + __FILE__, __LINE__, __FUNCTION__); + bad_sdu = 1; + } + if (!bad_sdu && len > 0) { + memcpy(sdu + so, pdu->data, len); + so += len; + } + free(pdu->data); + pdu->data = NULL; + entity->rx_size -= pdu->size; + pdu = pdu->next; + } + + if (bad_sdu) + return; + + /* deliver */ + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + sdu, so); +} + +static void reception_actions(nr_rlc_entity_am_t *entity, nr_rlc_pdu_t *pdu) +{ + int x = pdu->sn; + + if (sn_compare_rx(entity, x, entity->rx_next_highest) >= 0) + entity->rx_next_highest = (x + 1) % entity->sn_modulus; + + /* todo: room for optimization: we can run through rx_list only once */ + if (sdu_full(entity, x)) { + reassemble_and_deliver(entity, x); + + if (x == entity->rx_highest_status) { + int rx_highest_status = entity->rx_highest_status; + while (sdu_delivered(entity, rx_highest_status)) + rx_highest_status = (rx_highest_status + 1) % entity->sn_modulus; + entity->rx_highest_status = rx_highest_status; + } + + if (x == entity->rx_next) { + /* update rx_next and free all delivered SDUs at the head of the + * rx_list + */ + int rx_next = entity->rx_next; + while (entity->rx_list != NULL && entity->rx_list->data == NULL && + entity->rx_list->sn == rx_next) { + /* free all segments of this SDU */ + do { + nr_rlc_pdu_t *p = entity->rx_list; + entity->rx_list = p->next; + free(p); + } while (entity->rx_list != NULL && + entity->rx_list->sn == rx_next); + rx_next = (rx_next + 1) % entity->sn_modulus; + } + entity->rx_next = rx_next; + } + } + + if (entity->t_reassembly_start) { + if (entity->rx_next_status_trigger == entity->rx_next || + (entity->rx_next_status_trigger == (entity->rx_next + 1) + % entity->sn_modulus && + !sdu_has_missing_bytes(entity, entity->rx_next)) || + (!sn_in_recv_window(entity, entity->rx_next_status_trigger) && + entity->rx_next_status_trigger != + (entity->rx_next + entity->window_size) % entity->sn_modulus)) { + entity->t_reassembly_start = 0; + } + } + + if (entity->t_reassembly_start == 0) { + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_next + 1) % entity->sn_modulus) > 0 || + (entity->rx_next_highest == (entity->rx_next + 1) + % entity->sn_modulus && + sdu_has_missing_bytes(entity, entity->rx_next))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_next_status_trigger = entity->rx_next_highest; + } + } +} + +static void process_received_ack(nr_rlc_entity_am_t *entity, int ack_sn) +{ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + unsigned char sn_set[32768]; /* used to dec retx_count only once per sdu */ + + memset(sn_set, 0, 32768); + +#define IS_SN_SET(b) (sn_set[(b)/8] & (1 << ((b) % 8))) +#define SET_SN(b) do { sn_set[(b)/8] |= (1 << ((b) % 8)); } while (0) + + /* put SDUs from wait and retransmit lists with SN < 'ack_sn' to ack_list */ + + /* process wait list */ + head.next = entity->wait_list; + prev = &head; + cur = entity->wait_list; + while (cur != NULL) { + if (sn_compare_tx(entity, cur->sdu->sn, ack_sn) < 0) { + /* remove from wait list */ + prev->next = cur->next; + /* put the PDU in the ack list */ + entity->ack_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity, + entity->ack_list, cur); + entity->wait_end = prev; + cur = prev->next; + } else { + entity->wait_end = cur; + prev = cur; + cur = cur->next; + } + } + entity->wait_list = head.next; + if (entity->wait_list == NULL) + entity->wait_end = NULL; + + /* process retransmit list */ + head.next = entity->retransmit_list; + prev = &head; + cur = entity->retransmit_list; + while (cur != NULL) { + if (sn_compare_tx(entity, cur->sdu->sn, ack_sn) < 0) { + /* dec. retx_count in case we put this segment back in retransmit list + * in 'process_received_nack' + * do it only once per SDU + */ + if (!IS_SN_SET(cur->sdu->sn)) { + cur->sdu->retx_count--; + SET_SN(cur->sdu->sn); + } + /* remove from retransmit list */ + prev->next = cur->next; + /* put the PDU in the ack list */ + entity->ack_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity, + entity->ack_list, cur); + entity->retransmit_end = prev; + cur = prev->next; + } else { + entity->retransmit_end = cur; + prev = cur; + cur = cur->next; + } + } + entity->retransmit_list = head.next; + if (entity->retransmit_list == NULL) + entity->retransmit_end = NULL; + +#undef IS_BIT_SET +#undef SET_BIT +} + +static int so_overlap(int s1, int e1, int s2, int e2) +{ + if (s1 < s2) { + if (e1 == -1 || e1 >= s2) + return 1; + return 0; + } + if (e2 == -1 || s1 <= e2) + return 1; + return 0; +} + +static void process_nack_sn(nr_rlc_entity_am_t *entity, int nack_sn, + int so_start, int so_end, unsigned char *sn_set) +{ + /* put all SDU segments with SN == 'sn' and with an overlapping so start/end + * to the retransmit list + * source lists are ack list and wait list. + * Not sure if we should consider wait list, isn't the other end supposed + * to only NACK SNs lower than the ACK SN sent in the status PDU, in which + * case all potential SDU segments should all be in ack list when calling + * the current function? in doubt let's accept anything and thus process + * also wait list. + */ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + +#define IS_SN_SET(b) (sn_set[(b)/8] & (1 << ((b) % 8))) +#define SET_SN(b) do { sn_set[(b)/8] |= (1 << ((b) % 8)); } while (0) + + /* check that tx_next_ack <= sn < tx_next */ + if (!(sn_compare_tx(entity, entity->tx_next_ack, nack_sn) <= 0 && + sn_compare_tx(entity, nack_sn, entity->tx_next) < 0)) + return; + + /* process wait list */ + head.next = entity->wait_list; + prev = &head; + cur = entity->wait_list; + while (cur != NULL) { + if (cur->sdu->sn == nack_sn && + so_overlap(so_start, so_end, cur->so, cur->so + cur->size - 1)) { + /* remove from wait list */ + prev->next = cur->next; + cur->next = NULL; + /* consider the SDU segment for retransmission */ + consider_retransmission(entity, cur, !IS_SN_SET(cur->sdu->sn)); + SET_SN(cur->sdu->sn); + entity->wait_end = prev; + cur = prev->next; + } else { + entity->wait_end = cur; + prev = cur; + cur = cur->next; + } + } + entity->wait_list = head.next; + if (entity->wait_list == NULL) + entity->wait_end = NULL; + + /* process ack list */ + head.next = entity->ack_list; + prev = &head; + cur = entity->ack_list; + while (cur != NULL) { + if (cur->sdu->sn == nack_sn && + so_overlap(so_start, so_end, cur->so, cur->so + cur->size - 1)) { + /* remove from ack list */ + prev->next = cur->next; + cur->next = NULL; + /* consider the SDU segment for retransmission */ + consider_retransmission(entity, cur, !IS_SN_SET(cur->sdu->sn)); + SET_SN(cur->sdu->sn); + cur = prev->next; + } else { + prev = cur; + cur = cur->next; + } + } + entity->ack_list = head.next; + +#undef IS_BIT_SET +#undef SET_BIT +} + +static void process_received_nack(nr_rlc_entity_am_t *entity, int nack_sn, + int so_start, int so_end, int range, + unsigned char *sn_set) +{ + int i; + + for (i = 0; i < range; i++) + process_nack_sn(entity, (nack_sn + i) % entity->sn_modulus, + i == 0 ? so_start : 0, + i == range - 1 ? so_end : -1, + sn_set); +} + +static int sdu_segment_in_ack_list_full(nr_rlc_sdu_segment_t *sdu) +{ + int target_count = sdu->sdu->ref_count; + int actual_count = 0; + int sn = sdu->sdu->sn; + + while (sdu != NULL && sdu->sdu->sn == sn) { + actual_count++; + sdu = sdu->next; + } + + return actual_count == target_count; +} + +static void finalize_ack_nack_processing(nr_rlc_entity_am_t *entity) +{ + nr_rlc_sdu_segment_t *cur = entity->ack_list; + int sn; + + /* - send indication of successful delivery for all consecutive acked SDUs + * starting from tx_next_ack. Also free them. + * - update tx_next_ack to the next SN not acked yet + */ + /* todo: send indication of successful delivery as soon as possible as + * the specs say (38.322 5.2.3.1.1). As the code is, if we receive + * ack for SN+2 we won't indicate successful delivery before + * SN+1 has been indicated. + */ + while (cur != NULL && cur->sdu->sn == entity->tx_next_ack && + sdu_segment_in_ack_list_full(cur)) { + entity->tx_size -= cur->sdu->size; + sn = cur->sdu->sn; + entity->common.sdu_successful_delivery( + entity->common.sdu_successful_delivery_data, + (nr_rlc_entity_t *)entity, cur->sdu->upper_layer_id); + while (cur != NULL && cur->sdu->sn == sn) { + nr_rlc_sdu_segment_t *s = cur; + cur = cur->next; + nr_rlc_free_sdu_segment(s); + } + entity->ack_list = cur; + entity->tx_next_ack = (entity->tx_next_ack + 1) % entity->sn_modulus; + } +} + +void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ +#define R(d) do { if (nr_rlc_pdu_decoder_in_error(&d)) goto err; } while (0) + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_pdu_decoder_t decoder; + nr_rlc_pdu_decoder_t control_decoder; + nr_rlc_pdu_t *pdu; + int dc; + int p = 0; + int si; + int sn; + int so = 0; + int data_size; + int is_first; + int is_last; + + int cpt; + int e1; + int e2; + int e3; + int ack_sn; + int nack_sn; + int so_start; + int so_end; + int range; + int control_e1; + int control_e2; + int control_e3; + unsigned char sn_set[32768]; /* used to dec retx_count only once per sdu */ + + nr_rlc_pdu_decoder_init(&decoder, buffer, size); + dc = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + if (dc == 0) goto control; + + /* data PDU */ + p = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + si = nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + + is_first = (si & 0x2) == 0; + is_last = (si & 0x1) == 0; + + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + } + + sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); + R(decoder); + + if (!is_first) { + so = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + if (so == 0) { + LOG_E(RLC, "%s:%d:%s: warning: discard PDU, bad so\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + } + + data_size = size - decoder.byte; + + /* dicard PDU if no data */ + if (data_size <= 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* dicard PDU if rx buffer is full */ + if (entity->rx_size + data_size > entity->rx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + if (!sn_in_recv_window(entity, sn)) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, sn out of window (sn %d rx_next %d)\n", + __FILE__, __LINE__, __FUNCTION__, + sn, entity->rx_next); + goto discard; + } + + /* discard segment if all the bytes of the segment are already there */ + if (segment_already_received(entity, sn, so, data_size)) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, already received\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* put in pdu reception list */ + entity->rx_size += data_size; + pdu = nr_rlc_new_pdu(sn, so, is_first, is_last, + buffer + size - data_size, data_size); + entity->rx_list = nr_rlc_pdu_list_add(sn_compare_rx, entity, + entity->rx_list, pdu); + + /* do reception actions (38.322 5.2.3.2.3) */ + reception_actions(entity, pdu); + + if (p) { + /* 38.322 5.3.4 says status triggering should be delayed + * until x < rx_highest_status or x >= rx_next + am_window_size. + * This is not clear (what is x then? we keep the same?). So let's + * trigger no matter what. + * todo: delay status triggering properly + */ + int v = (entity->rx_next + entity->window_size) % entity->sn_modulus; + entity->status_triggered = 1; + if (!(sn_compare_rx(entity, sn, entity->rx_highest_status) < 0 || + sn_compare_rx(entity, sn, v) >= 0)) { + LOG_D(RLC, "%s:%d:%s: warning: STATUS trigger should be delayed, according to specs\n", + __FILE__, __LINE__, __FUNCTION__); + } + } + + return; + +control: + cpt = nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder); + if (cpt != 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, CPT not 0 (%d)\n", + __FILE__, __LINE__, __FUNCTION__, cpt); + goto discard; + } + ack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder); + e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + /* r bits */ + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + } else { + nr_rlc_pdu_decoder_get_bits(&decoder, 7); R(decoder); + } + + /* let's try to parse the control PDU once to check consistency */ + control_decoder = decoder; + control_e1 = e1; + while (control_e1) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, entity->sn_field_length); R(control_decoder); /* NACK_SN */ + control_e1 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + control_e2 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + control_e3 = nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + /* r bits */ + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 3); R(control_decoder); + } else { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 1); R(control_decoder); + } + if (control_e2) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOstart */ + nr_rlc_pdu_decoder_get_bits(&control_decoder, 16); R(control_decoder); /* SOend */ + } + if (control_e3) { + nr_rlc_pdu_decoder_get_bits(&control_decoder, 8); R(control_decoder); /* NACK range */ + } + } + + /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is + * received for the SN 'poll_sn' + */ + if (sn_compare_tx(entity, entity->poll_sn, ack_sn) < 0) + entity->t_poll_retransmit_start = 0; + + /* at this point, accept the PDU even if the actual values + * may be incorrect (eg. if so_start > so_end) + */ + process_received_ack(entity, ack_sn); + + if (e1) + memset(sn_set, 0, 32768); + + while (e1) { + nack_sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); R(decoder); + e1 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + e2 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + e3 = nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + /* r bits */ + if (entity->sn_field_length == 18) { + nr_rlc_pdu_decoder_get_bits(&decoder, 3); R(decoder); + } else { + nr_rlc_pdu_decoder_get_bits(&decoder, 1); R(decoder); + } + if (e2) { + so_start = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + so_end = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + if (so_end < so_start) { + LOG_W(RLC, "%s:%d:%s: warning, bad so start/end, NACK the whole PDU (sn %d)\n", + __FILE__, __LINE__, __FUNCTION__, nack_sn); + so_start = 0; + so_end = -1; + } + /* special value 0xffff indicates 'all bytes to the end' */ + if (so_end == 0xffff) + so_end = -1; + } else { + so_start = 0; + so_end = -1; + } + if (e3) { + range = nr_rlc_pdu_decoder_get_bits(&decoder, 8); R(decoder); + } else { + range = 1; + } + process_received_nack(entity, nack_sn, so_start, so_end, range, sn_set); + + /* 38.322 5.3.3.3 says to stop t_poll_retransmit if a ACK or NACK is + * received for the SN 'poll_sn' + */ + if (sn_compare_tx(entity, nack_sn, entity->poll_sn) <= 0 && + sn_compare_tx(entity, entity->poll_sn, (nack_sn + range) % entity->sn_modulus) < 0) + entity->t_poll_retransmit_start = 0; + } + + finalize_ack_nack_processing(entity); + + return; + +err: + LOG_W(RLC, "%s:%d:%s: error decoding PDU, discarding\n", __FILE__, __LINE__, __FUNCTION__); + goto discard; + +discard: + if (p) + entity->status_triggered = 1; + +#undef R +} + +/*************************************************************************/ +/* TX functions */ +/*************************************************************************/ + +static int is_window_stalling(nr_rlc_entity_am_t *entity) +{ + /* we are stalling if tx_next is not: + * tx_next_ack <= tx_next < tx_next_ack + window_size + */ + return !(sn_compare_tx(entity, entity->tx_next_ack, entity->tx_next) <= 0 && + sn_compare_tx(entity, entity->tx_next, + (entity->tx_next_ack + entity->window_size) % + entity->sn_modulus) < 0); +} + +static void include_poll(nr_rlc_entity_am_t *entity, char *buffer) +{ + /* set the P bit to 1 */ + buffer[0] |= 0x40; + + entity->pdu_without_poll = 0; + entity->byte_without_poll = 0; + + /* set POLL_SN to highest SN submitted to lower layer + * (this is: entity->tx_next - 1) (todo: be sure of this) + */ + entity->poll_sn = (entity->tx_next - 1 + entity->sn_modulus) + % entity->sn_modulus; + + /* start/restart t_poll_retransmit */ + entity->t_poll_retransmit_start = entity->t_current; +} + +static int check_poll_after_pdu_assembly(nr_rlc_entity_am_t *entity) +{ + int retransmission_buffer_empty; + int transmission_buffer_empty; + + /* is transmission buffer empty? */ + if (entity->tx_list == NULL) + transmission_buffer_empty = 1; + else + transmission_buffer_empty = 0; + + /* is retransmission buffer empty? */ + if (entity->retransmit_list == NULL) + retransmission_buffer_empty = 1; + else + retransmission_buffer_empty = 0; + + return (transmission_buffer_empty && retransmission_buffer_empty) || + is_window_stalling(entity); +} + +static int serialize_sdu(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *sdu, char *buffer, int bufsize, + int p) +{ + nr_rlc_pdu_encoder_t encoder; + + /* generate header */ + nr_rlc_pdu_encoder_init(&encoder, buffer, bufsize); + + nr_rlc_pdu_encoder_put_bits(&encoder, 1, 1); /* D/C: 1 = data */ + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 1); /* P: reserve, set later */ + + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_first,1);/* 1st bit of SI */ + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_last,1); /* 2nd bit of SI */ + + if (entity->sn_field_length == 18) + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 2); /* R */ + + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->sdu->sn, + entity->sn_field_length); /* SN */ + + if (!sdu->is_first) + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->so, 16); /* SO */ + + /* data */ + memcpy(buffer + encoder.byte, sdu->sdu->data + sdu->so, sdu->size); + + if (p) + include_poll(entity, buffer); + + return encoder.byte + sdu->size; +} + +/* for a given SDU/SDU segment, computes the corresponding PDU header size */ +static int compute_pdu_header_size(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *sdu) +{ + int header_size = 2; + /* one more byte if SN field length is 18 */ + if (entity->sn_field_length == 18) + header_size++; + /* two more bytes for SO if SDU segment is not the first */ + if (!sdu->is_first) header_size += 2; + return header_size; +} + +/* resize SDU/SDU segment for the corresponding PDU to fit into 'pdu_size' + * bytes + * - modifies SDU/SDU segment to become an SDU segment + * - returns a new SDU segment covering the remaining data bytes + */ +static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu, + nr_rlc_entity_am_t *entity, + int pdu_size) +{ + nr_rlc_sdu_segment_t *next; + int pdu_header_size; + int over_size; + + sdu->sdu->ref_count++; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + next = calloc(1, sizeof(nr_rlc_sdu_segment_t)); + if (next == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + *next = *sdu; + + over_size = pdu_header_size + sdu->size - pdu_size; + + /* update SDU */ + sdu->size -= over_size; + sdu->is_last = 0; + + /* create new segment */ + next->size = over_size; + next->so = sdu->so + sdu->size; + next->is_first = 0; + + return next; +} + +/*************************************************************************/ +/* TX functions - status reporting [begin] */ +/*************************************************************************/ + +typedef struct { + /* data for missing bytes */ + int sn_start; /* set to -1 when no more missing part to report */ + int so_start; + int sn_end; + int so_end; + /* data for maximum ack */ + int ack_sn; /* -1 if not to be used */ + /* pdu to use for next call to 'next_missing' */ + nr_rlc_pdu_t *next; +} missing_data_t; + +/* todo: rewrite this function, too messy */ +static missing_data_t next_missing(nr_rlc_entity_am_t *entity, + nr_rlc_pdu_t *cur, int check_head) +{ + missing_data_t ret; + int cur_max_so; + int sn; + int max_so = 0; + int last_reached = 0; + + ret.ack_sn = -1; + + /* special case: missing part before the head of RX list */ + if (check_head) { + if (cur->sn != entity->rx_next || !cur->is_first) { + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, cur->sn) <= 0) { + ret.sn_start = -1; + return ret; + } + /* the missing part is starting from rx_next(0) + * going to min of: + * - cur->sn(cur->so-1) [if cur->sn is not first] + * or (cur->sn-1)(0xffff) [if cur->sn is first] + * - (entity->rx_highest_status-1)(0xffff) + */ + ret.sn_start = entity->rx_next; + ret.so_start = 0; + goto set_end_different_sdu; + } + } + +next_pdu: + sn = cur->sn; + cur_max_so = cur->so + cur->size - 1; + if (cur_max_so > max_so) + max_so = cur_max_so; + last_reached = last_reached | cur->is_last; + + /* if cur already processed, it can be the acked SDU */ + if (cur->data == NULL) + ret.ack_sn = (cur->sn + 1) % entity->sn_modulus; + + /* no next? */ + if (cur->next == NULL) { + /* inform the caller that work is over */ + ret.next = NULL; + + /* already processed => next SDU to rx_highest_status - 1 to be nacked */ + if (cur->data == NULL) { + ret.sn_start = (cur->sn + 1) % entity->sn_modulus; + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, + ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.so_start = 0; + ret.sn_end = (entity->rx_highest_status - 1 + entity->sn_modulus) % + entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + /* not already processed => all bytes after max_so (if any) then all SDU + * to rx_highest_status-1 to be nacked + */ + if (last_reached) { + ret.sn_start = (cur->sn + 1) % entity->sn_modulus; + ret.so_start = 0; + } else { + ret.sn_start = cur->sn; + ret.so_start = max_so + 1; + } + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, + ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.sn_end = (entity->rx_highest_status - 1 + entity->sn_modulus) % + entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + + cur = cur->next; + + /* no discontinuity in data => process to next PDU */ + if (cur->sn == sn && max_so >= cur->so - 1) + goto next_pdu; + if (cur->sn == (sn + 1) % entity->sn_modulus && last_reached && + cur->is_first) { + last_reached = 0; + max_so = 0; + goto next_pdu; + } + + /* discontinuity in data */ + + /* remember where to start from for the next call */ + ret.next = cur; + + /* discontinuity in same SDU */ + if (cur->sn == sn) { + ret.sn_start = sn; + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, + ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.so_start = max_so + 1; + ret.sn_end = sn; + ret.so_end = cur->so - 1; + return ret; + } + + /* discontinuity between different SDUs */ + ret.sn_start = sn; + /* don't report if out of reporting window */ + if (sn_compare_rx(entity, entity->rx_highest_status, ret.sn_start) <= 0) { + ret.sn_start = -1; + return ret; + } + ret.so_start = max_so + 1; + +set_end_different_sdu: + /* don't go more than rx_highest_status - 1 */ + if (sn_compare_rx(entity, entity->rx_highest_status, cur->sn) <= 0) { + ret.so_end = (entity->rx_highest_status - 1 + entity->sn_modulus) % + entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + + /* if cur is the head of a SDU, then use cur-1 */ + if (cur->is_first) { + ret.sn_end = (cur->sn - 1 + entity->sn_modulus) % entity->sn_modulus; + ret.so_end = 0xffff; + return ret; + } + + ret.sn_end = cur->sn; + ret.so_end = cur->so - 1; + return ret; +} + +static int nack_size(nr_rlc_entity_am_t *entity, missing_data_t *m) +{ + int nack_length = 2 + (entity->sn_field_length == 18); + + if (m->sn_start == m->sn_end) { + /* only nack_sn, no so_start/end, no nack range */ + if (m->so_start == 0 && m->so_end == 0xffff) + return nack_length; + /* nack_sn + so_start/end */ + return nack_length + 4; + } + + /* nack_sn + nack range, no so_start/end */ + if (m->so_start == 0 && m->so_end == 0xffff) + return nack_length + 1; + + /* nack_sn + so_start/end + nack range */ + return nack_length + 5; +} + +/* returns the e1 byte/bit position supposing the encoder points at + * the beginning of a nack_sn block + */ +static void get_e1_position(nr_rlc_entity_am_t *entity, + nr_rlc_pdu_encoder_t *encoder, + int *e1_byte, int *e1_bit) +{ + if (entity->sn_field_length == 18) { + *e1_byte = encoder->byte + 2; + *e1_bit = 5; + } else { + *e1_byte = encoder->byte + 1; + *e1_bit = 3; + } +} + +/* returns the number of nacks serialized. + * In most cases it is 1, it can be more if the + * missing data consists of a range that is more + * than 255 SNs in which case it has to be cut in + * smaller ranges. + * If there is no more room in the status buffer, + * will set m->next = NULL (and may serialize + * less nacks than required by 'm'). + */ +static int generate_missing(nr_rlc_entity_am_t *entity, + nr_rlc_pdu_encoder_t *encoder, + missing_data_t *m, int *e1_byte, int *e1_bit) +{ + int r_bits = entity->sn_field_length == 18 ? 3 : 1; + int range_count = 0; + int sn_start; + int so_start; + int sn_end; + int so_end; + int sn_count; + missing_data_t m_nack; + int e2; + int e3; + + /* be careful to limit a range to 255 SNs, that is: cut if needed */ + sn_count = (m->sn_end - m->sn_start + entity->sn_modulus) + % entity->sn_modulus + 1; + + sn_start = m->sn_start; + + while (sn_count) { + int cur_sn_count = sn_count; + if (cur_sn_count > 255) + cur_sn_count = 255; + + /* for first range, so_start is the one of the initial range + * for the following ones, it is 0 + */ + if (sn_start == m->sn_start) { + /* first range */ + so_start = m->so_start; + } else { + /* following ranges */ + so_start = 0; + } + + /* for the last range, sn_end/so_end are the ones of the initial range + * for the previous ones, it is sn_start+254/0xffff + */ + if (cur_sn_count == sn_count) { + /* last range */ + sn_end = m->sn_end; + so_end = m->so_end; + } else { + /* previous ranges */ + sn_end = (sn_start + 254) % entity->sn_modulus; + so_end = 0xffff; + } + + /* check that there is room for a nack */ + m_nack.sn_start = sn_start; + m_nack.so_start = so_start; + m_nack.sn_end = sn_end; + m_nack.so_end = so_end; + if (encoder->byte + nack_size(entity, &m_nack) > encoder->size) { + m->next = NULL; + break; + } + + /* set the previous e1 bit to 1 */ + encoder->buffer[*e1_byte] |= 1 << *e1_bit; + + get_e1_position(entity, encoder, e1_byte, e1_bit); + + if (sn_start == sn_end) { + if (so_start == 0 && so_end == 0xffff) { + /* only nack_sn, no so_start/end, no nack range */ + e2 = 0; + e3 = 0; + } else { + /* nack_sn + so_start/end, no nack range */ + e2 = 1; + e3 = 0; + } + } else { + if (so_start == 0 && so_end == 0xffff) { + /* nack_sn + nack range, no so_start/end */ + e2 = 0; + e3 = 1; + } else { + /* nack_sn + so_start/end + nack range */ + e2 = 1; + e3 = 1; + } + } + + /* nack_sn */ + nr_rlc_pdu_encoder_put_bits(encoder, sn_start, + entity->sn_field_length); + /* e1 = 0 (set later if needed) */ + nr_rlc_pdu_encoder_put_bits(encoder, 0, 1); + /* e2 */ + nr_rlc_pdu_encoder_put_bits(encoder, e2, 1); + /* e3 */ + nr_rlc_pdu_encoder_put_bits(encoder, e3, 1); + /* r */ + nr_rlc_pdu_encoder_put_bits(encoder, 0, r_bits); + /* so_start/so_end */ + if (e2) { + nr_rlc_pdu_encoder_put_bits(encoder, so_start, 16); + nr_rlc_pdu_encoder_put_bits(encoder, so_end, 16); + } + /* nack range */ + if (e3) + nr_rlc_pdu_encoder_put_bits(encoder, cur_sn_count, 8); + + sn_count -= cur_sn_count; + sn_start = (sn_start + cur_sn_count) % entity->sn_modulus; + range_count++; + } + + return range_count; +} + +static int generate_status(nr_rlc_entity_am_t *entity, char *buffer, int size) +{ + int ack_sn = entity->rx_next; + missing_data_t m; + nr_rlc_pdu_t *cur; + int nack_count = 0; + nr_rlc_pdu_encoder_t encoder; + int e1_byte; + int e1_bit; + + /* if not enough room, do nothing */ + if (size < 3) + return 0; + + nr_rlc_pdu_encoder_init(&encoder, buffer, size); + + /* first 3 bytes, ack_sn and e1 will be set later */ + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 8*3); + + cur = entity->rx_list; + + /* store the position of the e1 bit to be set if + * there is a nack following + */ + e1_byte = 2; + e1_bit = entity->sn_field_length == 18 ? 1 : 7; + + while (cur != NULL) { + m = next_missing(entity, cur, nack_count == 0); + + /* update ack_sn if the returned value is valid */ + if (m.ack_sn != -1) + ack_sn = m.ack_sn; + + /* stop here if no more nack to report */ + if (m.sn_start == -1) + break; + + nack_count += generate_missing(entity, &encoder, &m, &e1_byte, &e1_bit); + + cur = m.next; + } + + /* put ack_sn */ + if (entity->sn_field_length == 12) { + buffer[0] = ack_sn >> 8; + buffer[1] = ack_sn & 255; + } else { + buffer[0] = ack_sn >> 14; + buffer[1] = (ack_sn >> 6) & 255; + buffer[2] |= (ack_sn & 0x3f) << 2; + } + + /* reset the trigger */ + entity->status_triggered = 0; + + /* start t_status_prohibit */ + entity->t_status_prohibit_start = entity->t_current; + + return encoder.byte; +} + +static int status_to_report(nr_rlc_entity_am_t *entity) +{ + return entity->status_triggered && + (entity->t_status_prohibit_start == 0 || + entity->t_current - entity->t_status_prohibit_start > + entity->t_status_prohibit); +} + +static int missing_size(nr_rlc_entity_am_t *entity, missing_data_t *m, + int *size, int maxsize) +{ + int r_bits = entity->sn_field_length == 18 ? 3 : 1; + int range_count = 0; + int sn_start; + int so_start; + int sn_end; + int so_end; + int sn_count; + missing_data_t m_nack; + + /* be careful to limit a range to 255 SNs, that is: cut if needed */ + sn_count = m->sn_end - m->sn_start; + if (sn_count < 0) + sn_count += entity->sn_modulus; + + sn_start = m->sn_start; + + while (sn_count) { + int cur_sn_count = sn_count; + if (cur_sn_count > 255) + cur_sn_count = 255; + + /* for first range, so_start is the one of the initial range + * for the following ones, it is 0 + */ + if (sn_start == m->sn_start) { + /* first range */ + so_start = m->so_start; + } else { + /* following ranges */ + so_start = 0; + } + + /* for the last range, sn_end/so_end are the ones of the initial range + * for the previous ones, it is sn_start+254/0xffff + */ + if (cur_sn_count == sn_count) { + /* last range */ + sn_end = m->sn_end; + so_end = m->so_end; + } else { + /* previous ranges */ + sn_end = (sn_start + 254) % entity->sn_modulus; + so_end = 0xffff; + } + + /* check that there is room for a nack */ + m_nack.sn_start = sn_start; + m_nack.so_start = so_start; + m_nack.sn_end = sn_end; + m_nack.so_end = so_end; + if (*size + nack_size(entity, &m_nack) > maxsize) { + m->next = NULL; + break; + } + + if (sn_start == sn_end) { + if (so_start == 0 && so_end == 0xffff) { + /* only nack_sn, no so_start/end, no nack range */ + *size += (entity->sn_field_length + 3 + r_bits) / 8; + } else { + /* nack_sn + so_start/end, no nack range */ + *size += (entity->sn_field_length + 3 + r_bits + 16*2) / 8; + } + } else { + if (so_start == 0 && so_end == 0xffff) { + /* nack_sn + nack range, no so_start/end */ + *size += (entity->sn_field_length + 3 + r_bits + 8) / 8; + } else { + /* nack_sn + so_start/end + nack range */ + *size += (entity->sn_field_length + 3 + r_bits + 16*2 + 8) / 8; + } + } + + sn_count -= cur_sn_count; + sn_start = (sn_start + cur_sn_count) % entity->sn_modulus; + range_count++; + } + + return range_count; +} + +static int status_size(nr_rlc_entity_am_t *entity, int maxsize) +{ + missing_data_t m; + nr_rlc_pdu_t *cur; + int nack_count = 0; + int size; + + /* if not enough room, do nothing */ + if (maxsize < 3) + return 0; + + /* minimum 3 bytes */ + size = 3; + + cur = entity->rx_list; + + while (cur != NULL) { + m = next_missing(entity, cur, nack_count == 0); + + /* stop here if no more nack to report */ + if (m.sn_start == -1) + break; + + nack_count += missing_size(entity, &m, &size, maxsize); + + cur = m.next; + } + + return size; +} + +/*************************************************************************/ +/* TX functions - status reporting [end] */ +/*************************************************************************/ + +static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer, + int size) +{ + nr_rlc_sdu_segment_t *sdu; + int pdu_header_size; + int pdu_size; + int p; + + sdu = entity->retransmit_list; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + /* not enough room for at least one byte of data? do nothing */ + if (pdu_header_size + 1 > size) + return 0; + + entity->retransmit_list = entity->retransmit_list->next; + if (entity->retransmit_list == NULL) + entity->retransmit_end = NULL; + + sdu->next = NULL; + + /* segment if necessary */ + pdu_size = pdu_header_size + sdu->size; + if (pdu_size > size) { + nr_rlc_sdu_segment_t *next_sdu; + next_sdu = resegment(sdu, entity, size); + /* put the second SDU back at the head of the retransmit list */ + next_sdu->next = entity->retransmit_list; + entity->retransmit_list = next_sdu; + if (entity->retransmit_end == NULL) + entity->retransmit_end = entity->retransmit_list; + } + + /* put SDU/SDU segment in the wait list */ + nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu); + + p = check_poll_after_pdu_assembly(entity); + + if (entity->force_poll) { + p = 1; + entity->force_poll = 0; + } + + return serialize_sdu(entity, sdu, buffer, size, p); +} + +static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size) +{ + nr_rlc_sdu_segment_t *sdu; + int pdu_header_size; + int pdu_size; + int p; + + /* sn out of window (that is: we have window stalling)? do nothing */ + if (is_window_stalling(entity)) + return 0; + + if (entity->tx_list == NULL) + return 0; + + sdu = entity->tx_list; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + /* not enough room for at least one byte of data? do nothing */ + if (pdu_header_size + 1 > size) + return 0; + + entity->tx_list = entity->tx_list->next; + if (entity->tx_list == NULL) + entity->tx_end = NULL; + + sdu->next = NULL; + + /* assign SN to SDU */ + sdu->sdu->sn = entity->tx_next; + + /* segment if necessary */ + pdu_size = pdu_header_size + sdu->size; + if (pdu_size > size) { + nr_rlc_sdu_segment_t *next_sdu; + next_sdu = resegment(sdu, entity, size); + /* put the second SDU back at the head of the TX list */ + next_sdu->next = entity->tx_list; + entity->tx_list = next_sdu; + if (entity->tx_end == NULL) + entity->tx_end = entity->tx_list; + } + + /* update tx_next if the SDU segment is the last */ + if (sdu->is_last) + entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus; + + /* put SDU/SDU segment in the wait list */ + nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu); + + /* polling actions for a new PDU */ + entity->pdu_without_poll++; + entity->byte_without_poll += sdu->size; + if ((entity->poll_pdu != -1 && + entity->pdu_without_poll >= entity->poll_pdu) || + (entity->poll_byte != -1 && + entity->byte_without_poll >= entity->poll_byte)) + p = 1; + else + p = check_poll_after_pdu_assembly(entity); + + if (entity->force_poll) { + p = 1; + entity->force_poll = 0; + } + + return serialize_sdu(entity, sdu, buffer, size, p); +} + +/* Pretend to serialize all the SDUs in a list and return the size + * of all the PDUs it would produce, limited to 'maxsize'. + * Used for buffer status reporting. + */ +static int tx_list_size(nr_rlc_entity_am_t *entity, + nr_rlc_sdu_segment_t *l, int maxsize) +{ + int ret = 0; + + while (l != NULL) { + ret += compute_pdu_header_size(entity, l) + l->size; + l = l->next; + } + + if (ret > maxsize) ret = maxsize; + return ret; +} + +nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status( + nr_rlc_entity_t *_entity, int maxsize) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_entity_buffer_status_t ret; + + if (status_to_report(entity)) + ret.status_size = status_size(entity, maxsize); + else + ret.status_size = 0; + + ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize); + ret.retx_size = tx_list_size(entity, entity->retransmit_list, maxsize); + + return ret; +} + +int nr_rlc_entity_am_generate_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + int ret; + + if (status_to_report(entity)) { + ret = generate_status(entity, buffer, size); + if (ret != 0) + return ret; + } + + if (entity->retransmit_list != NULL) { + ret = generate_retx_pdu(entity, buffer, size); + if (ret != 0) + return ret; + } + + return generate_tx_pdu(entity, buffer, size); +} + +/*************************************************************************/ +/* SDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity, + char *buffer, int size, + int sdu_id) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_sdu_segment_t *sdu; + + if (size > NR_SDU_MAX) { + LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", + __FILE__, __LINE__, __FUNCTION__, size); + exit(1); + } + + if (entity->tx_size + size > entity->tx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + entity->tx_size += size; + + sdu = nr_rlc_new_sdu(buffer, size, sdu_id); + + nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu); +} + +/*************************************************************************/ +/* time/timers */ +/*************************************************************************/ + +static void check_t_poll_retransmit(nr_rlc_entity_am_t *entity) +{ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + int sn; + int old_retx_count; + + /* 38.322 5.3.3.4 */ + /* did t_poll_retransmit expire? */ + if (entity->t_poll_retransmit_start == 0 || + entity->t_current <= entity->t_poll_retransmit_start + + entity->t_poll_retransmit) + return; + + /* stop timer */ + entity->t_poll_retransmit_start = 0; + + /* 38.322 5.3.3.4 says: + * + * - include a poll in a RLC data PDU as described in section 5.3.3.2 + * + * That does not seem to be conditional. So we forcefully will send + * a poll as soon as we generate a PDU. + * Hopefully this interpretation is correct. In the worst case we generate + * more polling than necessary, but it's not a big deal. When + * 't_poll_retransmit' expires it means we didn't receive a status report, + * meaning a bad radio link, so things are quite bad at this point and + * asking again for a poll won't hurt much more. + */ + entity->force_poll = 1; + + LOG_D(RLC, "%s:%d:%s: warning: t_poll_retransmit expired\n", + __FILE__, __LINE__, __FUNCTION__); + + /* do we meet conditions of 38.322 5.3.3.4? */ + if (!check_poll_after_pdu_assembly(entity)) + return; + + /* search wait list for SDU with highest SN */ + /* this code may be incorrect: in LTE we had to look for PDU + * with SN = VT(S) - 1, but for NR the specs say "highest SN among the + * ones submitted to lower layers" not 'tx_next - 1'. So we should look + * for the highest SN in the wait list. But that's no big deal. If the + * program runs this code, then the connection is in a bad state and we + * can retransmit whatever we want. At some point we will receive a status + * report and retransmit what we really have to. Actually we could just + * retransmit the head of wait list (the specs have this 'or'). + * (Actually, maybe this interpretation is not correct and what the code + * does is correct. The specs are confusing.) + */ + sn = (entity->tx_next - 1 + entity->sn_modulus) % entity->sn_modulus; + + head.next = entity->wait_list; + cur = entity->wait_list; + prev = &head; + + while (cur != NULL) { + if (cur->sdu->sn == sn) + break; + prev = cur; + cur = cur->next; + } + + /* SDU with highest SN not found? take the head of wait list */ + if (cur == NULL) { + cur = entity->wait_list; + prev = &head; + sn = cur->sdu->sn; + } + + /* todo: do we need to for check cur == NULL? + * It seems that no, the wait list should not be empty here, but not sure. + */ + + old_retx_count = cur->sdu->retx_count; + + /* 38.322 says "SDU", not "SDU segment", so let's retransmit all + * SDU segments with this SN + */ + /* todo: maybe we could simply retransmit the current SDU segment, + * so that we don't have to run through the full wait list. + */ + while (cur != NULL) { + if (cur->sdu->sn == sn) { + prev->next = cur->next; + cur->next = NULL; + /* put in retransmit list */ + consider_retransmission(entity, cur, + old_retx_count == cur->sdu->retx_count); + } else { + prev = cur; + } + cur = prev->next; + } + entity->wait_list = head.next; + /* reset wait_end (todo: optimize?) */ + entity->wait_end = entity->wait_list; + while (entity->wait_end != NULL && entity->wait_end->next != NULL) + entity->wait_end = entity->wait_end->next; +} + +static void check_t_reassembly(nr_rlc_entity_am_t *entity) +{ + int sn; + + /* is t_reassembly running and if yes has it expired? */ + if (entity->t_reassembly_start == 0 || + entity->t_current <= entity->t_reassembly_start + entity->t_reassembly) + return; + + /* stop timer */ + entity->t_reassembly_start = 0; + + LOG_D(RLC, "%s:%d:%s: t_reassembly expired\n", + __FILE__, __LINE__, __FUNCTION__); + + /* update RX_Highest_Status */ + sn = entity->rx_next_status_trigger; + while (sdu_delivered(entity, sn)) + sn = (sn + 1) % entity->sn_modulus; + entity->rx_highest_status = sn; + + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_highest_status+1) % entity->sn_modulus) > 0 || + (entity->rx_next_highest == + (entity->rx_highest_status+1) % entity->sn_modulus && + sdu_has_missing_bytes(entity, entity->rx_highest_status))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_next_status_trigger = entity->rx_next_highest; + } +} + +void nr_rlc_entity_am_set_time(nr_rlc_entity_t *_entity, uint64_t now) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + + entity->t_current = now; + + check_t_poll_retransmit(entity); + + check_t_reassembly(entity); +} + +/*************************************************************************/ +/* discard/re-establishment/delete */ +/*************************************************************************/ + +void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id) +{ + /* implements 38.322 5.4 */ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + + head.next = entity->tx_list; + cur = entity->tx_list; + prev = &head; + + while (cur != NULL && cur->sdu->upper_layer_id != sdu_id) { + prev = cur; + cur = cur->next; + } + + /* if sdu_id not found or some bytes have already been 'PDU-ized' + * then do nothing + */ + if (cur == NULL || !cur->is_first || !cur->is_last) + return; + + /* remove SDU from tx_list */ + prev->next = cur->next; + entity->tx_list = head.next; + if (entity->tx_end == cur) { + if (prev != &head) + entity->tx_end = prev; + else + entity->tx_end = NULL; + } + + nr_rlc_free_sdu_segment(cur); +} + +static void clear_entity(nr_rlc_entity_am_t *entity) +{ + nr_rlc_pdu_t *cur_rx; + + entity->rx_next = 0; + entity->rx_next_status_trigger = 0; + entity->rx_highest_status = 0; + entity->rx_next_highest = 0; + + entity->status_triggered = 0; + + entity->tx_next = 0; + entity->tx_next_ack = 0; + entity->poll_sn = 0; + entity->pdu_without_poll = 0; + entity->byte_without_poll = 0; + entity->force_poll = 0; + + entity->t_current = 0; + + entity->t_poll_retransmit_start = 0; + entity->t_reassembly_start = 0; + entity->t_status_prohibit_start = 0; + + cur_rx = entity->rx_list; + while (cur_rx != NULL) { + nr_rlc_pdu_t *p = cur_rx; + cur_rx = cur_rx->next; + nr_rlc_free_pdu(p); + } + entity->rx_list = NULL; + entity->rx_size = 0; + + nr_rlc_free_sdu_segment_list(entity->tx_list); + nr_rlc_free_sdu_segment_list(entity->wait_list); + nr_rlc_free_sdu_segment_list(entity->retransmit_list); + nr_rlc_free_sdu_segment_list(entity->ack_list); + + entity->tx_list = NULL; + entity->tx_end = NULL; + entity->tx_size = 0; + + entity->wait_list = NULL; + entity->wait_end = NULL; + + entity->retransmit_list = NULL; + entity->retransmit_end = NULL; + + entity->ack_list = NULL; +} + +void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + clear_entity(entity); +} + +void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + clear_entity(entity); + free(entity); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h new file mode 100644 index 0000000000000000000000000000000000000000..7a553a22a9d166bcd36b24ccc6b9fda6929897a7 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h @@ -0,0 +1,102 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_AM_H_ +#define _NR_RLC_ENTITY_AM_H_ + +#include "nr_rlc_entity.h" +#include "nr_rlc_sdu.h" +#include "nr_rlc_pdu.h" + +typedef struct { + nr_rlc_entity_t common; + + /* configuration */ + int t_poll_retransmit; + int t_reassembly; + int t_status_prohibit; + int poll_pdu; /* -1 means infinity */ + int poll_byte; /* -1 means infinity */ + int max_retx_threshold; + int sn_field_length; + + int sn_modulus; + int window_size; + + /* runtime rx */ + int rx_next; + int rx_next_status_trigger; + int rx_highest_status; + int rx_next_highest; + + int status_triggered; + + /* runtime tx */ + int tx_next; + int tx_next_ack; + int poll_sn; + int pdu_without_poll; + int byte_without_poll; + int force_poll; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* timers (stores the TTI of activation, 0 means not active) */ + uint64_t t_poll_retransmit_start; + uint64_t t_reassembly_start; + uint64_t t_status_prohibit_start; + + /* rx management */ + nr_rlc_pdu_t *rx_list; + int rx_size; + int rx_maxsize; + + /* tx management */ + nr_rlc_sdu_segment_t *tx_list; + nr_rlc_sdu_segment_t *tx_end; + int tx_size; + int tx_maxsize; + + nr_rlc_sdu_segment_t *wait_list; + nr_rlc_sdu_segment_t *wait_end; + + nr_rlc_sdu_segment_t *retransmit_list; + nr_rlc_sdu_segment_t *retransmit_end; + + nr_rlc_sdu_segment_t *ack_list; +} nr_rlc_entity_am_t; + +void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *entity, + char *buffer, int size, + int sdu_id); +void nr_rlc_entity_am_recv_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +nr_rlc_entity_buffer_status_t nr_rlc_entity_am_buffer_status( + nr_rlc_entity_t *entity, int maxsize); +int nr_rlc_entity_am_generate_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +void nr_rlc_entity_am_set_time(nr_rlc_entity_t *entity, uint64_t now); +void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); +void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity); +void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_ENTITY_AM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c new file mode 100644 index 0000000000000000000000000000000000000000..86a0697624091d9d41dae21a095753ed8bf928d4 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c @@ -0,0 +1,181 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity_tm.h" + +#include <stdlib.h> +#include <string.h> + +#include "nr_rlc_pdu.h" + +#include "LOG/log.h" + +/*************************************************************************/ +/* PDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + buffer, size); +} + +/*************************************************************************/ +/* TX functions */ +/*************************************************************************/ + +static int generate_tx_pdu(nr_rlc_entity_tm_t *entity, char *buffer, int size) +{ + nr_rlc_sdu_segment_t *sdu; + int ret; + + if (entity->tx_list == NULL) + return 0; + + sdu = entity->tx_list; + + /* not enough room? do nothing */ + if (sdu->size > size) + return 0; + + entity->tx_list = entity->tx_list->next; + if (entity->tx_list == NULL) + entity->tx_end = NULL; + + ret = sdu->size; + + memcpy(buffer, sdu->sdu->data, sdu->size); + + entity->tx_size -= sdu->size; + nr_rlc_free_sdu_segment(sdu); + + return ret; +} + +static int tx_list_size(nr_rlc_entity_tm_t *entity, + nr_rlc_sdu_segment_t *l, int maxsize) +{ + int ret = 0; + + while (l != NULL) { + ret += l->size; + l = l->next; + } + + if (ret > maxsize) ret = maxsize; + return ret; +} + +nr_rlc_entity_buffer_status_t nr_rlc_entity_tm_buffer_status( + nr_rlc_entity_t *_entity, int maxsize) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + nr_rlc_entity_buffer_status_t ret; + + ret.status_size = 0; + ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize); + ret.retx_size = 0; + + return ret; +} + +int nr_rlc_entity_tm_generate_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + + return generate_tx_pdu(entity, buffer, size); +} + +/*************************************************************************/ +/* SDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity, + char *buffer, int size, + int sdu_id) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + nr_rlc_sdu_segment_t *sdu; + + if (size > NR_SDU_MAX) { + LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", + __FILE__, __LINE__, __FUNCTION__, size); + exit(1); + } + + if (entity->tx_size + size > entity->tx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + entity->tx_size += size; + + sdu = nr_rlc_new_sdu(buffer, size, sdu_id); + + nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu); +} + +/*************************************************************************/ +/* time/timers */ +/*************************************************************************/ + +void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *_entity, uint64_t now) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + + entity->t_current = now; +} + +/*************************************************************************/ +/* discard/re-establishment/delete */ +/*************************************************************************/ + +void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id) +{ + /* nothing to do */ +} + +static void clear_entity(nr_rlc_entity_tm_t *entity) +{ + nr_rlc_free_sdu_segment_list(entity->tx_list); + + entity->tx_list = NULL; + entity->tx_end = NULL; + entity->tx_size = 0; +} + +void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + clear_entity(entity); +} + +void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + clear_entity(entity); + free(entity); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h new file mode 100644 index 0000000000000000000000000000000000000000..7c8c7e40a01cabb2b013f83469f0e9d91c4ed124 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h @@ -0,0 +1,55 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_TM_H_ +#define _NR_RLC_ENTITY_TM_H_ + +#include "nr_rlc_entity.h" +#include "nr_rlc_sdu.h" + +typedef struct { + nr_rlc_entity_t common; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* tx management */ + nr_rlc_sdu_segment_t *tx_list; + nr_rlc_sdu_segment_t *tx_end; + int tx_size; + int tx_maxsize; +} nr_rlc_entity_tm_t; + +void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *entity, + char *buffer, int size, + int sdu_id); +void nr_rlc_entity_tm_recv_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +nr_rlc_entity_buffer_status_t nr_rlc_entity_tm_buffer_status( + nr_rlc_entity_t *entity, int maxsize); +int nr_rlc_entity_tm_generate_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *entity, uint64_t now); +void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); +void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity); +void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_ENTITY_TM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c new file mode 100644 index 0000000000000000000000000000000000000000..09f29ebe6784a7b190cd5147ffe533be29d660b3 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -0,0 +1,697 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_entity_um.h" + +#include <stdlib.h> +#include <string.h> + +#include "nr_rlc_pdu.h" + +#include "LOG/log.h" + +/*************************************************************************/ +/* PDU RX functions */ +/*************************************************************************/ + +static int modulus_rx(nr_rlc_entity_um_t *entity, int a) +{ + /* as per 38.322 7.1, modulus base is rx_next_highest - window_size */ + int r = a - (entity->rx_next_highest - entity->window_size); + if (r < 0) r += entity->sn_modulus; + return r % entity->sn_modulus; +} + +static int sn_compare_rx(void *_entity, int a, int b) +{ + nr_rlc_entity_um_t *entity = _entity; + return modulus_rx(entity, a) - modulus_rx(entity, b); +} + +/* checks that all the bytes of the SDU sn have been received (but SDU + * has not been already processed) + */ +static int sdu_full(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 0; + if (l->is_last) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +/* checks that an SDU has already been delivered */ +static int sdu_delivered(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + return l != NULL && l->data == NULL; +} + +/* check if there is some missing bytes before the last received of SDU sn */ +/* todo: be sure that when no byte was received or the SDU has already been + * processed then the SDU has no missing byte + */ +static int sdu_has_missing_bytes(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *l = entity->rx_list; + int last_byte; + int new_last_byte; + + last_byte = -1; + while (l != NULL) { + if (l->sn == sn) + break; + l = l->next; + } + + /* check if the data has already been processed */ + if (l != NULL && l->data == NULL) + return 0; /* data already processed: no missing byte */ + + while (l != NULL && l->sn == sn) { + if (l->so > last_byte + 1) + return 1; + new_last_byte = l->so + l->size - 1; + if (new_last_byte > last_byte) + last_byte = new_last_byte; + l = l->next; + } + + return 0; +} + +static void reassemble_and_deliver(nr_rlc_entity_um_t *entity, int sn) +{ + nr_rlc_pdu_t *pdu; + char sdu[NR_SDU_MAX]; + int so = 0; + int bad_sdu = 0; + + /* go to first segment of sn */ + pdu = entity->rx_list; + while (pdu->sn != sn) + pdu = pdu->next; + + /* reassemble - free 'data' of each segment after processing */ + while (pdu != NULL && pdu->sn == sn) { + int len = pdu->size - (so - pdu->so); + if (so + len > NR_SDU_MAX && !bad_sdu) { + LOG_E(RLC, "%s:%d:%s: bad SDU, too big, discarding\n", + __FILE__, __LINE__, __FUNCTION__); + bad_sdu = 1; + } + if (!bad_sdu && len > 0) { + memcpy(sdu + so, pdu->data, len); + so += len; + } + free(pdu->data); + pdu->data = NULL; + entity->rx_size -= pdu->size; + pdu->size = 0; + pdu = pdu->next; + } + + if (bad_sdu) + return; + + /* deliver */ + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + sdu, so); +} + +static void reception_actions(nr_rlc_entity_um_t *entity, nr_rlc_pdu_t *pdu) +{ + int x = pdu->sn; + + if (sdu_full(entity, x)) { + /* SDU full */ + reassemble_and_deliver(entity, x); + + if (x == entity->rx_next_reassembly) { + int rx_next_reassembly = entity->rx_next_reassembly; + while (sdu_delivered(entity, rx_next_reassembly)) + rx_next_reassembly = (rx_next_reassembly + 1) % entity->sn_modulus; + entity->rx_next_reassembly = rx_next_reassembly; + } + } else { + /* SDU not full */ + /* test if x is not in reassembly window, that is x >= rx_next_highest */ + if (sn_compare_rx(entity, x, entity->rx_next_highest) >= 0) { + entity->rx_next_highest = (x + 1) % entity->sn_modulus; + + /* discard PDUs not in reassembly window */ + while (entity->rx_list != NULL && + sn_compare_rx(entity, entity->rx_list->sn, + entity->rx_next_highest) >= 0) { + nr_rlc_pdu_t *p = entity->rx_list; + entity->rx_size -= p->size; + entity->rx_list = p->next; + nr_rlc_free_pdu(p); + } + + /* if rx_next_reassembly not in reassembly window */ + if (sn_compare_rx(entity, entity->rx_next_reassembly, + entity->rx_next_highest) >= 0) { + int rx_next_reassembly; + /* set rx_next_reassembly to first SN >= rx_next_highest - window_size + * not delivered yet + */ + rx_next_reassembly = (entity->rx_next_highest - entity->window_size + + entity->sn_modulus) % entity->sn_modulus; + while (sdu_delivered(entity, rx_next_reassembly)) + rx_next_reassembly = (rx_next_reassembly + 1) % entity->sn_modulus; + entity->rx_next_reassembly = rx_next_reassembly; + } + } + } + + if (entity->t_reassembly_start) { + if (/* rx_timer_trigger <= rx_next_reassembly */ + sn_compare_rx(entity, entity->rx_timer_trigger, + entity->rx_next_reassembly) <= 0 || + /* or rx_timer_trigger outside of reassembly window and not equal + * to rx_next_highest, that is is > rx_next_highest + */ + sn_compare_rx(entity, entity->rx_timer_trigger, + entity->rx_next_highest) > 0 || + /* or rx_next_highest == rx_next_reassembly + 1 and no missing byte + * for rx_next_reassembly + */ + (entity->rx_next_highest == (entity->rx_next_reassembly + 1) % + entity->sn_modulus && + !sdu_has_missing_bytes(entity, entity->rx_next_reassembly))) + entity->t_reassembly_start = 0; + } + + if (entity->t_reassembly_start == 0) { + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_next_reassembly + 1) + % entity->sn_modulus) > 0 || + (entity->rx_next_highest == (entity->rx_next_reassembly + 1) + % entity->sn_modulus && + sdu_has_missing_bytes(entity, entity->rx_next_reassembly))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_timer_trigger = entity->rx_next_highest; + } + } +} + +void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ +#define R(d) do { if (nr_rlc_pdu_decoder_in_error(&d)) goto err; } while (0) + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_pdu_decoder_t decoder; + nr_rlc_pdu_t *pdu; + int si; + int sn; + int so = 0; + int data_size; + int is_first; + int is_last; + + nr_rlc_pdu_decoder_init(&decoder, buffer, size); + + si = nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + + is_first = (si & 0x2) == 0; + is_last = (si & 0x1) == 0; + + /* if full, deliver SDU */ + if (is_first && is_last) { + if (size < 2) { + LOG_E(RLC, "%s:%d:%s: warning: discard PDU, no data\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + /* deliver */ + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_rlc_entity_t *)entity, + buffer + 1, size - 1); + return; + } + + if (entity->sn_field_length == 12) { + nr_rlc_pdu_decoder_get_bits(&decoder, 2); R(decoder); + } + + sn = nr_rlc_pdu_decoder_get_bits(&decoder, entity->sn_field_length); + R(decoder); + + if (!is_first) { + so = nr_rlc_pdu_decoder_get_bits(&decoder, 16); R(decoder); + if (so == 0) { + LOG_E(RLC, "%s:%d:%s: warning: discard PDU, bad so\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + } + + data_size = size - decoder.byte; + + /* dicard PDU if no data */ + if (data_size <= 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, no data\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* dicard PDU if rx buffer is full */ + if (entity->rx_size + data_size > entity->rx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, RX buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + goto discard; + } + + /* discard PDU if sn < rx_next_reassembly */ + if (sn_compare_rx(entity, sn, entity->rx_next_reassembly) < 0) { + LOG_D(RLC, "%s:%d:%s: warning: discard PDU, SN (%d) < rx_next_reassembly (%d)\n", + __FILE__, __LINE__, __FUNCTION__, + sn, entity->rx_next_reassembly); + goto discard; + } + + /* put in pdu reception list */ + entity->rx_size += data_size; + pdu = nr_rlc_new_pdu(sn, so, is_first, is_last, + buffer + size - data_size, data_size); + entity->rx_list = nr_rlc_pdu_list_add(sn_compare_rx, entity, + entity->rx_list, pdu); + + /* do reception actions (38.322 5.2.2.2.3) */ + reception_actions(entity, pdu); + + return; + +err: + LOG_W(RLC, "%s:%d:%s: error decoding PDU, discarding\n", __FILE__, __LINE__, __FUNCTION__); + goto discard; + +discard: + return; + +#undef R +} + +/*************************************************************************/ +/* TX functions */ +/*************************************************************************/ + +static int serialize_sdu(nr_rlc_entity_um_t *entity, + nr_rlc_sdu_segment_t *sdu, char *buffer, int bufsize) +{ + nr_rlc_pdu_encoder_t encoder; + + /* generate header */ + nr_rlc_pdu_encoder_init(&encoder, buffer, bufsize); + + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_first,1);/* 1st bit of SI */ + nr_rlc_pdu_encoder_put_bits(&encoder, 1-sdu->is_last,1); /* 2nd bit of SI */ + + /* SN, if required */ + if (sdu->is_first == 1 && sdu->is_last == 1) { + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 6); /* R */ + } else { + if (entity->sn_field_length == 12) + nr_rlc_pdu_encoder_put_bits(&encoder, 0, 2); /* R */ + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->sdu->sn, + entity->sn_field_length); /* SN */ + } + + if (!sdu->is_first) + nr_rlc_pdu_encoder_put_bits(&encoder, sdu->so, 16); /* SO */ + + /* data */ + memcpy(buffer + encoder.byte, sdu->sdu->data + sdu->so, sdu->size); + + return encoder.byte + sdu->size; +} + +/* for a given SDU/SDU segment, computes the corresponding PDU header size */ +static int compute_pdu_header_size(nr_rlc_entity_um_t *entity, + nr_rlc_sdu_segment_t *sdu) +{ + int header_size = 1; + + /* if SN to be included then one more byte if SN field length is 12 */ + if (!(sdu->is_first && sdu->is_last) && entity->sn_field_length == 12) + header_size++; + /* two more bytes for SO if SDU segment is not the first */ + if (!sdu->is_first) header_size += 2; + return header_size; +} + +/* resize SDU/SDU segment for the corresponding PDU to fit into 'pdu_size' + * bytes + * - modifies SDU/SDU segment to become an SDU segment + * - returns a new SDU segment covering the remaining data bytes + * returns NULL if pdu_size is too small to contain the new segment + */ +static nr_rlc_sdu_segment_t *resegment(nr_rlc_sdu_segment_t *sdu, + nr_rlc_entity_um_t *entity, + int pdu_size) +{ + nr_rlc_sdu_segment_t *next; + int pdu_header_size; + int over_size; + int old_is_last; + + sdu->sdu->ref_count++; + + /* clear is_last to compute header size */ + old_is_last = sdu->is_last; + sdu->is_last = 0; + pdu_header_size = compute_pdu_header_size(entity, sdu); + sdu->is_last = old_is_last; + + /* if no room for at least 1 data byte, do nothing */ + if (pdu_header_size + 1 > pdu_size) + return NULL; + + next = calloc(1, sizeof(nr_rlc_sdu_segment_t)); + if (next == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + *next = *sdu; + + over_size = pdu_header_size + sdu->size - pdu_size; + + /* update SDU */ + sdu->size -= over_size; + sdu->is_last = 0; + + /* create new segment */ + next->size = over_size; + next->so = sdu->so + sdu->size; + next->is_first = 0; + + return next; +} + +static int generate_tx_pdu(nr_rlc_entity_um_t *entity, char *buffer, int size) +{ + nr_rlc_sdu_segment_t *sdu; + int pdu_header_size; + int pdu_size; + int ret; + + if (entity->tx_list == NULL) + return 0; + + sdu = entity->tx_list; + + pdu_header_size = compute_pdu_header_size(entity, sdu); + + /* not enough room for at least one byte of data? do nothing */ + if (pdu_header_size + 1 > size) + return 0; + + entity->tx_list = entity->tx_list->next; + if (entity->tx_list == NULL) + entity->tx_end = NULL; + + /* assign SN to SDU */ + sdu->sdu->sn = entity->tx_next; + + /* segment if necessary */ + pdu_size = pdu_header_size + sdu->size; + if (pdu_size > size) { + nr_rlc_sdu_segment_t *next_sdu; + next_sdu = resegment(sdu, entity, size); + if (next_sdu == NULL) + return 0; + /* put the second SDU back at the head of the TX list */ + next_sdu->next = entity->tx_list; + entity->tx_list = next_sdu; + if (entity->tx_end == NULL) + entity->tx_end = entity->tx_list; + } + + /* update tx_next if the SDU is an SDU segment and is the last */ + if (!sdu->is_first && sdu->is_last) + entity->tx_next = (entity->tx_next + 1) % entity->sn_modulus; + + ret = serialize_sdu(entity, sdu, buffer, size); + + entity->tx_size -= sdu->size; + nr_rlc_free_sdu_segment(sdu); + + return ret; +} + +/* Pretend to serialize all the SDUs in a list and return the size + * of all the PDUs it would produce, limited to 'maxsize'. + * Used for buffer status reporting. + */ +static int tx_list_size(nr_rlc_entity_um_t *entity, + nr_rlc_sdu_segment_t *l, int maxsize) +{ + int ret = 0; + + while (l != NULL) { + ret += compute_pdu_header_size(entity, l) + l->size; + l = l->next; + } + + if (ret > maxsize) ret = maxsize; + return ret; +} + +nr_rlc_entity_buffer_status_t nr_rlc_entity_um_buffer_status( + nr_rlc_entity_t *_entity, int maxsize) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_entity_buffer_status_t ret; + + ret.status_size = 0; + ret.tx_size = tx_list_size(entity, entity->tx_list, maxsize); + ret.retx_size = 0; + + return ret; +} + +int nr_rlc_entity_um_generate_pdu(nr_rlc_entity_t *_entity, + char *buffer, int size) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + + return generate_tx_pdu(entity, buffer, size); +} + +/*************************************************************************/ +/* SDU RX functions */ +/*************************************************************************/ + +void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity, + char *buffer, int size, + int sdu_id) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_sdu_segment_t *sdu; + + if (size > NR_SDU_MAX) { + LOG_E(RLC, "%s:%d:%s: fatal: SDU size too big (%d bytes)\n", + __FILE__, __LINE__, __FUNCTION__, size); + exit(1); + } + + if (entity->tx_size + size > entity->tx_maxsize) { + LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n", + __FILE__, __LINE__, __FUNCTION__); + return; + } + + entity->tx_size += size; + + sdu = nr_rlc_new_sdu(buffer, size, sdu_id); + + nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu); +} + +/*************************************************************************/ +/* time/timers */ +/*************************************************************************/ + +static void check_t_reassembly(nr_rlc_entity_um_t *entity) +{ + nr_rlc_pdu_t *cur; + + /* is t_reassembly running and if yes has it expired? */ + if (entity->t_reassembly_start == 0 || + entity->t_current <= entity->t_reassembly_start + entity->t_reassembly) + return; + + /* stop timer */ + entity->t_reassembly_start = 0; + + LOG_D(RLC, "%s:%d:%s: t_reassembly expired\n", + __FILE__, __LINE__, __FUNCTION__); + + /* update rx_next_reassembly to first SN >= rx_timer_trigger not reassembled + * (ie. not delivered yet) + */ + entity->rx_next_reassembly = entity->rx_timer_trigger; + while (sdu_delivered(entity, entity->rx_next_reassembly)) + entity->rx_next_reassembly = (entity->rx_next_reassembly + 1) + % entity->sn_modulus; + + /* discard all segments < entity->rx_next_reassembly */ + cur = entity->rx_list; + while (cur != NULL && + sn_compare_rx(entity, cur->sn, entity->rx_next_reassembly) < 0) { + nr_rlc_free_pdu(cur); + cur = cur->next; + entity->rx_list = cur; + } + + if (sn_compare_rx(entity, entity->rx_next_highest, + (entity->rx_next_reassembly + 1) + % entity->sn_modulus) > 0 || + (entity->rx_next_highest == entity->rx_next_reassembly + 1 && + sdu_has_missing_bytes(entity, entity->rx_next_reassembly))) { + entity->t_reassembly_start = entity->t_current; + entity->rx_timer_trigger = entity->rx_next_highest; + } +} + +void nr_rlc_entity_um_set_time(nr_rlc_entity_t *_entity, uint64_t now) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + + entity->t_current = now; + + check_t_reassembly(entity); +} + +/*************************************************************************/ +/* discard/re-establishment/delete */ +/*************************************************************************/ + +void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id) +{ + /* implements 38.322 5.4 */ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + + head.next = entity->tx_list; + cur = entity->tx_list; + prev = &head; + + while (cur != NULL && cur->sdu->upper_layer_id != sdu_id) { + prev = cur; + cur = cur->next; + } + + /* if sdu_id not found or some bytes have already been 'PDU-ized' + * then do nothing + */ + if (cur == NULL || !cur->is_first || !cur->is_last) + return; + + /* remove SDU from tx_list */ + prev->next = cur->next; + entity->tx_list = head.next; + if (entity->tx_end == cur) { + if (prev != &head) + entity->tx_end = prev; + else + entity->tx_end = NULL; + } + + nr_rlc_free_sdu_segment(cur); +} + +static void clear_entity(nr_rlc_entity_um_t *entity) +{ + nr_rlc_pdu_t *cur_rx; + + entity->rx_next_highest = 0; + entity->rx_next_reassembly = 0; + entity->rx_timer_trigger = 0; + + + entity->tx_next = 0; + + entity->t_current = 0; + + entity->t_reassembly_start = 0; + + cur_rx = entity->rx_list; + while (cur_rx != NULL) { + nr_rlc_pdu_t *p = cur_rx; + cur_rx = cur_rx->next; + nr_rlc_free_pdu(p); + } + entity->rx_list = NULL; + entity->rx_size = 0; + + nr_rlc_free_sdu_segment_list(entity->tx_list); + + entity->tx_list = NULL; + entity->tx_end = NULL; + entity->tx_size = 0; +} + +void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + clear_entity(entity); +} + +void nr_rlc_entity_um_delete(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + clear_entity(entity); + free(entity); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h new file mode 100644 index 0000000000000000000000000000000000000000..21063a1ea18f08abc2e00d0aedd1f09fc4b86d6a --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h @@ -0,0 +1,79 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_ENTITY_UM_H_ +#define _NR_RLC_ENTITY_UM_H_ + +#include "nr_rlc_entity.h" +#include "nr_rlc_sdu.h" +#include "nr_rlc_pdu.h" + +typedef struct { + nr_rlc_entity_t common; + + /* configuration */ + int t_reassembly; + int sn_field_length; + + int sn_modulus; + int window_size; + + /* runtime rx */ + int rx_next_highest; + int rx_next_reassembly; + int rx_timer_trigger; + + /* runtime tx */ + int tx_next; + + /* set to the latest know time by the user of the module. Unit: ms */ + uint64_t t_current; + + /* timers (stores the TTI of activation, 0 means not active) */ + uint64_t t_reassembly_start; + + /* rx management */ + nr_rlc_pdu_t *rx_list; + int rx_size; + int rx_maxsize; + + /* tx management */ + nr_rlc_sdu_segment_t *tx_list; + nr_rlc_sdu_segment_t *tx_end; + int tx_size; + int tx_maxsize; +} nr_rlc_entity_um_t; + +void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *entity, + char *buffer, int size, + int sdu_id); +void nr_rlc_entity_um_recv_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +nr_rlc_entity_buffer_status_t nr_rlc_entity_um_buffer_status( + nr_rlc_entity_t *entity, int maxsize); +int nr_rlc_entity_um_generate_pdu(nr_rlc_entity_t *entity, + char *buffer, int size); +void nr_rlc_entity_um_set_time(nr_rlc_entity_t *entity, uint64_t now); +void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); +void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity); +void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_ENTITY_UM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c new file mode 100644 index 0000000000000000000000000000000000000000..b56e8b11e96c3831b3e1979e90a30286deb5044b --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -0,0 +1,874 @@ +/* + * 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 + */ + +/* from openair */ +#include "rlc.h" +#include "pdcp.h" + +/* from nr rlc module */ +#include "asn1_utils.h" +#include "nr_rlc_ue_manager.h" +#include "nr_rlc_entity.h" + +#include <stdint.h> + +static nr_rlc_ue_manager_t *nr_rlc_ue_manager; + +/* TODO: handle time a bit more properly */ +static uint64_t nr_rlc_current_time; +static int nr_rlc_current_time_last_frame; +static int nr_rlc_current_time_last_subframe; + +void mac_rlc_data_ind ( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + char *buffer_pP, + const tb_size_t tb_sizeP, + num_tb_t num_tbP, + crc_t *crcs_pP) +{ + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + + if (module_idP != 0 || eNB_index != 0 || /*enb_flagP != 1 ||*/ MBMS_flagP != 0) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (enb_flagP) + T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(rntiP), + T_INT(channel_idP), T_INT(tb_sizeP)); + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + rb->set_time(rb, nr_rlc_current_time); + rb->recv_pdu(rb, buffer_pP, tb_sizeP); + } else { + LOG_E(RLC, "%s:%d:%s: fatal: no RB found (channel ID %d)\n", + __FILE__, __LINE__, __FUNCTION__, channel_idP); + exit(1); + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +tbs_size_t mac_rlc_data_req( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP, + char *buffer_pP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) +{ + int ret; + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + int is_enb; + int maxsize; + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + rb->set_time(rb, nr_rlc_current_time); + /* UE does not seem to use saved_status_ind_tb_size */ + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + if (is_enb) + maxsize = ue->saved_status_ind_tb_size[channel_idP - 1]; + else + maxsize = tb_sizeP; + ret = rb->generate_pdu(rb, buffer_pP, maxsize); + } else { + LOG_E(RLC, "%s:%d:%s: fatal: data req for unknown RB\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + ret = 0; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + if (enb_flagP) + T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(rntiP), + T_INT(channel_idP), T_INT(ret)); + + return ret; +} + +mac_rlc_status_resp_t mac_rlc_status_ind( + const module_id_t module_idP, + const rnti_t rntiP, + const eNB_index_t eNB_index, + const frame_t frameP, + const sub_frame_t subframeP, + const eNB_flag_t enb_flagP, + const MBMS_flag_t MBMS_flagP, + const logical_chan_id_t channel_idP, + const tb_size_t tb_sizeP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) +{ + nr_rlc_ue_t *ue; + mac_rlc_status_resp_t ret; + nr_rlc_entity_t *rb; + + /* TODO: handle time a bit more properly */ + if (nr_rlc_current_time_last_frame != frameP || + nr_rlc_current_time_last_subframe != subframeP) { + nr_rlc_current_time++; + nr_rlc_current_time_last_frame = frameP; + nr_rlc_current_time_last_subframe = subframeP; + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 2: rb = ue->srb[channel_idP - 1]; break; + case 3 ... 7: rb = ue->drb[channel_idP - 3]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + nr_rlc_entity_buffer_status_t buf_stat; + rb->set_time(rb, nr_rlc_current_time); + /* 36.321 deals with BSR values up to 3000000 bytes, after what it + * reports '> 3000000' (table 6.1.3.1-2). Passing 4000000 is thus + * more than enough. + */ + buf_stat = rb->buffer_status(rb, 4000000); + ret.bytes_in_buffer = buf_stat.status_size + + buf_stat.retx_size + + buf_stat.tx_size; + ue->saved_status_ind_tb_size[channel_idP - 1] = tb_sizeP; + } else { + ret.bytes_in_buffer = 0; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + ret.pdus_in_buffer = 0; + /* TODO: creation time may be important (unit: frame, as it seems) */ + ret.head_sdu_creation_time = 0; + ret.head_sdu_remaining_size_to_send = 0; + ret.head_sdu_is_segmented = 0; + return ret; +} + +int oai_emulation; + +rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + confirm_t confirmP, + sdu_size_t sdu_sizeP, + mem_block_t *sdu_pP +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t *const sourceL2Id + ,const uint32_t *const destinationL2Id +#endif + ) +{ + int rnti = ctxt_pP->rnti; + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + + LOG_D(RLC, "%s rnti %d srb_flag %d rb_id %d mui %d confirm %d sdu_size %d MBMS_flag %d\n", + __FUNCTION__, rnti, srb_flagP, rb_idP, muiP, confirmP, sdu_sizeP, + MBMS_flagP); + + if (ctxt_pP->enb_flag) + T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP)); + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + + rb = NULL; + + if (srb_flagP) { + if (rb_idP >= 1 && rb_idP <= 2) + rb = ue->srb[rb_idP - 1]; + } else { + if (rb_idP >= 1 && rb_idP <= 5) + rb = ue->drb[rb_idP - 1]; + } + + if (rb != NULL) { + rb->set_time(rb, nr_rlc_current_time); + rb->recv_sdu(rb, (char *)sdu_pP->data, sdu_sizeP, muiP); + } else { + LOG_E(RLC, "%s:%d:%s: fatal: SDU sent to unknown RB\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + free_mem_block(sdu_pP, __func__); + + return RLC_OP_STATUS_OK; +} + +int rlc_module_init(int enb_flag) +{ + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + static int inited = 0; + + if (pthread_mutex_lock(&lock)) abort(); + + if (inited) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + inited = 1; + + nr_rlc_ue_manager = new_nr_rlc_ue_manager(enb_flag); + + if (pthread_mutex_unlock(&lock)) abort(); + + return 0; +} + +void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP) +{ +} + +static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) +{ + nr_rlc_ue_t *ue = _ue; + int is_srb; + int rb_id; + protocol_ctxt_t ctx; + mem_block_t *memblock; + int i; + int is_enb; + + /* is it SRB? */ + for (i = 0; i < 2; i++) { + if (entity == ue->srb[i]) { + is_srb = 1; + rb_id = i+1; + goto rb_found; + } + } + + /* maybe DRB? */ + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + is_srb = 0; + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + +rb_found: + LOG_D(RLC, "%s:%d:%s: delivering SDU (rnti %d is_srb %d rb_id %d) size %d", + __FILE__, __LINE__, __FUNCTION__, ue->rnti, is_srb, rb_id, size); + + memblock = get_free_mem_block(size, __func__); + if (memblock == NULL) { + LOG_E(RLC, "%s:%d:%s: ERROR: get_free_mem_block failed\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + memcpy(memblock->data, buf, size); + + /* unused fields? */ + ctx.instance = 0; + ctx.frame = 0; + ctx.subframe = 0; + ctx.eNB_index = 0; + ctx.configured = 1; + ctx.brOption = 0; + + /* used fields? */ + ctx.module_id = 0; + ctx.rnti = ue->rnti; + + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + ctx.enb_flag = is_enb; + + if (is_enb) { + T(T_ENB_RLC_UL, + T_INT(0 /*ctxt_pP->module_id*/), + T_INT(ue->rnti), T_INT(rb_id), T_INT(size)); + } + + if (!pdcp_data_ind(&ctx, is_srb, 0, rb_id, size, memblock)) { + LOG_E(RLC, "%s:%d:%s: ERROR: pdcp_data_ind failed\n", __FILE__, __LINE__, __FUNCTION__); + /* what to do in case of failure? for the moment: nothing */ + } +} + +static void successful_delivery(void *_ue, nr_rlc_entity_t *entity, int sdu_id) +{ + nr_rlc_ue_t *ue = _ue; + int i; + int is_srb; + int rb_id; +#if 0 + MessageDef *msg; +#endif + int is_enb; + + /* is it SRB? */ + for (i = 0; i < 2; i++) { + if (entity == ue->srb[i]) { + is_srb = 1; + rb_id = i+1; + goto rb_found; + } + } + + /* maybe DRB? */ + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + is_srb = 0; + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + +rb_found: + LOG_D(RLC, "sdu %d was successfully delivered on %s %d\n", + sdu_id, + is_srb ? "SRB" : "DRB", + rb_id); + + /* TODO: do something for DRBs? */ + if (is_srb == 0) + return; + + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + if (!is_enb) + return; + +#if 0 + msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); + RLC_SDU_INDICATION(msg).rnti = ue->rnti; + RLC_SDU_INDICATION(msg).is_successful = 1; + RLC_SDU_INDICATION(msg).srb_id = rb_id; + RLC_SDU_INDICATION(msg).message_id = sdu_id; + /* TODO: accept more than 1 instance? here we send to instance id 0 */ + itti_send_msg_to_task(TASK_RRC_ENB, 0, msg); +#endif +} + +static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity) +{ + nr_rlc_ue_t *ue = _ue; + int i; + int is_srb; + int rb_id; +#if 0 + MessageDef *msg; +#endif + int is_enb; + + /* is it SRB? */ + for (i = 0; i < 2; i++) { + if (entity == ue->srb[i]) { + is_srb = 1; + rb_id = i+1; + goto rb_found; + } + } + + /* maybe DRB? */ + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + is_srb = 0; + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(RLC, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + +rb_found: + LOG_D(RLC, "max RETX reached on %s %d\n", + is_srb ? "SRB" : "DRB", + rb_id); + + /* TODO: do something for DRBs? */ + if (is_srb == 0) + return; + + is_enb = nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager); + if (!is_enb) + return; + +#if 0 + msg = itti_alloc_new_message(TASK_RLC_ENB, RLC_SDU_INDICATION); + RLC_SDU_INDICATION(msg).rnti = ue->rnti; + RLC_SDU_INDICATION(msg).is_successful = 0; + RLC_SDU_INDICATION(msg).srb_id = rb_id; + RLC_SDU_INDICATION(msg).message_id = -1; + /* TODO: accept more than 1 instance? here we send to instance id 0 */ + itti_send_msg_to_task(TASK_RRC_ENB, 0, msg); +#endif +} + +static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) +{ + nr_rlc_entity_t *nr_rlc_am; + nr_rlc_ue_t *ue; + + struct LTE_SRB_ToAddMod__rlc_Config *r = s->rlc_Config; + struct LTE_SRB_ToAddMod__logicalChannelConfig *l = s->logicalChannelConfig; + int srb_id = s->srb_Identity; + int logical_channel_group; + + //int t_reordering; + int t_status_prohibit; + int t_poll_retransmit; + int poll_pdu; + int poll_byte; + int max_retx_threshold; + int t_reassembly; + int sn_field_length; + + if (srb_id != 1 && srb_id != 2) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n", + __FILE__, __LINE__, __FUNCTION__, srb_id); + exit(1); + } + + switch (l->present) { + case LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue: + logical_channel_group = *l->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup; + break; + case LTE_SRB_ToAddMod__logicalChannelConfig_PR_defaultValue: + /* default value from 36.331 9.2.1 */ + logical_channel_group = 0; + break; + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + /* TODO: accept other values? */ + if (logical_channel_group != 0) { + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + switch (r->present) { + case LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue: { + struct LTE_RLC_Config__am *am; + if (r->choice.explicitValue.present != LTE_RLC_Config_PR_am) { + LOG_E(RLC, "%s:%d:%s: fatal error, must be RLC AM\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + am = &r->choice.explicitValue.choice.am; + //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering); + t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); + t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); + poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); + poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte); + max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold); + break; + } + case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue: + /* default values from 36.331 9.2.1 */ + //t_reordering = 35; + t_status_prohibit = 0; + t_poll_retransmit = 45; + poll_pdu = -1; + poll_byte = -1; + max_retx_threshold = 4; + break; + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue->srb[srb_id-1] != NULL) { + LOG_D(RLC, "%s:%d:%s: warning SRB %d already exist for ue %d, do nothing\n", + __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); + } else { + /* hack: hardcode values for NR */ + t_poll_retransmit = 45; + t_reassembly = 35; + t_status_prohibit = 0; + poll_pdu = -1; + poll_byte = -1; + max_retx_threshold = 8; + sn_field_length = 12; + nr_rlc_am = new_nr_rlc_entity_am(100000, + 100000, + deliver_sdu, ue, + successful_delivery, ue, + max_retx_reached, ue, + t_poll_retransmit, + t_reassembly, t_status_prohibit, + poll_pdu, poll_byte, max_retx_threshold, + sn_field_length); + nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am); + + LOG_D(RLC, "%s:%d:%s: added srb %d to ue %d\n", + __FILE__, __LINE__, __FUNCTION__, srb_id, rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s) +{ + nr_rlc_entity_t *nr_rlc_am; + nr_rlc_ue_t *ue; + + struct LTE_RLC_Config *r = s->rlc_Config; + struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig; + int drb_id = s->drb_Identity; + int channel_id = *s->logicalChannelIdentity; + int logical_channel_group; + + //int t_reordering; + int t_status_prohibit; + int t_poll_retransmit; + int poll_pdu; + int poll_byte; + int max_retx_threshold; + int t_reassembly; + int sn_field_length; + + if (!(drb_id >= 1 && drb_id <= 5)) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id); + exit(1); + } + + if (channel_id != drb_id + 2) { + LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup; + + /* TODO: accept other values? */ + if (logical_channel_group != 1) { + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + switch (r->present) { + case LTE_RLC_Config_PR_am: { + struct LTE_RLC_Config__am *am; + am = &r->choice.am; + //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering); + t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); + t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); + poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); + poll_byte = decode_poll_byte(am->ul_AM_RLC.pollByte); + max_retx_threshold = decode_max_retx_threshold(am->ul_AM_RLC.maxRetxThreshold); + break; + } + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue->drb[drb_id-1] != NULL) { + LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } else { + /* hack: hardcode values for NR */ + t_poll_retransmit = 45; + t_reassembly = 35; + t_status_prohibit = 0; + poll_pdu = -1; + poll_byte = -1; + max_retx_threshold = 8; + sn_field_length = 12; + nr_rlc_am = new_nr_rlc_entity_am(100000, + 100000, + deliver_sdu, ue, + successful_delivery, ue, + max_retx_reached, ue, + t_poll_retransmit, + t_reassembly, t_status_prohibit, + poll_pdu, poll_byte, max_retx_threshold, + sn_field_length); + nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am); + + LOG_D(RLC, "%s:%d:%s: added drb %d to ue %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s) +{ + nr_rlc_entity_t *nr_rlc_um; + nr_rlc_ue_t *ue; + + struct LTE_RLC_Config *r = s->rlc_Config; + struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig; + int drb_id = s->drb_Identity; + int channel_id = *s->logicalChannelIdentity; + int logical_channel_group; + + //int t_reordering; + int sn_field_length; + int t_reassembly; + + if (!(drb_id >= 1 && drb_id <= 5)) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id); + exit(1); + } + + if (channel_id != drb_id + 2) { + LOG_E(RLC, "%s:%d:%s: todo, remove this limitation\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + logical_channel_group = *l->ul_SpecificParameters->logicalChannelGroup; + + /* TODO: accept other values? */ + if (logical_channel_group != 1) { + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + switch (r->present) { + case LTE_RLC_Config_PR_um_Bi_Directional: { + struct LTE_RLC_Config__um_Bi_Directional *um; + um = &r->choice.um_Bi_Directional; + //t_reordering = decode_t_reordering(um->dl_UM_RLC.t_Reordering); + if (um->dl_UM_RLC.sn_FieldLength != um->ul_UM_RLC.sn_FieldLength) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + sn_field_length = decode_sn_field_length(um->dl_UM_RLC.sn_FieldLength); + break; + } + default: + LOG_E(RLC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rnti); + if (ue->drb[drb_id-1] != NULL) { + LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } else { + /* hack: hardcode values for NR */ + t_reassembly = 35; + sn_field_length = 6; + nr_rlc_um = new_nr_rlc_entity_um(1000000, + 1000000, + deliver_sdu, ue, + t_reassembly, + sn_field_length); + nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_um); + + LOG_D(RLC, "%s:%d:%s: added drb %d to ue %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); +} + +static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) +{ + switch (s->rlc_Config->present) { + case LTE_RLC_Config_PR_am: + add_drb_am(rnti, s); + break; + case LTE_RLC_Config_PR_um_Bi_Directional: + add_drb_um(rnti, s); + break; + default: + LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, + const LTE_SRB_ToAddModList_t * const srb2add_listP, + const LTE_DRB_ToAddModList_t * const drb2add_listP, + const LTE_DRB_ToReleaseList_t * const drb2release_listP +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP + ,const uint32_t sourceL2Id + ,const uint32_t destinationL2Id +#endif + ) +{ + int rnti = ctxt_pP->rnti; + int i; + + if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*|| + ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 || + ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) { + LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %d %d %d %d)\n", __FUNCTION__, + ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance, + ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption); + exit(1); + } + + if (pmch_InfoList_r9_pP != NULL) { + LOG_E(RLC, "%s: pmch_InfoList_r9_pP not handled\n", __FUNCTION__); + exit(1); + } + + if (drb2release_listP != NULL) { + LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (srb2add_listP != NULL) { + for (i = 0; i < srb2add_listP->list.count; i++) { + add_srb(rnti, srb2add_listP->list.array[i]); + } + } + + if (drb2add_listP != NULL) { + for (i = 0; i < drb2add_listP->list.count; i++) { + add_drb(rnti, drb2add_listP->list.array[i]); + } + } + + return RLC_OP_STATUS_OK; +} + +rlc_op_status_t rrc_rlc_config_req ( + const protocol_ctxt_t* const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t mbms_flagP, + const config_action_t actionP, + const rb_id_t rb_idP, + const rlc_info_t rlc_infoP) +{ + nr_rlc_ue_t *ue; + int i; + + if (mbms_flagP) { + LOG_E(RLC, "%s:%d:%s: todo (MBMS NOT supported)\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + if (actionP != CONFIG_ACTION_REMOVE) { + LOG_E(RLC, "%s:%d:%s: todo (only CONFIG_ACTION_REMOVE supported)\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + if (ctxt_pP->module_id) { + LOG_E(RLC, "%s:%d:%s: todo (only module_id 0 supported)\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + if ((srb_flagP && !(rb_idP >= 1 && rb_idP <= 2)) || + (!srb_flagP && !(rb_idP >= 1 && rb_idP <= 5))) { + LOG_E(RLC, "%s:%d:%s: bad rb_id (%d) (is_srb %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP); + exit(1); + } + nr_rlc_manager_lock(nr_rlc_ue_manager); + LOG_D(RLC, "%s:%d:%s: remove rb %d (is_srb %d) for UE %d\n", __FILE__, __LINE__, __FUNCTION__, rb_idP, srb_flagP, ctxt_pP->rnti); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ctxt_pP->rnti); + if (srb_flagP) { + if (ue->srb[rb_idP-1] != NULL) { + ue->srb[rb_idP-1]->delete(ue->srb[rb_idP-1]); + ue->srb[rb_idP-1] = NULL; + } else + LOG_W(RLC, "removing non allocated SRB %d, do nothing\n", rb_idP); + } else { + if (ue->drb[rb_idP-1] != NULL) { + ue->drb[rb_idP-1]->delete(ue->drb[rb_idP-1]); + ue->drb[rb_idP-1] = NULL; + } else + LOG_W(RLC, "removing non allocated DRB %d, do nothing\n", rb_idP); + } + /* remove UE if it has no more RB configured */ + for (i = 0; i < 2; i++) + if (ue->srb[i] != NULL) + break; + if (i == 2) { + for (i = 0; i < 5; i++) + if (ue->drb[i] != NULL) + break; + if (i == 5) + nr_rlc_manager_remove_ue(nr_rlc_ue_manager, ctxt_pP->rnti); + } + nr_rlc_manager_unlock(nr_rlc_ue_manager); + return RLC_OP_STATUS_OK; +} + +void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t rrc_data_confP) +{ + /* nothing to do */ +} + +rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) +{ + LOG_D(RLC, "%s:%d:%s: remove UE %d\n", __FILE__, __LINE__, __FUNCTION__, x->rnti); + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_manager_remove_ue(nr_rlc_ue_manager, x->rnti); + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return RLC_OP_STATUS_OK; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_pdu.c b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.c new file mode 100644 index 0000000000000000000000000000000000000000..b42410ab720d76d6c9820fb25476a94781c1bf1f --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.c @@ -0,0 +1,190 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_pdu.h" + +#include <stdlib.h> +#include <string.h> + +#include "LOG/log.h" + +/**************************************************************************/ +/* RX PDU management */ +/**************************************************************************/ + +nr_rlc_pdu_t *nr_rlc_new_pdu(int sn, int so, int is_first, + int is_last, char *data, int size) +{ + nr_rlc_pdu_t *ret = malloc(sizeof(nr_rlc_pdu_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + ret->sn = sn; + ret->so = so; + ret->size = size; + ret->is_first = is_first; + ret->is_last = is_last; + ret->next = NULL; + + ret->data = malloc(size); + if (ret->data == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + memcpy(ret->data, data, size); + + return ret; +} + +void nr_rlc_free_pdu(nr_rlc_pdu_t *pdu) +{ + free(pdu->data); + free(pdu); +} + +nr_rlc_pdu_t *nr_rlc_pdu_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_pdu_t *list, nr_rlc_pdu_t *pdu) +{ + nr_rlc_pdu_t head; + nr_rlc_pdu_t *cur; + nr_rlc_pdu_t *prev; + + head.next = list; + cur = list; + prev = &head; + + /* order is by 'sn', if 'sn' is the same then order is by 'so' */ + while (cur != NULL) { + /* check if 'pdu' is before 'cur' in the list */ + if (sn_compare(sn_compare_data, cur->sn, pdu->sn) > 0 || + (cur->sn == pdu->sn && cur->so > pdu->so)) { + break; + } + prev = cur; + cur = cur->next; + } + prev->next = pdu; + pdu->next = cur; + return head.next; +} + +/**************************************************************************/ +/* PDU decoder */ +/**************************************************************************/ + +void nr_rlc_pdu_decoder_init(nr_rlc_pdu_decoder_t *decoder, + char *buffer, int size) +{ + decoder->error = 0; + decoder->byte = 0; + decoder->bit = 0; + decoder->buffer = buffer; + decoder->size = size; +} + +static int get_bit(nr_rlc_pdu_decoder_t *decoder) +{ + int ret; + + if (decoder->byte >= decoder->size) { + decoder->error = 1; + return 0; + } + + ret = (decoder->buffer[decoder->byte] >> (7 - decoder->bit)) & 1; + + decoder->bit++; + if (decoder->bit == 8) { + decoder->bit = 0; + decoder->byte++; + } + + return ret; +} + +int nr_rlc_pdu_decoder_get_bits(nr_rlc_pdu_decoder_t *decoder, int count) +{ + int ret = 0; + int i; + + if (count > 31) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + for (i = 0; i < count; i++) { + ret <<= 1; + ret |= get_bit(decoder); + if (decoder->error) return -1; + } + + return ret; +} + +/**************************************************************************/ +/* PDU encoder */ +/**************************************************************************/ + +void nr_rlc_pdu_encoder_init(nr_rlc_pdu_encoder_t *encoder, + char *buffer, int size) +{ + encoder->byte = 0; + encoder->bit = 0; + encoder->buffer = buffer; + encoder->size = size; +} + +static void put_bit(nr_rlc_pdu_encoder_t *encoder, int bit) +{ + if (encoder->byte == encoder->size) { + LOG_E(RLC, "%s:%d:%s: fatal, buffer full\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + encoder->buffer[encoder->byte] <<= 1; + if (bit) + encoder->buffer[encoder->byte] |= 1; + + encoder->bit++; + if (encoder->bit == 8) { + encoder->bit = 0; + encoder->byte++; + } +} + +void nr_rlc_pdu_encoder_put_bits(nr_rlc_pdu_encoder_t *encoder, + int value, int count) +{ + int i; + int x; + + if (count > 31) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + x = 1 << (count - 1); + for (i = 0; i < count; i++, x >>= 1) + put_bit(encoder, value & x); +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_pdu.h b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.h new file mode 100644 index 0000000000000000000000000000000000000000..8e9872522ffe2549ddf2570423aa176765a8cc4b --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_pdu.h @@ -0,0 +1,84 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_PDU_H_ +#define _NR_RLC_PDU_H_ + +/**************************************************************************/ +/* RX PDU management */ +/**************************************************************************/ + +typedef struct nr_rlc_pdu_t { + int sn; + char *data; /* contains only SDU bytes, no PDU header */ + int size; /* size of SDU data, no PDU header bytes counted */ + int so; + int is_first; + int is_last; + struct nr_rlc_pdu_t *next; +} nr_rlc_pdu_t; + +nr_rlc_pdu_t *nr_rlc_new_pdu(int sn, int so, int is_first, + int is_last, char *data, int size); + +void nr_rlc_free_pdu(nr_rlc_pdu_t *pdu); + +nr_rlc_pdu_t *nr_rlc_pdu_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_pdu_t *list, nr_rlc_pdu_t *pdu); + +/**************************************************************************/ +/* PDU decoder */ +/**************************************************************************/ + +typedef struct { + int error; + int byte; /* next byte to decode */ + int bit; /* next bit in next byte to decode */ + char *buffer; + int size; +} nr_rlc_pdu_decoder_t; + +void nr_rlc_pdu_decoder_init(nr_rlc_pdu_decoder_t *decoder, + char *buffer, int size); + +#define nr_rlc_pdu_decoder_in_error(d) ((d)->error == 1) + +int nr_rlc_pdu_decoder_get_bits(nr_rlc_pdu_decoder_t *decoder, int count); + +/**************************************************************************/ +/* PDU encoder */ +/**************************************************************************/ + +typedef struct { + int byte; /* next byte to encode */ + int bit; /* next bit in next byte to encode */ + char *buffer; + int size; +} nr_rlc_pdu_encoder_t; + +void nr_rlc_pdu_encoder_init(nr_rlc_pdu_encoder_t *encoder, + char *buffer, int size); + +void nr_rlc_pdu_encoder_put_bits(nr_rlc_pdu_encoder_t *encoder, + int value, int count); + +#endif /* _NR_RLC_PDU_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c new file mode 100644 index 0000000000000000000000000000000000000000..ef0d52558aa402c3701d72ab9f8e0d2a492a6d57 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.c @@ -0,0 +1,121 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_sdu.h" + +#include <stdlib.h> +#include <string.h> + +#include "LOG/log.h" + +nr_rlc_sdu_segment_t *nr_rlc_new_sdu( + char *buffer, int size, + int upper_layer_id) +{ + nr_rlc_sdu_t *sdu = calloc(1, sizeof(nr_rlc_sdu_t)); + nr_rlc_sdu_segment_t *ret = calloc(1, sizeof(nr_rlc_sdu_segment_t)); + if (sdu == NULL || ret == NULL) + goto oom; + + sdu->ref_count = 1; + sdu->sn = -1; /* set later */ + sdu->upper_layer_id = upper_layer_id; + sdu->data = malloc(size); + if (sdu->data == NULL) + goto oom; + memcpy(sdu->data, buffer, size); + sdu->size = size; + sdu->retx_count = -1; + + ret->sdu = sdu; + ret->size = size; + ret->so = 0; + ret->is_first = 1; + ret->is_last = 1; + + return ret; + +oom: + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); +} + +void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu) +{ + sdu->sdu->ref_count--; + if (sdu->sdu->ref_count == 0) { + free(sdu->sdu->data); + free(sdu->sdu); + } + free(sdu); +} + +void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list, + nr_rlc_sdu_segment_t **end, + nr_rlc_sdu_segment_t *sdu) +{ + if (*list == NULL) { + *list = sdu; + *end = sdu; + return; + } + + (*end)->next = sdu; + *end = sdu; +} + +nr_rlc_sdu_segment_t *nr_rlc_sdu_segment_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment) +{ + nr_rlc_sdu_segment_t head; + nr_rlc_sdu_segment_t *cur; + nr_rlc_sdu_segment_t *prev; + + head.next = list; + cur = list; + prev = &head; + + /* order is by 'sn', if 'sn' is the same then order is by 'so' */ + while (cur != NULL) { + /* check if 'sdu_segment' is before 'cur' in the list */ + if (sn_compare(sn_compare_data, cur->sdu->sn, sdu_segment->sdu->sn) > 0 || + (cur->sdu->sn == sdu_segment->sdu->sn && cur->so > sdu_segment->so)) { + break; + } + prev = cur; + cur = cur->next; + } + prev->next = sdu_segment; + sdu_segment->next = cur; + return head.next; +} + +void nr_rlc_free_sdu_segment_list(nr_rlc_sdu_segment_t *l) +{ + nr_rlc_sdu_segment_t *cur; + + while (l != NULL) { + cur = l; + l = l->next; + nr_rlc_free_sdu_segment(cur); + } +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h new file mode 100644 index 0000000000000000000000000000000000000000..f4585fb7d62342f4b5a5065c1c778d05c27ff063 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_sdu.h @@ -0,0 +1,56 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_SDU_H_ +#define _NR_RLC_SDU_H_ + +typedef struct nr_rlc_sdu_t { + int sn; + int upper_layer_id; + char *data; + int size; + int retx_count; + + int ref_count; /* incremented each time the SDU is segmented */ +} nr_rlc_sdu_t; + +typedef struct nr_rlc_sdu_segment_t { + nr_rlc_sdu_t *sdu; + int size; + int so; + int is_first; + int is_last; + struct nr_rlc_sdu_segment_t *next; +} nr_rlc_sdu_segment_t; + +nr_rlc_sdu_segment_t *nr_rlc_new_sdu( + char *buffer, int size, + int upper_layer_id); +void nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu); +void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list, + nr_rlc_sdu_segment_t **end, + nr_rlc_sdu_segment_t *sdu); +nr_rlc_sdu_segment_t *nr_rlc_sdu_segment_list_add( + int (*sn_compare)(void *, int, int), void *sn_compare_data, + nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment); +void nr_rlc_free_sdu_segment_list(nr_rlc_sdu_segment_t *l); + +#endif /* _NR_RLC_SDU_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..09f1e4f599e5ca98389dc577782b35594671f130 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.c @@ -0,0 +1,190 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_rlc_ue_manager.h" + +#include <pthread.h> +#include <stdlib.h> +#include <string.h> + +#include "LOG/log.h" + +typedef struct { + pthread_mutex_t lock; + nr_rlc_ue_t **ue_list; + int ue_count; + int enb_flag; +} nr_rlc_ue_manager_internal_t; + +nr_rlc_ue_manager_t *new_nr_rlc_ue_manager(int enb_flag) +{ + nr_rlc_ue_manager_internal_t *ret; + + ret = calloc(1, sizeof(nr_rlc_ue_manager_internal_t)); + if (ret == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + ret->enb_flag = enb_flag; + + return ret; +} + +int nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager_t *_m) +{ + nr_rlc_ue_manager_internal_t *m = _m; + return m->enb_flag; +} + +void nr_rlc_manager_lock(nr_rlc_ue_manager_t *_m) +{ + nr_rlc_ue_manager_internal_t *m = _m; + if (pthread_mutex_lock(&m->lock)) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +void nr_rlc_manager_unlock(nr_rlc_ue_manager_t *_m) +{ + nr_rlc_ue_manager_internal_t *m = _m; + if (pthread_mutex_unlock(&m->lock)) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +/* must be called with lock acquired */ +nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *_m, int rnti) +{ + /* TODO: optimze */ + nr_rlc_ue_manager_internal_t *m = _m; + int i; + + for (i = 0; i < m->ue_count; i++) + if (m->ue_list[i]->rnti == rnti) + return m->ue_list[i]; + + LOG_D(RLC, "%s:%d:%s: new UE %d\n", __FILE__, __LINE__, __FUNCTION__, rnti); + + m->ue_count++; + m->ue_list = realloc(m->ue_list, sizeof(nr_rlc_ue_t *) * m->ue_count); + if (m->ue_list == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + m->ue_list[m->ue_count-1] = calloc(1, sizeof(nr_rlc_ue_t)); + if (m->ue_list[m->ue_count-1] == NULL) { + LOG_E(RLC, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + m->ue_list[m->ue_count-1]->rnti = rnti; + + return m->ue_list[m->ue_count-1]; +} + +/* must be called with lock acquired */ +void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *_m, int rnti) +{ + nr_rlc_ue_manager_internal_t *m = _m; + nr_rlc_ue_t *ue; + int i; + int j; + + for (i = 0; i < m->ue_count; i++) + if (m->ue_list[i]->rnti == rnti) + break; + + if (i == m->ue_count) { + LOG_D(RLC, "%s:%d:%s: warning: ue %d not found\n", + __FILE__, __LINE__, __FUNCTION__, + rnti); + return; + } + + ue = m->ue_list[i]; + + for (j = 0; j < 2; j++) + if (ue->srb[j] != NULL) + ue->srb[j]->delete(ue->srb[j]); + + for (j = 0; j < 5; j++) + if (ue->drb[j] != NULL) + ue->drb[j]->delete(ue->drb[j]); + + free(ue); + + m->ue_count--; + if (m->ue_count == 0) { + free(m->ue_list); + m->ue_list = NULL; + return; + } + + memmove(&m->ue_list[i], &m->ue_list[i+1], + (m->ue_count - i) * sizeof(nr_rlc_ue_t *)); + m->ue_list = realloc(m->ue_list, m->ue_count * sizeof(nr_rlc_ue_t *)); + if (m->ue_list == NULL) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +/* must be called with lock acquired */ +void nr_rlc_ue_add_srb_rlc_entity(nr_rlc_ue_t *ue, int srb_id, nr_rlc_entity_t *entity) +{ + if (srb_id < 1 || srb_id > 2) { + LOG_E(RLC, "%s:%d:%s: fatal, bad srb id\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + srb_id--; + + if (ue->srb[srb_id] != NULL) { + LOG_E(RLC, "%s:%d:%s: fatal, srb already present\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ue->srb[srb_id] = entity; +} + +/* must be called with lock acquired */ +void nr_rlc_ue_add_drb_rlc_entity(nr_rlc_ue_t *ue, int drb_id, nr_rlc_entity_t *entity) +{ + if (drb_id < 1 || drb_id > 5) { + LOG_E(RLC, "%s:%d:%s: fatal, bad drb id\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + drb_id--; + + if (ue->drb[drb_id] != NULL) { + LOG_E(RLC, "%s:%d:%s: fatal, drb already present\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ue->drb[drb_id] = entity; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..97da28cdce2136f01bef2d0c8625269e7ba5edf0 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -0,0 +1,60 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_RLC_UE_MANAGER_H_ +#define _NR_RLC_UE_MANAGER_H_ + +#include "nr_rlc_entity.h" + +typedef void nr_rlc_ue_manager_t; + +typedef struct nr_rlc_ue_t { + int rnti; + /* due to openair calling status_ind/data_req, we need to keep this. + * To be considered 'hackish'. + */ + int saved_status_ind_tb_size[2+5]; + nr_rlc_entity_t *srb[2]; + nr_rlc_entity_t *drb[5]; +} nr_rlc_ue_t; + +/***********************************************************************/ +/* manager functions */ +/***********************************************************************/ + +nr_rlc_ue_manager_t *new_nr_rlc_ue_manager(int enb_flag); + +int nr_rlc_manager_get_enb_flag(nr_rlc_ue_manager_t *m); + +void nr_rlc_manager_lock(nr_rlc_ue_manager_t *m); +void nr_rlc_manager_unlock(nr_rlc_ue_manager_t *m); + +nr_rlc_ue_t *nr_rlc_manager_get_ue(nr_rlc_ue_manager_t *m, int rnti); +void nr_rlc_manager_remove_ue(nr_rlc_ue_manager_t *m, int rnti); + +/***********************************************************************/ +/* ue functions */ +/***********************************************************************/ + +void nr_rlc_ue_add_srb_rlc_entity(nr_rlc_ue_t *ue, int srb_id, nr_rlc_entity_t *entity); +void nr_rlc_ue_add_drb_rlc_entity(nr_rlc_ue_t *ue, int drb_id, nr_rlc_entity_t *entity); + +#endif /* _NR_RLC_UE_MANAGER_H_ */ diff --git a/openair2/LAYER2/nr_rlc/test.c b/openair2/LAYER2/nr_rlc/test.c new file mode 100644 index 0000000000000000000000000000000000000000..52b0891bc3037702e6eb2a78d213dc36a27daadc --- /dev/null +++ b/openair2/LAYER2/nr_rlc/test.c @@ -0,0 +1,32 @@ +#include "nr_rlc_entity.h" + +#include <stdio.h> + +int main(void) +{ + char out[32768]; + nr_rlc_entity_t *am; + int sdu_id = 0; + int size; + int i; + + am = new_nr_rlc_entity_am(100000, 100000, + 0, 0, + 0, 0, + 0, 0, + 45, 35, 0, + -1, -1, 8, + 12); + + char data[8] = { 1, 2, 3, 4, 8, 7, 6, 5 }; + + am->recv_sdu(am, data, sizeof(data), sdu_id++); + + size = am->generate_pdu(am, out, 32768); + + printf("generate_pdu[%d]:", size); + for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)out[i]); + printf("\n"); + + return 0; +} diff --git a/openair2/LAYER2/nr_rlc/tests/LOG/log.h b/openair2/LAYER2/nr_rlc/tests/LOG/log.h new file mode 100644 index 0000000000000000000000000000000000000000..5c9fcd643cfca036cc81eca221f4a5e818aee685 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/LOG/log.h @@ -0,0 +1,10 @@ +#ifndef _LOG_H_ +#define _LOG_H_ + +#include <stdio.h> + +#define LOG_E(x, ...) printf(__VA_ARGS__) +#define LOG_D(x, ...) printf(__VA_ARGS__) +#define LOG_W(x, ...) printf(__VA_ARGS__) + +#endif /* _LOG_H_ */ diff --git a/openair2/LAYER2/nr_rlc/tests/Makefile b/openair2/LAYER2/nr_rlc/tests/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..746d61483b6523ab708a861e25d0d884363b10e8 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/Makefile @@ -0,0 +1,33 @@ +CC=gcc +CFLAGS=-Wall -g --coverage -I. + +LIB=nr_rlc_entity.o nr_rlc_entity_am.o nr_rlc_entity_um.o nr_rlc_entity_tm.o \ + nr_rlc_pdu.o nr_rlc_sdu.o + +tests: + @./run_tests.sh + +all: clean_run $(TEST).run + +%.run: $(TEST).bin + #valgrind ./$(TEST).bin > $(TEST).run_pre 2> $(TEST).valgrind + ./$(TEST).bin > $(TEST).run_pre + grep ^TEST $(TEST).run_pre > $(TEST).run + gunzip -c $(TEST).txt.gz > $(TEST).txt + diff -q $(TEST).txt $(TEST).run + +$(TEST).bin: $(TEST).o $(LIB) + $(CC) $(CFLAGS) -o $@ $^ + +%.o: ../%.c + $(CC) $(CFLAGS) -I.. -c -o $@ $< + +$(TEST).o: test.c + $(CC) $(CFLAGS) -c -o $@ $< -DTEST='"$(TEST).h"' + +clean_run: + rm -f $(TEST).run $(TEST).bin $(TEST).o + +clean: + rm -f *.o *.bin *.run *.run_pre *.gcov *.gcda *.gcno test*.txt a.out \ + *.valgrind diff --git a/openair2/LAYER2/nr_rlc/tests/run_tests.sh b/openair2/LAYER2/nr_rlc/tests/run_tests.sh new file mode 100755 index 0000000000000000000000000000000000000000..ac225160646d869235976445f35f9a4ec3cff52d --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/run_tests.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +test_count=13 + +for i in `seq $test_count` +do + make all TEST=test$i >/dev/null 2>/dev/null + if [ $? != 0 ] + then + echo TEST $i FAILURE + fi +done diff --git a/openair2/LAYER2/nr_rlc/tests/test.c b/openair2/LAYER2/nr_rlc/tests/test.c new file mode 100644 index 0000000000000000000000000000000000000000..742e79ca2c1cf788a38e95b9b2f4457c3e6deeb9 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test.c @@ -0,0 +1,483 @@ +#include "../nr_rlc_entity.h" +#include "../nr_rlc_entity_am.h" +#include "../nr_rlc_entity_um.h" +#include "../nr_rlc_entity_tm.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> +#include <sys/wait.h> +#include <unistd.h> + +/* + * GNB_AM <rx_maxsize> <tx_maxsize> <t_poll_retransmit> <t_reassembly> + * <t_status_prohibit> <poll_pdu> <poll_byte> <max_retx_threshold> + * <sn_field_length> + * create the gNB RLC AM entity with given parameters + * + * UE_AM <rx_maxsize> <tx_maxsize> <t_poll_retransmit> <t_reassembly> + * <t_status_prohibit> <poll_pdu> <poll_byte> <max_retx_threshold> + * <sn_field_length> + * create the UE RLC AM entity with given parameters + * + * GNB_UM <rx_maxsize> <tx_maxsize> <t_reassembly> <sn_field_length> + * create the eNB RLC UM entity with given parameters + * + * UE_UM <rx_maxsize> <tx_maxsize> <t_reassembly> <sn_field_length> + * create the UE RLC UM entity with given parameters + * + * GNB_TM <tx_maxsize> + * create the eNB RLC TM entity with given parameters + * + * UE_UM <tx_maxsize> + * create the UE RLC TM entity with given parameters + * + * TIME <time> + * following actions to be performed at time <time> + * <time> starts at 1 + * You must end your test definition with a line 'TIME, -1'. + * + * GNB_SDU <id> <size> + * send an SDU to eNB with id <i> and size <size> + * the SDU is [00 01 ... ff 01 ...] + * (ie. start byte is 00 then we increment for each byte, loop if needed) + * + * UE_SDU <id> <size> + * same as GNB_SDU but the SDU is sent to the UE + * + * GNB_PDU <size> <'size' bytes> + * send a custom PDU from eNB to UE (eNB does not see this PDU at all) + * + * UE_PDU <size> <'size' bytes> + * send a custom PDU from UE to eNB (UE does not see this PDU at all) + * + * GNB_PDU_SIZE <size> + * set 'gnb_pdu_size' + * + * UE_PDU_SIZE <size> + * set 'ue_pdu_size' + * + * GNB_RECV_FAILS <fails> + * set the 'gnb_recv_fails' flag to <fails> + * (1: recv will fail, 0: recv will succeed) + * + * UE_RECV_FAILS <fails> + * same as GNB_RECV_FAILS but for 'ue_recv_fails' + * + * MUST_FAIL + * to be used as first command after the first TIME to indicate + * that the test must fail (ie. exit with non zero, crash not allowed) + * + * GNB_BUFFER_STATUS + * call buffer_status for eNB and print result + * + * UE_BUFFER_STATUS + * call buffer_status for UE and print result + * + * GNB_DISCARD_SDU <sdu ID> + * discards given SDU + * + * UE_DISCARD_SDU <sdu ID> + * discards given SDU + * + * RE_ESTABLISH + * re-establish both eNB and UE + */ + +enum action { + GNB_AM, UE_AM, + GNB_UM, UE_UM, + GNB_TM, UE_TM, + TIME, GNB_SDU, UE_SDU, GNB_PDU, UE_PDU, + GNB_PDU_SIZE, UE_PDU_SIZE, + GNB_RECV_FAILS, UE_RECV_FAILS, + MUST_FAIL, + GNB_BUFFER_STATUS, UE_BUFFER_STATUS, + GNB_DISCARD_SDU, UE_DISCARD_SDU, + RE_ESTABLISH +}; + +int test[] = { +/* TEST is defined at compilation time */ +#include TEST +}; + +void deliver_sdu_gnb_am(void *deliver_sdu_data, + struct nr_rlc_entity_t *_entity, + char *buf, int size) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", + entity->t_current, size); + for (int i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + printf("]\n"); +} + +void deliver_sdu_gnb_um(void *deliver_sdu_data, + struct nr_rlc_entity_t *_entity, + char *buf, int size) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", + entity->t_current, size); + for (int i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + printf("]\n"); +} + +void deliver_sdu_gnb_tm(void *deliver_sdu_data, + struct nr_rlc_entity_t *_entity, + char *buf, int size) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + printf("TEST: GNB: %"PRIu64": deliver SDU size %d [", + entity->t_current, size); + for (int i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + printf("]\n"); +} + +void successful_delivery_gnb(void *successful_delivery_data, + nr_rlc_entity_t *_entity, int sdu_id) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + printf("TEST: GNB: %"PRIu64": SDU %d was successfully delivered.\n", + entity->t_current, sdu_id); +} + +void max_retx_reached_gnb(void *max_retx_reached_data, + nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + printf("TEST: GNB: %"PRIu64": max RETX reached! radio link failure!\n", + entity->t_current); + exit(1); +} + +void deliver_sdu_ue_am(void *deliver_sdu_data, + struct nr_rlc_entity_t *_entity, + char *buf, int size) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + printf("TEST: UE: %"PRIu64": deliver SDU size %d [", + entity->t_current, size); + for (int i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + printf("]\n"); +} + +void deliver_sdu_ue_um(void *deliver_sdu_data, + struct nr_rlc_entity_t *_entity, + char *buf, int size) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + printf("TEST: UE: %"PRIu64": deliver SDU size %d [", + entity->t_current, size); + for (int i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + printf("]\n"); +} + +void deliver_sdu_ue_tm(void *deliver_sdu_data, + struct nr_rlc_entity_t *_entity, + char *buf, int size) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + printf("TEST: UE: %"PRIu64": deliver SDU size %d [", + entity->t_current, size); + for (int i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + printf("]\n"); +} + +void successful_delivery_ue(void *successful_delivery_data, + nr_rlc_entity_t *_entity, int sdu_id) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + printf("TEST: UE: %"PRIu64": SDU %d was successfully delivered.\n", + entity->t_current, sdu_id); +} + +void max_retx_reached_ue(void *max_retx_reached_data, + nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + printf("TEST: UE: %"PRIu64", max RETX reached! radio link failure!\n", + entity->t_current); + exit(1); +} + +int test_main(void) +{ + nr_rlc_entity_t *gnb = NULL; + nr_rlc_entity_t *ue = NULL; + int i; + int k; + char *sdu; + char *pdu; + nr_rlc_entity_buffer_status_t buffer_status; + int gnb_do_buffer_status = 0; + int ue_do_buffer_status = 0; + int size; + int pos; + int next_byte_gnb = 0; + int next_byte_ue = 0; + int gnb_recv_fails = 0; + int ue_recv_fails = 0; + int gnb_pdu_size = 1000; + int ue_pdu_size = 1000; + + printf("TEST: start\n"); + + sdu = malloc(16001); + pdu = malloc(3000); + if (sdu == NULL || pdu == NULL) { + printf("out of memory\n"); + exit(1); + } + + for (i = 0; i < 16001; i++) + sdu[i] = i & 255; + + pos = 0; + if (test[pos] != TIME) { + printf("%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + for (i = 1; i < 1000; i++) { + if (i == test[pos+1]) { + pos += 2; + while (test[pos] != TIME) + switch (test[pos]) { + default: printf("fatal: unknown action\n"); exit(1); + case GNB_AM: + gnb = new_nr_rlc_entity_am(test[pos+1], test[pos+2], + deliver_sdu_gnb_am, NULL, + successful_delivery_gnb, NULL, + max_retx_reached_gnb, NULL, + test[pos+3], test[pos+4], test[pos+5], + test[pos+6], test[pos+7], test[pos+8], + test[pos+9]); + pos += 10; + break; + case UE_AM: + ue = new_nr_rlc_entity_am(test[pos+1], test[pos+2], + deliver_sdu_ue_am, NULL, + successful_delivery_ue, NULL, + max_retx_reached_ue, NULL, + test[pos+3], test[pos+4], test[pos+5], + test[pos+6], test[pos+7], test[pos+8], + test[pos+9]); + pos += 10; + break; + case GNB_UM: + gnb = new_nr_rlc_entity_um(test[pos+1], test[pos+2], + deliver_sdu_gnb_um, NULL, + test[pos+3], test[pos+4]); + pos += 5; + break; + case UE_UM: + ue = new_nr_rlc_entity_um(test[pos+1], test[pos+2], + deliver_sdu_ue_um, NULL, + test[pos+3], test[pos+4]); + pos += 5; + break; + case GNB_TM: + gnb = new_nr_rlc_entity_tm(test[pos+1], deliver_sdu_gnb_tm, NULL); + pos += 2; + break; + case UE_TM: + ue = new_nr_rlc_entity_tm(test[pos+1], deliver_sdu_ue_tm, NULL); + pos += 2; + break; + case GNB_SDU: + for (k = 0; k < test[pos+2]; k++, next_byte_gnb++) + sdu[k] = next_byte_gnb; + printf("TEST: GNB: %d: recv_sdu (id %d): size %d: [", + i, test[pos+1], test[pos+2]); + for (k = 0; k < test[pos+2]; k++) + printf(" %2.2x", (unsigned char)sdu[k]); + printf("]\n"); + gnb->recv_sdu(gnb, sdu, test[pos+2], test[pos+1]); + pos += 3; + break; + case UE_SDU: + for (k = 0; k < test[pos+2]; k++, next_byte_ue++) + sdu[k] = next_byte_ue; + printf("TEST: UE: %d: recv_sdu (id %d): size %d: [", + i, test[pos+1], test[pos+2]); + for (k = 0; k < test[pos+2]; k++) + printf(" %2.2x", (unsigned char)sdu[k]); + printf("]\n"); + ue->recv_sdu(ue, sdu, test[pos+2], test[pos+1]); + pos += 3; + break; + case GNB_PDU: + for (k = 0; k < test[pos+1]; k++) + pdu[k] = test[pos+2+k]; + printf("TEST: GNB: %d: custom PDU: size %d: [", i, test[pos+1]); + for (k = 0; k < test[pos+1]; k++) printf(" %2.2x", (unsigned char)pdu[k]); + printf("]\n"); + if (!ue_recv_fails) + ue->recv_pdu(ue, pdu, test[pos+1]); + pos += 2 + test[pos+1]; + break; + case UE_PDU: + for (k = 0; k < test[pos+1]; k++) + pdu[k] = test[pos+2+k]; + printf("TEST: UE: %d: custom PDU: size %d: [", i, test[pos+1]); + for (k = 0; k < test[pos+1]; k++) printf(" %2.2x", (unsigned char)pdu[k]); + printf("]\n"); + if (!gnb_recv_fails) + gnb->recv_pdu(gnb, pdu, test[pos+1]); + pos += 2 + test[pos+1]; + break; + case GNB_PDU_SIZE: + gnb_pdu_size = test[pos+1]; + pos += 2; + break; + case UE_PDU_SIZE: + ue_pdu_size = test[pos+1]; + pos += 2; + break; + case GNB_RECV_FAILS: + gnb_recv_fails = test[pos+1]; + pos += 2; + break; + case UE_RECV_FAILS: + ue_recv_fails = test[pos+1]; + pos += 2; + break; + case MUST_FAIL: + /* do nothing, only used by caller */ + pos++; + break; + case GNB_BUFFER_STATUS: + gnb_do_buffer_status = 1; + pos++; + break; + case UE_BUFFER_STATUS: + ue_do_buffer_status = 1; + pos++; + break; + case GNB_DISCARD_SDU: + printf("TEST: GNB: %d: discard SDU %d\n", i, test[pos+1]); + gnb->discard_sdu(gnb, test[pos+1]); + pos += 2; + break; + case UE_DISCARD_SDU: + printf("TEST: UE: %d: discard SDU %d\n", i, test[pos+1]); + ue->discard_sdu(ue, test[pos+1]); + pos += 2; + break; + case RE_ESTABLISH: + printf("TEST: %d: re-establish eNB and UE\n", i); + gnb->reestablishment(gnb); + ue->reestablishment(ue); + pos++; + break; + } + } + + gnb->set_time(gnb, i); + ue->set_time(ue, i); + + if (gnb_do_buffer_status) { + gnb_do_buffer_status = 0; + buffer_status = gnb->buffer_status(gnb, gnb_pdu_size); + printf("TEST: GNB: %d: buffer_status: status_size %d tx_size %d retx_size %d\n", + i, + buffer_status.status_size, + buffer_status.tx_size, + buffer_status.retx_size); + } + + size = gnb->generate_pdu(gnb, pdu, gnb_pdu_size); + if (size) { + printf("TEST: GNB: %d: generate_pdu: size %d: [", i, size); + for (k = 0; k < size; k++) printf(" %2.2x", (unsigned char)pdu[k]); + printf("]\n"); + if (!ue_recv_fails) + ue->recv_pdu(ue, pdu, size); + } + + if (ue_do_buffer_status) { + ue_do_buffer_status = 0; + buffer_status = ue->buffer_status(ue, ue_pdu_size); + printf("TEST: UE: %d: buffer_status: status_size %d tx_size %d retx_size %d\n", + i, + buffer_status.status_size, + buffer_status.tx_size, + buffer_status.retx_size); + } + + size = ue->generate_pdu(ue, pdu, ue_pdu_size); + if (size) { + printf("TEST: UE: %d: generate_pdu: size %d: [", i, size); + for (k = 0; k < size; k++) printf(" %2.2x", (unsigned char)pdu[k]); + printf("]\n"); + if (!gnb_recv_fails) + gnb->recv_pdu(gnb, pdu, size); + } + } + + gnb->delete(gnb); + ue->delete(ue); + + free(sdu); + free(pdu); + + return 0; +} + +void usage(void) +{ + printf("options:\n"); + printf(" -no-fork\n"); + printf(" don't fork (to ease debugging with gdb)\n"); + exit(0); +} + +int main(int n, char **v) +{ + int must_fail = 0; + int son; + int status; + int i; + int no_fork = 0; + + for (i = 1; i < n; i++) { + if (!strcmp(v[i], "-no-fork")) { no_fork = 1; continue; } + usage(); + } + + if (test[2] == MUST_FAIL) + must_fail = 1; + + if (no_fork) return test_main(); + + son = fork(); + if (son == -1) { + perror("fork"); + return 1; + } + + if (son == 0) + return test_main(); + + if (wait(&status) == -1) { + perror("wait"); + return 1; + } + + /* child must quit properly */ + if (!WIFEXITED(status)) + return 1; + + /* child must fail if expected to */ + if (must_fail && WEXITSTATUS(status) == 0) + return 1; + + /* child must not fail if not expected to */ + if (!must_fail && WEXITSTATUS(status)) + return 1; + + return 0; +} diff --git a/openair2/LAYER2/nr_rlc/tests/test1.h b/openair2/LAYER2/nr_rlc/tests/test1.h new file mode 100644 index 0000000000000000000000000000000000000000..3240ecfc3686092f446eea9c72e373d2a436db12 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test1.h @@ -0,0 +1,14 @@ +/* + * basic am test (SN field size 12): + * at time 1, gNB receives an SDU of 10 bytes + * at time 10, UE receives an SDU of 5 bytes + */ + +TIME, 1, + GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 12, + UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 12, + GNB_SDU, 0, 10, + UE_BUFFER_STATUS, +TIME, 10, + UE_SDU, 0, 5, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test1.txt.gz b/openair2/LAYER2/nr_rlc/tests/test1.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..d3852d070cb17dae5f7db1678ef427b0e7f85a96 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test1.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test10.h b/openair2/LAYER2/nr_rlc/tests/test10.h new file mode 100644 index 0000000000000000000000000000000000000000..1653736f2665229c70cbe3fbe797b934ee2fbfe7 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test10.h @@ -0,0 +1,13 @@ +/* + * um test (SN field size 6): + * test reassembly + * at time 1, gNB receives an SDU of 50 bytes + * sends it in 3 parts + */ + +TIME, 1, + GNB_UM, 100000, 100000, 35, 6, + UE_UM, 100000, 100000, 35, 6, + GNB_PDU_SIZE, 22, + GNB_SDU, 0, 50, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test10.txt.gz b/openair2/LAYER2/nr_rlc/tests/test10.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..12430b53c5647e7c17d1428aa1413ada5b7e5b67 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test10.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test11.h b/openair2/LAYER2/nr_rlc/tests/test11.h new file mode 100644 index 0000000000000000000000000000000000000000..41465e09e1dcd41148814f0a84e34af22dabe61f --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test11.h @@ -0,0 +1,13 @@ +/* + * um test (SN field size 12): + * test reassembly + * at time 1, gNB receives an SDU of 50 bytes + * sends it in 3 parts + */ + +TIME, 1, + GNB_UM, 100000, 100000, 35, 12, + UE_UM, 100000, 100000, 35, 12, + GNB_PDU_SIZE, 22, + GNB_SDU, 0, 50, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test11.txt.gz b/openair2/LAYER2/nr_rlc/tests/test11.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..1a5294ffa023c3fa3a2b2853e0f846fbbc9d4807 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test11.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test12.h b/openair2/LAYER2/nr_rlc/tests/test12.h new file mode 100644 index 0000000000000000000000000000000000000000..4ab28dd3f23901f665b66c7deb6eec44b9da1ce2 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test12.h @@ -0,0 +1,18 @@ +/* + * um test (SN field size 6): + * test reassembly and timeout + * at time 1, gNB receives an SDU of 50 bytes + * sends it in 3 parts + * part 2 not received + */ + +TIME, 1, + GNB_UM, 100000, 100000, 35, 6, + UE_UM, 100000, 100000, 35, 6, + GNB_PDU_SIZE, 22, + GNB_SDU, 0, 50, +TIME, 2, + UE_RECV_FAILS, 1, +TIME, 3, + UE_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test12.txt.gz b/openair2/LAYER2/nr_rlc/tests/test12.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..ac85aa89f39fb5c76f5e21b07d1658c461839e0c Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test12.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test13.h b/openair2/LAYER2/nr_rlc/tests/test13.h new file mode 100644 index 0000000000000000000000000000000000000000..fc973fdcff60c1fe3a1c8f32e698755edc89f15a --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test13.h @@ -0,0 +1,18 @@ +/* + * um test (SN field size 12): + * test reassembly and timeout + * at time 1, gNB receives an SDU of 50 bytes + * sends it in 3 parts + * part 2 not received + */ + +TIME, 1, + GNB_UM, 100000, 100000, 35, 12, + UE_UM, 100000, 100000, 35, 12, + GNB_PDU_SIZE, 22, + GNB_SDU, 0, 50, +TIME, 2, + UE_RECV_FAILS, 1, +TIME, 3, + UE_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test13.txt.gz b/openair2/LAYER2/nr_rlc/tests/test13.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..3838dcf15214dda2c8bbd7fba5e60c9016b4a8c2 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test13.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test2.h b/openair2/LAYER2/nr_rlc/tests/test2.h new file mode 100644 index 0000000000000000000000000000000000000000..7adc349c1ea3765b7dc0e0293cd756139dd1f368 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test2.h @@ -0,0 +1,14 @@ +/* + * basic am test (SN field size 18): + * at time 1, gNB receives an SDU of 10 bytes + * at time 10, UE receives an SDU of 5 bytes + */ + +TIME, 1, + GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + GNB_SDU, 0, 10, + UE_BUFFER_STATUS, +TIME, 10, + UE_SDU, 0, 5, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test2.txt.gz b/openair2/LAYER2/nr_rlc/tests/test2.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..04092cdaa2d778f3a65dfbe26e9879a01c740428 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test2.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test3.h b/openair2/LAYER2/nr_rlc/tests/test3.h new file mode 100644 index 0000000000000000000000000000000000000000..db5454f8de0dd9e66917df88134f03ddeca7c325 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test3.h @@ -0,0 +1,14 @@ +/* + * basic um test (SN field size 6): + * at time 1, gNB receives an SDU of 10 bytes + * at time 10, UE receives an SDU of 5 bytes + */ + +TIME, 1, + GNB_UM, 100000, 100000, 35, 6, + UE_UM, 100000, 100000, 35, 6, + GNB_SDU, 0, 10, + UE_BUFFER_STATUS, +TIME, 10, + UE_SDU, 0, 5, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test3.txt.gz b/openair2/LAYER2/nr_rlc/tests/test3.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..070981d99126bc7e90585422defb1befa6f315bf Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test3.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test4.h b/openair2/LAYER2/nr_rlc/tests/test4.h new file mode 100644 index 0000000000000000000000000000000000000000..1c9bcbc0b9823514177642acc82b78d9cdc4c200 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test4.h @@ -0,0 +1,14 @@ +/* + * basic um test (SN field size 12): + * at time 1, gNB receives an SDU of 10 bytes + * at time 10, UE receives an SDU of 5 bytes + */ + +TIME, 1, + GNB_UM, 100000, 100000, 35, 6, + UE_UM, 100000, 100000, 35, 6, + GNB_SDU, 0, 10, + UE_BUFFER_STATUS, +TIME, 10, + UE_SDU, 0, 5, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test4.txt.gz b/openair2/LAYER2/nr_rlc/tests/test4.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..f4230c8522fe334bb0a8d294b36d62e70c761f88 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test4.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test5.h b/openair2/LAYER2/nr_rlc/tests/test5.h new file mode 100644 index 0000000000000000000000000000000000000000..ea090adcb53b19e3a7c2339a3318cc15047fc87b --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test5.h @@ -0,0 +1,15 @@ +/* + * basic am test (SN field size 11, not exiting, test must fail): + * at time 1, gNB receives an SDU of 10 bytes + * at time 10, UE receives an SDU of 5 bytes + */ + +TIME, 1, + MUST_FAIL, + GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 11, + UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 11, + GNB_SDU, 0, 10, + UE_BUFFER_STATUS, +TIME, 10, + UE_SDU, 0, 5, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test5.txt.gz b/openair2/LAYER2/nr_rlc/tests/test5.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..812365c1e36f0b492cb94e3e45c4fe74f6d5888d Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test5.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test6.h b/openair2/LAYER2/nr_rlc/tests/test6.h new file mode 100644 index 0000000000000000000000000000000000000000..86d7724dd2f733d320ef248852f8cfa6b3e41bfc --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test6.h @@ -0,0 +1,15 @@ +/* + * basic um test (SN field size 19, bad size, test must fail): + * at time 1, gNB receives an SDU of 10 bytes + * at time 10, UE receives an SDU of 5 bytes + */ + +TIME, 1, + MUST_FAIL, + GNB_UM, 100000, 100000, 35, 19, + UE_UM, 100000, 100000, 35, 19, + GNB_SDU, 0, 10, + UE_BUFFER_STATUS, +TIME, 10, + UE_SDU, 0, 5, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test6.txt.gz b/openair2/LAYER2/nr_rlc/tests/test6.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..1d8575cef043478db1d98f22b0e1aa37dc578bdb Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test6.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test7.h b/openair2/LAYER2/nr_rlc/tests/test7.h new file mode 100644 index 0000000000000000000000000000000000000000..4a380261f44365ba23588d70e51f9b98e713bc7a --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test7.h @@ -0,0 +1,14 @@ +/* + * basic tm test: + * at time 1, gNB receives an SDU of 10 bytes + * at time 10, UE receives an SDU of 5 bytes + */ + +TIME, 1, + GNB_TM, 100000, + UE_TM, 100000, + GNB_SDU, 0, 10, + UE_BUFFER_STATUS, +TIME, 10, + UE_SDU, 0, 5, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test7.txt.gz b/openair2/LAYER2/nr_rlc/tests/test7.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..8689670886558883003d140847b37b2f6c723049 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test7.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test8.h b/openair2/LAYER2/nr_rlc/tests/test8.h new file mode 100644 index 0000000000000000000000000000000000000000..c205f7ab57755d025108d1e432b04930226ab6b6 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test8.h @@ -0,0 +1,20 @@ +/* + * am test (SN field size 12): + * test reassembly + * at time 1, gNB receives an SDU of 50 bytes + * sends 1st part, received by UE + * then sends 2nd part, not received + * then sends 3rd part, received + * then UE receives all + */ + +TIME, 1, + GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 12, + UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 12, + GNB_PDU_SIZE, 22, + GNB_SDU, 0, 50, +TIME, 2, + UE_RECV_FAILS, 1, +TIME, 3, + UE_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test8.txt.gz b/openair2/LAYER2/nr_rlc/tests/test8.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..d69e43acdce5dd621905f0c2d731d189b0807e70 Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test8.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test9.h b/openair2/LAYER2/nr_rlc/tests/test9.h new file mode 100644 index 0000000000000000000000000000000000000000..c3fb0e31d11b7dbe823d8bb5bd84abd23398622b --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/test9.h @@ -0,0 +1,20 @@ +/* + * am test (SN field size 18): + * test reassembly + * at time 1, gNB receives an SDU of 50 bytes + * sends 1st part, received by UE + * then sends 2nd part, not received + * then sends 3rd part, received + * then UE receives all + */ + +TIME, 1, + GNB_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + UE_AM, 100000, 100000, 45, 35, 0, -1, -1, 8, 18, + GNB_PDU_SIZE, 22, + GNB_SDU, 0, 50, +TIME, 2, + UE_RECV_FAILS, 1, +TIME, 3, + UE_RECV_FAILS, 0, +TIME, -1 diff --git a/openair2/LAYER2/nr_rlc/tests/test9.txt.gz b/openair2/LAYER2/nr_rlc/tests/test9.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..6def9c20f8dab3b8faa9284fc8cc24dc4201db2e Binary files /dev/null and b/openair2/LAYER2/nr_rlc/tests/test9.txt.gz differ diff --git a/openair2/NETWORK_DRIVER/MESH/common.c b/openair2/NETWORK_DRIVER/MESH/common.c index 493236cb30ab790de117d89519633ce052abaa4d..c5b46440dcf2f24e442a45ef4c4cd767db98d6db 100644 --- a/openair2/NETWORK_DRIVER/MESH/common.c +++ b/openair2/NETWORK_DRIVER/MESH/common.c @@ -407,7 +407,7 @@ void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct class if (bytes_wrote != NAS_PDCPH_SIZE) { printk("NAS_COMMON_QOS_SEND: problem while writing PDCP's header (bytes wrote = %d )\n",bytes_wrote); - printk("rb_id %d, Wrote %d, Header Size %lu\n", pdcph.rb_id , bytes_wrote, NAS_PDCPH_SIZE); + printk("rb_id %ld, Wrote %d, Header Size %lu\n", pdcph.rb_id , bytes_wrote, NAS_PDCPH_SIZE); #ifndef PDCP_USE_NETLINK rtf_reset(NAS2PDCP_FIFO); #endif //PDCP_USE_NETLINK @@ -421,7 +421,7 @@ void nas_COMMON_QOS_send(struct sk_buff *skb, struct cx_entity *cx, struct class #endif //PDCP_USE_NETLINK if (bytes_wrote != skb->len+NAS_PDCPH_SIZE) { - printk("NAS_COMMON_QOS_SEND: Inst %d, RB_ID %d: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %lu\n", + printk("NAS_COMMON_QOS_SEND: Inst %d, RB_ID %ld: problem while writing PDCP's data, bytes_wrote = %d, Data_len %d, PDCPH_SIZE %lu\n", inst, pdcph.rb_id, bytes_wrote, diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index ac855a46e643ae49df4ed9842eb698882f0f5f9e..54dba6862883011e13e702d380e56bc01c202477 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -68,7 +68,7 @@ mac_rrc_data_req( uint8_t sfn = (uint8_t)((frameP>>2)&0xff); if (LOG_DEBUGFLAG(DEBUG_RRC)) { - LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); + LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); } eNB_RRC_INST *rrc; @@ -167,7 +167,7 @@ mac_rrc_data_req( if (ue_context_p == NULL) return(0); eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; - LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d, rnti %x)\n",Mod_idP,frameP, Srb_id,rnti); + LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %ld, rnti %x)\n",Mod_idP,frameP, Srb_id,rnti); Srb_info=&ue_p->Srb0; // check if data is there for MAC @@ -182,7 +182,7 @@ mac_rrc_data_req( } if( (Srb_id & RAB_OFFSET ) == PCCH) { - LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id); + LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %ld)\n",Mod_idP,frameP, Srb_id); // check if data is there for MAC if(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] > 0) { //Fill buffer @@ -254,7 +254,7 @@ mac_rrc_data_ind( //-------------------------------------------------------------------------- { if (NODE_IS_DU(RC.rrc[module_idP]->node_type)) { - LOG_W(RRC,"[DU %d][RAPROC] Received SDU for CCCH on SRB %d length %d for UE id %d RNTI %x \n", + LOG_W(RRC,"[DU %d][RAPROC] Received SDU for CCCH on SRB %ld length %d for UE id %d RNTI %x \n", module_idP, srb_idP, sdu_lenP, UE_id, rntiP); /* do ITTI message */ DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER( @@ -279,7 +279,7 @@ mac_rrc_data_ind( PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0); if((srb_idP & RAB_OFFSET) == CCCH) { - LOG_D(RRC, "[eNB %d] Received SDU for CCCH on SRB %d\n", module_idP, srb_idP); + LOG_D(RRC, "[eNB %d] Received SDU for CCCH on SRB %ld\n", module_idP, srb_idP); ctxt.brOption = brOption; /*Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0; diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c index b5cc99bc3a78fa1fba0dfbb1d40ab9d15545f66c..20df462938f960f3f436d28c51bd97c8708c9e45 100644 --- a/openair2/RRC/LTE/L2_interface_common.c +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -123,10 +123,10 @@ rrc_data_ind( rb_id_t DCCH_index = Srb_id; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", + LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %ld message on SRB %ld with Size %d from eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); } else { - LOG_D(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n", + LOG_D(RRC, "[eNB %d] Frame %d: received a DCCH %ld message on SRB %ld with Size %d from UE %x\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index, diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index a8a0086a4d832b795f9a5e3c2ddf9f19ea9d28d3..c9d4e61d0ae7a19ff251dd8903c67cf3fb1d9e69 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -59,8 +59,8 @@ mac_rrc_data_req_ue( ) //-------------------------------------------------------------------------- { - LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); - LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id); + LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); + LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %ld\n",Mod_idP,frameP,Srb_id); LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); //TTN (for D2D) @@ -72,7 +72,7 @@ mac_rrc_data_req_ue( return(Ret_size); } - LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id); + LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %ld\n",Mod_idP,frameP,Srb_id); LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size); if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) { @@ -137,7 +137,7 @@ mac_rrc_data_ind_ue( PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, 0, rntiP, frameP, sub_frameP,eNB_indexP); if(srb_idP == BCCH_SI_MBMS) { - LOG_D(RRC,"[UE %d] Received SDU for BCCH on MBMS SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + LOG_D(RRC,"[UE %d] Received SDU for BCCH on MBMS SRB %ld from eNB %d\n",module_idP,srb_idP,eNB_indexP); #if defined(ENABLE_ITTI) { MessageDef *message_p; @@ -167,7 +167,7 @@ mac_rrc_data_ind_ue( } if(srb_idP == BCCH) { - LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %ld from eNB %d\n",module_idP,srb_idP,eNB_indexP); #if defined(ENABLE_ITTI) { MessageDef *message_p; @@ -197,13 +197,13 @@ mac_rrc_data_ind_ue( } if(srb_idP == PCCH) { - LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP); + LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %ld from eNB %d\n",module_idP,srb_idP,eNB_indexP); decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t *)sduP,sdu_lenP); } if((srb_idP & RAB_OFFSET) == CCCH) { if (sdu_lenP>0) { - LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); + LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %ld from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP); #if defined(ENABLE_ITTI) { MessageDef *message_p; @@ -237,7 +237,7 @@ mac_rrc_data_ind_ue( } if ((srb_idP & RAB_OFFSET) == MCCH) { - LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", + LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %ld from eNB %d\n", module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP); #if defined(ENABLE_ITTI) { @@ -266,7 +266,7 @@ mac_rrc_data_ind_ue( //TTN (for D2D) if(srb_idP == SL_DISCOVERY) { - LOG_I(RRC,"[UE %d] Received SDU (%d bytes) for SL_DISCOVERY on SRB %d from eNB %d\n",module_idP, sdu_lenP, srb_idP,eNB_indexP); + LOG_I(RRC,"[UE %d] Received SDU (%d bytes) for SL_DISCOVERY on SRB %ld from eNB %d\n",module_idP, sdu_lenP, srb_idP,eNB_indexP); decode_SL_Discovery_Message(&ctxt, eNB_indexP, sduP, sdu_lenP); } @@ -350,7 +350,7 @@ rrc_data_ind_ue( //------------------------------------------------------------------------------ { rb_id_t DCCH_index = Srb_id; - LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n", + LOG_I(RRC, "[UE %x] Frame %d: received a DCCH %ld message on SRB %ld with Size %d from eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP, ctxt_pP->eNB_index); #if defined(ENABLE_ITTI) { diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 17cef8112e79b34605954c5c80d4fd3cb9b074d8..66c4401e57c66238b25bd2214f4c2899312c9e4f 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -1307,7 +1307,7 @@ rrc_ue_process_radioResourceConfigDedicated( // configure the first DRB ID as the default DRB ID UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t)); *UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioResourceConfigDedicated->drb_ToAddModList->list.array[0]->drb_Identity; - LOG_I(RRC,"[UE %d] default DRB = %d\n",ctxt_pP->module_id, *UE_rrc_inst[ctxt_pP->module_id].defaultDRB); + LOG_I(RRC,"[UE %d] default DRB = %ld\n",ctxt_pP->module_id, *UE_rrc_inst[ctxt_pP->module_id].defaultDRB); } uint8_t *kUPenc = NULL; @@ -1889,7 +1889,7 @@ rrc_ue_decode_dcch( MessageDef *msg_p; if (Srb_id != 1) { - LOG_E(RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%d), should not have ...\n", + LOG_E(RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n", ctxt_pP->module_id, ctxt_pP->frame, Srb_id); return; } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 3751f2ddfb3a3d0ec3fd4c866c010d454e50f162..dbeaa9f6a548c2d329e5fbd4a9ece1c9f90c61c8 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4774,7 +4774,7 @@ check_handovers( GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).frame, 0, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).eNB_index); - LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + LOG_D(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %ld, muiP %d, confirmP %d, mode %d\n", PROTOCOL_CTXT_ARGS(&ctxt), ITTI_MSG_NAME (msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), @@ -4783,7 +4783,7 @@ check_handovers( GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode); - LOG_I(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id); + LOG_I(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %ld \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id); result = pdcp_data_req (&ctxt, SRB_FLAG_NO, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id, @@ -4842,7 +4842,7 @@ check_handovers( GTPV1U_ENB_END_MARKER_IND (msg_p).frame, 0, GTPV1U_ENB_END_MARKER_IND (msg_p).eNB_index); - LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + LOG_I(RRC, PROTOCOL_CTXT_FMT"[check_handovers]Received %s from %s: instance %d, rb_id %ld, muiP %d, confirmP %d, mode %d\n", PROTOCOL_CTXT_ARGS(&ctxt), ITTI_MSG_NAME (msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), @@ -4851,7 +4851,7 @@ check_handovers( GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).muip, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).confirmp, GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode); - LOG_D(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %d \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id); + LOG_D(RRC, "Before calling pdcp_data_req from check_handovers! GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id: %ld \n", GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).rb_id); result = pdcp_data_req (&ctxt, SRB_FLAG_NO, GTPV1U_ENB_END_MARKER_IND (msg_p).rb_id, @@ -7144,11 +7144,11 @@ rrc_eNB_decode_dcch( T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); if ((Srb_id != 1) && (Srb_id != 2)) { - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%d, should not have ...\n", + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%ld, should not have ...\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), Srb_id); } else { - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%d\n", + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%ld\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), Srb_id); } diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index d873a825ba9ee2661c5c88ec4dab6c876a4955cf..749dff3acedf0832f1a737e5382ad66dcdba601a 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -112,7 +112,7 @@ gtpv_data_req( LOG_I(GTPU,"gtpv_data_req sdu_sizeP == 0"); return FALSE; } - LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %d", ctxt_pP->rnti, sdu_sizeP, rb_idP); + LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %ld", ctxt_pP->rnti, sdu_sizeP, rb_idP); #if defined(ENABLE_ITTI) { MessageDef *message_p; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 00282c5dfa8f58531597a3c060448eba8a26398c..86cff69517f31df92d4fd9c65496cdf30c27f5f9 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -58,7 +58,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP, uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f); #ifdef DEBUG_RRC - LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); + LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); #endif gNB_RRC_INST *rrc; diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 78f0529512f0c2f59bc87b8fc1d5c114ede3a073..d9829a46dc48d03cf184c856004dfa85c95316f8 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -519,8 +519,6 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id, bwp_dl_searchspace->monitoringSymbolsWithinSlot->buf = MALLOC(2); bwp_dl_searchspace->nrofCandidates = CALLOC(1,sizeof(struct NR_SearchSpace__nrofCandidates)); bwp_dl_searchspace->searchSpaceType = CALLOC(1,sizeof(struct NR_SearchSpace__searchSpaceType)); - bwp_dl_searchspace->searchSpaceType->choice.common = CALLOC(1,sizeof(struct NR_SearchSpace__searchSpaceType__common)); - bwp_dl_searchspace->searchSpaceType->choice.ue_Specific = CALLOC(1,sizeof(struct NR_SearchSpace__searchSpaceType__ue_Specific)); bwp_dl_timedomainresourceallocation->k0 = CALLOC(1,sizeof(long)); pusch_configcommontimedomainresourceallocation = CALLOC(1,sizeof(NR_PUSCH_TimeDomainResourceAllocation_t)); pusch_configcommontimedomainresourceallocation->k2 = CALLOC(1,sizeof(long)); @@ -647,6 +645,7 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id, bwp_dl_searchspace->searchSpaceType->present = configuration->SearchSpace_searchSpaceType[CC_id]; if(bwp_dl_searchspace->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { + bwp_dl_searchspace->searchSpaceType->choice.common = CALLOC(1,sizeof(struct NR_SearchSpace__searchSpaceType__common)); bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0 = CALLOC(1,sizeof(struct NR_SearchSpace__searchSpaceType__common__dci_Format2_0)); bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel1 = CALLOC(1,sizeof(long)); bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_0->nrofCandidates_SFI.aggregationLevel2 = CALLOC(1,sizeof(long)); @@ -663,6 +662,7 @@ void do_SERVINGCELLCONFIGCOMMON(uint8_t Mod_id, *(bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->dummy1) = configuration->Common_dci_Format2_3_monitoringPeriodicity[CC_id]; bwp_dl_searchspace->searchSpaceType->choice.common->dci_Format2_3->dummy2 = configuration->Common_dci_Format2_3_nrofPDCCH_Candidates[CC_id]; } else if (bwp_dl_searchspace->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { + bwp_dl_searchspace->searchSpaceType->choice.ue_Specific = CALLOC(1,sizeof(struct NR_SearchSpace__searchSpaceType__ue_Specific)); bwp_dl_searchspace->searchSpaceType->choice.ue_Specific->dci_Formats = configuration->ue_Specific__dci_Formats[CC_id]; } diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index 10935ddf89f200ce6c7cec42e333f4bb1baac12d..c3154b708eda2581fff0093af7f7c13a70a52e7a 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -74,7 +74,7 @@ uint8_t do_MIB_NR(rrc_gNB_carrier_data_t *carrier, /** \brief Generate configuration for SIB1 (gNB). @param carrier pointer to Carrier information -@param configuration Pointer Configuration Request structure +@param configuration Pointer Configuration Request structure @return size of encoded bit stream in bytes*/ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier #if defined(ENABLE_ITTI) diff --git a/openair2/UTIL/FIFO/pad_list.c b/openair2/UTIL/FIFO/pad_list.c index e15041118d0f182492d34f596c829c988c0dd371..124893a756c5c9533378f34af8e56a64235209d4 100644 --- a/openair2/UTIL/FIFO/pad_list.c +++ b/openair2/UTIL/FIFO/pad_list.c @@ -591,7 +591,7 @@ void pkt_list_display (Packet_OTG_List_t *listP) { if (cursor) { while (cursor != NULL) { - printf ("Pkt (DST %d, RB %d)\n", (cursor->otg_pkt).dst_id, (cursor->otg_pkt).rb_id); + printf ("Pkt (DST %d, RB %ld)\n", (cursor->otg_pkt).dst_id, (cursor->otg_pkt).rb_id); //msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2); cursor = cursor->next; nb_elements++; diff --git a/openair2/UTIL/MEM/mem_block.h b/openair2/UTIL/MEM/mem_block.h index 4d8ed4e89bc9e881ca0a6a346a3f2d97f36e0b61..f40566f6ed2d8051e5cfb8bae9220f1f531e2bec 100644 --- a/openair2/UTIL/MEM/mem_block.h +++ b/openair2/UTIL/MEM/mem_block.h @@ -180,8 +180,6 @@ typedef struct { } mem_pool; -mem_pool *memBlockVar; -#define mem_block_var (*memBlockVar) #ifdef __cplusplus } diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 54c4153e46d753e1d1c27c95f7faa5dd5752e38a..f15f295548e9e4a474479f12501df1a99ad3ef75 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -831,7 +831,7 @@ int gtpv1u_delete_x2u_tunnel( if (hash_rc == HASH_TABLE_OK) { for (erab_index = 0; erab_index < ue_context_p->ue_context.nb_x2u_e_rabs; erab_index++) { eps_bearer_id = ue_context_p->ue_context.enb_gtp_x2u_ebi[erab_index]; - LOG_I(GTPU, "gtpv1u_delete_x2u_tunnel user rnti %x teNB X2U teid %u eps bearer id %u\n", + LOG_I(GTPU, "gtpv1u_delete_x2u_tunnel user rnti %x teNB X2U teid %u eps bearer id %ld\n", req_pP->rnti, gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_teNB, ue_context_p->ue_context.enb_gtp_x2u_ebi[erab_index]); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 10e591294b727eedac9e57b1e823e19a86cc8d3c..8cfa398615b3e27323d6cee4ae6ec87f64cf79f9 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -455,14 +455,14 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; - __m256i buff_tx[2][nsamps2]; + __m256i buff_tx[8][nsamps2]; #else nsamps2 = (nsamps+3)>>2; - __m128i buff_tx[2][nsamps2]; + __m128i buff_tx[8][nsamps2]; #endif #elif defined(__arm__) nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tx[2][nsamps2]; + int16x8_t buff_tx[8][nsamps2]; #else #error Unsupported CPU architecture, USRP device cannot be built #endif @@ -566,14 +566,14 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp #if defined(__x86_64) || defined(__i386__) #ifdef __AVX2__ nsamps2 = (nsamps+7)>>3; - __m256i buff_tmp[2][nsamps2]; + __m256i buff_tmp[8][nsamps2]; #else nsamps2 = (nsamps+3)>>2; - __m128i buff_tmp[2][nsamps2]; + __m128i buff_tmp[8][nsamps2]; #endif #elif defined(__arm__) nsamps2 = (nsamps+3)>>2; - int16x8_t buff_tmp[2][nsamps2]; + int16x8_t buff_tmp[8][nsamps2]; #endif if (device->type == USRP_B200_DEV) { diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 76d0ad667478d89899063a7f9676156d9af7981d..cfaa7b8f5353f0adad589e875e3b44fced9c9d5b 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -276,7 +276,7 @@ sin_addr: }; bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr)); AssertFatal(listen(t->listen_sock, 5) == 0, ""); - struct epoll_event ev; + struct epoll_event ev={0}; ev.events = EPOLLIN; ev.data.fd = t->listen_sock; AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, ""); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 2a2ebd45fda3da67c1ea99d875f7d44b907aa38a..b98adf5a95eebd1b02476d7bebac3f977c7991e0 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -246,15 +246,16 @@ L1s = ( RUs = ( { local_rf = "yes" - nb_tx = 1 - nb_rx = 1 - att_tx = 0 + nb_tx = 1; + nb_rx = 1; + att_tx = 0; att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,mgmt_addr=192.168.10.2,clock_source=external,time_source=external"; + + sdr_addrs = "addr=192.168.10.2,second_addr=192.168.20.2,clock_source=external,time_source=external"; } ); @@ -284,9 +285,9 @@ NETWORK_CONTROLLER : global_log_verbosity ="medium"; hw_log_level ="info"; hw_log_verbosity ="medium"; - phy_log_level ="debug"; + phy_log_level ="info"; phy_log_verbosity ="medium"; - mac_log_level ="debug"; + mac_log_level ="info"; mac_log_verbosity ="high"; rlc_log_level ="info"; rlc_log_verbosity ="medium"; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index a11bf9d515bfa11106f25ce5a2b2d3ae9652482e..420188b80e8d4d280263e0b52b7d54bd4b76813a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -70,7 +70,7 @@ gNBs = UL_BWP_prefix_type = "NORMAL"; UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" - ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; + ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01;##### ServingCellConfigCommon_ssb_periodicityServingCell = 10; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; @@ -246,7 +246,7 @@ L1s = ( RUs = ( { local_rf = "yes" - nb_tx = 1 + nb_tx = 1 nb_rx = 1 att_tx = 0 att_rx = 0; @@ -264,7 +264,7 @@ THREAD_STRUCT = ( #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" - worker_config = "WORKER_DISABLE"; + worker_config = "WORKER_ENABLE"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf index 73f2214baf684154dccf9d075de50d0165934f62..691224b8835a9c3da20dd71b8643477a90c95267 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf @@ -70,7 +70,7 @@ gNBs = UL_BWP_prefix_type = "NORMAL"; UL_timeAlignmentTimerCommon = "infinity"; ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" - ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x01; + ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x0ff; ServingCellConfigCommon_ssb_periodicityServingCell = 10; ServingCellConfigCommon_dmrs_TypeA_Position = 2; NIA_SubcarrierSpacing = "kHz15"; @@ -246,7 +246,7 @@ L1s = ( RUs = ( { local_rf = "yes" - nb_tx = 1 + nb_tx = 8 nb_rx = 1 att_tx = 0 att_rx = 0; @@ -264,7 +264,7 @@ THREAD_STRUCT = ( #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" - worker_config = "WORKER_DISABLE"; + worker_config = "WORKER_ENABLE"; } ); diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.beamw.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.beamw.usrpn300.conf new file mode 100644 index 0000000000000000000000000000000000000000..a9d251efa2dc5d826ad34bd00d81d333ea3ce0b7 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.beamw.usrpn300.conf @@ -0,0 +1,291 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_gNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + DL_prefix_type = "NORMAL"; + UL_prefix_type = "NORMAL"; + eutra_band = 78; + downlink_frequency = 3510000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 217; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 90; + rx_gain = 125; + MIB_subCarrierSpacingCommon = 30; + MIB_ssb_SubcarrierOffset = 0; + MIB_dmrs_TypeA_Position = 2; + pdcch_ConfigSIB1 = 0; + SIB1_frequencyOffsetSSB = "khz5"; + SIB1_ssb_PeriodicityServingCell = 5; + SIB1_ss_PBCH_BlockPower = -60; + absoluteFrequencySSB = 0; + DL_FreqBandIndicatorNR = 15; + DL_absoluteFrequencyPointA = 15; + DL_offsetToCarrier = 15; + DL_SCS_SubcarrierSpacing = "kHz30"; + DL_SCS_SpecificCarrier_k0 = 0; + DL_carrierBandwidth = 15; + DL_locationAndBandwidth = 15; + DL_BWP_SubcarrierSpacing = "kHz30"; + DL_BWP_prefix_type = "NORMAL"; + UL_FreqBandIndicatorNR = 15; + UL_absoluteFrequencyPointA = 13; + UL_additionalSpectrumEmission = 3; + UL_p_Max = -1; + UL_frequencyShift7p5khz = "TRUE"; + UL_offsetToCarrier = 10; + UL_SCS_SubcarrierSpacing = "kHz30"; + UL_SCS_SpecificCarrier_k0 = 0; + UL_carrierBandwidth = 15; + UL_locationAndBandwidth = 15; + UL_BWP_SubcarrierSpacing = "kHz30"; + UL_BWP_prefix_type = "NORMAL"; + UL_timeAlignmentTimerCommon = "infinity"; + ServingCellConfigCommon_n_TimingAdvanceOffset = "n0" + ServingCellConfigCommon_ssb_PositionsInBurst_PR = 0x03; + ServingCellConfigCommon_ssb_periodicityServingCell = 10; + ServingCellConfigCommon_dmrs_TypeA_Position = 2; + NIA_SubcarrierSpacing = "kHz15"; + ServingCellConfigCommon_ss_PBCH_BlockPower = -60; + referenceSubcarrierSpacing = "kHz15"; + dl_UL_TransmissionPeriodicity = "ms0p5"; + nrofDownlinkSlots = 10; + nrofDownlinkSymbols = 10; + nrofUplinkSlots = 10; + nrofUplinkSymbols = 10; + rach_totalNumberOfRA_Preambles = 63; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_choice = "oneEighth"; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneEighth = 4; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneFourth = 8; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_oneHalf = 16; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_one = 24; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_two = 32; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_four = 8; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_eight = 4; + rach_ssb_perRACH_OccasionAndCB_PreamblesPerSSB_sixteen = 2; + rach_groupBconfigured = "ENABLE"; + rach_ra_Msg3SizeGroupA = 56; + rach_messagePowerOffsetGroupB = "dB0"; + rach_numberOfRA_PreamblesGroupA = 32; + rach_ra_ContentionResolutionTimer = 8; + rsrp_ThresholdSSB = 64; + rsrp_ThresholdSSB_SUL = 64; + prach_RootSequenceIndex_choice = "l839"; + prach_RootSequenceIndex_l839 = 0; + prach_RootSequenceIndex_l139 = 0; + prach_msg1_SubcarrierSpacing = "kHz30"; + restrictedSetConfig = "unrestrictedSet"; + msg3_transformPrecoding = "ENABLE"; + prach_ConfigurationIndex = 10; + prach_msg1_FDM = "one"; + prach_msg1_FrequencyStart = 10; + zeroCorrelationZoneConfig = 10; + preambleReceivedTargetPower = -150; + preambleTransMax = 6; + powerRampingStep = "dB0"; + ra_ResponseWindow = 8; + groupHoppingEnabledTransformPrecoding = "ENABLE"; + msg3_DeltaPreamble = 0; + p0_NominalWithGrant = 0; + PUSCH_TimeDomainResourceAllocation_k2 = 0; + PUSCH_TimeDomainResourceAllocation_mappingType = "typeA"; + PUSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + pucch_ResourceCommon = 0; + pucch_GroupHopping = "neither"; + hoppingId = 0; + p0_nominal = -30; + PDSCH_TimeDomainResourceAllocation_k0 = 2; + PDSCH_TimeDomainResourceAllocation_mappingType = "typeA"; + PDSCH_TimeDomainResourceAllocation_startSymbolAndLength = 0; + rateMatchPatternId = 0; + RateMatchPattern_patternType = "bitmaps"; + symbolsInResourceBlock = "oneSlot"; + periodicityAndPattern = 2; + RateMatchPattern_controlResourceSet = 5; + RateMatchPattern_subcarrierSpacing = "kHz30"; + RateMatchPattern_mode = "dynamic"; + controlResourceSetZero = 0; + searchSpaceZero = 0; + searchSpaceSIB1 = 10; + searchSpaceOtherSystemInformation = 10; + pagingSearchSpace = 10; + ra_SearchSpace = 10; + PDCCH_common_controlResourceSetId = 5; + PDCCH_common_ControlResourceSet_duration = 2; + PDCCH_cce_REG_MappingType = "nonInterleaved"; + PDCCH_reg_BundleSize = 3; + PDCCH_interleaverSize = 3; + PDCCH_shiftIndex = 10; + PDCCH_precoderGranularity = "sameAsREG-bundle"; + PDCCH_TCI_StateId = 32; + tci_PresentInDCI = "ENABLE"; + PDCCH_DMRS_ScramblingID = 0; + SearchSpaceId = 10; + commonSearchSpaces_controlResourceSetId = 5; + SearchSpace_monitoringSlotPeriodicityAndOffset_choice = "sl1"; + SearchSpace_monitoringSlotPeriodicityAndOffset_value = 0; + SearchSpace_duration = 2; + SearchSpace_nrofCandidates_aggregationLevel1 = 0; + SearchSpace_nrofCandidates_aggregationLevel2 = 0; + SearchSpace_nrofCandidates_aggregationLevel4 = 0; + SearchSpace_nrofCandidates_aggregationLevel8 = 0; + SearchSpace_nrofCandidates_aggregationLevel16 = 0; + SearchSpace_searchSpaceType = "common"; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel1 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel2 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel4 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel8 = 1; + Common_dci_Format2_0_nrofCandidates_SFI_aggregationLevel16 = 1; + Common_dci_Format2_3_monitoringPeriodicity = 1; + Common_dci_Format2_3_nrofPDCCH_Candidates = 1; + ue_Specific__dci_Formats = "formats0-0-And-1-0"; + RateMatchPatternLTE_CRS_carrierFreqDL = 6; + RateMatchPatternLTE_CRS_carrierBandwidthDL = 6; + RateMatchPatternLTE_CRS_nrofCRS_Ports = 1; + RateMatchPatternLTE_CRS_v_Shift = 0; + RateMatchPatternLTE_CRS_radioframeAllocationPeriod = 1; + RateMatchPatternLTE_CRS_radioframeAllocationOffset = 0; + RateMatchPatternLTE_CRS_subframeAllocation_choice = "oneFrame"; + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 2 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + sdr_addrs = "addr=192.168.10.2"; + # beamforming weights for static beams each of them is a int32 composed by two int16 representing imaginary and real part of the weight + # weights are input in an array, starting with the weights associated to first logical beam for all nb_tx , than the weights for 2nd logical beam and so on + # the list size is (nb_tx) X (number of logical beams) + bf_weights = [0x00007fff, 0x00000000, 0x00000000, 0x00007fff]; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/RT/USER/gNB_usrp.gtkw b/targets/RT/USER/gNB_usrp.gtkw index 069d1765a95358b9f4875addcac6bb9277a712e4..416dd3b62ba48806e7df7fdf43f1dd6d265ae09d 100644 --- a/targets/RT/USER/gNB_usrp.gtkw +++ b/targets/RT/USER/gNB_usrp.gtkw @@ -1,19 +1,19 @@ [*] -[*] GTKWave Analyzer v3.3.61 (w)1999-2014 BSI -[*] Sat May 18 17:25:11 2019 +[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI +[*] Fri Sep 6 15:01:30 2019 [*] -[dumpfile] "/tmp/openair_dump_gNB40.vcd" -[dumpfile_mtime] "Sat May 18 17:11:31 2019" -[dumpfile_size] 53148516 -[savefile] "/home/caracal/raymond/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw" -[timestart] 11552775390 -[size] 1840 795 +[dumpfile] "/tmp/gNB_prec.vcd" +[dumpfile_mtime] "Fri Sep 6 14:59:50 2019" +[dumpfile_size] 13106022 +[savefile] "/homes/wangts/openairinterface5g/targets/RT/USER/gNB_usrp.gtkw" +[timestart] 2183320000 +[size] 1920 1018 [pos] -1 -1 -*-13.848083 11552814436 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +*-18.423141 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [sst_width] 386 [signals_width] 344 [sst_expanded] 1 -[sst_vpaned_height] 197 +[sst_vpaned_height] 267 @28 functions.trx_read functions.trx_write @@ -24,9 +24,8 @@ variables.frame_number_TX1_UE[63:0] functions.ue_gain_control @420 variables.frame_number_RX1_UE[63:0] -@25 -variables.trx_ts_ue[63:0] @24 +variables.trx_ts_ue[63:0] variables.trx_ts[63:0] variables.trx_tst[63:0] variables.frame_number_RX0_RU[63:0] @@ -63,5 +62,7 @@ functions.phy_procedures_ru_feptx_ofdm0 functions.phy_procedures_ru_feptx_ofdm1 functions.phy_procedures_ru_feptx_prec0 functions.phy_procedures_ru_feptx_prec1 +@23 +variables.ru_tx_ofdm_mask[63:0] [pattern_trace] 1 [pattern_trace] 0 diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index dea8c7a2b521399e1af66ac7f60a25566879d7e9..af96fa68dc998f59171e2d79a8475252388240d7 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -81,6 +81,7 @@ /* these variables have to be defined before including ENB_APP/enb_paramdef.h */ static int DEFBANDS[] = {7}; static int DEFENBS[] = {0}; +static int DEFBFW[] = {0x00007fff}; #include "ENB_APP/enb_paramdef.h" #include "common/config/config_userapi.h" diff --git a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c index 9f28fd7c78a6c3182fec9f763676e2e68ecd6dac..378ee95c3bea10fbf8b4a019fb788dd4208184fa 100644 --- a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c +++ b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c @@ -226,7 +226,7 @@ int main(int argc, char **argv) mac_xface = malloc(sizeof(MAC_xface)); Mac_rlc_xface = (MAC_RLC_XFACE*)malloc16(sizeof(MAC_RLC_XFACE)); - rlc_module_init (); + rlc_module_init (1); pdcp_module_init(); logInit();