diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index ef2637965f..72fa29aa39 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 b1d2346392..237a1a5d5e 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 ce40134cec..fb9dc9ad76 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 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 9e69145a8f..ded67443bc 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/ci-scripts/xml_files/simple_dummy_build.xml b/ci-scripts/xml_files/simple_dummy_build.xml new file mode 100644 index 0000000000..75e5f6339a --- /dev/null +++ b/ci-scripts/xml_files/simple_dummy_build.xml @@ -0,0 +1,41 @@ + + + build-tab + Build + wrench + + 010101 + + + + + + Build_eNB + Build Master eNB (USRP) + -w USRP -c --eNB + 0 + 0 + + + diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 35f24d0925..2a040922af 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1483,15 +1483,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 @@ -1519,6 +1512,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 @@ -1529,7 +1545,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 @@ -1548,40 +1569,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 @@ -1589,37 +1583,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 @@ -1707,6 +1675,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} @@ -2359,7 +2331,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) @@ -2431,7 +2403,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) @@ -2774,7 +2746,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_COMMON 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 a407171d01..6795f2d1fa 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 $OPENAIR_DIR/cmake_targets/build_oai @@ -1105,7 +1105,7 @@ -n100 -R106 -a51 -n100 -R217 -b100 -n100 -R217 -a80 - -n100 -R217 -a80 -b100 + -n100 -R217 -a110 -b100 -n100 -e28 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 diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index e14f28f829..56c3c0951f 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 6bad041641..7f177b90ce 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 7ea15cf9db..63c5336bd8 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 a7c4c10fe3..3a6fb6d6ab 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 4f2b10c3ae..ab275d4d62 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 0b10b6e25e..407bb66be1 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 50c2ec8324..e9641f8e0c 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; nsize; ++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 3f770684fa..09f8623ce2 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 7d4d517ec3..732534ad68 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;inum_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 c73142cd46..0b96f3c9c8 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}; @@ -313,7 +314,6 @@ void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); - if ((nr_slot_select(ru->nr_frame_parms,ru->proc.frame_tx,ru->proc.tti_tx)&NR_DOWNLINK_SLOT) > 0) send_IF4p5(ru,frame, slot, IF4p5_PDLFFT); } @@ -671,9 +671,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, @@ -759,6 +756,7 @@ void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { flags = 4; // start of burst and end of burst (only one DL SF between two UL) sf_extension = ru->N_TA_offset<<1; } */ + 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 ); @@ -783,6 +781,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 @@ -869,7 +868,7 @@ 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; } @@ -1206,14 +1205,20 @@ 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); } @@ -1270,7 +1275,7 @@ 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) { @@ -1281,8 +1286,17 @@ void *ru_thread_tx( void *param ) { } else { if(proc->frame_tx == print_frame) { for (i=0; inb_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); @@ -1335,14 +1349,14 @@ 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); } } } @@ -1504,7 +1518,7 @@ 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) { @@ -1643,6 +1657,7 @@ int stop_rf(RU_t *ru) { return 0; } + void init_RU_proc(RU_t *ru) { int i=0; RU_proc_t *proc; @@ -1665,6 +1680,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; @@ -2022,9 +2038,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 @@ -2052,8 +2068,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 @@ -2077,7 +2093,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 @@ -2320,6 +2336,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; inum_gNB; i++) { + RC.ru[j]->bw_list[i] = (int32_t *)malloc16_clear((RC.ru[j]->nb_bfw)*sizeof(int32_t)); + for (int b=0; bnb_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 b457c7cc9a..7654a6771c 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -920,6 +920,9 @@ init_opt(); #endif LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); + if(IS_SOFTMODEM_NOS1) + init_pdcp(); + if (RC.nb_nr_inst > 0) { // don't create if node doesn't connect to RRC/S1/GTP @@ -940,9 +943,6 @@ init_opt(); } */ - 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 667a6bb192..9e7ce3c217 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 9bfb76ddc8..7e2ffebb35 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -521,14 +521,23 @@ void init_openair0(void) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=92.16e6; openair0_cfg[card].samples_per_frame = 921600; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; } else { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; + } + } else { + LOG_E(PHY,"Unsupported numerology!\n"); + exit(-1); + } + }else if(frame_parms[0]->N_RB_DL == 273) { + if (numerology==1) { + if (frame_parms[0]->threequarter_fs) { + AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); + } + else { + openair0_cfg[card].sample_rate=122.88e6; + openair0_cfg[card].samples_per_frame = 1228800; } } else { LOG_E(PHY,"Unsupported numerology!\n"); @@ -539,32 +548,22 @@ void init_openair0(void) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=23.04e6; openair0_cfg[card].samples_per_frame = 230400; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; } else { openair0_cfg[card].sample_rate=30.72e6; openair0_cfg[card].samples_per_frame = 307200; - openair0_cfg[card].tx_bw = 10e6; - openair0_cfg[card].rx_bw = 10e6; } } else if (numerology==1) { if (frame_parms[0]->threequarter_fs) { openair0_cfg[card].sample_rate=46.08e6; openair0_cfg[card].samples_per_frame = 480800; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; } else { openair0_cfg[card].sample_rate=61.44e6; openair0_cfg[card].samples_per_frame = 614400; - openair0_cfg[card].tx_bw = 20e6; - openair0_cfg[card].rx_bw = 20e6; } } else if (numerology==2) { openair0_cfg[card].sample_rate=122.88e6; openair0_cfg[card].samples_per_frame = 1228800; - openair0_cfg[card].tx_bw = 40e6; - openair0_cfg[card].rx_bw = 40e6; } else { LOG_E(PHY,"Unsupported numerology!\n"); exit(-1); @@ -572,18 +571,12 @@ void init_openair0(void) { } else if(frame_parms[0]->N_RB_DL == 50) { openair0_cfg[card].sample_rate=15.36e6; openair0_cfg[card].samples_per_frame = 153600; - openair0_cfg[card].tx_bw = 5e6; - openair0_cfg[card].rx_bw = 5e6; } else if (frame_parms[0]->N_RB_DL == 25) { openair0_cfg[card].sample_rate=7.68e6; openair0_cfg[card].samples_per_frame = 76800; - openair0_cfg[card].tx_bw = 2.5e6; - openair0_cfg[card].rx_bw = 2.5e6; } else if (frame_parms[0]->N_RB_DL == 6) { openair0_cfg[card].sample_rate=1.92e6; openair0_cfg[card].samples_per_frame = 19200; - openair0_cfg[card].tx_bw = 1.5e6; - openair0_cfg[card].rx_bw = 1.5e6; } else { LOG_E(PHY,"Unknown NB_RB %d!\n",frame_parms[0]->N_RB_DL); @@ -671,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 73305e3586..bd3ed77785 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, @@ -104,37 +108,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; ibeam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); - for (j=0; jnb_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; reofdm_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; reofdm_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 (pnb_tx>1) { + for (p=0;pLmax;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; iLmax;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; jnb_tx; j++) { + ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); + for (re=0; reofdm_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); @@ -161,6 +161,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); @@ -175,10 +179,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; jnb_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 816998d904..3e3b597065 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -80,31 +80,6 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb) return symbol; } -int nr_is_ssb_slot(uint8_t n_hf, uint8_t period, int slot) -{ - - - int rel_slot; - - // if SSB periodicity is 5ms, they are transmitted in both half frames - if ( period == 0) { - if (slot<10) - n_hf=0; - else - n_hf=1; - } - - // 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-10) : slot; - - if(rel_slot<10 && rel_slot>=0) - return 1; - else - return 0; - -} - - int nr_init_frame_parms0(NR_DL_FRAME_PARMS *fp, int mu, int Ncp, @@ -264,15 +239,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; pLmax; p++) + fp->N_ssb += ((fp->L_ssb >> p) & 0x01); return 0; } diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index d2b614633b..f0a1abe0ac 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -378,7 +378,6 @@ void phy_config_request(PHY_Config_t *phy_config); int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf); void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms); int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp, uint8_t i_ssb); -int nr_is_ssb_slot(uint8_t n_hf, uint8_t period, int slot); int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms); int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms,int mu,int Ncp,int N_RB_DL,int n_ssb_crb,int ssb_subcarrier_offset); int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag); diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index ab3271c61c..79e220ac37 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; pL_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 8a6abd5de5..706b4dc113 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 b23fd2e2bf..cbeeca1327 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 89321f637b..16fc94a59f 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 9a1b5d4431..24f8bc7267 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -89,6 +89,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, uint8_t Qm = rel15->qamModOrder[0]; 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); @@ -199,10 +200,9 @@ for (int i=0; i>4; i++) { start_sc -= frame_parms->ofdm_symbol_size; #ifdef DEBUG_DLSCH_MAPPING - printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n", - start_sc, rel15->StartSymbolIndex, rel15->rbSize, rel15->NrOfSymbols); + printf("PDSCH resource mapping started (start SC %d\tstart symbol %d\tN_PRB %d\tnb_symbols %d)\n", + start_sc, rel15->StartSymbolIndex, rel15->rbSize, rel15->NrOfSymbols); #endif - for (int ap=0; apnrOfLayers; ap++) { // DMRS params for this ap @@ -212,11 +212,13 @@ for (int i=0; i>4; i++) { l_prime[0] = 0; // single symbol ap 0 uint8_t dmrs_symbol = l0+l_prime[0]; #ifdef DEBUG_DLSCH_MAPPING -printf("DMRS params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", -ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); + printf("DMRS params for ap %d: Wt %d %d \t Wf %d %d \t delta %d \t l_prime %d \t l0 %d\tDMRS symbol %d\n", + 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->rbStart*6; else @@ -226,12 +228,12 @@ ap, Wt[0], Wt[1], Wf[0], Wf[1], delta, l_prime[0], l0, dmrs_symbol); k = start_sc; for (int i=0; irbSize*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]); + 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) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif dmrs_idx++; k_prime++; @@ -241,12 +243,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]); + 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) + (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 4942ffe2f4..dc7489ea51 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 6e991faf37..db0c601b25 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 //#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 6ab6a73866..aaa304ec63 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -205,9 +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; + //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]; @@ -873,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 737cbb4ec1..02390aedea 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -47,7 +47,16 @@ //#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 +//#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) @@ -131,9 +140,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); @@ -142,11 +149,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++; @@ -164,13 +169,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++) { @@ -181,9 +184,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++; } @@ -204,7 +205,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); } @@ -327,43 +328,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 @@ -381,9 +372,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; @@ -396,40 +385,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 } @@ -437,30 +418,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]; @@ -468,7 +443,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++) { @@ -494,10 +469,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)) { @@ -532,21 +505,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 } } @@ -655,15 +624,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; @@ -792,11 +759,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 @@ -812,9 +777,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++) { @@ -823,22 +786,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, @@ -849,10 +808,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, @@ -871,10 +828,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, @@ -892,17 +847,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, @@ -920,9 +871,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, @@ -939,12 +888,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 @@ -1003,22 +948,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){ @@ -1032,16 +975,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]); } } @@ -1087,19 +1026,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++) { @@ -1113,9 +1048,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, @@ -1169,9 +1102,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) { @@ -1208,9 +1139,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 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; @@ -1280,9 +1201,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 @@ -1295,15 +1214,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++){ @@ -1328,7 +1243,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}; @@ -1339,17 +1254,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; @@ -1417,10 +1328,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; @@ -1429,31 +1338,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); } } } @@ -1581,9 +1488,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 @@ -1625,7 +1530,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); @@ -2050,9 +1955,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: @@ -2521,7 +2424,7 @@ uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, for (int i=0 ; i i=%d, j=%d\n", i, j); + // LOG_DDD("i=%d, j=%d\n", i, j); //#endif for (int j=0; jframe_parms, nr_tti_rx); -#ifdef NR_PDCCH_DCI_DEBUG - printf("\t<-NR_PDCCH_DCI_DEBUG (nr_dci_decoding_procedure)-> searSpaceType=%d\n",do_common); + LOG_DD("searSpaceType=%d\n",do_common); + LOG_DD("%s_dci_format=%d\n",do_common?"uss":"css",css_dci_format); - 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); - } - -#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 @@ -2736,18 +2622,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<current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2775,16 +2657,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<current_thread_id[nr_tti_rx], frame_parms, @@ -2809,16 +2687,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<current_thread_id[nr_tti_rx], frame_parms, @@ -2843,16 +2717,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<current_thread_id[nr_tti_rx], frame_parms, @@ -2877,16 +2747,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<current_thread_id[nr_tti_rx], frame_parms, @@ -2912,18 +2778,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<current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2947,18 +2809,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<current_thread_id[nr_tti_rx], frame_parms, crc_scrambled_values, aggregationLevel, @@ -2981,12 +2839,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 947483e8f0..88e1884c12 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 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>i)&1)<<(dci_fields_sizes[dci_field]-i-1);*/ - return ((uint16_t)(*dci_pdu>>first_bit_position)&((1< (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> (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; iDCINdi; + for (int i=0; iDCINdi; + + /* + * 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 dci_fields_sizes[%d][%d] = %d\n",dci_field,dci_format,dci_fields_sizes[dci_field][dci_format]); - #endif + 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])); - #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; + 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; + 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 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 } - 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; + 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 - } - 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 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 } - 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) + 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 * - */ - /* - * 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); - } + * + 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]; + } - }*/ - #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 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 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; - } - 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; + 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 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 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; - 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 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) + 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,40 +981,38 @@ 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))); AssertFatal(1==0,"Not ready for this ...\n"); if (frame_parms->frame_type == FDD) { - + ret = (((frame<<1)+nr_tti_rx)&7); } else { - } + if (ret == 255) { 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; AssertFatal(1==0,"Not ready for this\n"); } -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; + AssertFatal(1==0,"Not ready for this\n"); } - diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 12aaebc917..d2dbd6fef2 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 80d63cbdd9..0ec04dd537 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 539539eb89..baf5915dad 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -332,6 +332,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 150b0c194f..e74b9a312f 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/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index 3ebef0f227..36f020ec9a 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -56,158 +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; aanb_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; - RU_proc_t *proc = &ru->proc; - struct timespec wait; + + RU_proc_t *proc = &ru->proc; + RU_feptx_t *feptx = proc->feptx; + + PHY_VARS_gNB *gNB; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + int slot = tti_tx; - wait.tv_sec=0; - wait.tv_nsec=5000000L; - - start_meas(&ru->ofdm_mod_stats); + 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(fp,frame_tx,slot) == NR_UPLINK_SLOT) return; - - // this copy should be done in the precoding thread (currently inactive) - for (int aa=0;aanb_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)); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 ); - - if (nr_slot_select(fp,frame_tx,slot)==NR_DOWNLINK_SLOT) { - // 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 (aa=0; aaLmax; aa++) { + memset(ru->common.txdataF[aa],0,fp->samples_per_slot_wCP*sizeof(int32_t)); } - // 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"); + start_meas(&ru->ofdm_total_stats); + AssertFatal(ru->num_gNB == 1, "ru->num_gNB = %d != 1\n",ru->num_gNB); + for(j=0; jsymbols_per_slot; ++j){ + + 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]; + + for(i=0; icommon.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(fp,frame_tx,slot)==NR_DOWNLINK_SLOT) { + // If this is not an S-tti + for(i=0; inb_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; + } + }//jsymbols_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); + + 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 ); - nr_feptx0(ru,slot,ru->nr_frame_parms->symbols_per_slot>>1,ru->nr_frame_parms->symbols_per_slot>>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; - 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; + + 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) { + for (int p=0; pLmax; 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); + + + 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) @@ -222,21 +300,15 @@ 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(fp,frame_tx,slot) == NR_UPLINK_SLOT) 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;aanb_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(fp,frame_tx,slot)==NR_DOWNLINK_SLOT)|| - ((nr_slot_select(fp,frame_tx,slot)==NR_MIXED_SLOT))) { // 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); @@ -247,14 +319,79 @@ void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx) { } -/* - // PRACH component - int frame=ru->proc.frame_rx, slot=ru->proc.tti_rx; - - if (do_prach_rx(ru->nr_frame_parms,frame,slot)) rx_nr_prach_ru(ru, - frame, - slot/ru->nr_frame_parms->slots_per_subframe); -*/ +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_tx,int tti_tx) { + + int l,aa; + PHY_VARS_gNB **gNB_list = ru->gNB_list,*gNB; + NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + int32_t ***bw; + int i=0; + int slot_tx = tti_tx; + + start_meas(&ru->precoding_stats); + if (ru->num_gNB == 1){ + gNB = gNB_list[0]; + + if (nr_slot_select(fp,frame_tx,slot_tx) == NR_UPLINK_SLOT) return; + + for(i=0; iLmax; ++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; pLmax; 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;lsymbols_per_slot;l++) { + for (aa=0;aanb_tx;aa++) { + nr_beam_precoding(ru->common.txdataF, + ru->common.txdataF_BF, + fp, + bw, + tti_tx, + l, + aa, + fp->Lmax); + }// for (aa=0;aanb_tx;aa++) + }// for (l=0;lsymbols_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 6b05771a6a..0168c21e5c 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -95,19 +95,21 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) { int **txdataF = gNB->common_vars.txdataF; 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 = fp->half_frame_bit; // if SSB periodicity is 5ms, they are transmitted in both half frames if ( cfg->ssb_table.ssb_period.value == 0) { - if (slot<10) + if (slotgNB_config; int offset = gNB->CC_id; uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated + int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP; @@ -166,8 +169,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; aaLmax; 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); @@ -178,6 +181,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_COMMON_TX,0); + LOG_D(PHY, "[gNB %d] Frame %d slot %d \ Calling nr_generate_dci_top (number of DCI %d)\n", gNB->Mod_id, frame, slot, gNB->pdcch_pdu->pdcch_pdu_rel15.numDlDci); @@ -369,7 +373,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 a33e0e4612..5f54539b71 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 910718e081..5a3d14ca02 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -213,17 +213,41 @@ 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){ - LOG_I(MAC,"[L1][IF module][PHY CONFIG]\n"); - LOG_I(MAC,"subcarrier spacing: %d\n", phy_config->config_req.rf_config.dl_subcarrierspacing); - LOG_I(MAC,"ssb carrier offset: %d\n", phy_config->config_req.sch_config.ssb_subcarrier_offset); - LOG_I(MAC,"dmrs TypeA Position: %d\n", phy_config->config_req.pdsch_config.dmrs_TypeA_Position); - LOG_I(MAC,"controlResourceSetZero: %d\n", phy_config->config_req.pdcch_config.controlResourceSetZero); - LOG_I(MAC,"searchSapceZero: %d\n", phy_config->config_req.pdcch_config.searchSpaceZero); - - LOG_I(MAC,"-------------------------------\n"); + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_PBCH){ + LOG_I(MAC,"[L1][IF module][PHY CONFIG]\n"); + LOG_I(MAC,"subcarrier spacing: %d\n", phy_config->config_req.pbch_config.subcarrier_spacing_common); + LOG_I(MAC,"ssb carrier offset: %d\n", phy_config->config_req.pbch_config.ssb_subcarrier_offset); + LOG_I(MAC,"dmrs type A position: %d\n", phy_config->config_req.pbch_config.dmrs_type_a_position); + LOG_I(MAC,"pdcch config sib1: %d\n", phy_config->config_req.pbch_config.pdcch_config_sib1); + LOG_I(MAC,"cell barred: %d\n", phy_config->config_req.pbch_config.cell_barred); + LOG_I(MAC,"intra frequency reselection: %d\n", phy_config->config_req.pbch_config.intra_frequency_reselection); + LOG_I(MAC,"system frame number: %d\n", phy_config->config_req.pbch_config.system_frame_number); + LOG_I(MAC,"ssb index: %d\n", phy_config->config_req.pbch_config.ssb_index); + 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)); + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_COMMON){ + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_COMMON){ + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_DEDICATED){ + + } + + if(phy_config->config_req.config_mask & FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_DEDICATED){ + + } } diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 2ee22fee2a..00f47d52d8 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -115,7 +115,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, @@ -681,24 +681,27 @@ 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; aaframe_parms.nb_antennas_tx; aa++) { + if (cyclic_prefix_type == 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 21a59b25e2..94c7740eef 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -149,7 +149,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){} @@ -180,7 +180,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; @@ -442,7 +442,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)); @@ -476,7 +476,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 4f81c22fb0..054f3f3734 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 c90490b0fd..1551e4283f 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 977f44a310..49c1b340a6 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 106a9f297e..0fedc04abd 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_config.c b/openair2/GNB_APP/gnb_config.c index 6dba9633c8..bbc13ad6d1 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -639,6 +639,7 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { // Parse optional physical parameters sprintf(gnbpath,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k), + printf("SSB SCO %d\n",ssb_SubcarrierOffset); NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = ssb_SubcarrierOffset; NRRRC_CONFIGURATION_REQ (msg_p).scc = scc; diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 1386c6d646..67dbeca2e7 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 b1e1fb5d73..04757dab16 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 8c90118609..5355a614a6 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 8fb8d44e0a..4e139dcf92 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 f482806e1d..e8b0593717 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 0240be5a18..76077aaeaa 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 c96acccf9b..0478a6b7d5 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 5834dac0d6..b428eb2f1c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -362,6 +362,7 @@ int8_t nr_ue_decode_mib( AssertFatal(num_symbols != -1, "Type0 PDCCH coreset num_symbols undefined"); AssertFatal(rb_offset != -1, "Type0 PDCCH coreset rb_offset undefined"); + //uint32_t cell_id = 0; // obtain from L1 later //mac->type0_pdcch_dci_config.coreset.rb_start = rb_offset; @@ -462,7 +463,6 @@ int8_t nr_ue_decode_mib( break; default: break; } - }else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){ // 38.213 Table 13-14 AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index d270f7e8c9..6b6f738f2f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -326,10 +326,15 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, start_meas(&RC.nrmac[module_idP]->eNB_scheduler); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN); + + // Check if there are downlink symbols in the slot, if not return, no scheduling opportunities + if (is_nr_DL_slot(cc,slot_txP)==0) return; + RC.nrmac[module_idP]->frame = frame_rxP; RC.nrmac[module_idP]->slot = slot_rxP; + memset(RC.nrmac[module_idP]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int)); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { //mbsfn_status[CC_id] = 0; @@ -339,7 +344,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, clear_nr_nfapi_information(RC.nrmac[module_idP], CC_id, frame_txP, slot_txP); } - memset(RC.nrmac[module_idP]->cce_list[0][0],0,sizeof(int)*MAX_NUM_CCE); // refresh UE list based on UEs dropped by PHY in previous subframe /* @@ -367,7 +371,8 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // Phytest scheduling/ option not activated because of pending bug // Phytest scheduling - + + if (slot_rxP==2){ nr_schedule_uss_ulsch_phytest(module_idP, frame_rxP, slot_rxP); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index d3e7da5a87..e54de70352 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -357,8 +357,11 @@ int configure_fapi_dl_Tx(int Mod_idP, dci_pdu_rel15[0].pucch_resource_indicator = 7; dci_pdu_rel15[0].pdsch_to_harq_feedback_timing_indicator = 7; - LOG_I(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d, time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", + LOG_I(MAC, "[gNB scheduler phytest] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d ndi %d rv %d\n", dci_pdu_rel15[0].frequency_domain_assignment, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275), dci_pdu_rel15[0].time_domain_assignment, dci_pdu_rel15[0].vrb_to_prb_mapping, dci_pdu_rel15[0].mcs, @@ -428,11 +431,14 @@ int configure_fapi_dl_Tx(int Mod_idP, return TBS/8; //Return TBS in bytes } -void config_uldci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types) { +void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types) { + + dci_pdu_rel15->frequency_domain_assignment = PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_start, + pusch_pdu->rb_size, + NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); - dci_pdu_rel15->frequency_domain_assignment = 0; // PRBalloc_to_locationandbandwidth0(0,50,NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275)); // to be changed with UL bwp dci_pdu_rel15->time_domain_assignment = 2; // row index used here instead of SLIV; - dci_pdu_rel15->frequency_hopping_flag = 1; + dci_pdu_rel15->frequency_hopping_flag = 0; dci_pdu_rel15->mcs = 9; dci_pdu_rel15->format_indicator = 0; @@ -441,14 +447,15 @@ void config_uldci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_re dci_pdu_rel15->harq_pid = 0; dci_pdu_rel15->tpc = 2; - LOG_I(MAC, "[gNB scheduler phytest] DCI type 0 payload: freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", - dci_pdu_rel15->frequency_domain_assignment, - dci_pdu_rel15->time_domain_assignment, - dci_pdu_rel15->frequency_hopping_flag, - dci_pdu_rel15->mcs, - dci_pdu_rel15->tpc, - dci_pdu_rel15->ndi, - dci_pdu_rel15->rv); + LOG_I(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", + pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci], + dci_pdu_rel15->frequency_domain_assignment, + dci_pdu_rel15->time_domain_assignment, + dci_pdu_rel15->frequency_hopping_flag, + dci_pdu_rel15->mcs, + dci_pdu_rel15->tpc, + dci_pdu_rel15->ndi, + dci_pdu_rel15->rv); dci_formats[pdcch_pdu_rel15->numDlDci] = NR_UL_DCI_FORMAT_0_0; rnti_types[pdcch_pdu_rel15->numDlDci] = NR_RNTI_C; @@ -656,11 +663,12 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, 1, // search_space, 0 common, 1 ue-specific UE_id, 0); // m + AssertFatal(CCEIndex>=0,"CCEIndex is negative\n"); if (CCEIndex == -1) return; int CCEIndices[2]; CCEIndices[0] = CCEIndex; - + LOG_I(MAC,"Configuring DL_TX in %d.%d\n",frameP,slotP); TBS_bytes = configure_fapi_dl_Tx(module_idP,CCEIndices,dl_req, TX_req); // HOT FIX for all zero pdu problem // ------------------------------------------------------------------------------------------------ @@ -711,8 +719,8 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]; NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; - nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0]; @@ -720,85 +728,85 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, uint16_t rnti = UE_list->rnti[UE_id]; nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu; - for (uint8_t CC_id=0; CC_idUL_tti_req[CC_id]; - UL_tti_req->SFN = frameP; - UL_tti_req->Slot = slotP; - UL_tti_req->n_pdus = 1; - UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; - UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); - nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; - memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); - /* - // original configuration - rel15_ul->rnti = 0x1234; - rel15_ul->ulsch_pdu_rel15.start_rb = 30; - rel15_ul->ulsch_pdu_rel15.number_rbs = 50; - rel15_ul->ulsch_pdu_rel15.start_symbol = 2; - rel15_ul->ulsch_pdu_rel15.number_symbols = 12; - rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; - rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; - rel15_ul->ulsch_pdu_rel15.Qm = 2; - rel15_ul->ulsch_pdu_rel15.mcs = 9; - rel15_ul->ulsch_pdu_rel15.rv = 0; - rel15_ul->ulsch_pdu_rel15.n_layers = 1; - */ - pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - pusch_pdu->rnti = rnti; - pusch_pdu->handle = 0; //not yet used - //BWP related paramters - we don't yet use them as the PHY only uses one default BWP - //pusch_pdu->bwp_size; - //pusch_pdu->bwp_start; - //pusch_pdu->subcarrier_spacing; - //pusch_pdu->cyclic_prefix; - //pusch information always include - //this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined. - pusch_pdu->mcs_index = 9; - pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY - pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; - pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; - pusch_pdu->transform_precoding = 0; - pusch_pdu->data_scrambling_id = 0; //It equals the higher-layer parameter Data-scrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id.; - pusch_pdu->nrOfLayers = 1; - //DMRS - pusch_pdu->ul_dmrs_symb_pos = 1; - pusch_pdu->dmrs_config_type = 0; //dmrs-type 1 (the one with a single DMRS symbol in the beginning) - pusch_pdu->ul_dmrs_scrambling_id = 0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. - pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. - //pusch_pdu->num_dmrs_cdm_grps_no_data; - //pusch_pdu->dmrs_ports; //DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used - //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] - pusch_pdu->resource_alloc = 1; //type 1 - //pusch_pdu->rb_bitmap;// for ressource alloc type 0 - pusch_pdu->rb_start = 0; - pusch_pdu->rb_size = 50; - pusch_pdu->vrb_to_prb_mapping = 0; - pusch_pdu->frequency_hopping = 0; - //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] - pusch_pdu->uplink_frequency_shift_7p5khz = 0; - //Resource Allocation in time domain - pusch_pdu->start_symbol_index = 2; - pusch_pdu->nr_of_symbols = 12; - //Optional Data only included if indicated in pduBitmap - pusch_pdu->pusch_data.rv_index = 0; - pusch_pdu->pusch_data.harq_process_id = 0; - pusch_pdu->pusch_data.new_data_indicator = 0; - pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, - pusch_pdu->target_code_rate, - pusch_pdu->rb_size, - pusch_pdu->nr_of_symbols, - 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI - 0, //nb_rb_oh - pusch_pdu->nrOfLayers = 1); - pusch_pdu->pusch_data.num_cb = 0; //CBG not supported - //pusch_pdu->pusch_data.cb_present_and_position; - //pusch_pdu->pusch_uci; - //pusch_pdu->pusch_ptrs; - //pusch_pdu->dfts_ofdm; - //beamforming - //pusch_pdu->beamforming; //not used for now - } + UL_tti_req->SFN = frameP; + UL_tti_req->Slot = slotP; + UL_tti_req->n_pdus = 1; + UL_tti_req->pdus_list[0].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + UL_tti_req->pdus_list[0].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; + memset(pusch_pdu,0,sizeof(nfapi_nr_pusch_pdu_t)); + + LOG_D(MAC, "Scheduling UE specific PUSCH\n"); + //UL_tti_req = &nr_mac->UL_tti_req[CC_id]; + /* + // original configuration + rel15_ul->rnti = 0x1234; + rel15_ul->ulsch_pdu_rel15.start_rb = 30; + rel15_ul->ulsch_pdu_rel15.number_rbs = 50; + rel15_ul->ulsch_pdu_rel15.start_symbol = 2; + rel15_ul->ulsch_pdu_rel15.number_symbols = 12; + rel15_ul->ulsch_pdu_rel15.nb_re_dmrs = 6; + rel15_ul->ulsch_pdu_rel15.length_dmrs = 1; + rel15_ul->ulsch_pdu_rel15.Qm = 2; + rel15_ul->ulsch_pdu_rel15.mcs = 9; + rel15_ul->ulsch_pdu_rel15.rv = 0; + rel15_ul->ulsch_pdu_rel15.n_layers = 1; + */ + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = rnti; + pusch_pdu->handle = 0; //not yet used + + pusch_pdu->bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + pusch_pdu->cyclic_prefix = 0; + //pusch information always include + //this informantion seems to be redundant. with hthe mcs_index and the modulation table, the mod_order and target_code_rate can be determined. + pusch_pdu->mcs_index = 9; + pusch_pdu->mcs_table = 0; //0: notqam256 [TS38.214, table 5.1.3.1-1] - corresponds to nr_target_code_rate_table1 in PHY + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table) ; + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = 0; //It equals the higher-layer parameter Data-scrambling-Identity if configured and the RNTI equals the C-RNTI, otherwise L2 needs to set it to physical cell id.; + pusch_pdu->nrOfLayers = 1; + //DMRS + pusch_pdu->ul_dmrs_symb_pos = 1; + pusch_pdu->dmrs_config_type = 0; //dmrs-type 1 (the one with a single DMRS symbol in the beginning) + pusch_pdu->ul_dmrs_scrambling_id = 0; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. + pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. + //pusch_pdu->num_dmrs_cdm_grps_no_data; + //pusch_pdu->dmrs_ports; //DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used + //Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2] + pusch_pdu->resource_alloc = 1; //type 1 + //pusch_pdu->rb_bitmap;// for ressource alloc type 0 + pusch_pdu->rb_start = 0; + pusch_pdu->rb_size = 50; + pusch_pdu->vrb_to_prb_mapping = 0; + pusch_pdu->frequency_hopping = 0; + //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + //Resource Allocation in time domain + pusch_pdu->start_symbol_index = 2; + pusch_pdu->nr_of_symbols = 12; + //Optional Data only included if indicated in pduBitmap + pusch_pdu->pusch_data.rv_index = 0; + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->mcs_index, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI + 0, //nb_rb_oh + pusch_pdu->nrOfLayers = 1); + pusch_pdu->pusch_data.num_cb = 0; //CBG not supported + //pusch_pdu->pusch_data.cb_present_and_position; + //pusch_pdu->pusch_uci; + //pusch_pdu->pusch_ptrs; + //pusch_pdu->dfts_ofdm; + //beamforming + //pusch_pdu->beamforming; //not used for now + ul_dci_request_pdu = &UL_dci_req->ul_dci_pdu_list[UL_dci_req->numPdus]; memset((void*)ul_dci_request_pdu,0,sizeof(nfapi_nr_ul_dci_request_pdus_t)); @@ -809,17 +817,31 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, int dci_formats[2]; int rnti_types[2]; + int CCEIndex = allocate_nr_CCEs(nr_mac, + 1, // bwp_id + 0, // coreset_id + 4, // aggregation, + 1, // search_space, 0 common, 1 ue-specific + UE_id, + 0); // m + dci_formats[0] = NR_UL_DCI_FORMAT_0_0; rnti_types[0] = NR_RNTI_C; - + LOG_I(MAC,"Configuring ULDCI/PDCCH in %d.%d\n", frameP,slotP); nr_configure_pdcch(pdcch_pdu_rel15, 1, // ue-specific, scc, bwp); + dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; - config_uldci(pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); + AssertFatal(CCEIndex>=0,"CCEIndex is negative \n"); + pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci] = CCEIndex; + + LOG_I(PHY,"CCEIndex %d\n",pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci]); + + config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); pdcch_pdu_rel15->PayloadSizeBits[0]=nr_dci_size(dci_formats[0],rnti_types[0],pdcch_pdu_rel15->BWPSize); fill_dci_pdu_rel15(pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index ecec1efbe2..9c84b97533 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -131,11 +131,6 @@ static inline uint8_t get_max_cces(uint8_t scs) { return (nr_max_number_of_cces_per_slot[scs]); } -int is_nr_UL_slot(NR_COMMON_channels_t * ccP, int slot){ - - return (0); -} - int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, int bwp_id, int coreset_id, @@ -144,9 +139,10 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, int UE_id, int m ) { + // uncomment these when we allocate for common search space + // NR_COMMON_channels_t *cc = nr_mac->common_channels; + // NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - NR_COMMON_channels_t *cc = nr_mac->common_channels; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_UE_list_t *UE_list = &nr_mac->UE_list; NR_BWP_Downlink_t *bwp; @@ -155,9 +151,9 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, NR_ControlResourceSet_t *coreset; if (search_space == 1) { - AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n",UE_id); - bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id); secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[coreset_id]; } else { @@ -175,7 +171,7 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, n_rb*=6; uint16_t N_reg = n_rb * coreset->duration; - uint16_t Y=0, N_cce, M_s_max, n_CI=0, tmp, C=0; + uint16_t Y=0, N_cce, M_s_max, n_CI=0; uint16_t n_RNTI = search_space == 1 ? UE_list->rnti[UE_id]:0; uint32_t A[3]={39827,39829,39839}; @@ -209,11 +205,11 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, uint16_t nb_slots_per_frame, uint16_t N_RB) { - uint8_t O, M; - uint8_t ss_idx = rmsi_pdcch_config&0xf; - uint8_t cset_idx = (rmsi_pdcch_config>>4)&0xf; - uint8_t mu = scs_common; - uint8_t O_scale=0, M_scale=0; // used to decide if the values of O and M need to be divided by 2 + // uint8_t O, M; + // uint8_t ss_idx = rmsi_pdcch_config&0xf; + // uint8_t cset_idx = (rmsi_pdcch_config>>4)&0xf; + // uint8_t mu = scs_common; + // uint8_t O_scale=0, M_scale=0; // used to decide if the values of O and M need to be divided by 2 AssertFatal(1==0,"todo\n"); /* @@ -418,10 +414,8 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, int ss_type, NR_ServingCellConfigCommon_t *scc, - NR_BWP_Downlink_t *bwp) { + NR_BWP_Downlink_t *bwp){ - uint16_t N_RB=NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); - if (bwp) { // This is not the InitialBWP /// coreset @@ -437,7 +431,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; - pdcch_pdu->CyclicPrefix = bwp->bwp_Common->genericParameters.cyclicPrefix; + pdcch_pdu->CyclicPrefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix; pdcch_pdu->DurationSymbols = coreset0->duration; @@ -502,8 +496,9 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, for (int i=0;inumDlDci;i++) { //pdcch-DMRS-ScramblingID - pdcch_pdu->ScramblingId[i] = coreset0->pdcch_DMRS_ScramblingID; - + AssertFatal(coreset0->pdcch_DMRS_ScramblingID != NULL,"coreset0->pdcch_DMRS_ScramblingID is null\n"); + pdcch_pdu->ScramblingId[i] = *coreset0->pdcch_DMRS_ScramblingID; + } /// SearchSpace @@ -544,8 +539,8 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, pdcch_pdu->StartSymbolIndex=i; break; } - } } + else { // this is for InitialBWP AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n"); } @@ -560,17 +555,13 @@ void fill_dci_pdu_rel15(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, ) { uint16_t N_RB = pdcch_pdu_rel15->BWPSize; - uint8_t fsize=0, pos=0, cand_idx=0; + uint8_t fsize=0, pos=0; for (int d=0;dnumDlDci;d++) { uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->Payload[d]; AssertFatal(pdcch_pdu_rel15->PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported"); - /* - n_shift = (dci_alloc->pdcch_pdu.config_type == NFAPI_NR_CSET_CONFIG_MIB_SIB1)? - cfg->sch_config.physical_cell_id.value : dci_alloc->pdcch_pdu.shift_index; - nr_fill_cce_list(dci_alloc, n_shift, cand_idx); - */ + int dci_size = pdcch_pdu_rel15->PayloadSizeBits[d]; /// Payload generation @@ -1378,7 +1369,6 @@ int add_new_nr_ue(module_id_t mod_idP, */ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols) { - int mapping_Type = 0; // TypeA int l0; if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos2) l0=2; else if (dmrs_TypeA_Position == NR_ServingCellConfigCommon__dmrs_TypeA_Position_pos3) l0=3; @@ -1450,13 +1440,73 @@ int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,i if (*dmrs_config->dmrs_AdditionalPosition!=NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1) return(1<dmrs_DownlinkForPDSCH_MappingTypeB && - pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) { - // Relative to start of PDSCH resource - AssertFatal(1==0,"TypeB DMRS not supported yet\n"); - } + else if (pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeB && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->present == NR_SetupRelease_DMRS_DownlinkConfig_PR_setup) { + // Relative to start of PDSCH resource + AssertFatal(1==0,"TypeB DMRS not supported yet\n"); + } } + AssertFatal(1==0,"Shouldn't get here\n"); + return(-1); } +int tdd_period_to_num[8] = {500,625,1000,1250,2000,2500,5000,10000}; +int is_nr_DL_slot(NR_COMMON_channels_t *cc,slot_t slot) { + + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + int period,period1,period2=0; + + if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1); + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530) + period1 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period1 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity]; + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) { + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530) + period2 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period2 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity]; + } + period = period1+period2; + int scs=scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; + int slots=period*(1<tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0); + else return(slot_in_period <= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); +} + +int is_nr_UL_slot(NR_COMMON_channels_t *cc,slot_t slot) { + + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + int period,period1,period2=0; + + if (scc->tdd_UL_DL_ConfigurationCommon==NULL) return(1); + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530) + period1 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern1.ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period1 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity]; + + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) { + if (scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1 && + scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530) + period2 = 3000+*scc->tdd_UL_DL_ConfigurationCommon->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530; + else + period2 = tdd_period_to_num[scc->tdd_UL_DL_ConfigurationCommon->pattern2->dl_UL_TransmissionPeriodicity]; + } + period = period1+period2; + int scs=scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; + int slots=period*(1<= scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots ? 1 : 0); + else return(slot_in_period >= slots1+scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofDownlinkSlots ? 1 : 0); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index d7147b4fa9..d7fce03dc2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -48,7 +48,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, uint32_t rnti, NR_CellGroupConfig_t *secondaryCellGroup ); -int is_nr_UL_slot(NR_COMMON_channels_t * ccP, int slotP); void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, @@ -70,11 +69,7 @@ int configure_fapi_dl_Tx(int Mod_id, nfapi_nr_dl_tti_request_body_t *dl_req, nfapi_nr_pdu_t *TX_req); -void config_uldci(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, - dci_pdu_rel15_t *dci_pdu_rel15, - int *dci_formats, - int *rnti_types); - +void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types); void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, @@ -165,4 +160,7 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, int m ); +int is_nr_DL_slot(NR_COMMON_channels_t *cc,slot_t slotP); +int is_nr_UL_slot(NR_COMMON_channels_t *cc,slot_t slotP); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 1c2cf606a9..43635b965e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -75,12 +75,15 @@ void mac_top_init_gNB(void) RC.nrmac[i]->Mod_id = i; }//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(); + if(IS_SOFTMODEM_NOS1) + nr_ip_over_LTE_DRB_preconfiguration(); + rrc_init_nr_global_param(); }else { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 224cc12a7b..5afc142c68 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -72,7 +72,6 @@ typedef struct { uint64_t dl_CarrierFreq; NR_BCCH_BCH_Message_t *mib; NR_ServingCellConfigCommon_t *ServingCellConfigCommon; - NR_TDD_UL_DL_ConfigCommon_t *tdd_Config; NR_ARFCN_ValueEUTRA_t ul_CarrierFreq; long ul_Bandwidth; /// Outgoing MIB PDU for PHY diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index d7cbb33c9e..f234e02c04 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 14507f2589..1d4c612743 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 bc3474a369..9e873379b1 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_idpdcp_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 a18713fbb6..8f9ee0af18 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 02e1b63129..a11c029bd3 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 ef40b186e0..865a815359 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 c6a5ca7213..f2cb456e8c 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 369c7fd0da..793d0057ac 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 a5bd0b9ef5..1ea9988707 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 78d7cc515f..22e6f4d78d 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 66a544f962..c7dc11f51d 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 fc6e449acf..8000196b32 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 77194f3a9e..940740943e 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 b6ab367bc1..90e006cd17 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 1563a01de3..2fb844f05a 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 dddffed241..dfdf527123 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_iDlist.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 0000000000..071930c4f4 --- /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 0000000000..4e2d3147c9 --- /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 0000000000..46f7d90da5 --- /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 0000000000..61394c9c69 --- /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 0000000000..fefe2fc77d --- /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 + +#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 0000000000..5b12a90cfd --- /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 + +#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 0000000000..8f3d49d8c2 --- /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 +#include + +#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 0000000000..7a553a22a9 --- /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 0000000000..86a0697624 --- /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 +#include + +#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 0000000000..7c8c7e40a0 --- /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 0000000000..09f29ebe67 --- /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 +#include + +#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 0000000000..21063a1ea1 --- /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 0000000000..b56e8b11e9 --- /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 + +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 0000000000..b42410ab72 --- /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 +#include + +#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 0000000000..8e9872522f --- /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 0000000000..ef0d52558a --- /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 +#include + +#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 0000000000..f4585fb7d6 --- /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 0000000000..09f1e4f599 --- /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 +#include +#include + +#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 0000000000..97da28cdce --- /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 0000000000..52b0891bc3 --- /dev/null +++ b/openair2/LAYER2/nr_rlc/test.c @@ -0,0 +1,32 @@ +#include "nr_rlc_entity.h" + +#include + +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 0000000000..5c9fcd643c --- /dev/null +++ b/openair2/LAYER2/nr_rlc/tests/LOG/log.h @@ -0,0 +1,10 @@ +#ifndef _LOG_H_ +#define _LOG_H_ + +#include + +#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 0000000000..746d61483b --- /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 0000000000..ac22516064 --- /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 0000000000..742e79ca2c --- /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 +#include +#include +#include +#include +#include + +/* + * GNB_AM + * + * + * create the gNB RLC AM entity with given parameters + * + * UE_AM + * + * + * create the UE RLC AM entity with given parameters + * + * GNB_UM + * create the eNB RLC UM entity with given parameters + * + * UE_UM + * create the UE RLC UM entity with given parameters + * + * GNB_TM + * create the eNB RLC TM entity with given parameters + * + * UE_UM + * create the UE RLC TM entity with given parameters + * + * TIME