From 75cca9be3ecc8d20a7856640d9699b8e0fe8b12f Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 6 Nov 2024 21:31:32 -0500 Subject: [PATCH 01/36] Fix logging --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index cf1ebf8319..1011fbfe7f 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -409,13 +409,13 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue, if (ret==0) { #ifdef DEBUG_PHY_PROC - uint16_t frame_tx; - LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n", - ue->Mod_id, - frame_rx, - nr_slot_rx, - frame_tx, - ue->frame_parms.N_RB_DL); + LOG_D(PHY, + "[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): ssb idx: %d, N_RB_DL %d\n", + ue->Mod_id, + frame_rx, + nr_slot_rx, + ssb_index, + ue->frame_parms.N_RB_DL); #endif } else { From 210b92338ffe3d870390577d0523d96507c1d1da Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Tue, 12 Nov 2024 11:43:28 -0500 Subject: [PATCH 02/36] Decode PBCH with ssb index from init sync --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 25 +++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 1011fbfe7f..046852a06e 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -874,12 +874,21 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, return dec; } +static bool is_ssb_index_transmitted(const PHY_VARS_NR_UE *ue, const int index) +{ + if (ue->received_config_request) { + const fapi_nr_config_request_t *cfg = &ue->nrUE_config; + const uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[index / 32].ssb_mask; + return ((curr_mask >> (31 - (index % 32))) & 0x01); + } else + return ue->frame_parms.ssb_index == index; +} + int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data) { int frame_rx = proc->frame_rx; int nr_slot_rx = proc->nr_slot_rx; int gNB_id = proc->gNB_id; - fapi_nr_config_request_t *cfg = &ue->nrUE_config; NR_DL_FRAME_PARMS *fp = &ue->frame_parms; NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config; int sampleShift = INT_MAX; @@ -893,16 +902,18 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_ const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP; __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz]; // checking if current frame is compatible with SSB periodicity - if (cfg->ssb_table.ssb_period == 0 || !(frame_rx % (1 << (cfg->ssb_table.ssb_period - 1)))) { + + const int default_ssb_period = 2; + const int ssb_period = ue->received_config_request ? ue->nrUE_config.ssb_table.ssb_period : default_ssb_period; + if (ssb_period == 0 || !(frame_rx % (1 << (ssb_period - 1)))) { const int estimateSz = fp->symbols_per_slot * fp->ofdm_symbol_size; // loop over SSB blocks - for(int ssb_index=0; ssb_indexLmax; ssb_index++) { - uint32_t curr_mask = cfg->ssb_table.ssb_mask_list[ssb_index/32].ssb_mask; - // check if if current SSB is transmitted - if ((curr_mask >> (31-(ssb_index%32))) &0x01) { + for (int ssb_index = 0; ssb_index < fp->Lmax; ssb_index++) { + // check if current SSB is transmitted + if (is_ssb_index_transmitted(ue, ssb_index)) { int ssb_start_symbol = nr_get_ssb_start_symbol(fp, ssb_index); int ssb_slot = ssb_start_symbol/fp->symbols_per_slot; - int ssb_slot_2 = (cfg->ssb_table.ssb_period == 0) ? ssb_slot+(fp->slots_per_frame>>1) : -1; + int ssb_slot_2 = (ssb_period == 0) ? ssb_slot + (fp->slots_per_frame >> 1) : -1; if (ssb_slot == nr_slot_rx || ssb_slot_2 == nr_slot_rx) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_IN); From 70849816c47c44193a2f64c93b79db8991da49a6 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 22 Oct 2024 10:42:47 +0200 Subject: [PATCH 03/36] Test for init_RA Extract nr_ra_procedures.c into a separate library and add a testcase for init_RA function. The testcase redefines the following functions as stubs: - nr_mac_rrc_ra_ind - nr_write_ce_ulsch_pdu - mac_rlc_data_req - *lockGet_ul_config - release_ul_config - remove_ul_config_last_item - nr_ue_configure_pucch These stubs can be used to check init_RA behavior --- CMakeLists.txt | 5 +- openair2/LAYER2/NR_MAC_UE/CMakeLists.txt | 2 + openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 24 --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 24 +++ .../LAYER2/NR_MAC_UE/tests/CMakeLists.txt | 6 + .../tests/test_nr_ue_ra_procedures.cpp | 148 ++++++++++++++++++ 6 files changed, 182 insertions(+), 27 deletions(-) create mode 100644 openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1de118a383..2c777cb394 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1374,7 +1374,6 @@ set (MAC_NR_SRC_UE ${NR_UE_MAC_DIR}/nr_ue_scheduler.c ${NR_UE_MAC_DIR}/nr_ue_scheduler_sl.c ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c - ${NR_UE_MAC_DIR}/nr_ra_procedures.c ) set (ENB_APP_SRC @@ -1423,7 +1422,7 @@ endif() add_library(MAC_UE_NR ${MAC_NR_SRC_UE}) -target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures) +target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures nr_ue_ra_procedures) add_library(L2_LTE ${L2_LTE_SRC}) target_link_libraries(L2_LTE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) @@ -1478,7 +1477,7 @@ target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs) add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} ) target_link_libraries(NR_L2_UE PRIVATE f1ap nr_rlc) -target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common nr_ue_power_procedures) +target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common nr_ue_power_procedures nr_ue_ra_procedures) add_library(MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c diff --git a/openair2/LAYER2/NR_MAC_UE/CMakeLists.txt b/openair2/LAYER2/NR_MAC_UE/CMakeLists.txt index 6589a2fda5..aa583c8598 100644 --- a/openair2/LAYER2/NR_MAC_UE/CMakeLists.txt +++ b/openair2/LAYER2/NR_MAC_UE/CMakeLists.txt @@ -1,5 +1,7 @@ add_library(nr_ue_power_procedures nr_ue_power_procedures.c) target_link_libraries(nr_ue_power_procedures PUBLIC asn1_nr_rrc ${T_LIB} MAC_NR_COMMON nr_common) +add_library(nr_ue_ra_procedures nr_ra_procedures.c) +target_link_libraries(nr_ue_ra_procedures PUBLIC asn1_nr_rrc asn1_lte_rrc_hdrs ${T_LIB} MAC_NR_COMMON nr_common) if (ENABLE_TESTS) add_subdirectory(tests) endif() diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index a60d8d2c43..6b103b3f54 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -325,27 +325,3 @@ void release_mac_configuration(NR_UE_MAC_INST_t *mac, NR_UE_MAC_reset_cause_t ca for (int i = mac->TAG_list.count; i > 0 ; i--) asn_sequence_del(&mac->TAG_list, i - 1, 1); } - -void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id) -{ - for (int j = 0; j < MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD; j++) - for (int k = 0; k < MAX_NB_FRAME_IN_PRACH_CONF_PERIOD; k++) - for (int l = 0; l < MAX_NB_SLOT_IN_FRAME; l++) - free(nr_mac->prach_assoc_pattern[bwp_id].prach_conf_period_list[j].prach_occasion_slot_map[k][l].prach_occasion); - - free(nr_mac->ssb_list[bwp_id].tx_ssb); -} - -void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach) -{ - RA_config_t *ra = &nr_mac->ra; - if(ra->rach_ConfigDedicated) - asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated); - memset(ra, 0, sizeof(RA_config_t)); - - if (!free_prach) - return; - - for (int i = 0; i < MAX_NUM_BWP_UE; i++) - free_rach_structures(nr_mac, i); -} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index da183b3b14..44ff283679 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -1076,3 +1076,27 @@ void prepare_msg4_msgb_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack) remove_ul_config_last_item(pdu); release_ul_config(pdu, false); } + +void free_rach_structures(NR_UE_MAC_INST_t *nr_mac, int bwp_id) +{ + for (int j = 0; j < MAX_NB_PRACH_CONF_PERIOD_IN_ASSOCIATION_PATTERN_PERIOD; j++) + for (int k = 0; k < MAX_NB_FRAME_IN_PRACH_CONF_PERIOD; k++) + for (int l = 0; l < MAX_NB_SLOT_IN_FRAME; l++) + free(nr_mac->prach_assoc_pattern[bwp_id].prach_conf_period_list[j].prach_occasion_slot_map[k][l].prach_occasion); + + free(nr_mac->ssb_list[bwp_id].tx_ssb); +} + +void reset_ra(NR_UE_MAC_INST_t *nr_mac, bool free_prach) +{ + RA_config_t *ra = &nr_mac->ra; + if (ra->rach_ConfigDedicated) + asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated); + memset(ra, 0, sizeof(RA_config_t)); + + if (!free_prach) + return; + + for (int i = 0; i < MAX_NUM_BWP_UE; i++) + free_rach_structures(nr_mac, i); +} diff --git a/openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt b/openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt index 40c8c5372b..6bb9d1b480 100644 --- a/openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt +++ b/openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt @@ -4,3 +4,9 @@ target_link_libraries(test_nr_ue_power_procedures PRIVATE nr_ue_power_procedures add_dependencies(tests test_nr_ue_power_procedures) add_test(NAME test_nr_ue_power_procedures COMMAND ./test_nr_ue_power_procedures) + +add_executable(test_nr_ue_ra_procedures test_nr_ue_ra_procedures.cpp) +target_link_libraries(test_nr_ue_ra_procedures PRIVATE nr_ue_ra_procedures nr_ue_power_procedures GTest::gtest minimal_lib) +add_dependencies(tests test_nr_ue_ra_procedures) +add_test(NAME test_nr_ue_ra_procedures + COMMAND ./test_nr_ue_ra_procedures) diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp new file mode 100644 index 0000000000..0c613bf6cc --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_ra_procedures.cpp @@ -0,0 +1,148 @@ +/* + * 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 "gtest/gtest.h" +extern "C" { +#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "executables/softmodem-common.h" +uint64_t get_softmodem_optmask(void) +{ + return 0; +} +static softmodem_params_t softmodem_params; +softmodem_params_t *get_softmodem_params(void) +{ + return &softmodem_params; +} +void nr_mac_rrc_ra_ind(const module_id_t mod_id, int frame, bool success) +{ +} +int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, + NR_UE_MAC_INST_t *mac, + NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, + uint16_t *crnti, + NR_BSR_SHORT *truncated_bsr, + NR_BSR_SHORT *short_bsr, + NR_BSR_LONG *long_bsr) +{ + return 0; +} +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, + const uint32_t sourceL2Id, + const uint32_t destinationL2Id) +{ + return 0; +} +fapi_nr_ul_config_request_pdu_t *lockGet_ul_config(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, uint8_t pdu_type) +{ + return nullptr; +} +void release_ul_config(fapi_nr_ul_config_request_pdu_t *configPerSlot, bool clearIt) +{ +} +void remove_ul_config_last_item(fapi_nr_ul_config_request_pdu_t *pdu) +{ +} +int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, + int slot, + frame_t frame, + uint16_t rnti, + PUCCH_sched_t *pucch, + fapi_nr_ul_config_pucch_pdu *pucch_pdu) +{ + return 0; +} +} +#include +#include "common/utils/LOG/log.h" + +TEST(test_init_ra, four_step_cbra) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_PRACH_RESOURCES_t prach_resources = {0}; + NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; + NR_RACH_ConfigGeneric_t rach_ConfigGeneric = {0}; + NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = nullptr; + NR_UE_UL_BWP_t current_bwp; + mac.current_UL_BWP = ¤t_bwp; + long scs = 1; + current_bwp.scs = scs; + current_bwp.channel_bandwidth = 40; + nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs; + mac.p_Max = 23; + mac.nr_band = 78; + mac.frame_type = TDD; + mac.frequency_range = FR1; + + init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, rach_ConfigDedicated); + + EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); + EXPECT_EQ(mac.state, UE_PERFORMING_RA); + EXPECT_EQ(mac.ra.RA_active, true); + EXPECT_EQ(mac.ra.cfra, 0); +} + +TEST(test_init_ra, four_step_cfra) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_PRACH_RESOURCES_t prach_resources = {0}; + NR_RACH_ConfigCommon_t nr_rach_ConfigCommon = {0}; + NR_RACH_ConfigGeneric_t rach_ConfigGeneric = {0}; + NR_UE_UL_BWP_t current_bwp; + mac.current_UL_BWP = ¤t_bwp; + long scs = 1; + current_bwp.scs = scs; + current_bwp.channel_bandwidth = 40; + nr_rach_ConfigCommon.msg1_SubcarrierSpacing = &scs; + mac.p_Max = 23; + mac.nr_band = 78; + mac.frame_type = TDD; + mac.frequency_range = FR1; + + NR_RACH_ConfigDedicated_t rach_ConfigDedicated = {0}; + struct NR_CFRA cfra; + rach_ConfigDedicated.cfra = &cfra; + + init_RA(&mac, &prach_resources, &nr_rach_ConfigCommon, &rach_ConfigGeneric, &rach_ConfigDedicated); + + EXPECT_EQ(mac.ra.ra_type, RA_4_STEP); + EXPECT_EQ(mac.state, UE_PERFORMING_RA); + EXPECT_EQ(mac.ra.RA_active, true); + EXPECT_EQ(mac.ra.cfra, 1); +} + +int main(int argc, char **argv) +{ + logInit(); + uniqCfg = load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY); + g_log->log_component[MAC].level = OAILOG_DEBUG; + g_log->log_component[NR_MAC].level = OAILOG_DEBUG; + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From d641a76196096bf1c5d701002e0a877ce0dd444d Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 27 Sep 2024 11:35:52 +0200 Subject: [PATCH 04/36] fix BSR report malformed, add SHORT BSR when it can (instead of LONG BSR) simplify the code and make the code more explicit, but the may structure remain (nr_write_ce_ulsch_pdu interface is complex, merging it into the called would make simpler and more interstandable code), fix some asserts related to this part of code --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 19 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 14 +- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 27 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 1 - openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 245 +++--- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 763 ++++++++----------- 7 files changed, 429 insertions(+), 642 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index b7e2da6f10..04304f8b9a 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -122,6 +122,11 @@ static inline int get_mac_len(uint8_t *pdu, uint32_t pdu_len, uint16_t *mac_ce_l *mac_subheader_len = sizeof(*s); *mac_ce_len = s->L; } + if (*mac_ce_len > pdu_len) { + LOG_E(NR_MAC, "MAC sdu len impossible (%d)\n", *mac_ce_len); + return false; + } + return true; } @@ -133,8 +138,6 @@ typedef struct { uint8_t LcgID: 3; // octet 1 MSB } __attribute__ ((__packed__)) NR_BSR_SHORT; -typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED; - // Long BSR for all logical channel group ID typedef struct { uint8_t LcgID0: 1; // octet 1 [0] @@ -144,19 +147,9 @@ typedef struct { uint8_t LcgID4: 1; // octet 1 [4] uint8_t LcgID5: 1; // octet 1 [5] uint8_t LcgID6: 1; // octet 1 [6] - uint8_t LcgID7: 1; // octet 1 [7] - uint8_t Buffer_size0: 8; // octet 2 [7:0] - uint8_t Buffer_size1: 8; // octet 3 [7:0] - uint8_t Buffer_size2: 8; // octet 4 [7:0] - uint8_t Buffer_size3: 8; // octet 5 [7:0] - uint8_t Buffer_size4: 8; // octet 6 [7:0] - uint8_t Buffer_size5: 8; // octet 7 [7:0] - uint8_t Buffer_size6: 8; // octet 8 [7:0] - uint8_t Buffer_size7: 8; // octet 9 [7:0] + uint8_t LcgID7: 1; // octet 1 [7] } __attribute__ ((__packed__)) NR_BSR_LONG; -typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED; - // 38.321 ch. 6.1.3.4 typedef struct { uint8_t TA_COMMAND: 6; // octet 1 [5:0] diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 426d8f88d1..6b0322fc50 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -70,8 +70,7 @@ #define NR_BSR_TRIGGER_NONE (0) /* No BSR Trigger */ #define NR_BSR_TRIGGER_REGULAR (1) /* For Regular and ReTxBSR Expiry Triggers */ -#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */ -#define NR_BSR_TRIGGER_PADDING (4) /* For Padding BSR Trigger */ +#define NR_BSR_TRIGGER_PERIODIC (2) /* For BSR Periodic Timer Expiry Trigger */ #define NR_INVALID_LCGID (NR_MAX_NUM_LCGID) @@ -194,8 +193,6 @@ typedef enum { typedef struct { // after multiplexing buffer remain for each lcid int32_t LCID_buffer_remain; - // buffer status for each lcid - bool LCID_buffer_with_data; // logical channel group id of this LCID long LCGID; // Bj bucket usage per lcid @@ -203,13 +200,6 @@ typedef struct { NR_timer_t Bj_timer; } NR_LC_SCHEDULING_INFO; -typedef struct { - // buffer status for each lcgid - uint8_t BSR; // should be more for mesh topology - // keep the number of bytes in rlc buffer for each lcgid - int32_t BSR_bytes; -} NR_LCG_SCHEDULING_INFO; - typedef struct { bool active_SR_ID; /// SR pending as defined in 38.321 @@ -244,8 +234,6 @@ typedef struct { typedef struct { // lcs scheduling info NR_LC_SCHEDULING_INFO lc_sched_info[NR_MAX_NUM_LCID]; - // lcg scheduling info - NR_LCG_SCHEDULING_INFO lcg_sched_info[NR_MAX_NUM_LCGID]; // SR INFO nr_sr_info_t sr_info[NR_MAX_SR_ID]; /// BSR report flag management diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6feca8756e..53d1183693 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -172,13 +172,22 @@ void nr_ue_send_sdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_info, in void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac,nr_downlink_indication_t *dl_info, int pdu_id); +typedef struct { + union { + NR_BSR_SHORT s; + NR_BSR_LONG l; + uint8_t lc_bsr[8]; + } bsr; + enum { b_none, b_long, b_short, b_short_trunc, b_long_trunc } type_bsr; +} type_bsr_t; + +int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end); + int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, - uint16_t *crnti, - NR_BSR_SHORT *truncated_bsr, - NR_BSR_SHORT *short_bsr, - NR_BSR_LONG *long_bsr); + const type_bsr_t *bsr, + uint8_t *mac_ce_end); void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, @@ -188,16 +197,6 @@ void config_dci_pdu(NR_UE_MAC_INST_t *mac, void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, const frame_t frame, const int slot); -uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, - int cc_id, - frame_t frameP, - sub_frame_t subframe, - uint8_t gNB_index, - uint8_t *ulsch_buffer, - uint32_t buflen, - int16_t tx_power, - int16_t P_CMAX); - void set_harq_status(NR_UE_MAC_INST_t *mac, uint8_t pucch_id, uint8_t harq_id, diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index f535d7f3b8..38097464fc 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -192,7 +192,6 @@ void reset_mac_inst(NR_UE_MAC_INST_t *nr_mac) for (int i = 0; i < NR_MAX_NUM_LCID; i++) { LOG_D(NR_MAC, "Applying default logical channel config for LCID %d\n", i); nr_mac->scheduling_info.lc_sched_info[i].Bj = 0; - nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_with_data = false; nr_mac->scheduling_info.lc_sched_info[i].LCID_buffer_remain = 0; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 493d90eaf6..2ac3c3b219 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -785,7 +785,7 @@ void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB } else if (!IS_SA_MODE(get_softmodem_params())) { uint8_t temp_pdu[16] = {0}; - size_sdu = nr_write_ce_ulsch_pdu(temp_pdu, mac, 0, &(mac->crnti), NULL, NULL, NULL); + size_sdu = nr_write_ce_msg3_pdu(temp_pdu, mac, mac->crnti, temp_pdu + sizeof(temp_pdu)); ra->Msg3_size = size_sdu; } } else if (ra->RA_window_cnt != -1) { // RACH is active diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index bd233f2163..c9c72bc2b9 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2524,7 +2524,7 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *p AssertFatal(sr_count < 2, "Cannot handle more than 1 SR per slot yet\n"); } } - return sr_count > 0 ? true : false; + return sr_count > 0; } int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_SchedulingRequestId_t sr_id) @@ -2537,12 +2537,14 @@ int8_t nr_ue_get_SR(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_Schedu return 0; } - LOG_D(NR_MAC, "[UE %d] Frame %d slot %d SR %s for ID %ld\n", + LOG_D(NR_MAC, + "[UE %d] Frame %d slot %d SR %s for ID %ld, timer %d\n", mac->ue_id, frame, slot, sr_info->pending ? "pending" : "not pending", - sr_id); // todo + sr_id, // todo + nr_timer_is_active(&sr_info->prohibitTimer)); // TODO check if the PUCCH resource for the SR transmission occasion does not overlap with a UL-SCH resource if (!sr_info->pending || nr_timer_is_active(&sr_info->prohibitTimer)) @@ -3772,9 +3774,23 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i } } +int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end) +{ + uint8_t *pdu = mac_ce; + if (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != nrRA_SUCCEEDED) { + LOG_D(NR_MAC, "Generating C-RNTI MAC CE with C-RNTI %x\n", crnti); + *(NR_MAC_SUBHEADER_FIXED *)mac_ce = (NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = UL_SCH_LCID_C_RNTI}; + mac_ce += sizeof(NR_MAC_SUBHEADER_FIXED); + // C-RNTI MAC CE (2 octets) + memcpy(mac_ce, &crnti, sizeof(crnti)); + // update pointer and length + mac_ce += sizeof(crnti); + } + return mac_ce - pdu; +} + /** * Function: generating MAC CEs (MAC CE and subheader) for the ULSCH PDU - * Notes: TODO: PHR and BSR reporting * Parameters: * @mac_ce pointer to the MAC sub-PDUs including the MAC CEs * @mac pointer to the MAC instance @@ -3783,158 +3799,99 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, NR_SINGLE_ENTRY_PHR_MAC_CE *power_headroom, - uint16_t *crnti, - NR_BSR_SHORT *truncated_bsr, - NR_BSR_SHORT *short_bsr, - NR_BSR_LONG *long_bsr) + const type_bsr_t *bsr, + uint8_t *mac_ce_end) { - int mac_ce_len = 0; uint8_t *pdu = mac_ce; if (power_headroom) { // MAC CE fixed subheader - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR; - mac_ce++; - - // PHR MAC CE (1 octet) - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PH = power_headroom->PH; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R1 = 0; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->PCMAX = power_headroom->PCMAX; - ((NR_SINGLE_ENTRY_PHR_MAC_CE *) mac_ce)->R2 = 0; - - // update pointer and length - int mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); - mac_ce += mac_ce_size; - mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + *(NR_MAC_SUBHEADER_FIXED *)mac_ce = (NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR}; + mac_ce += sizeof(NR_MAC_SUBHEADER_FIXED); + *(NR_SINGLE_ENTRY_PHR_MAC_CE *)mac_ce = *power_headroom; + mac_ce += sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : power_headroom pdu %p mac_ce %p b\n", pdu, mac_ce); } - if (crnti && (!IS_SA_MODE(get_softmodem_params()) && get_softmodem_params()->do_ra && mac->ra.ra_state != nrRA_SUCCEEDED)) { - LOG_D(NR_MAC, "In %s: generating C-RNTI MAC CE with C-RNTI %x\n", __FUNCTION__, (*crnti)); - - // MAC CE fixed subheader - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_C_RNTI; - mac_ce++; - - // C-RNTI MAC CE (2 octets) - memcpy(mac_ce, crnti, sizeof(*crnti)); - - // update pointer and length - int mac_ce_size = sizeof(uint16_t); - mac_ce += mac_ce_size; - mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); + switch (bsr->type_bsr) { + case b_short: + case b_short_trunc: { + *(NR_MAC_SUBHEADER_FIXED *)mac_ce = + (NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = bsr->type_bsr == b_short ? UL_SCH_LCID_S_BSR : UL_SCH_LCID_S_TRUNCATED_BSR}; + mac_ce += sizeof(NR_MAC_SUBHEADER_FIXED); + *(NR_BSR_SHORT *)mac_ce = bsr->bsr.s; + mac_ce += sizeof(NR_BSR_SHORT); + LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : bsr Buffer_size %d LcgID %d \n", bsr->bsr.s.Buffer_size, bsr->bsr.s.LcgID); + } break; + case b_long: + case b_long_trunc: { + // ch 6.1.3.1. TS 38.321 + NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *)mac_ce; + mac_ce += sizeof(NR_MAC_SUBHEADER_SHORT); + uint8_t *mark = mac_ce; + // Could move to nr_get_sdu() + NR_BSR_LONG *ceLong = (NR_BSR_LONG *)mac_ce; + *ceLong = (NR_BSR_LONG){0}; + mac_ce += sizeof(NR_BSR_LONG); + // int NR_BSR_LONG_SIZE = 1; + if (bsr->bsr.lc_bsr[0] && mac_ce < mac_ce_end) { + ceLong->LcgID0 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[0]; + } + if (bsr->bsr.lc_bsr[1] && mac_ce < mac_ce_end) { + ceLong->LcgID1 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[1]; + } + if (bsr->bsr.lc_bsr[2] && mac_ce < mac_ce_end) { + ceLong->LcgID2 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[2]; + } + if (bsr->bsr.lc_bsr[3] && mac_ce < mac_ce_end) { + ceLong->LcgID3 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[3]; + } + if (bsr->bsr.lc_bsr[4] && mac_ce < mac_ce_end) { + ceLong->LcgID4 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[4]; + } + if (bsr->bsr.lc_bsr[5] && mac_ce < mac_ce_end) { + ceLong->LcgID5 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[5]; + } + if (bsr->bsr.lc_bsr[6] && mac_ce < mac_ce_end) { + ceLong->LcgID6 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[6]; + } + if (bsr->bsr.lc_bsr[7] && mac_ce < mac_ce_end) { + ceLong->LcgID7 = 1; + *mac_ce++ = bsr->bsr.lc_bsr[7]; + } + *mac_pdu_subheader_ptr = + (NR_MAC_SUBHEADER_SHORT){.LCID = bsr->type_bsr == b_long ? UL_SCH_LCID_L_BSR : UL_SCH_LCID_L_TRUNCATED_BSR, + .L = mac_ce - mark}; + LOG_D(NR_MAC, + "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", + ((NR_MAC_SUBHEADER_SHORT *)mac_pdu_subheader_ptr)->L, + *mac_ce, + bsr->bsr.lc_bsr[0], + bsr->bsr.lc_bsr[1], + bsr->bsr.lc_bsr[2], + bsr->bsr.lc_bsr[3], + bsr->bsr.lc_bsr[4], + bsr->bsr.lc_bsr[5], + bsr->bsr.lc_bsr[6], + bsr->bsr.lc_bsr[7]); + } break; + case b_none: + break; + default: + DevAssert(false); +>>>>>>> 4a6be6c8ce (fix BSR report malformed, add SHORT BSR when it can (instead of LONG BSR) simplify the code and make the code more explicit, but the may structure remain (nr_write_ce_ulsch_pdu interface is complex, merging it into the called would make simpler and more interstandable code), fix some asserts related to this part of code) } - if (truncated_bsr) { - - // MAC CE fixed subheader - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_TRUNCATED_BSR; - mac_ce++; - - // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> Buffer_size = truncated_bsr->Buffer_size; - ((NR_BSR_SHORT_TRUNCATED *) mac_ce)-> LcgID = truncated_bsr->LcgID;; - - // update pointer and length - int mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED); - mac_ce += mac_ce_size; - mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); - LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : truncated_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n", - truncated_bsr->Buffer_size, truncated_bsr->LcgID, pdu, mac_ce); - - } else if (short_bsr) { - - // MAC CE fixed subheader - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_ce)->LCID = UL_SCH_LCID_S_BSR; - mac_ce++; - - // Short truncated BSR MAC CE (1 octet) - ((NR_BSR_SHORT *) mac_ce)->Buffer_size = short_bsr->Buffer_size; - ((NR_BSR_SHORT *) mac_ce)->LcgID = short_bsr->LcgID; - - // update pointer and length - int mac_ce_size = sizeof(NR_BSR_SHORT); - mac_ce += mac_ce_size; - mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_FIXED); - LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : short_bsr Buffer_size %d LcgID %d pdu %p mac_ce %p\n", - short_bsr->Buffer_size, short_bsr->LcgID, pdu, mac_ce); - } else if (long_bsr) { - - // MAC CE variable subheader - // ch 6.1.3.1. TS 38.321 - ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->R = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->F = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_ce)->LCID = UL_SCH_LCID_L_BSR; - - NR_MAC_SUBHEADER_SHORT *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT *) mac_ce; - mac_ce += 2; - - // Could move to nr_get_sdu() - uint8_t *Buffer_size_ptr= (uint8_t*) mac_ce + 1; - //int NR_BSR_LONG_SIZE = 1; - if (long_bsr->Buffer_size0 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID0 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID0 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size0; - } - if (long_bsr->Buffer_size1 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID1 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID1 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size1; - } - if (long_bsr->Buffer_size2 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID2 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID2 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size2; - } - if (long_bsr->Buffer_size3 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID3 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID3 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size3; - } - if (long_bsr->Buffer_size4 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID4 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID4 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size4; - } - if (long_bsr->Buffer_size5 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID5 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID5 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size5; - } - if (long_bsr->Buffer_size6 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID6 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID6 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size6; - } - if (long_bsr->Buffer_size7 == 0) { - ((NR_BSR_LONG *) mac_ce)->LcgID7 = 0; - } else { - ((NR_BSR_LONG *) mac_ce)->LcgID7 = 1; - *Buffer_size_ptr++ = long_bsr->Buffer_size7; - } - int mac_ce_size = ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_subheader_ptr)->L = (uint8_t*) Buffer_size_ptr - (uint8_t*) mac_ce; - LOG_D(NR_MAC, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", mac_ce_size, *((uint8_t*) mac_ce), - ((NR_BSR_LONG *) mac_ce)->Buffer_size0, ((NR_BSR_LONG *) mac_ce)->Buffer_size1, ((NR_BSR_LONG *) mac_ce)->Buffer_size2, ((NR_BSR_LONG *) mac_ce)->Buffer_size3, - ((NR_BSR_LONG *) mac_ce)->Buffer_size4, ((NR_BSR_LONG *) mac_ce)->Buffer_size5, ((NR_BSR_LONG *) mac_ce)->Buffer_size6, ((NR_BSR_LONG *) mac_ce)->Buffer_size7); - mac_ce_len += mac_ce_size + sizeof(NR_MAC_SUBHEADER_SHORT); - } - - return mac_ce_len; + return mac_ce - pdu; } - ///////////////////////////////////// // Random Access Response PDU // // TS 38.213 ch 8.2 // diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 26b2f35e0f..a15715ad85 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -68,6 +68,16 @@ static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac, float tx_power, frame_t frameP, sub_frame_t subframe); +static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, + int cc_id, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + const uint32_t buflen, + int tx_power, + int P_MAX, + bool *BSRsent); void clear_ul_config_request(NR_UE_MAC_INST_t *mac, int scs) { @@ -865,8 +875,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, if (pusch_config_pdu->scid == 0 && NR_DMRS_ulconfig && NR_DMRS_ulconfig->transformPrecodingDisabled && NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0) pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID0; - if (pusch_config_pdu->scid == 1 && NR_DMRS_ulconfig && - NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1) + if (pusch_config_pdu->scid == 1 && NR_DMRS_ulconfig && NR_DMRS_ulconfig->transformPrecodingDisabled + && NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1) pusch_config_pdu->ul_dmrs_scrambling_id = *NR_DMRS_ulconfig->transformPrecodingDisabled->scramblingID1; } @@ -1386,20 +1396,20 @@ void schedule_RA_after_SR_failure(NR_UE_MAC_INST_t *mac) // TODO we don't have semi-persistent CSI reporting } -static void nr_update_sr(NR_UE_MAC_INST_t *mac) +static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent) { NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info; // if no pending data available for transmission // All pending SR(s) shall be cancelled and each respective sr-ProhibitTimer shall be stopped - bool data_avail = false; - for (int i = 0; i < NR_MAX_NUM_LCID; i++) { - if (sched_info->lc_sched_info[i].LCID_buffer_remain > 0) { - data_avail = true; + + int idx = 0; + for (idx = 0; idx < NR_MAX_NUM_LCID; idx++) { + if (sched_info->lc_sched_info[idx].LCID_buffer_remain) break; - } } - if (!data_avail) { + + if (idx == NR_MAX_NUM_LCID) { // all queues are empty for (int i = 0; i < NR_MAX_SR_ID; i++) { nr_sr_info_t *sr = &sched_info->sr_info[i]; if (sr->active_SR_ID) { @@ -1409,14 +1419,14 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac) nr_timer_stop(&sr->prohibitTimer); } } + return; } // if a Regular BSR has been triggered and logicalChannelSR-DelayTimer is not running - if (((sched_info->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) - || nr_timer_is_active(&sched_info->sr_DelayTimer)) + if (BSRsent || nr_timer_is_active(&sched_info->sr_DelayTimer)) return; - nr_lcordered_info_t *lc_info = get_lc_info_from_lcid(mac, sched_info->regularBSR_trigger_lcid); + nr_lcordered_info_t *lc_info = get_lc_info_from_lcid(mac, idx + 1 /* see lcid_buffer_index() */); AssertFatal(lc_info, "Couldn't find logical channel with LCID %ld\n", sched_info->regularBSR_trigger_lcid); // if there is no UL-SCH resource available for a new transmission (ie we are at this point) @@ -1453,68 +1463,66 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac) } } -static void nr_update_bsr(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t gNB_index) +static void nr_update_rlc_buffers_status(NR_UE_MAC_INST_t *mac, frame_t frameP, slot_t slotP, uint8_t gNB_index) { - // Reset All BSR Infos - for (int id = 0; id < NR_MAX_NUM_LCID; id++) { - // Reset transmission status - mac->scheduling_info.lc_sched_info[id].LCID_buffer_with_data = false; - } + for (int i = 0; i < mac->lc_ordered_list.count; i++) { + nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; + int lcid = lc_info->lcid; + NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid); + mac_rlc_status_resp_t rlc_status = + mac_rlc_status_ind(mac->ue_id, mac->ue_id, gNB_index, frameP, slotP, ENB_FLAG_NO, MBMS_FLAG_NO, lcid, 0, 0); - for (int lcgid = 0; lcgid < NR_MAX_NUM_LCGID; lcgid++) { - // Reset Buffer Info - mac->scheduling_info.lcg_sched_info[lcgid].BSR = 0; - mac->scheduling_info.lcg_sched_info[lcgid].BSR_bytes = 0; + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(NR_MAC, + "[UE %d] LCID %d has %d bytes to transmit at sfn %d.%d\n", + mac->ue_id, + lcid, + rlc_status.bytes_in_buffer, + frameP, + slotP); + lc_sched_info->LCID_buffer_remain = rlc_status.bytes_in_buffer; + } } +} +/*TS 38.321 +A BSR shall be triggered if any of the following events occur: +- UL data, for a logical channel which belongs to an LCG, becomes available to the MAC entity; and either + => here we don't implement exactly the same, there is no direct relation with new data came in the UE since last BSR + +- this UL data belongs to a logical channel with higher priority than the priority of any logical channel + containing available UL data which belong to any LCG; or + => same, we don't know the last BSR content + +- none of the logical channels which belong to an LCG contains any available UL data. + in which case the BSR is referred below to as 'Regular BSR'; + +- UL resources are allocated and number of padding bits is equal to or larger than the size of the Buffer Status +Report MAC CE plus its subheader, in which case the BSR is referred below to as 'Padding BSR'; + +- retxBSR-Timer expires, and at least one of the logical channels which belong to an LCG contains UL data, in +which case the BSR is referred below to as 'Regular BSR'; + +- periodicBSR-Timer expires, in which case the BSR is referred below to as 'Periodic BSR'. + +*/ + +static void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *BSR_bytes) +{ bool bsr_regular_triggered = mac->scheduling_info.BSR_reporting_active & NR_BSR_TRIGGER_REGULAR; for (int i = 0; i < mac->lc_ordered_list.count; i++) { nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[i]; int lcid = lc_info->lcid; NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid); int lcgid = lc_sched_info->LCGID; - // check if UL data for a logical channel which belongs to a LCG becomes available for transmission if (lcgid != NR_INVALID_LCGID) { - mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mac->ue_id, - mac->ue_id, - gNB_index, - frameP, - slotP, - ENB_FLAG_NO, - MBMS_FLAG_NO, - lcid, - 0, - 0); - - lc_sched_info->LCID_buffer_remain = rlc_status.bytes_in_buffer; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(NR_MAC, - "[UE %d] LCID %d LCGID %d has %d bytes to transmit at frame %d slot %d\n", - mac->ue_id, - lcid, - lcgid, - rlc_status.bytes_in_buffer, - frameP, - slotP); - - lc_sched_info->LCID_buffer_with_data = true; - - //Update BSR_bytes - mac->scheduling_info.lcg_sched_info[lcgid].BSR_bytes += rlc_status.bytes_in_buffer; - - if (!bsr_regular_triggered) { - bsr_regular_triggered = true; - trigger_regular_bsr(mac, lcid, lc_info->sr_DelayTimerApplied); - LOG_D(NR_MAC, - "[UE %d] MAC BSR Triggered LCID %d LCGID %d data become available at %d.%d\n", - mac->ue_id, - lcid, - lcgid, - frameP, - slotP); - } + // Update BSR_bytes + BSR_bytes[lcgid] += lc_sched_info->LCID_buffer_remain; + if (!bsr_regular_triggered) { + bsr_regular_triggered = true; + trigger_regular_bsr(mac, lcid, lc_info->sr_DelayTimerApplied); + LOG_D(NR_MAC, "[UE %d] MAC BSR Triggered\n", mac->ue_id); } } } @@ -1533,14 +1541,11 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) nr_ue_prach_scheduler(mac, frame_tx, slot_tx); } - // Periodic SRS scheduling - if(mac->state == UE_CONNECTED) + bool BSRsent = false; + if (mac->state == UE_CONNECTED) { nr_ue_periodic_srs_scheduling(mac, frame_tx, slot_tx); - - // Call BSR procedure as described in Section 5.4.5 in 38.321 - // Check whether BSR is triggered before scheduling ULSCH - if(mac->state == UE_CONNECTED) - nr_update_bsr(mac, frame_tx, slot_tx, gNB_index); + nr_update_rlc_buffers_status(mac, frame_tx, slot_tx, gNB_index); + } // Schedule ULSCH only if the current frame and slot match those in ul_config_req // AND if a UL grant (UL DCI or Msg3) has been received (as indicated by num_pdus) @@ -1594,7 +1599,7 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) ulcfg_pdu->pusch_config_pdu.rb_size, ulcfg_pdu->pusch_config_pdu.rb_start); - nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX); + nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = ulsch_input_buffer; ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes; number_of_pdus++; @@ -1637,7 +1642,10 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) } if(mac->state == UE_CONNECTED) - nr_update_sr(mac); + nr_update_sr(mac, BSRsent); + // Global variables implicit logic + // far away, BSR_reporting_active is set + mac->scheduling_info.BSR_reporting_active = NR_BSR_TRIGGER_NONE; // update Bj for all active lcids before LCP procedure if (mac->current_UL_BWP) { @@ -2979,95 +2987,68 @@ static void nr_ue_prach_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, sub_fra } typedef struct { - uint8_t bsr_len; - uint8_t bsr_ce_len; - uint8_t bsr_header_len; uint8_t phr_len; - uint8_t phr_ce_len; - uint8_t phr_header_len; - uint16_t sdu_length_total; - NR_BSR_SHORT *bsr_s; - NR_BSR_LONG *bsr_l; - NR_BSR_SHORT *bsr_t; - NR_SINGLE_ENTRY_PHR_MAC_CE* phr; - //NR_POWER_HEADROOM_CMD *phr_pr; - int tot_mac_ce_len; - uint8_t total_mac_pdu_header_len; + uint sdu_length_total; + NR_SINGLE_ENTRY_PHR_MAC_CE phr; + type_bsr_t bsr; + uint8_t *pdu_end; + uint8_t *end_for_tailer; + uint8_t *cur_ptr; + uint num_sdus; + // int highest_priority = 16; + // variable used to store the lcid data status during lcp + bool lcids_data_status[NR_MAX_NUM_LCID]; + uint32_t lcp_allocation_counter; } NR_UE_MAC_CE_INFO; -/* - nr_ue_get_sdu_mac_ce_pre finds length in various mac_ce field - Need nothing from mac_ce_p: - Update the following in mac_ce_p: - bsr_len; - bsr_ce_len; - bsr_header_len; - phr_len; TBD - phr_ce_len; TBD - phr_header_len; TBD -*/ -static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, - int CC_id, - frame_t frameP, - sub_frame_t subframe, - uint8_t gNB_index, - uint8_t *ulsch_buffer, - uint32_t buflen, - int16_t tx_power, - int16_t P_CMAX, - NR_UE_MAC_CE_INFO *mac_ce_p) +static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, + int CC_id, + frame_t frameP, + sub_frame_t subframe, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + uint32_t buflen, + uint32_t *BSR_bytes, + NR_UE_MAC_CE_INFO *mac_ce_p, + int tx_power, + int P_CMAX) { - int num_lcg_id_with_data = 0; // Preparing the MAC CEs sub-PDUs and get the total size - mac_ce_p->bsr_header_len = 0; - int lcg_id = 0; - while (lcg_id != NR_INVALID_LCGID) { - if (mac->scheduling_info.lcg_sched_info[lcg_id].BSR_bytes) { - num_lcg_id_with_data++; - } - lcg_id++; - } + *mac_ce_p = (NR_UE_MAC_CE_INFO){.pdu_end = ulsch_buffer + buflen, .cur_ptr = ulsch_buffer}; + memset(mac_ce_p->lcids_data_status, 1, NR_MAX_NUM_LCID); // Compute BSR Length if Regular or Periodic BSR is triggered - // WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing + // If we decide here to send BSR long, we may decide later to use BSR short // if there remains less than 1 LCGROUP with data after Tx + int bsr_len = 0; if (mac->scheduling_info.BSR_reporting_active) { - AssertFatal((mac->scheduling_info.BSR_reporting_active & NR_BSR_TRIGGER_PADDING) == 0, - "Inconsistent BSR Trigger=%d !\n", - mac->scheduling_info.BSR_reporting_active); - + // count the active channels + int num_lcg_id_with_data = 0; + for (int i = 0; i < NR_MAX_NUM_LCGID; i++) { + if (BSR_bytes[i]) + num_lcg_id_with_data++; + } // A Regular or Periodic BSR can only be sent if TBS is sufficient // as transmitting only a BSR is not allowed if UE has data to transmit - if (num_lcg_id_with_data <= 1) { - if (buflen >= (sizeof(NR_BSR_SHORT) + sizeof(NR_MAC_SUBHEADER_FIXED) + 1)) { - mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); // 1 byte - mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); // 1 byte - } - } else { - if (buflen >= (num_lcg_id_with_data + 1 + sizeof(NR_MAC_SUBHEADER_SHORT) + 1)) { - mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; // variable size - mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); // 2 bytes - } - } + int size_for_long = num_lcg_id_with_data + sizeof(NR_BSR_LONG) + sizeof(NR_MAC_SUBHEADER_SHORT); + int size_for_short = sizeof(NR_BSR_SHORT) + sizeof(NR_MAC_SUBHEADER_FIXED); + if (num_lcg_id_with_data > 1 && buflen >= size_for_long) + bsr_len = size_for_long; + else if ((num_lcg_id_with_data > 0 && buflen >= size_for_short) + || mac->scheduling_info.BSR_reporting_active & NR_BSR_TRIGGER_PERIODIC) + bsr_len = size_for_short; } - mac_ce_p->bsr_len = mac_ce_p->bsr_ce_len + mac_ce_p->bsr_header_len; - - nr_phr_info_t *phr_info = &mac->scheduling_info.phr_info; - mac_ce_p->phr_header_len = 0; - mac_ce_p->phr_ce_len = 0; if (phr_info->is_configured && phr_info->phr_reporting > 0) { - if (buflen >= (mac_ce_p->bsr_len + sizeof(NR_MAC_SUBHEADER_FIXED) + sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE))) { + int needed = sizeof(NR_MAC_SUBHEADER_FIXED) + sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); + if (buflen >= bsr_len + needed) { if (mac->scheduling_info.phr_info.phr_reporting) { - mac_ce_p->phr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); - mac_ce_p->phr_ce_len = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); - nr_ue_fill_phr(mac, mac_ce_p->phr, P_CMAX, tx_power, frameP, subframe); + mac_ce_p->phr_len = needed; + nr_ue_fill_phr(mac, &mac_ce_p->phr, P_CMAX, tx_power, frameP, subframe); } } } - mac_ce_p->phr_len = mac_ce_p->phr_header_len + mac_ce_p->phr_ce_len; - - return (mac_ce_p->bsr_len + mac_ce_p->phr_len); + mac_ce_p->end_for_tailer = mac_ce_p->pdu_end - bsr_len - mac_ce_p->phr_len; } /* @@ -3075,14 +3056,11 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, Need the following from mac_ce_p: bsr_ce_len bsr_len - sdu_length_total - total_mac_pdu_header_len Update the following in mac_ce_p: bsr_ce_len bsr_header_len bsr_len tot_mac_ce_len - total_mac_pdu_header_len bsr_s bsr_l bsr_t @@ -3090,30 +3068,27 @@ static int nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, - uint8_t *ulsch_buffer, - uint32_t buflen, - NR_UE_MAC_CE_INFO *mac_ce_p) + NR_UE_MAC_CE_INFO *mac_ce_p, + uint32_t *BSR_bytes, + bool *BSRsent) { // Compute BSR Values and update Nb LCGID with data after multiplexing - uint32_t padding_len = 0; int num_lcg_id_with_data = 0; - int lcg_id_bsr_trunc = 0; + int lcg_id_bsr_max = 0; + uint max = 0; NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info; + // Search the LCGID within max size + // at this point the BSR_bytes array of waiting buffers for (int lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) { - if (mac_ce_p->bsr_ce_len == sizeof(NR_BSR_SHORT)) { - sched_info->lcg_sched_info[lcg_id].BSR = - nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, - NR_SHORT_BSR_TABLE_SIZE, - sched_info->lcg_sched_info[lcg_id].BSR_bytes); - } else { - sched_info->lcg_sched_info[lcg_id].BSR = - nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, - NR_LONG_BSR_TABLE_SIZE, - sched_info->lcg_sched_info[lcg_id].BSR_bytes); - } - if (sched_info->lcg_sched_info[lcg_id].BSR_bytes) { + if (sched_info->lc_sched_info[lcg_id].LCGID == NR_INVALID_LCGID) + continue; + uint sz = BSR_bytes[lcg_id]; + if (sz) { num_lcg_id_with_data++; - lcg_id_bsr_trunc = lcg_id; + if (sz >= max) { + lcg_id_bsr_max = lcg_id; + max = sz; + } } } @@ -3128,119 +3103,74 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, - else report Short BSR. - else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR. */ - if (mac_ce_p->sdu_length_total) { - padding_len = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total); - } - - if ((padding_len) && (mac_ce_p->bsr_len == 0)) { - /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR */ - if (padding_len >= (num_lcg_id_with_data + 1 + sizeof(NR_MAC_SUBHEADER_SHORT))) { - mac_ce_p->bsr_ce_len = num_lcg_id_with_data + 1; //variable size - mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_SHORT); //2 bytes - // Trigger BSR Padding - sched_info->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING; - } else if (padding_len >= (sizeof(NR_BSR_SHORT)+sizeof(NR_MAC_SUBHEADER_FIXED))) { - mac_ce_p->bsr_ce_len = sizeof(NR_BSR_SHORT); //1 byte - mac_ce_p->bsr_header_len = sizeof(NR_MAC_SUBHEADER_FIXED); //1 byte - - if (num_lcg_id_with_data > 1) { - // REPORT SHORT TRUNCATED BSR - // Get LCGID of highest priority LCID with data (todo) - for (int lcid = 1; lcid <= NR_MAX_NUM_LCID; lcid++) { - NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); - if ((sched_info->LCGID != NR_INVALID_LCGID) && (mac->scheduling_info.lcg_sched_info[sched_info->LCGID].BSR_bytes)) { - lcg_id_bsr_trunc = sched_info->LCGID; - } - } - } else { - // Report SHORT BSR, clear bsr_t - mac_ce_p->bsr_t = NULL; - } - - // Trigger BSR Padding - sched_info->BSR_reporting_active |= NR_BSR_TRIGGER_PADDING; - } - - mac_ce_p->bsr_len = mac_ce_p->bsr_header_len + mac_ce_p->bsr_ce_len; - mac_ce_p->tot_mac_ce_len += mac_ce_p->bsr_len; - mac_ce_p->total_mac_pdu_header_len += mac_ce_p->bsr_len; - } - - //Fill BSR Infos - if (mac_ce_p->bsr_ce_len == 0) { - mac_ce_p->bsr_s = NULL; - mac_ce_p->bsr_l = NULL; - mac_ce_p->bsr_t = NULL; - } else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_SHORT)) { - mac_ce_p->bsr_s = NULL; - mac_ce_p->bsr_t = NULL; - mac_ce_p->bsr_l->Buffer_size0 = sched_info->lcg_sched_info[0].BSR; - mac_ce_p->bsr_l->Buffer_size1 = sched_info->lcg_sched_info[1].BSR; - mac_ce_p->bsr_l->Buffer_size2 = sched_info->lcg_sched_info[2].BSR; - mac_ce_p->bsr_l->Buffer_size3 = sched_info->lcg_sched_info[3].BSR; - mac_ce_p->bsr_l->Buffer_size4 = sched_info->lcg_sched_info[4].BSR; - mac_ce_p->bsr_l->Buffer_size5 = sched_info->lcg_sched_info[5].BSR; - mac_ce_p->bsr_l->Buffer_size6 = sched_info->lcg_sched_info[6].BSR; - mac_ce_p->bsr_l->Buffer_size7 = sched_info->lcg_sched_info[7].BSR; + uint32_t padding_len = mac_ce_p->pdu_end - mac_ce_p->cur_ptr - mac_ce_p->phr_len; + AssertFatal(padding_len >= 0, "Error in buffer size compute"); + mac_ce_p->bsr.type_bsr = b_none; + int short_bsr_sz = sizeof(NR_BSR_SHORT) + sizeof(NR_MAC_SUBHEADER_FIXED); + int long_bsr_sz = num_lcg_id_with_data + sizeof(NR_BSR_LONG) + sizeof(NR_MAC_SUBHEADER_SHORT); + if (num_lcg_id_with_data < 2 && padding_len >= short_bsr_sz) { + mac_ce_p->bsr.type_bsr = b_short; + mac_ce_p->bsr.bsr.s.LcgID = lcg_id_bsr_max; + mac_ce_p->bsr.bsr.s.Buffer_size = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, max); LOG_D(NR_MAC, - "[UE %d] Frame %d subframe %d BSR Trig=%d report LONG BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 " - "%d level LCGID4 %d,level LCGID5 %d,level LCGID6 %d,level LCGID7 %d)\n", + "[UE %d] sfn %d.%d BSR Trigger=0x%x report SHORT BSR with level %d for LCGID %d\n", mac->ue_id, frame, slot, sched_info->BSR_reporting_active, - sched_info->lcg_sched_info[0].BSR, - sched_info->lcg_sched_info[1].BSR, - sched_info->lcg_sched_info[2].BSR, - sched_info->lcg_sched_info[3].BSR, - sched_info->lcg_sched_info[4].BSR, - sched_info->lcg_sched_info[5].BSR, - sched_info->lcg_sched_info[6].BSR, - sched_info->lcg_sched_info[7].BSR); - } else if (mac_ce_p->bsr_header_len == sizeof(NR_MAC_SUBHEADER_FIXED)) { - mac_ce_p->bsr_l = NULL; - - if ((mac_ce_p->bsr_t != NULL) && (sched_info->BSR_reporting_active & NR_BSR_TRIGGER_PADDING)) { - //Truncated BSR - mac_ce_p->bsr_s = NULL; - mac_ce_p->bsr_t->LcgID = lcg_id_bsr_trunc; - mac_ce_p->bsr_t->Buffer_size = sched_info->lcg_sched_info[lcg_id_bsr_trunc].BSR; - LOG_D(NR_MAC, - "[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n", - mac->ue_id, - frame, - slot, - sched_info->BSR_reporting_active, - sched_info->lcg_sched_info[lcg_id_bsr_trunc].BSR, - lcg_id_bsr_trunc); - } else { - mac_ce_p->bsr_t = NULL; - mac_ce_p->bsr_s->LcgID = lcg_id_bsr_trunc; - mac_ce_p->bsr_s->Buffer_size = sched_info->lcg_sched_info[lcg_id_bsr_trunc].BSR; - LOG_D(NR_MAC, - "[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n", - mac->ue_id, - frame, - slot, - sched_info->BSR_reporting_active, - sched_info->lcg_sched_info[lcg_id_bsr_trunc].BSR, - lcg_id_bsr_trunc); + mac_ce_p->bsr.bsr.s.Buffer_size, + lcg_id_bsr_max); + } else if (padding_len >= long_bsr_sz) { + /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, + report Long BSR whatever periodic or regular BSR*/ + mac_ce_p->bsr.type_bsr = b_long; + uint8_t *tmp = mac_ce_p->bsr.bsr.lc_bsr; + for (int lcg_id = 0; lcg_id < 8; lcg_id++) { + tmp[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, BSR_bytes[lcg_id]); } - } + LOG_D(NR_MAC, + "[UE %d] sfn %d.%d BSR Trig=0x%x report LONG BSR (level LCGID %d %d %d %d %d %d %d %d)\n", + mac->ue_id, + frame, + slot, + sched_info->BSR_reporting_active, + tmp[0], + tmp[1], + tmp[2], + tmp[3], + tmp[4], + tmp[5], + tmp[6], + tmp[7]); + } else if (padding_len == short_bsr_sz) { + mac_ce_p->bsr.type_bsr = b_short_trunc; + mac_ce_p->bsr.bsr.s.LcgID = lcg_id_bsr_max; + mac_ce_p->bsr.bsr.s.Buffer_size = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, max); + } else if (padding_len >= sizeof(NR_BSR_LONG) + sizeof(NR_MAC_SUBHEADER_SHORT)) { + mac_ce_p->bsr.type_bsr = b_long_trunc; + // Fixme: this should be sorted by (TS 38.321, 5.4.5) + // the logical channels having data available for + // transmission following a decreasing order of the highest priority logical channel (with or without data + // available for transmission) in each of these LCG(s), and in case of equal priority, in increasing order of LCGID + uint8_t *tmp = mac_ce_p->bsr.bsr.lc_bsr; + for (int lcg_id = 0; lcg_id < 8; lcg_id++) { + tmp[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, BSR_bytes[lcg_id]); + } + } else + LOG_D(NR_MAC, "Can't add any BSR, not enough padding\n"); /* Actions when a BSR is sent */ - if (mac_ce_p->bsr_ce_len) { + if (mac_ce_p->bsr.type_bsr != b_none) { LOG_D(NR_MAC, - "[UE %d] MAC BSR Sent! ce %d, hdr %d buff_len %d triggering LCID %ld\n", + "[UE %d] MAC BSR Sent! buff_len %ld triggering LCID %ld\n", mac->ue_id, - mac_ce_p->bsr_ce_len, - mac_ce_p->bsr_header_len, - buflen, + mac_ce_p->pdu_end - mac_ce_p->cur_ptr, sched_info->regularBSR_trigger_lcid); + *BSRsent = true; // Reset ReTx BSR Timer nr_timer_start(&sched_info->retxBSR_Timer); // Reset Periodic Timer except when BSR is truncated - if (mac_ce_p->bsr_t == NULL) { + if (mac_ce_p->bsr.type_bsr != b_long_trunc && mac_ce_p->bsr.type_bsr != b_short_trunc) { nr_timer_start(&sched_info->periodicBSR_Timer); LOG_D(NR_MAC, "[UE %d] MAC Periodic BSR Timer Reset\n", mac->ue_id); } @@ -3256,10 +3186,12 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, nr_timer_stop(&sr->prohibitTimer); } } - // Reset BSR Trigger flags - sched_info->BSR_reporting_active = NR_BSR_TRIGGER_NONE; - sched_info->regularBSR_trigger_lcid = 0; } + + int size = + nr_write_ce_ulsch_pdu(mac_ce_p->cur_ptr, mac, mac_ce_p->phr_len ? &mac_ce_p->phr : NULL, &mac_ce_p->bsr, mac_ce_p->pdu_end); + LOG_D(NR_MAC, "Added %d bytes of BSR\n", size); + mac_ce_p->cur_ptr += size; } uint32_t get_count_lcids_same_priority(uint8_t start, uint8_t total_active_lcids, nr_lcordered_info_t *lcid_ordered_array) @@ -3276,19 +3208,19 @@ uint32_t get_count_lcids_same_priority(uint8_t start, uint8_t total_active_lcids return same_priority_count; } -long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac, - uint8_t same_priority_count, - uint8_t lc_num, - uint32_t buflen_remain_ep, - int32_t buflen_remain, - uint8_t round_id, - uint32_t *bytes_read_fromlc, - long *target) +static long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac, + uint8_t same_priority_count, + uint8_t lc_num, + uint32_t buflen_remain_ep, + int32_t buflen_remain, + uint8_t round_id, + uint32_t *bytes_read_fromlc, + long *target) { /* Calculates the number of bytes the logical channel should request from the correcponding RLC buffer*/ nr_lcordered_info_t *lc_info = get_lc_info_from_lcid(mac, lc_num); AssertFatal(lc_info, "Couldn't find logical channel with LCID %d\n", lc_num); - uint32_t pbr = lc_info->pbr; + const uint32_t pbr = lc_info->pbr; NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lc_num); int32_t lcid_remain_buffer = sched_info->LCID_buffer_remain; *target = (same_priority_count > 1) ? min(buflen_remain_ep, pbr) : pbr; @@ -3309,7 +3241,8 @@ long get_num_bytes_to_reqlc(NR_UE_MAC_INST_t *mac, num_bytes_requested = min(buflen_remain, lcid_remain_buffer); } } - AssertFatal(num_remaining_bytes >= 0, "the total number of bytes allocated until target length is greater than expected\n"); + AssertFatal(num_remaining_bytes >= 0 && num_bytes_requested <= buflen_remain, + "the total number of bytes allocated until target length is greater than expected\n"); LOG_D(NR_MAC, "number of bytes requested for lcid %d is %li\n", lc_num, num_bytes_requested); return num_bytes_requested; @@ -3327,64 +3260,68 @@ bool get_dataavailability_buffers(uint8_t total_active_lcids, nr_lcordered_info_ return false; } -static void select_logical_channels(NR_UE_MAC_INST_t *mac, int *num_active_lcids, nr_lcordered_info_t *active_lcids) +static uint select_logical_channels(NR_UE_MAC_INST_t *mac, nr_lcordered_info_t *active_lcids) { // (TODO: selection of logical channels for logical channel prioritization procedure as per 5.4.3.1.2 Selection of logical // channels, TS38.321) - + int nb = 0; // selection of logical channels with Bj > 0 for (int i = 0; i < mac->lc_ordered_list.count; i++) { int lcid = mac->lc_ordered_list.array[i]->lcid; NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); if (sched_info->Bj > 0) { - active_lcids[*num_active_lcids] = *mac->lc_ordered_list.array[i]; - (*num_active_lcids)++; - LOG_D(NR_MAC, "The available lcid is %d with total active channels count = %d\n", lcid, *num_active_lcids); + active_lcids[nb++] = *mac->lc_ordered_list.array[i]; + LOG_D(NR_MAC, "The available lcid is %d with total active channels count = %d\n", lcid, nb); } } + return nb; } static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, uint8_t gNB_index, - uint32_t buflen, - int32_t *buflen_remain, int lcid, - uint8_t **pdu, - uint32_t *counter, - uint8_t count_same_priority_lcids, + uint count_same_priority_lcids, uint32_t buflen_ep, uint32_t *lcids_bytes_tot, - uint16_t *num_sdus, NR_UE_MAC_CE_INFO *mac_ce_p, - bool *lcids_data_status, - uint8_t *num_lcids_same_priority) + uint *num_lcids_same_priority, + uint32_t *BSR_bytes) { - const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG); - /* prepare the MAC sdu */ NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); int32_t lcid_remain_buffer = sched_info->LCID_buffer_remain; + uint usable = mac_ce_p->end_for_tailer - mac_ce_p->cur_ptr; LOG_D(NR_MAC, - "[UE %d] [%d.%d] lcp round = %d, remaining mac pdu length = %d, lcid buffer remaining = %d, lcid = %d \n", + "[UE %d] [%d.%d] lcp round = %d, remaining mac pdu length before BSR = %d, lcid buffer remaining = %d, lcid = %d \n", mac->ue_id, frame, slot, - *counter, - *buflen_remain, + mac_ce_p->lcp_allocation_counter, + usable, lcid_remain_buffer, lcid); - // Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU - NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *)(*pdu); + if (mac_ce_p->end_for_tailer - mac_ce_p->cur_ptr < sizeof(NR_MAC_SUBHEADER_LONG)) + // We can't add one byte after the header + return false; - *pdu += sh_size; + // Pointer used to build the MAC sub-PDU headers in the ULSCH buffer for each SDU + NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *)mac_ce_p->cur_ptr; // number of bytes requested from RLC for each LCID long target = 0; - long bytes_requested = - get_num_bytes_to_reqlc(mac, count_same_priority_lcids, lcid, buflen_ep, *buflen_remain, *counter, lcids_bytes_tot, &target); + int header_sz = usable < 256 ? sizeof(NR_MAC_SUBHEADER_SHORT) : sizeof(NR_MAC_SUBHEADER_LONG); + long bytes_requested = get_num_bytes_to_reqlc(mac, + count_same_priority_lcids, + lcid, + buflen_ep, + usable - header_sz, + mac_ce_p->lcp_allocation_counter, + lcids_bytes_tot, + &target); + header_sz = bytes_requested < 256 ? sizeof(NR_MAC_SUBHEADER_SHORT) : sizeof(NR_MAC_SUBHEADER_LONG); uint16_t sdu_length = mac_rlc_data_req(mac->ue_id, mac->ue_id, @@ -3394,7 +3331,7 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, MBMS_FLAG_NO, lcid, bytes_requested, - (char *)(*pdu), + (char *)mac_ce_p->cur_ptr + header_sz, 0, 0); @@ -3418,62 +3355,49 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, int lc_idx = lcid_buffer_index(lcid); if (sdu_length > 0) { + mac_ce_p->num_sdus++; LOG_D(NR_MAC, "[UE %d] [%d.%d] UL-DXCH -> ULSCH, Generating UL MAC sub-PDU for SDU %d, length %d bytes, RB with LCID " - "0x%02x (buflen (TBS) %d bytes)\n", + "0x%02x (buflen (TBS) %ld bytes)\n", mac->ue_id, frame, slot, - (*num_sdus) + 1, + mac_ce_p->num_sdus, sdu_length, lcid, - buflen); - - header->R = 0; - header->F = 1; - header->LCID = lcid; - header->L = htons(sdu_length); - + mac_ce_p->end_for_tailer - mac_ce_p->cur_ptr); + if (header_sz == sizeof(NR_MAC_SUBHEADER_SHORT)) { + *(NR_MAC_SUBHEADER_SHORT *)header = (NR_MAC_SUBHEADER_SHORT){.R = 0, .F = 0, .LCID = lcid, .L = sdu_length}; + } else { + *header = (NR_MAC_SUBHEADER_LONG){.R = 0, .F = 1, .LCID = lcid, .L = htons(sdu_length)}; #ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "dumping MAC sub-header with length %d: \n", sh_size); - log_dump(NR_MAC, header, sh_size, LOG_DUMP_CHAR, "\n"); - LOG_I(NR_MAC, "dumping MAC SDU with length %d \n", sdu_length); - log_dump(NR_MAC, *pdu, sdu_length, LOG_DUMP_CHAR, "\n"); + LOG_I(NR_MAC, "dumping MAC SDU with length %d: \n", sduL); + log_dump(NR_MAC, header, sduL, LOG_DUMP_CHAR, "\n"); #endif - - *pdu += sdu_length; - mac_ce_p->sdu_length_total += sdu_length; - mac_ce_p->total_mac_pdu_header_len += sh_size; - - (*num_sdus)++; + } + mac_ce_p->cur_ptr += header_sz + sdu_length; } else { - *pdu -= sh_size; - lcids_data_status[lc_idx] = false; + mac_ce_p->lcids_data_status[lc_idx] = false; (*num_lcids_same_priority)--; - LOG_D(NR_MAC, "No data to transmit for RB with LCID 0x%02x and hence set to false\n", lcid); - return 0; + LOG_D(NR_MAC, "No data to transmit for RB with LCID 0x%02x\n and hence set to false", lcid); + return false; } - *buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); - // Update Buffer remain and BSR bytes after transmission - NR_LCG_SCHEDULING_INFO *lcg_info = &mac->scheduling_info.lcg_sched_info[0]; sched_info->LCID_buffer_remain -= sdu_length; - (lcg_info + sched_info->LCGID)->BSR_bytes -= sdu_length; + BSR_bytes[sched_info->LCGID] -= sdu_length; LOG_D(NR_MAC, "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%ld = %d\n", mac->ue_id, frame, slot, sched_info->LCGID, - (lcg_info + sched_info->LCGID)->BSR_bytes); - if ((lcg_info + sched_info->LCGID)->BSR_bytes < 0) - (lcg_info + sched_info->LCGID)->BSR_bytes = 0; + BSR_bytes[sched_info->LCGID]); // update number of bytes served from the current lcid - lcids_bytes_tot[lc_idx] += (sdu_length + (count_same_priority_lcids > 1 ? 1 : 0) * sh_size); + lcids_bytes_tot[lc_idx] += (sdu_length + (count_same_priority_lcids > 1 ? 1 : 0) * sizeof(NR_MAC_SUBHEADER_LONG)); - if ((*counter == 0 && lcids_bytes_tot[lc_idx] >= target) + if ((mac_ce_p->lcp_allocation_counter == 0 && lcids_bytes_tot[lc_idx] >= target) || (count_same_priority_lcids > 1 && lcids_bytes_tot[lc_idx] >= buflen_ep)) { // only prioritized bit rate should be taken from logical channel in // the first lcp run except when infinity @@ -3482,9 +3406,9 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, lcid, lcids_bytes_tot[lc_idx]); (*num_lcids_same_priority)--; - return 0; + return false; } - return 1; + return true; } /** @@ -3499,77 +3423,55 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, * @ulsch_buffer Pointer to ULSCH PDU * @buflen TBS */ -uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, - int CC_id, - frame_t frame, - slot_t slot, - uint8_t gNB_index, - uint8_t *ulsch_buffer, - uint32_t buflen, - int16_t tx_power, - int16_t P_CMAX) +static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, + int CC_id, + frame_t frame, + slot_t slot, + uint8_t gNB_index, + uint8_t *ulsch_buffer, + const uint32_t buflen, + int tx_power, + int P_CMAX, + bool *BSRsent) { NR_UE_MAC_CE_INFO mac_ce_info; - NR_UE_MAC_CE_INFO *mac_ce_p=&mac_ce_info; - int32_t buflen_remain = 0; - mac_ce_p->bsr_len = 0; - mac_ce_p->bsr_ce_len = 0; - mac_ce_p->bsr_header_len = 0; - mac_ce_p->phr_len = 0; - //mac_ce_p->phr_ce_len = 0; - //mac_ce_p->phr_header_len = 0; - - uint16_t num_sdus = 0; - mac_ce_p->sdu_length_total = 0; - NR_BSR_SHORT bsr_short, bsr_truncated; - NR_BSR_LONG bsr_long; - mac_ce_p->bsr_s = &bsr_short; - mac_ce_p->bsr_l = &bsr_long; - mac_ce_p->bsr_t = &bsr_truncated; - - NR_SINGLE_ENTRY_PHR_MAC_CE phr; - mac_ce_p->phr = &phr; - - //int highest_priority = 16; - const uint8_t sh_size = sizeof(NR_MAC_SUBHEADER_LONG); - - // Pointer used to build the MAC PDU by placing the RLC SDUs in the ULSCH buffer - uint8_t *pdu = ulsch_buffer; - - // variable used to store the lcid data status during lcp - bool lcids_data_status[NR_MAX_NUM_LCID] = {0}; - memset(lcids_data_status, 1, NR_MAX_NUM_LCID); // in the first run all the lc are allocated as per bj and prioritized bit rate but in subsequent runs, no need to consider - uint32_t lcp_allocation_counter = 0; // bj and prioritized bit rate but just consider priority uint32_t buflen_ep = 0; // this variable holds the length in bytes in mac pdu when multiple equal priority channels are present // because as per standard(TS38.321), all equal priority channels should be served equally - // nr_ue_get_sdu_mac_ce_pre updates all mac_ce related header field related to length - mac_ce_p->tot_mac_ce_len = nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, tx_power, P_CMAX, mac_ce_p); - mac_ce_p->total_mac_pdu_header_len = mac_ce_p->tot_mac_ce_len; + // Call BSR procedure as described in Section 5.4.5 in 38.321 + // Check whether BSR is triggered before scheduling ULSCH + uint32_t BSR_bytes[NR_MAX_NUM_LCGID] = {0}; + nr_update_bsr(mac, BSR_bytes); - LOG_D(NR_MAC, "[UE %d] [%d.%d] process UL transport block at with size TBS = %d bytes \n", mac->ue_id, frame, slot, buflen); + nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, BSR_bytes, &mac_ce_info, tx_power, P_CMAX); + + LOG_D(NR_MAC, + "[UE %d] [%d.%d] process UL transport block with size TBS = %d bytes, number of existing LCids %d \n", + mac->ue_id, + frame, + slot, + buflen, + mac->lc_ordered_list.count); - // selection of logical channels - int avail_lcids_count = 0; // variable used to build the lcids with positive Bj nr_lcordered_info_t lcids_bj_pos[mac->lc_ordered_list.count]; - select_logical_channels(mac, &avail_lcids_count, lcids_bj_pos); + int avail_lcids_count = select_logical_channels(mac, lcids_bj_pos); // multiplex in the order of highest priority do { /* go until there is space availabile in the MAC PDU and there is data available in RLC buffers of active logical channels */ - uint8_t num_lcids_same_priority = 0; - uint8_t count_same_priority_lcids = 0; + uint num_lcids_same_priority = 0; + uint count_same_priority_lcids = 0; // variable used to store the total bytes read from rlc for each lcid uint32_t lcids_bytes_tot[NR_MAX_NUM_LCID] = {0}; - for (uint8_t id = 0; id < avail_lcids_count; id++) { + for (uint id = 0; id < avail_lcids_count; id++) { /* loop over all logical channels in the order of priority. As stated in TS138.321 Section 5.4.3.1, in the first run, only prioritized number of bytes are taken out from the corresponding RLC buffers of all active logical channels and if there is @@ -3577,45 +3479,36 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, is placed in the MAC PDU before going on to next high priority logical channel */ int lcid = lcids_bj_pos[id].lcid; - NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lcid); int idx = lcid_buffer_index(lcid); // skip the logical channel if no data in the buffer initially or the data in the buffer was zero because it was written in to // MAC PDU - if (!lc_sched_info->LCID_buffer_with_data || !lcids_data_status[idx]) { - lcids_data_status[idx] = false; + if (!mac_ce_info.lcids_data_status[idx]) { continue; } // count number of lc with same priority as lcid if (!num_lcids_same_priority) { - num_lcids_same_priority = count_same_priority_lcids = - get_count_lcids_same_priority(id, avail_lcids_count, lcids_bj_pos); + num_lcids_same_priority = count_same_priority_lcids = get_count_lcids_same_priority(id, avail_lcids_count, lcids_bj_pos); } - buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total + sh_size); - + int remain = mac_ce_info.end_for_tailer - mac_ce_info.cur_ptr; LOG_D(NR_MAC, - "[UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x (TBS %d bytes, sdu_length_total %d bytes, MAC header " - "len %d bytes," - "buflen_remain %d bytes)\n", + "[UE %d] [%d.%d] UL-DXCH -> ULSCH, RLC with LCID 0x%02x buflen_remain %d bytes)\n", mac->ue_id, frame, slot, lcid, - buflen, - mac_ce_p->sdu_length_total, - mac_ce_p->tot_mac_ce_len, - buflen_remain); + remain); if (num_lcids_same_priority == count_same_priority_lcids) { - const int32_t buflen_ep_tmp = (buflen_remain - (count_same_priority_lcids * sh_size)) / count_same_priority_lcids; + buflen_ep = (remain - (count_same_priority_lcids * sizeof(NR_MAC_SUBHEADER_LONG))) / count_same_priority_lcids; /* after serving equal priority LCIDs in the first round, buflen_remain could be > 0 and < (count_same_priority_lcids * sh_size) if above division yeilds a remainder. hence the following sets buflen_ep to 0 if there is not enough buffer left for subsequent rounds */ buflen_ep = buflen_ep_tmp < 0 ? 0 : buflen_ep_tmp; } - while (buflen_remain > 0) { + while (mac_ce_info.end_for_tailer - mac_ce_info.cur_ptr > 0) { /* loops until the requested number of bytes from MAC to RLC are placed in the MAC PDU. The number of requested bytes depends on whether it is the first run or otherwise because in the first run only prioritited number of bytes of all @@ -3626,80 +3519,38 @@ uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, frame, slot, gNB_index, - buflen, - &buflen_remain, lcid, - &pdu, - &lcp_allocation_counter, count_same_priority_lcids, buflen_ep, lcids_bytes_tot, - &num_sdus, - mac_ce_p, - lcids_data_status, - &num_lcids_same_priority)) { + &mac_ce_info, + &num_lcids_same_priority, + BSR_bytes)) { break; } } } - lcp_allocation_counter++; - } while (buflen_remain > 0 && get_dataavailability_buffers(avail_lcids_count, lcids_bj_pos, lcids_data_status)); + mac_ce_info.lcp_allocation_counter++; + } while (mac_ce_info.end_for_tailer - mac_ce_info.cur_ptr > sizeof(NR_MAC_SUBHEADER_LONG) + && get_dataavailability_buffers(avail_lcids_count, lcids_bj_pos, mac_ce_info.lcids_data_status)); - //nr_ue_get_sdu_mac_ce_post recalculates all mac_ce related header fields since buffer has been changed after mac_rlc_data_req. - //Also, BSR padding is handled here after knowing mac_ce_p->sdu_length_total. - nr_ue_get_sdu_mac_ce_post(mac, frame, slot, ulsch_buffer, buflen, mac_ce_p); - - if (mac_ce_p->tot_mac_ce_len > 0) { - LOG_D(NR_MAC, "In %s copying %d bytes of MAC CEs to the UL PDU \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len); - int size = nr_write_ce_ulsch_pdu(pdu, mac, mac_ce_p->phr_ce_len ? mac_ce_p->phr : NULL, 0, mac_ce_p->bsr_t, mac_ce_p->bsr_s, mac_ce_p->bsr_l); - if (size != mac_ce_p->tot_mac_ce_len) - LOG_E(NR_MAC, "MAC CE size computed by nr_write_ce_ulsch_pdu is %d while the one assumed before is %d\n", size, mac_ce_p->tot_mac_ce_len); - pdu += (unsigned char) mac_ce_p->tot_mac_ce_len; - -#ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "In %s: dumping MAC CE with length tot_mac_ce_len %d: \n", __FUNCTION__, mac_ce_p->tot_mac_ce_len); - log_dump(NR_MAC, mac_header_control_elements, mac_ce_p->tot_mac_ce_len, LOG_DUMP_CHAR, "\n"); -#endif - } - - buflen_remain = buflen - (mac_ce_p->total_mac_pdu_header_len + mac_ce_p->sdu_length_total); + nr_ue_get_sdu_mac_ce_post(mac, frame, slot, &mac_ce_info, BSR_bytes, BSRsent); // Compute final offset for padding and fill remainder of ULSCH with 0 - if (buflen_remain > 0) { - - LOG_D(NR_MAC, "Filling remainder %d bytes to the UL PDU \n", buflen_remain); - ((NR_MAC_SUBHEADER_FIXED *) pdu)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) pdu)->LCID = UL_SCH_LCID_PADDING; - -#ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "Padding MAC sub-header with length %ld bytes \n", sizeof(NR_MAC_SUBHEADER_FIXED)); - log_dump(NR_MAC, pdu, sizeof(NR_MAC_SUBHEADER_FIXED), LOG_DUMP_CHAR, "\n"); -#endif - - pdu++; - buflen_remain--; - - if (IS_SOFTMODEM_RFSIM) { - for (int j = 0; j < buflen_remain; j++) { - pdu[j] = (unsigned char)rand(); - } - } else { - memset(pdu, 0, buflen_remain); - } - -#ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "MAC padding sub-PDU with length %d bytes \n", buflen_remain); - log_dump(NR_MAC, pdu, buflen_remain, LOG_DUMP_CHAR, "\n"); -#endif + int remain = mac_ce_info.pdu_end - mac_ce_info.cur_ptr; + if (remain) { + LOG_D(NR_MAC, "Filling remainder %d bytes to the UL PDU \n", remain); + *(NR_MAC_SUBHEADER_FIXED *)mac_ce_info.cur_ptr = (NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = UL_SCH_LCID_PADDING}; + mac_ce_info.cur_ptr++; + memset(mac_ce_info.cur_ptr, 0, mac_ce_info.pdu_end - mac_ce_info.cur_ptr); } - #ifdef ENABLE_MAC_PAYLOAD_DEBUG - LOG_I(NR_MAC, "Dumping MAC PDU with length %d: \n", buflen); + LOG_I(NR_MAC, "MAC PDU %d bytes \n", mac_ce_p->cur_ptr - ulsch_buffer); log_dump(NR_MAC, ulsch_buffer, buflen, LOG_DUMP_CHAR, "\n"); #endif - return num_sdus > 0 ? 1 : 0; + return mac_ce_info.num_sdus > 0; // success if we got at least one sdu } static void schedule_ta_command(fapi_nr_dl_config_request_t *dl_config, NR_UE_MAC_INST_t *mac) @@ -3726,7 +3577,7 @@ static void nr_ue_fill_phr(NR_UE_MAC_INST_t *mac, nr_phr_info_t *phr_info = &mac->scheduling_info.phr_info; // Value mapping according to 38.133 10.1.18.1 const int PC_MAX_00 = -29; - phr->PCMAX = max(0, (int)P_CMAX - PC_MAX_00) & 0x3f; + *phr = (NR_SINGLE_ENTRY_PHR_MAC_CE){.PCMAX = max(0, (int)P_CMAX - PC_MAX_00) & 0x3f}; // Value mapping according to 38.133 10.1.17.1.1 const int POWER_HEADROOM_55 = 22; int headroom = P_CMAX - tx_power; From 2348b3c0650b05b42563e604a58e0007ce31dc56 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Wed, 23 Oct 2024 18:07:48 +0200 Subject: [PATCH 05/36] select LCG that contains the highest priorit LC with data to transmit instead of the LC with maximum waiting data size --- openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 51 ++++--- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 140 +++++++++---------- 3 files changed, 95 insertions(+), 98 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 53d1183693..3f97c6c4fc 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -176,7 +176,7 @@ typedef struct { union { NR_BSR_SHORT s; NR_BSR_LONG l; - uint8_t lc_bsr[8]; + uint8_t lcg_bsr[8]; } bsr; enum { b_none, b_long, b_short, b_short_trunc, b_long_trunc } type_bsr; } type_bsr_t; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index c9c72bc2b9..36714fd80a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3777,7 +3777,7 @@ void nr_ue_process_mac_pdu(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *dl_i int nr_write_ce_msg3_pdu(uint8_t *mac_ce, NR_UE_MAC_INST_t *mac, rnti_t crnti, uint8_t *mac_ce_end) { uint8_t *pdu = mac_ce; - if (!get_softmodem_params()->sa && get_softmodem_params()->do_ra && mac->ra.ra_state != nrRA_SUCCEEDED) { + if (IS_SA_MODE(get_softmodem_params()) && mac->ra.ra_state != nrRA_SUCCEEDED) { LOG_D(NR_MAC, "Generating C-RNTI MAC CE with C-RNTI %x\n", crnti); *(NR_MAC_SUBHEADER_FIXED *)mac_ce = (NR_MAC_SUBHEADER_FIXED){.R = 0, .LCID = UL_SCH_LCID_C_RNTI}; mac_ce += sizeof(NR_MAC_SUBHEADER_FIXED); @@ -3834,37 +3834,37 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, *ceLong = (NR_BSR_LONG){0}; mac_ce += sizeof(NR_BSR_LONG); // int NR_BSR_LONG_SIZE = 1; - if (bsr->bsr.lc_bsr[0] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[0] && mac_ce < mac_ce_end) { ceLong->LcgID0 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[0]; + *mac_ce++ = bsr->bsr.lcg_bsr[0]; } - if (bsr->bsr.lc_bsr[1] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[1] && mac_ce < mac_ce_end) { ceLong->LcgID1 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[1]; + *mac_ce++ = bsr->bsr.lcg_bsr[1]; } - if (bsr->bsr.lc_bsr[2] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[2] && mac_ce < mac_ce_end) { ceLong->LcgID2 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[2]; + *mac_ce++ = bsr->bsr.lcg_bsr[2]; } - if (bsr->bsr.lc_bsr[3] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[3] && mac_ce < mac_ce_end) { ceLong->LcgID3 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[3]; + *mac_ce++ = bsr->bsr.lcg_bsr[3]; } - if (bsr->bsr.lc_bsr[4] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[4] && mac_ce < mac_ce_end) { ceLong->LcgID4 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[4]; + *mac_ce++ = bsr->bsr.lcg_bsr[4]; } - if (bsr->bsr.lc_bsr[5] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[5] && mac_ce < mac_ce_end) { ceLong->LcgID5 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[5]; + *mac_ce++ = bsr->bsr.lcg_bsr[5]; } - if (bsr->bsr.lc_bsr[6] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[6] && mac_ce < mac_ce_end) { ceLong->LcgID6 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[6]; + *mac_ce++ = bsr->bsr.lcg_bsr[6]; } - if (bsr->bsr.lc_bsr[7] && mac_ce < mac_ce_end) { + if (bsr->bsr.lcg_bsr[7] && mac_ce < mac_ce_end) { ceLong->LcgID7 = 1; - *mac_ce++ = bsr->bsr.lc_bsr[7]; + *mac_ce++ = bsr->bsr.lcg_bsr[7]; } *mac_pdu_subheader_ptr = (NR_MAC_SUBHEADER_SHORT){.LCID = bsr->type_bsr == b_long ? UL_SCH_LCID_L_BSR : UL_SCH_LCID_L_TRUNCATED_BSR, @@ -3873,20 +3873,19 @@ int nr_write_ce_ulsch_pdu(uint8_t *mac_ce, "[UE] Generating ULSCH PDU : long_bsr size %d Lcgbit 0x%02x Buffer_size %d %d %d %d %d %d %d %d\n", ((NR_MAC_SUBHEADER_SHORT *)mac_pdu_subheader_ptr)->L, *mac_ce, - bsr->bsr.lc_bsr[0], - bsr->bsr.lc_bsr[1], - bsr->bsr.lc_bsr[2], - bsr->bsr.lc_bsr[3], - bsr->bsr.lc_bsr[4], - bsr->bsr.lc_bsr[5], - bsr->bsr.lc_bsr[6], - bsr->bsr.lc_bsr[7]); + bsr->bsr.lcg_bsr[0], + bsr->bsr.lcg_bsr[1], + bsr->bsr.lcg_bsr[2], + bsr->bsr.lcg_bsr[3], + bsr->bsr.lcg_bsr[4], + bsr->bsr.lcg_bsr[5], + bsr->bsr.lcg_bsr[6], + bsr->bsr.lcg_bsr[7]); } break; case b_none: break; default: DevAssert(false); ->>>>>>> 4a6be6c8ce (fix BSR report malformed, add SHORT BSR when it can (instead of LONG BSR) simplify the code and make the code more explicit, but the may structure remain (nr_write_ce_ulsch_pdu interface is complex, merging it into the called would make simpler and more interstandable code), fix some asserts related to this part of code) } return mac_ce - pdu; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index a15715ad85..3f0e3a78a5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1402,14 +1402,22 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent) // if no pending data available for transmission // All pending SR(s) shall be cancelled and each respective sr-ProhibitTimer shall be stopped + // in TS 38.321: + // The SR configuration of the logical channel that triggered the BSR + // (subclause 5.4.5) (if such a configuration exists) is considered as corresponding SR configuration for the triggered SR + // in the hereafter code, we compute actual state at the time we compute the SR + // So, it might be more accurate than the logical channel that triggered the BSR some slots ago if new data came in the UE for + // ULSCH - int idx = 0; - for (idx = 0; idx < NR_MAX_NUM_LCID; idx++) { - if (sched_info->lc_sched_info[idx].LCID_buffer_remain) - break; + nr_lcordered_info_t *lc_info = NULL; + for (int idx = 0; idx < mac->lc_ordered_list.count && lc_info == NULL; idx++) { + nr_lcordered_info_t *lc_info_loop = mac->lc_ordered_list.array[idx]; + NR_LC_SCHEDULING_INFO *lc_sched_info = get_scheduling_info_from_lcid(mac, lc_info_loop->lcid); + if (lc_sched_info->LCID_buffer_remain) + lc_info = lc_info_loop; } - if (idx == NR_MAX_NUM_LCID) { // all queues are empty + if (lc_info == NULL) { // all queues are empty for (int i = 0; i < NR_MAX_SR_ID; i++) { nr_sr_info_t *sr = &sched_info->sr_info[i]; if (sr->active_SR_ID) { @@ -1426,15 +1434,12 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent) if (BSRsent || nr_timer_is_active(&sched_info->sr_DelayTimer)) return; - nr_lcordered_info_t *lc_info = get_lc_info_from_lcid(mac, idx + 1 /* see lcid_buffer_index() */); - AssertFatal(lc_info, "Couldn't find logical channel with LCID %ld\n", sched_info->regularBSR_trigger_lcid); - // if there is no UL-SCH resource available for a new transmission (ie we are at this point) - // if the MAC entity is configured with configured uplink grant(s) and the Regular BSR was triggered for a // logical channel for which logicalChannelSR-Mask is set to false or if (mac->current_UL_BWP->configuredGrantConfig && lc_info->lc_SRMask) return; + // if the UL-SCH resources available for a new transmission do not meet the LCP mapping restrictions // TODO not implemented @@ -1450,8 +1455,7 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac, bool BSRsent) LOG_D(NR_MAC, "Triggering SR for ID %d\n", lc_info->sr_id); sr->pending = true; sr->counter = 0; - } - else { + } else { // initiate a Random Access procedure on the SpCell and cancel the pending SR // if the MAC entity has no valid PUCCH resource configured for the pending SR sr->pending = false; @@ -1507,7 +1511,7 @@ which case the BSR is referred below to as 'Regular BSR'; */ -static void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *BSR_bytes) +static void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *LCG_bytes) { bool bsr_regular_triggered = mac->scheduling_info.BSR_reporting_active & NR_BSR_TRIGGER_REGULAR; for (int i = 0; i < mac->lc_ordered_list.count; i++) { @@ -1517,8 +1521,8 @@ static void nr_update_bsr(NR_UE_MAC_INST_t *mac, uint32_t *BSR_bytes) int lcgid = lc_sched_info->LCGID; // check if UL data for a logical channel which belongs to a LCG becomes available for transmission if (lcgid != NR_INVALID_LCGID) { - // Update BSR_bytes - BSR_bytes[lcgid] += lc_sched_info->LCID_buffer_remain; + // Update waiting bytes for this LCG + LCG_bytes[lcgid] += lc_sched_info->LCID_buffer_remain; if (!bsr_regular_triggered) { bsr_regular_triggered = true; trigger_regular_bsr(mac, lcid, lc_info->sr_DelayTimerApplied); @@ -1560,21 +1564,22 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) while (ulcfg_pdu->pdu_type != FAPI_NR_END) { uint8_t *ulsch_input_buffer = ulsch_input_buffer_array[number_of_pdus]; if (ulcfg_pdu->pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH) { - uint32_t TBS_bytes = ulcfg_pdu->pusch_config_pdu.pusch_data.tb_size; + nfapi_nr_ue_pusch_pdu_t *pdu = &ulcfg_pdu->pusch_config_pdu; + uint32_t TBS_bytes = pdu->pusch_data.tb_size; LOG_D(NR_MAC, "harq_id %d, new_data_indicator %d, TBS_bytes %d (ra_state %d)\n", - ulcfg_pdu->pusch_config_pdu.pusch_data.harq_process_id, - ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator, + pdu->pusch_data.harq_process_id, + pdu->pusch_data.new_data_indicator, TBS_bytes, ra->ra_state); - ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = NULL; + pdu->tx_request_body.fapiTxPdu = NULL; if ((ra->ra_state == nrRA_WAIT_RAR || ra->ra_state == nrRA_WAIT_MSGB) && !ra->cfra) { nr_get_Msg3_MsgA_PUSCH_payload(mac, ulsch_input_buffer, TBS_bytes); for (int k = 0; k < TBS_bytes; k++) { LOG_D(NR_MAC, "(%i): 0x%x\n", k, ulsch_input_buffer[k]); } - ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = ulsch_input_buffer; - ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes; + pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; + pdu->tx_request_body.pdu_length = TBS_bytes; number_of_pdus++; } else { if (ulcfg_pdu->pusch_config_pdu.pusch_data.new_data_indicator @@ -1585,23 +1590,23 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) return; } // Getting IP traffic to be transmitted - int tx_power = ulcfg_pdu->pusch_config_pdu.tx_power; + int tx_power = pdu->tx_power; int P_CMAX = nr_get_Pcmax(mac->p_Max, mac->nr_band, mac->frame_type, mac->frequency_range, mac->current_UL_BWP->channel_bandwidth, - ulcfg_pdu->pusch_config_pdu.qam_mod_order, + pdu->qam_mod_order, false, mac->current_UL_BWP->scs, mac->current_UL_BWP->BWPSize, - ulcfg_pdu->pusch_config_pdu.transform_precoding, - ulcfg_pdu->pusch_config_pdu.rb_size, - ulcfg_pdu->pusch_config_pdu.rb_start); + pdu->transform_precoding, + pdu->rb_size, + pdu->rb_start); nr_ue_get_sdu(mac, cc_id, frame_tx, slot_tx, gNB_index, ulsch_input_buffer, TBS_bytes, tx_power, P_CMAX, &BSRsent); - ulcfg_pdu->pusch_config_pdu.tx_request_body.fapiTxPdu = ulsch_input_buffer; - ulcfg_pdu->pusch_config_pdu.tx_request_body.pdu_length = TBS_bytes; + pdu->tx_request_body.fapiTxPdu = ulsch_input_buffer; + pdu->tx_request_body.pdu_length = TBS_bytes; number_of_pdus++; // start or restart dataInactivityTimer if any MAC entity transmits a MAC SDU for DTCH logical channel, // or DCCH logical channel @@ -1676,22 +1681,15 @@ void nr_ue_ul_scheduler(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info) static uint8_t nr_locate_BsrIndexByBufferSize(const uint32_t *table, int size, int value) { - uint8_t ju, jm, jl; - int ascend; - //DevAssert(size > 0); - //DevAssert(size <= 256); - if (value == 0) { return 0; //elseif (value > 150000) return 63; } - jl = 0; // lower bound - ju = size - 1; // upper bound - ascend = (table[ju] >= table[jl]) ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise - + int jl = 0; // lower bound + int ju = size - 1; // upper bound + bool ascend = table[ju] >= table[jl] ? 1 : 0; // determine the order of the the table: 1 if ascending order of table, 0 otherwise while (ju - jl > 1) { //If we are not yet done, - jm = (ju + jl) >> 1; //compute a midpoint, - + int jm = (ju + jl) / 2; // compute a midpoint, if ((value >= table[jm]) == ascend) { jl = jm; // replace the lower limit } else { @@ -3008,7 +3006,7 @@ static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, uint8_t gNB_index, uint8_t *ulsch_buffer, uint32_t buflen, - uint32_t *BSR_bytes, + uint32_t *LCG_bytes, NR_UE_MAC_CE_INFO *mac_ce_p, int tx_power, int P_CMAX) @@ -3025,7 +3023,7 @@ static void nr_ue_get_sdu_mac_ce_pre(NR_UE_MAC_INST_t *mac, // count the active channels int num_lcg_id_with_data = 0; for (int i = 0; i < NR_MAX_NUM_LCGID; i++) { - if (BSR_bytes[i]) + if (LCG_bytes[i]) num_lcg_id_with_data++; } // A Regular or Periodic BSR can only be sent if TBS is sufficient @@ -3069,26 +3067,20 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, frame_t frame, slot_t slot, NR_UE_MAC_CE_INFO *mac_ce_p, - uint32_t *BSR_bytes, + uint32_t *LCG_bytes, bool *BSRsent) { // Compute BSR Values and update Nb LCGID with data after multiplexing - int num_lcg_id_with_data = 0; int lcg_id_bsr_max = 0; - uint max = 0; NR_UE_SCHEDULING_INFO *sched_info = &mac->scheduling_info; - // Search the LCGID within max size - // at this point the BSR_bytes array of waiting buffers - for (int lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) { - if (sched_info->lc_sched_info[lcg_id].LCGID == NR_INVALID_LCGID) - continue; - uint sz = BSR_bytes[lcg_id]; - if (sz) { - num_lcg_id_with_data++; - if (sz >= max) { - lcg_id_bsr_max = lcg_id; - max = sz; - } + // Search the LCGID within waiting data for the highest priority LC + for (int i = 0; i < mac->lc_ordered_list.count; i++) { + int lcid = mac->lc_ordered_list.array[i]->lcid; + NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); + if (sched_info->LCID_buffer_remain) { + // this is the highest priority LC with data to transmit + lcg_id_bsr_max = sched_info->LCGID; + break; } } @@ -3107,11 +3099,15 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, AssertFatal(padding_len >= 0, "Error in buffer size compute"); mac_ce_p->bsr.type_bsr = b_none; int short_bsr_sz = sizeof(NR_BSR_SHORT) + sizeof(NR_MAC_SUBHEADER_FIXED); + int num_lcg_id_with_data = 0; + for (int lcg_id = 0; lcg_id < NR_MAX_NUM_LCGID; lcg_id++) + num_lcg_id_with_data += LCG_bytes > 0; int long_bsr_sz = num_lcg_id_with_data + sizeof(NR_BSR_LONG) + sizeof(NR_MAC_SUBHEADER_SHORT); if (num_lcg_id_with_data < 2 && padding_len >= short_bsr_sz) { mac_ce_p->bsr.type_bsr = b_short; mac_ce_p->bsr.bsr.s.LcgID = lcg_id_bsr_max; - mac_ce_p->bsr.bsr.s.Buffer_size = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, max); + mac_ce_p->bsr.bsr.s.Buffer_size = + nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, LCG_bytes[lcg_id_bsr_max]); LOG_D(NR_MAC, "[UE %d] sfn %d.%d BSR Trigger=0x%x report SHORT BSR with level %d for LCGID %d\n", mac->ue_id, @@ -3124,9 +3120,9 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR whatever periodic or regular BSR*/ mac_ce_p->bsr.type_bsr = b_long; - uint8_t *tmp = mac_ce_p->bsr.bsr.lc_bsr; + uint8_t *tmp = mac_ce_p->bsr.bsr.lcg_bsr; for (int lcg_id = 0; lcg_id < 8; lcg_id++) { - tmp[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, BSR_bytes[lcg_id]); + tmp[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, LCG_bytes[lcg_id]); } LOG_D(NR_MAC, "[UE %d] sfn %d.%d BSR Trig=0x%x report LONG BSR (level LCGID %d %d %d %d %d %d %d %d)\n", @@ -3145,16 +3141,17 @@ static void nr_ue_get_sdu_mac_ce_post(NR_UE_MAC_INST_t *mac, } else if (padding_len == short_bsr_sz) { mac_ce_p->bsr.type_bsr = b_short_trunc; mac_ce_p->bsr.bsr.s.LcgID = lcg_id_bsr_max; - mac_ce_p->bsr.bsr.s.Buffer_size = nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, max); + mac_ce_p->bsr.bsr.s.Buffer_size = + nr_locate_BsrIndexByBufferSize(NR_SHORT_BSR_TABLE, NR_SHORT_BSR_TABLE_SIZE, LCG_bytes[lcg_id_bsr_max]); } else if (padding_len >= sizeof(NR_BSR_LONG) + sizeof(NR_MAC_SUBHEADER_SHORT)) { mac_ce_p->bsr.type_bsr = b_long_trunc; // Fixme: this should be sorted by (TS 38.321, 5.4.5) // the logical channels having data available for // transmission following a decreasing order of the highest priority logical channel (with or without data // available for transmission) in each of these LCG(s), and in case of equal priority, in increasing order of LCGID - uint8_t *tmp = mac_ce_p->bsr.bsr.lc_bsr; + uint8_t *tmp = mac_ce_p->bsr.bsr.lcg_bsr; for (int lcg_id = 0; lcg_id < 8; lcg_id++) { - tmp[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, BSR_bytes[lcg_id]); + tmp[lcg_id] = nr_locate_BsrIndexByBufferSize(NR_LONG_BSR_TABLE, NR_LONG_BSR_TABLE_SIZE, LCG_bytes[lcg_id]); } } else LOG_D(NR_MAC, "Can't add any BSR, not enough padding\n"); @@ -3287,7 +3284,7 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, uint32_t *lcids_bytes_tot, NR_UE_MAC_CE_INFO *mac_ce_p, uint *num_lcids_same_priority, - uint32_t *BSR_bytes) + uint32_t *LCG_bytes) { /* prepare the MAC sdu */ NR_LC_SCHEDULING_INFO *sched_info = get_scheduling_info_from_lcid(mac, lcid); @@ -3312,6 +3309,7 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, // number of bytes requested from RLC for each LCID long target = 0; + // NR_MAC_SUBHEADER_SHORT can handle up to 256 bytes message int header_sz = usable < 256 ? sizeof(NR_MAC_SUBHEADER_SHORT) : sizeof(NR_MAC_SUBHEADER_LONG); long bytes_requested = get_num_bytes_to_reqlc(mac, count_same_priority_lcids, @@ -3385,14 +3383,14 @@ static bool fill_mac_sdu(NR_UE_MAC_INST_t *mac, // Update Buffer remain and BSR bytes after transmission sched_info->LCID_buffer_remain -= sdu_length; - BSR_bytes[sched_info->LCGID] -= sdu_length; + LCG_bytes[sched_info->LCGID] -= sdu_length; LOG_D(NR_MAC, - "[UE %d] Update BSR [%d.%d] BSR_bytes for LCG%ld = %d\n", + "[UE %d] Update BSR [%d.%d] LCG_bytes for LCG%ld = %d\n", mac->ue_id, frame, slot, sched_info->LCGID, - BSR_bytes[sched_info->LCGID]); + LCG_bytes[sched_info->LCGID]); // update number of bytes served from the current lcid lcids_bytes_tot[lc_idx] += (sdu_length + (count_same_priority_lcids > 1 ? 1 : 0) * sizeof(NR_MAC_SUBHEADER_LONG)); @@ -3443,10 +3441,10 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, // Call BSR procedure as described in Section 5.4.5 in 38.321 // Check whether BSR is triggered before scheduling ULSCH - uint32_t BSR_bytes[NR_MAX_NUM_LCGID] = {0}; - nr_update_bsr(mac, BSR_bytes); + uint32_t LCG_bytes[NR_MAX_NUM_LCGID] = {0}; + nr_update_bsr(mac, LCG_bytes); - nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, BSR_bytes, &mac_ce_info, tx_power, P_CMAX); + nr_ue_get_sdu_mac_ce_pre(mac, CC_id, frame, slot, gNB_index, ulsch_buffer, buflen, LCG_bytes, &mac_ce_info, tx_power, P_CMAX); LOG_D(NR_MAC, "[UE %d] [%d.%d] process UL transport block with size TBS = %d bytes, number of existing LCids %d \n", @@ -3505,7 +3503,7 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, /* after serving equal priority LCIDs in the first round, buflen_remain could be > 0 and < (count_same_priority_lcids * sh_size) if above division yeilds a remainder. hence the following sets buflen_ep to 0 if there is not enough buffer left for subsequent rounds */ - buflen_ep = buflen_ep_tmp < 0 ? 0 : buflen_ep_tmp; + buflen_ep = buflen_ep < 0 ? 0 : buflen_ep; } while (mac_ce_info.end_for_tailer - mac_ce_info.cur_ptr > 0) { @@ -3525,7 +3523,7 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, lcids_bytes_tot, &mac_ce_info, &num_lcids_same_priority, - BSR_bytes)) { + LCG_bytes)) { break; } } @@ -3535,7 +3533,7 @@ static uint8_t nr_ue_get_sdu(NR_UE_MAC_INST_t *mac, } while (mac_ce_info.end_for_tailer - mac_ce_info.cur_ptr > sizeof(NR_MAC_SUBHEADER_LONG) && get_dataavailability_buffers(avail_lcids_count, lcids_bj_pos, mac_ce_info.lcids_data_status)); - nr_ue_get_sdu_mac_ce_post(mac, frame, slot, &mac_ce_info, BSR_bytes, BSRsent); + nr_ue_get_sdu_mac_ce_post(mac, frame, slot, &mac_ce_info, LCG_bytes, BSRsent); // Compute final offset for padding and fill remainder of ULSCH with 0 int remain = mac_ce_info.pdu_end - mac_ce_info.cur_ptr; From 4f884ab172c305b8afb42aecb2c7a617f7a044c3 Mon Sep 17 00:00:00 2001 From: francescomani Date: Tue, 19 Mar 2024 08:43:12 +0100 Subject: [PATCH 06/36] bugfix: unlocking RLC manager in nr_rlc_get_lcid_from_rb function --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b8fd148876..409f1599ab 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -114,14 +114,19 @@ logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id) for (logical_chan_id_t id = 1; id <= 32; id++) { nr_rlc_rb_t *rb = &ue->lcid2rb[id - 1]; if (is_srb) { - if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) + if (rb->type == NR_RLC_SRB && rb->choice.srb_id == rb_id) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); return id; + } } else { - if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) + if (rb->type == NR_RLC_DRB && rb->choice.drb_id == rb_id) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); return id; + } } } LOG_E(RLC, "Couldn't find LCID corresponding to %s %d\n", is_srb ? "SRB" : "DRB", rb_id); + nr_rlc_manager_unlock(nr_rlc_ue_manager); return 0; } From 6beeb6eef1b3a60303bcdd4b05362973caf6396d Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 18 Dec 2023 14:48:34 +0100 Subject: [PATCH 07/36] handle rlf with re-establishment or going to idle --- openair2/RRC/NR_UE/rrc_UE.c | 20 +++++++++++++++++++ openair2/RRC/NR_UE/rrc_proto.h | 1 + openair2/RRC/NR_UE/rrc_timers_and_constants.c | 3 +-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 53364b0768..5a65dcd71d 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -2285,6 +2285,26 @@ void handle_RRCRelease(NR_UE_RRC_INST_t *rrc) asn1cFreeStruc(asn_DEF_NR_RRCRelease, rrc->RRCRelease); } +void handle_rlf_detection(NR_UE_RRC_INST_t *rrc) +{ + // 5.3.10.3 in 38.331 + bool srb2 = rrc->Srb[2] != RB_NOT_PRESENT; + bool any_drb = false; + for (int i = 0; i < MAX_DRBS_PER_UE; i++) { + if (rrc->status_DRBs[i] != RB_NOT_PRESENT) { + any_drb = true; + break; + } + } + + if (rrc->as_security_activated && srb2 && any_drb) // initiate the connection re-establishment procedure + nr_rrc_initiate_rrcReestablishment(rrc, NR_ReestablishmentCause_otherFailure, 0); + else { + NR_Release_Cause_t cause = rrc->as_security_activated ? RRC_CONNECTION_FAILURE : OTHER; + nr_rrc_going_to_IDLE(rrc, cause, NULL); + } +} + void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc, NR_Release_Cause_t release_cause, NR_RRCRelease_t *RRCRelease) diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 95685c8e2f..28b51d5320 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -63,6 +63,7 @@ void *rrc_nrue_task(void *args_p); void *rrc_nrue(void *args_p); void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc); +void handle_rlf_detection(NR_UE_RRC_INST_t *rrc); /**\brief RRC NSA UE task. \param void *args_p Pointer on arguments to start the task. */ diff --git a/openair2/RRC/NR_UE/rrc_timers_and_constants.c b/openair2/RRC/NR_UE/rrc_timers_and_constants.c index f0635b16b2..7e0c040731 100644 --- a/openair2/RRC/NR_UE/rrc_timers_and_constants.c +++ b/openair2/RRC/NR_UE/rrc_timers_and_constants.c @@ -157,10 +157,9 @@ void nr_rrc_handle_timers(NR_UE_RRC_INST_t *rrc) bool t310_expired = nr_timer_tick(&timers->T310); if(t310_expired) { LOG_W(NR_RRC, "Timer T310 expired\n"); - // TODO // handle detection of radio link failure // as described in 5.3.10.3 of 38.331 - AssertFatal(false, "Radio link failure! Not handled yet!\n"); + handle_rlf_detection(rrc); } bool t311_expired = nr_timer_tick(&timers->T311); From f380a48a3b05199834c1adf3e6f7c3d8501e62eb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Mar 2024 16:53:54 +0100 Subject: [PATCH 08/36] RLC: add per-UE RLF callback If the RLC cannot retransmit a package, 3GPP specs say that we should declare radio link failure (RLF). Up to this commit, the code did nothing though. In this commit, add a per-UE RLF callback; the RLC will call into this function to signal that RLF has been detected through maximum retransmissions on a particular RLC bearer. --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 31 ++++++++-------------- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h | 2 ++ openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h | 3 +++ 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 409f1599ab..16dae866ce 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -619,10 +619,6 @@ static void max_retx_reached(void *_ue, nr_rlc_entity_t *entity) 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++) { @@ -650,23 +646,18 @@ rb_found: is_srb ? "SRB" : "DRB", rb_id); - /* TODO: do something for DRBs? */ - if (is_srb == 0) - return; + if (ue->rlf_handler) + ue->rlf_handler(ue->ue_id); + else + LOG_W(RLC, "UE %04x: RLF detected, but no callable RLF handler registered\n", ue->ue_id); +} - 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 +void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id); + ue->rlf_handler = rlf_h; + nr_rlc_manager_unlock(nr_rlc_ue_manager); } void nr_rlc_reestablish_entity(int ue_id, int lc_id) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 736c42a0b7..10182f3793 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -44,6 +44,8 @@ struct NR_LogicalChannelConfig; void nr_rlc_add_srb(int ue_id, int srb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); void nr_rlc_add_drb(int ue_id, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); +void nr_rlc_set_rlf_handler(int ue_id, rlf_handler_t rlf_h); + logical_chan_id_t nr_rlc_get_lcid_from_rb(int ue_id, bool is_srb, int rb_id); void nr_rlc_reestablish_entity(int ue_id, int lc_id); void nr_rlc_remove_ue(int ue_id); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h index e37d7929d8..13f5c55a2f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h @@ -37,12 +37,15 @@ typedef struct nr_rlc_rb_t { } choice; } nr_rlc_rb_t; +typedef void (*rlf_handler_t)(int rnti); + typedef struct nr_rlc_ue_t { int ue_id; nr_rlc_entity_t *srb0; nr_rlc_entity_t *srb[3]; nr_rlc_entity_t *drb[MAX_DRBS_PER_UE]; nr_rlc_rb_t lcid2rb[32]; + rlf_handler_t rlf_handler; } nr_rlc_ue_t; /***********************************************************************/ From eee4a0c6523c674cad4fe08dea2ce6469ad539f8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 12 Mar 2024 18:56:08 +0100 Subject: [PATCH 09/36] UE: signal RLF to RRC --- openair2/COMMON/rrc_messages_def.h | 3 +++ openair2/COMMON/rrc_messages_types.h | 6 ++++++ openair2/RRC/NR_UE/rrc_UE.c | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/openair2/COMMON/rrc_messages_def.h b/openair2/COMMON/rrc_messages_def.h index ef09d98284..fb94aeb29e 100644 --- a/openair2/COMMON/rrc_messages_def.h +++ b/openair2/COMMON/rrc_messages_def.h @@ -85,3 +85,6 @@ MESSAGE_DEF(NRRRC_FRAME_PROCESS, MESSAGE_PRIORITY_MED, NRRrcFramePr // eNB: RLC -> RRC messages MESSAGE_DEF(RLC_SDU_INDICATION, MESSAGE_PRIORITY_MED, RlcSduIndication, rlc_sdu_indication) MESSAGE_DEF(NAS_PDU_SESSION_REQ, MESSAGE_PRIORITY_MED, nas_pdu_session_req_t, nas_pdu_session_req) + +// UE: RLC -> RRC messages +MESSAGE_DEF(NR_RRC_RLC_MAXRTX, MESSAGE_PRIORITY_MED, RlcMaxRtxIndication, nr_rlc_maxrtx_indication) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 15509b1807..0e57120ee4 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -97,6 +97,8 @@ #define NAS_OAI_TUN_NSA(mSGpTR) (mSGpTR)->ittiMsg.nas_oai_tun_nsa #define NAS_PDU_SESSION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdu_session_req +#define NR_RRC_RLC_MAXRTX(mSGpTR) (mSGpTR)->ittiMsg.nr_rlc_maxrtx_indication + //-------------------------------------------------------------------------------------------// typedef struct RrcStateInd_s { Rrc_State_t state; @@ -453,4 +455,8 @@ typedef struct rlc_sdu_indication_s { int message_id; } RlcSduIndication; +typedef struct { + int ue_id; +} RlcMaxRtxIndication; + #endif /* RRC_MESSAGES_TYPES_H_ */ diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 5a65dcd71d..602795bc4c 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -873,6 +873,13 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc, return 0; } +static void nr_rrc_signal_maxrtxindication(int ue_id) +{ + MessageDef *msg = itti_alloc_new_message(TASK_RLC_UE, ue_id, NR_RRC_RLC_MAXRTX); + NR_RRC_RLC_MAXRTX(msg).ue_id = ue_id; + itti_send_msg_to_task(TASK_RRC_NRUE, ue_id, msg); +} + static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, const NR_CellGroupConfig_t *cellGroupConfig) { @@ -901,9 +908,11 @@ static void nr_rrc_manage_rlc_bearers(NR_UE_RRC_INST_t *rrc, if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity; nr_rlc_add_srb(rrc->ue_id, srb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); } else { // DRB NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity; nr_rlc_add_drb(rrc->ue_id, drb_id, rlc_bearer); + nr_rlc_set_rlf_handler(rrc->ue_id, nr_rrc_signal_maxrtxindication); } } } @@ -1843,6 +1852,15 @@ void *rrc_nrue(void *notUsed) nr_rrc_going_to_IDLE(rrc, release_cause, NULL); break; + case NR_RRC_RLC_MAXRTX: + // detection of RLF upon indication from RLC that the maximum number of retransmissions has been reached + LOG_W(NR_RRC, + "[UE %ld ID %d] Received indication that RLC reached max retransmissions\n", + instance, + NR_RRC_RLC_MAXRTX(msg_p).ue_id); + handle_rlf_detection(rrc); + break; + case NR_RRC_MAC_MSG3_IND: nr_rrc_handle_msg3_indication(rrc, NR_RRC_MAC_MSG3_IND(msg_p).rnti); break; From c0f2d2447156d43fdd64641a8bedcbe9ff2c471f Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 11 Oct 2024 11:07:25 +0200 Subject: [PATCH 10/36] L1 beam allocation from symbol bitmap This is required because CSI-RS may not be allocated in consecutive symbols within a slot --- openair1/PHY/NR_TRANSPORT/nr_dci.c | 4 ++-- openair1/PHY/NR_TRANSPORT/nr_dlsch.c | 4 ++-- openair1/PHY/NR_TRANSPORT/nr_prach.c | 8 ++------ openair1/PHY/NR_TRANSPORT/nr_ulsch.c | 8 ++------ openair1/PHY/NR_TRANSPORT/pucch_rx.c | 8 ++------ openair1/PHY/NR_TRANSPORT/srs_rx.c | 8 ++------ openair1/SCHED_NR/phy_procedures_nr_gNB.c | 21 ++++++++++----------- openair1/SCHED_NR/sched_nr.h | 7 +------ 8 files changed, 23 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 6cae31d465..54ca8665c3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -80,12 +80,12 @@ static void nr_generate_dci(PHY_VARS_gNB *gNB, uint32_t cset_nsymb = pdcch_pdu_rel15->DurationSymbols; int dci_idx = 0; // multi-beam number (for concurrent beams) + int bitmap = SL_to_bitmap(cset_start_symb, pdcch_pdu_rel15->DurationSymbols); int beam_nb = beam_index_allocation(dci_pdu->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx, &gNB->common_vars, slot, frame_parms->symbols_per_slot, - cset_start_symb, - pdcch_pdu_rel15->DurationSymbols); + bitmap); LOG_D(NR_PHY_DCI, "pdcch: Coreset rb_offset %d, nb_rb %d BWP Start %d\n", rb_offset, n_rb, pdcch_pdu_rel15->BWPStart); LOG_D(NR_PHY_DCI, diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 321ff3028b..e69e6b2f89 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -471,12 +471,12 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, int frame, int slot) start_meas(&gNB->dlsch_precoding_stats); nfapi_nr_tx_precoding_and_beamforming_t *pb = &rel15->precodingAndBeamforming; // beam number in multi-beam scenario (concurrent beams) + int bitmap = SL_to_bitmap(rel15->StartSymbolIndex, rel15->NrOfSymbols); int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, &gNB->common_vars, slot, frame_parms->symbols_per_slot, - rel15->StartSymbolIndex, - rel15->NrOfSymbols); + bitmap); c16_t **txdataF = gNB->common_vars.txdataF[beam_nb]; diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index a043d93500..3f41712f2c 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -85,12 +85,8 @@ void nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach_pdu_t *p int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; // TODO no idea how to compute final prach symbol here so for now we go til the end of the slot int temp_nb_symbols = NR_NUMBER_OF_SYMBOLS_PER_SLOT - prach_pdu->prach_start_symbol; - prach->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - Slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - prach_pdu->prach_start_symbol, - temp_nb_symbols); + int bitmap = SL_to_bitmap(prach_pdu->prach_start_symbol, temp_nb_symbols); + prach->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, Slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } LOG_D(NR_PHY,"Copying prach pdu %d bytes to index %d\n", (int)sizeof(*prach_pdu), prach_id); memcpy(&prach->pdu, prach_pdu, sizeof(*prach_pdu)); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 47a0afc625..982b236b70 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -75,12 +75,8 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_nr_pusch_pdu_t ulsch->beam_nb = 0; if (gNB->common_vars.beam_id) { int fapi_beam_idx = ulsch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - ulsch->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - ulsch_pdu->start_symbol_index, - ulsch_pdu->nr_of_symbols); + int bitmap = SL_to_bitmap(ulsch_pdu->start_symbol_index, ulsch_pdu->nr_of_symbols); + ulsch->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } ulsch->frame = frame; ulsch->slot = slot; diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 084046cc38..72cb374470 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -75,12 +75,8 @@ void nr_fill_pucch(PHY_VARS_gNB *gNB, pucch->beam_nb = 0; if (gNB->common_vars.beam_id) { int fapi_beam_idx = pucch_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - pucch->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - pucch_pdu->start_symbol_index, - pucch_pdu->nr_of_symbols); + int bitmap = SL_to_bitmap(pucch_pdu->start_symbol_index, pucch_pdu->nr_of_symbols); + pucch->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } memcpy((void *)&pucch->pucch_pdu, (void *)pucch_pdu, sizeof(nfapi_nr_pucch_pdu_t)); LOG_D(PHY, diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 931bfe21e7..49ae659a06 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -57,13 +57,9 @@ void nr_fill_srs(PHY_VARS_gNB *gNB, frame_t frame, slot_t slot, nfapi_nr_srs_pdu srs->active = true; srs->beam_nb = 0; if (gNB->common_vars.beam_id) { + int bitmap = SL_to_bitmap(srs_pdu->time_start_position, 1 << srs_pdu->num_symbols); int fapi_beam_idx = srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx; - srs->beam_nb = beam_index_allocation(fapi_beam_idx, - &gNB->common_vars, - slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - srs_pdu->time_start_position, - 1 << srs_pdu->num_symbols); + srs->beam_nb = beam_index_allocation(fapi_beam_idx, &gNB->common_vars, slot, NR_NUMBER_OF_SYMBOLS_PER_SLOT, bitmap); } memcpy((void *)&srs->srs_pdu, (void *)srs_pdu, sizeof(nfapi_nr_srs_pdu_t)); break; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index a56c01ce99..3d35ab87e5 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -43,19 +43,16 @@ //#define DEBUG_RXDATA //#define SRS_IND_DEBUG -int beam_index_allocation(int fapi_beam_index, - NR_gNB_COMMON *common_vars, - int slot, - int symbols_per_slot, - int start_symbol, - int nb_symbols) +int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols) { if (!common_vars->beam_id) return 0; int idx = -1; for (int j = 0; j < common_vars->num_beams_period; j++) { - for (int i = start_symbol; i < start_symbol + nb_symbols; i++) { + for (int i = 0; i < symbols_per_slot; i++) { + if (((bitmap_symbols >> i) & 0x01) == 0) + continue; int current_beam = common_vars->beam_id[j][slot * symbols_per_slot + i]; if (current_beam == -1 || current_beam == fapi_beam_index) idx = j; @@ -68,8 +65,10 @@ int beam_index_allocation(int fapi_beam_index, break; } AssertFatal(idx >= 0, "Couldn't allocate beam ID %d\n", fapi_beam_index); - for (int j = start_symbol; j < start_symbol + nb_symbols; j++) - common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index; + for (int j = 0; j < symbols_per_slot; j++) { + if (((bitmap_symbols >> j) & 0x01)) + common_vars->beam_id[idx][slot * symbols_per_slot + j] = fapi_beam_index; + } LOG_D(PHY, "Allocating beam %d in slot %d\n", idx, slot); return idx; } @@ -129,12 +128,12 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, nfapi_n c16_t ***txdataF = gNB->common_vars.txdataF; int txdataF_offset = slot * fp->samples_per_slot_wCP; // beam number in a scenario with multiple concurrent beams + int bitmap = SL_to_bitmap(ssb_start_symbol, 4); // 4 ssb symbols int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, &gNB->common_vars, slot, fp->symbols_per_slot, - ssb_start_symbol, - 4); // 4 ssb symbols + bitmap); nr_generate_pss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); nr_generate_sss(&txdataF[beam_nb][0][txdataF_offset], gNB->TX_AMP, ssb_start_symbol, cfg, fp); diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 6cde0e8614..20028cea9f 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -47,10 +47,5 @@ void feptx_prec(RU_t *ru,int frame_tx,int tti_tx); int nr_phy_init_RU(RU_t *ru); void nr_phy_free_RU(RU_t *ru); void clear_slot_beamid(PHY_VARS_gNB *gNB, int slot); -int beam_index_allocation(int fapi_beam_index, - NR_gNB_COMMON *common_vars, - int slot, - int symbols_per_slot, - int start_symbol, - int nb_symbols); +int beam_index_allocation(int fapi_beam_index, NR_gNB_COMMON *common_vars, int slot, int symbols_per_slot, int bitmap_symbols); #endif From 0993eb4ed8c9aa48490b71314767d919f4d00004 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 19 Sep 2024 15:04:16 +0200 Subject: [PATCH 11/36] MAC beam allocation for CSI-RS --- .../nfapi/public_inc/nfapi_nr_interface_scf.h | 1 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 6 +---- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 22 ++++++++++--------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index dc2f8eef83..2476833d7c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -979,6 +979,7 @@ typedef struct uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023 uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming; } nfapi_nr_dl_tti_csi_rs_pdu_rel15_t; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 0a51c9c803..4e591b6a7a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -778,11 +778,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, if (is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) { const int n_slots_frame = nr_slots_per_frame[mu]; - NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, - sched_frame, - sched_slot, - ra->beam_id, - n_slots_frame); + NR_beam_alloc_t beam_ul = beam_allocation_procedure(&nr_mac->beam_info, sched_frame, sched_slot, ra->beam_id, n_slots_frame); if (beam_ul.idx < 0) return; NR_beam_alloc_t beam_dci = beam_allocation_procedure(&nr_mac->beam_info, frame, slot, ra->beam_id, n_slots_frame); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index dc442bedd0..a45dab00a4 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2729,10 +2729,6 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo NR_SCHED_ENSURE_LOCKED(&gNB_mac->sched_lock); - // TODO implement beam procedures - int beam = 0; - uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam]; - UE_info->sched_csirs = 0; UE_iterator(UE_info->list, UE) { @@ -2764,8 +2760,7 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo } } - if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL && - nzp != NULL) { + if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL && nzp != NULL) { NR_NZP_CSI_RS_Resource_t *nzpcsi; int period, offset; @@ -2779,12 +2774,14 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo continue; NR_CSI_RS_ResourceMapping_t resourceMapping = nzpcsi->resourceMapping; - csi_period_offset(NULL,nzpcsi->periodicityAndOffset,&period,&offset); + csi_period_offset(NULL, nzpcsi->periodicityAndOffset, &period, &offset); - if((frame*n_slots_frame+slot-offset)%period == 0) { + if((frame * n_slots_frame + slot - offset) % period == 0) { - LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", - frame, slot, nzpcsi->nzp_CSI_RS_ResourceId); + LOG_D(NR_MAC,"Scheduling CSI-RS in frame %d slot %d Resource ID %ld\n", frame, slot, nzpcsi->nzp_CSI_RS_ResourceId); + NR_beam_alloc_t beam_csi = beam_allocation_procedure(&gNB_mac->beam_info, frame, slot, UE->UE_beam_index, n_slots_frame); + AssertFatal(beam_csi.idx >= 0, "Cannot allocate CSI-RS in any available beam\n"); + uint16_t *vrb_map = gNB_mac->common_channels[CC_id].vrb_map[beam_csi.idx]; UE_info->sched_csirs |= (1 << dl_bwp->bwp_id); nfapi_nr_dl_tti_request_pdu_t *dl_tti_csirs_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; @@ -2793,6 +2790,11 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo dl_tti_csirs_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_csi_rs_pdu)); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csirs_pdu_rel15 = &dl_tti_csirs_pdu->csi_rs_pdu.csi_rs_pdu_rel15; + csirs_pdu_rel15->precodingAndBeamforming.num_prgs = 1; + csirs_pdu_rel15->precodingAndBeamforming.prg_size = resourceMapping.freqBand.nrofRBs; //1 PRG of max size + csirs_pdu_rel15->precodingAndBeamforming.dig_bf_interfaces = 1; + csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].pm_idx = 0; + csirs_pdu_rel15->precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = UE->UE_beam_index; csirs_pdu_rel15->bwp_size = dl_bwp->BWPSize; csirs_pdu_rel15->bwp_start = dl_bwp->BWPStart; csirs_pdu_rel15->subcarrier_spacing = dl_bwp->scs; From f3bee8ed25d4651c729e86a8ced2f36b497c9cb0 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 11 Oct 2024 15:37:54 +0200 Subject: [PATCH 12/36] L1 beam allocation for CSI-RS --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 3d35ab87e5..73eda60dcd 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -252,7 +252,6 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, for (int i = 0; i < NR_SYMBOLS_PER_SLOT; i++){ NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i]; if (csirs->active == 1) { - AssertFatal(gNB->common_vars.beam_id == NULL, "Cannot handle CSI in the framework of beamforming yet\n"); LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15; if (csi_params->csi_type == 2) { // ZP-CSI @@ -263,8 +262,19 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, csi_params->freq_domain, csi_params->symb_l0, csi_params->symb_l1); + nfapi_nr_tx_precoding_and_beamforming_t *pb = &csi_params->precodingAndBeamforming; + int csi_bitmap = 0; + int lprime_num = mapping_parms.lprime + 1; + for (int j = 0; j < mapping_parms.size; j++) + csi_bitmap |= ((1 << lprime_num) - 1) << mapping_parms.loverline[j]; + int beam_nb = beam_index_allocation(pb->prgs_list[0].dig_bf_interface_list[0].beam_idx, + &gNB->common_vars, + slot, + fp->symbols_per_slot, + csi_bitmap); + nr_generate_csi_rs(&gNB->frame_parms, - (int32_t **)gNB->common_vars.txdataF[0], + (int32_t **)gNB->common_vars.txdataF[beam_nb], gNB->TX_AMP, csi_params, slot, From 029cf8391808e5cf1df4befe099083c06abe1190 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 14 Nov 2024 11:56:56 +0100 Subject: [PATCH 13/36] Trigger registration only in SA mode Upon press of ^C, the UE triggers a NAS deregistration. This does not work in do-ra or phy-test modes, because there is no NAS. Therefore, in non-SA modes, just stop the UE directly. --- executables/nr-uesoftmodem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index ac5235b108..fbd10c5c04 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -334,7 +334,7 @@ static void trigger_stop(int sig) } static void trigger_deregistration(int sig) { - if (!stop_immediately) { + if (!stop_immediately && IS_SA_MODE(get_softmodem_params())) { MessageDef *msg = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_DEREGISTRATION_REQ); NAS_DEREGISTRATION_REQ(msg).cause = AS_DETACH; itti_send_msg_to_task(TASK_NAS_NRUE, 0, msg); From 362eba7e27525b9226db525010e4b41e734eaef7 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Fri, 15 Nov 2024 13:15:30 +0100 Subject: [PATCH 14/36] Clip the input for -32768 because this will make different result in mult_complex_vectors() compared to C version --- openair1/PHY/TOOLS/tests/test_vector_op.cpp | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/openair1/PHY/TOOLS/tests/test_vector_op.cpp b/openair1/PHY/TOOLS/tests/test_vector_op.cpp index 6173c40e7e..02d5df5fcd 100644 --- a/openair1/PHY/TOOLS/tests/test_vector_op.cpp +++ b/openair1/PHY/TOOLS/tests/test_vector_op.cpp @@ -46,6 +46,30 @@ int main() for (int vector_size = 1237; vector_size < 1237 + 8; vector_size++) { auto input1 = generate_random_c16(vector_size); auto input2 = generate_random_c16(vector_size); + + // Clip the input for -32768 because this will make different result + // C version promote the int16 to int before doing the conjugate (so negate imaginary part) + // simd version do it on the int16, so the result overflows to -32768 + // other overflows exist, but they make the same + // in C we do with int promotion, for real part: + // (int)x.r*(int)y.r - (int)x.i*(int)y.i + // that can overflow because each multiplication result is full int range + // so when we sum, it overflows + // _mm256_madd_epi16() overflows also, as do regular addition instruction + // so the result will be the same (the same wrong value) + + for(auto it = input1.begin(); it != input1.end(); it++ ) { + if (it->r == -32768) + it->r=-32767; + if (it->i == -32768) + it->i=-32767; + } + for(auto it = input2.begin(); it != input2.end(); it++ ) { + if (it->r == -32768) + it->r=-32767; + if (it->i == -32768) + it->i=-32767; + } AlignedVector512 output; output.resize(vector_size); mult_complex_vectors(input1.data(), input2.data(), output.data(), vector_size, shift); From a319cbfb19da524deb9be61b5c608104181cb1bf Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 14 Nov 2024 14:38:22 +0100 Subject: [PATCH 15/36] Prevent segfault when trying to schedule MAX_MOBILES_PER_GNB UEs When the UE list is full, the iterator will run through all MAX_MOBILES_PER_GNB UEs. It expects that eventually the pointer is NULL, which is not the case if we have MAX_MOBILES_PER_GNB (or it simply depends on the following memory). So give one array entry more, to ensure that the last one is NULL. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 82106d0ef2..4022476ac6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -613,7 +613,7 @@ static void pf_dl(module_id_t module_id, gNB_MAC_INST *mac = RC.nrmac[module_id]; NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon; // UEs that could be scheduled - UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0}; + UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0}; int remainUEs = max_num_ue; int curUE = 0; int CC_id = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 4c0d40d24f..8a38c6e66d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1790,7 +1790,7 @@ static void pf_ul(module_id_t module_id, const int min_rb = nrmac->min_grant_prb; // UEs that could be scheduled - UEsched_t UE_sched[MAX_MOBILES_PER_GNB] = {0}; + UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0}; int remainUEs = max_num_ue; int curUE = 0; From 268d409b5b823ddb59ac5998502c563d83ca8d53 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 14 Nov 2024 14:28:16 +0100 Subject: [PATCH 16/36] Prevent segfault in nr_mac_clean_cellgroup() In some runs of a multi-UE deployment, we see segfaults because cell_group->spCellConfig is NULL. We should not segfault in that case, so check for spCellConfig. --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index dc442bedd0..7e66a0e2ac 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2962,8 +2962,9 @@ void nr_csirs_scheduling(int Mod_idP, frame_t frame, sub_frame_t slot, int n_slo static void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group) { + DevAssert(cell_group != NULL); /* remove a reconfigurationWithSync, we don't need it anymore */ - if (cell_group->spCellConfig->reconfigurationWithSync != NULL) { + if (cell_group->spCellConfig && cell_group->spCellConfig->reconfigurationWithSync != NULL) { ASN_STRUCT_FREE(asn_DEF_NR_ReconfigurationWithSync, cell_group->spCellConfig->reconfigurationWithSync); cell_group->spCellConfig->reconfigurationWithSync = NULL; } From 0eb0325b96a7eb5b585370b552c77b2363b82ef3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 15 Nov 2024 16:02:52 +0100 Subject: [PATCH 17/36] T tracer: support float types in traces --- common/utils/T/tracer/event.c | 4 ++++ common/utils/T/tracer/event.h | 2 ++ common/utils/T/tracer/logger/textlog.c | 4 +++- common/utils/T/tracer/utils.c | 6 ++++++ common/utils/T/tracer/utils.h | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/common/utils/T/tracer/event.c b/common/utils/T/tracer/event.c index f75af1e398..61fb12dd2a 100644 --- a/common/utils/T/tracer/event.c +++ b/common/utils/T/tracer/event.c @@ -94,6 +94,10 @@ event new_event(int type, int length, char *buffer, void *database) e.e[i].type = EVENT_ULONG; e.e[i].ul = *(unsigned long *)(&buffer[offset]); offset += sizeof(unsigned long); + } else if (!strcmp(f.type[i], "float")) { + e.e[i].type = EVENT_FLOAT; + e.e[i].f = *(float *)(&buffer[offset]); + offset += sizeof(float); } else if (!strcmp(f.type[i], "string")) { e.e[i].type = EVENT_STRING; e.e[i].s = &buffer[offset]; diff --git a/common/utils/T/tracer/event.h b/common/utils/T/tracer/event.h index 4e631fbb49..e3d7637bf4 100644 --- a/common/utils/T/tracer/event.h +++ b/common/utils/T/tracer/event.h @@ -13,6 +13,7 @@ enum event_arg_type { EVENT_INT, EVENT_ULONG, + EVENT_FLOAT, EVENT_STRING, EVENT_BUFFER }; @@ -23,6 +24,7 @@ typedef struct { union { int i; unsigned long ul; + float f; char *s; struct { int bsize; diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index 8217c2b981..2003ff4233 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -11,7 +11,7 @@ enum format_item_type { INSTRING, - INT, ULONG, STRING, BUFFER }; + INT, ULONG, FLOAT, STRING, BUFFER }; struct format_item { enum format_item_type type; @@ -67,6 +67,7 @@ static void _event(void *p, event e) case INSTRING: PUTS(&l->o, l->f[i].s); break; case INT: PUTI(&l->o, e.e[l->f[i].event_arg].i); break; case ULONG: PUTUL(&l->o, e.e[l->f[i].event_arg].ul); break; + case FLOAT: PUTF(&l->o, e.e[l->f[i].event_arg].f); break; case STRING: PUTS_CLEAN(&l->o, e.e[l->f[i].event_arg].s); break; case BUFFER: PUTS(&l->o, "{buffer size:"); @@ -106,6 +107,7 @@ static int find_argument(char *name, database_event_format f, *event_arg = i; if (!strcmp(f.type[i], "int")) *it = INT; else if (!strcmp(f.type[i], "ulong")) *it = ULONG; + else if (!strcmp(f.type[i], "float")) *it = FLOAT; else if (!strcmp(f.type[i], "string")) *it = STRING; else if (!strcmp(f.type[i], "buffer")) *it = BUFFER; else return 0; diff --git a/common/utils/T/tracer/utils.c b/common/utils/T/tracer/utils.c index 39e04fb973..78b01a2516 100644 --- a/common/utils/T/tracer/utils.c +++ b/common/utils/T/tracer/utils.c @@ -276,3 +276,9 @@ void PUTUL(OBUF *o, unsigned long l) { sprintf(s, "%lu", l); PUTS(o, s); } + +void PUTF(OBUF *o, float f) { + char s[256]; + sprintf(s, "%g", f); + PUTS(o, s); +} diff --git a/common/utils/T/tracer/utils.h b/common/utils/T/tracer/utils.h index 6784117fa6..e1055d4efa 100644 --- a/common/utils/T/tracer/utils.h +++ b/common/utils/T/tracer/utils.h @@ -50,5 +50,6 @@ void PUTS_CLEAN(OBUF *o, char *s); void PUTI(OBUF *o, int i); void PUTX2(OBUF *o, int i); void PUTUL(OBUF *o, unsigned long i); +void PUTF(OBUF *o, float f); #endif /* _UTILS_H_ */ From db629e6b585a3d0d5453fac5bedbb354ad2a94d1 Mon Sep 17 00:00:00 2001 From: Raghavendra Dinavahi Date: Thu, 31 Oct 2024 15:46:44 +0100 Subject: [PATCH 18/36] NTN FDD FR1 bands added Added support for NTN FDD FR1 bands 254, 255, 256 as specified in 3GPP TS 38.101-5 Conf files added for 15Khz, 5Mhz and 30Khz, 10Mhz configurations added for these bands --- common/utils/nr/nr_common.c | 149 +++++----- openair1/PHY/INIT/nr_parms.c | 9 +- openair2/LAYER2/NR_MAC_gNB/config.c | 3 - openair2/RRC/NR/nr_rrc_config.c | 4 +- .../gnb.sa.band254.ntn.mu0.25prb.rfsim.conf | 280 ++++++++++++++++++ .../gnb.sa.band254.ntn.mu1.24prb.rfsim.conf | 280 ++++++++++++++++++ .../gnb.sa.band255.ntn.mu0.25prb.rfsim.conf | 279 +++++++++++++++++ .../gnb.sa.band256.ntn.mu0.25prb.rfsim.conf | 279 +++++++++++++++++ 8 files changed, 1206 insertions(+), 77 deletions(-) create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf create mode 100644 targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 09dd5e7d94..516c94cb46 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -194,76 +194,80 @@ int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_ // - N_OFFs for bands from 80 to 89 and band 95 is referred to UL // - Frequencies are expressed in KHz // - col: NR_band ul_min ul_max dl_min dl_max step N_OFFs_DL deltaf_raster -const nr_bandentry_t nr_bandtable[] = { - {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100}, - {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100}, - {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100}, - {5, 824000, 849000, 869000, 894000, 20, 173800, 100}, - {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100}, - {8, 880000, 915000, 925000, 960000, 20, 185000, 100}, - {12, 699000, 716000, 729000, 746000, 20, 145800, 100}, - {13, 777000, 787000, 746000, 756000, 20, 149200, 100}, - {14, 788000, 798000, 758000, 768000, 20, 151600, 100}, - {18, 815000, 830000, 860000, 875000, 20, 172000, 100}, - {20, 832000, 862000, 791000, 821000, 20, 158200, 100}, - {24, 1627500, 1656500, 1526000, 1536000, 20, 305000, 100}, - {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100}, - {26, 814000, 849000, 859000, 894000, 20, 171800, 100}, - {28, 703000, 758000, 758000, 813000, 20, 151600, 100}, - {29, 000, 000, 717000, 728000, 20, 143400, 100}, - {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100}, - {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100}, - {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100}, - {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100}, - {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100}, - {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, - {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, - {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15}, - {48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15}, - {48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30}, - {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100}, - {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100}, - {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100}, - {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100}, - {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100}, - {67, 000, 000, 738000, 758000, 20, 147600, 100}, - {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100}, - {71, 663000, 698000, 617000, 652000, 20, 123400, 100}, - {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100}, - {75, 000, 000, 1432000, 1517000, 20, 286400, 100}, - {76, 000, 000, 1427000, 1432000, 20, 285400, 100}, - {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15}, - {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30}, - {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15}, - {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30}, - {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, - {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, - {80, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {81, 880000, 915000, 000, 000, 20, 176000, 100}, - {82, 832000, 862000, 000, 000, 20, 166400, 100}, - {83, 703000, 748000, 000, 000, 20, 140600, 100}, - {84, 1920000, 1980000, 000, 000, 20, 384000, 100}, - {85, 698000, 716000, 728000, 746000, 20, 145600, 100}, - {86, 1710000, 1785000, 000, 000, 20, 342000, 100}, - {89, 824000, 849000, 000, 000, 20, 342000, 100}, - {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, - {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, - {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100}, - {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100}, - {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100}, - {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100}, - {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100}, - {95, 2010000, 2025000, 000, 000, 20, 402000, 100}, - {96, 5925000, 7125000, 5925000, 7125000, 1, 795000, 15}, - {257,26500020,29500000,26500020,29500000, 1,2054166, 60}, - {257,26500080,29500000,26500080,29500000, 2,2054167, 120}, - {258,24250080,27500000,24250080,27500000, 1,2016667, 60}, - {258,24250080,27500000,24250080,27500000, 2,2016667, 120}, - {260,37000020,40000000,37000020,40000000, 1,2229166, 60}, - {260,37000080,40000000,37000080,40000000, 2,2229167, 120}, - {261,27500040,28350000,27500040,28350000, 1,2070833, 60}, - {261,27500040,28350000,27500040,28350000, 2,2070833, 120} -}; +const nr_bandentry_t nr_bandtable[] = {{1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100}, + {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100}, + {3, 1710000, 1785000, 1805000, 1880000, 20, 361000, 100}, + {5, 824000, 849000, 869000, 894000, 20, 173800, 100}, + {7, 2500000, 2570000, 2620000, 2690000, 20, 524000, 100}, + {8, 880000, 915000, 925000, 960000, 20, 185000, 100}, + {12, 699000, 716000, 729000, 746000, 20, 145800, 100}, + {13, 777000, 787000, 746000, 756000, 20, 149200, 100}, + {14, 788000, 798000, 758000, 768000, 20, 151600, 100}, + {18, 815000, 830000, 860000, 875000, 20, 172000, 100}, + {20, 832000, 862000, 791000, 821000, 20, 158200, 100}, + {24, 1627500, 1656500, 1526000, 1536000, 20, 305000, 100}, + {25, 1850000, 1915000, 1930000, 1995000, 20, 386000, 100}, + {26, 814000, 849000, 859000, 894000, 20, 171800, 100}, + {28, 703000, 758000, 758000, 813000, 20, 151600, 100}, + {29, 000, 000, 717000, 728000, 20, 143400, 100}, + {30, 2305000, 2315000, 2350000, 2360000, 20, 470000, 100}, + {34, 2010000, 2025000, 2010000, 2025000, 20, 402000, 100}, + {38, 2570000, 2620000, 2570000, 2630000, 20, 514000, 100}, + {39, 1880000, 1920000, 1880000, 1920000, 20, 376000, 100}, + {40, 2300000, 2400000, 2300000, 2400000, 20, 460000, 100}, + {41, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, + {41, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {47, 5855000, 5925000, 5855000, 5925000, 1, 790334, 15}, + {48, 3550000, 3700000, 3550000, 3700000, 1, 636667, 15}, + {48, 3550000, 3700000, 3550000, 3700000, 2, 636668, 30}, + {50, 1432000, 1517000, 1432000, 1517000, 20, 286400, 100}, + {51, 1427000, 1432000, 1427000, 1432000, 20, 285400, 100}, + {53, 2483500, 2495000, 2483500, 2495000, 20, 496700, 100}, + {65, 1920000, 2010000, 2110000, 2200000, 20, 422000, 100}, + {66, 1710000, 1780000, 2110000, 2200000, 20, 422000, 100}, + {67, 000, 000, 738000, 758000, 20, 147600, 100}, + {70, 1695000, 1710000, 1995000, 2020000, 20, 399000, 100}, + {71, 663000, 698000, 617000, 652000, 20, 123400, 100}, + {74, 1427000, 1470000, 1475000, 1518000, 20, 295000, 100}, + {75, 000, 000, 1432000, 1517000, 20, 286400, 100}, + {76, 000, 000, 1427000, 1432000, 20, 285400, 100}, + {77, 3300000, 4200000, 3300000, 4200000, 1, 620000, 15}, + {77, 3300000, 4200000, 3300000, 4200000, 2, 620000, 30}, + {78, 3300000, 3800000, 3300000, 3800000, 1, 620000, 15}, + {78, 3300000, 3800000, 3300000, 3800000, 2, 620000, 30}, + {79, 4400010, 5000000, 4400010, 5000000, 1, 693334, 15}, + {79, 4400010, 5000000, 4400010, 5000000, 2, 693334, 30}, + {80, 1710000, 1785000, 000, 000, 20, 342000, 100}, + {81, 880000, 915000, 000, 000, 20, 176000, 100}, + {82, 832000, 862000, 000, 000, 20, 166400, 100}, + {83, 703000, 748000, 000, 000, 20, 140600, 100}, + {84, 1920000, 1980000, 000, 000, 20, 384000, 100}, + {85, 698000, 716000, 728000, 746000, 20, 145600, 100}, + {86, 1710000, 1785000, 000, 000, 20, 342000, 100}, + {89, 824000, 849000, 000, 000, 20, 342000, 100}, + {90, 2496000, 2690000, 2496000, 2690000, 3, 499200, 15}, + {90, 2496000, 2690000, 2496000, 2690000, 6, 499200, 30}, + {90, 2496000, 2690000, 2496000, 2690000, 20, 499200, 100}, + {91, 832000, 862000, 1427000, 1432000, 20, 285400, 100}, + {92, 832000, 862000, 1432000, 1517000, 20, 286400, 100}, + {93, 880000, 915000, 1427000, 1432000, 20, 285400, 100}, + {94, 880000, 915000, 1432000, 1517000, 20, 286400, 100}, + {95, 2010000, 2025000, 000, 000, 20, 402000, 100}, + {96, 5925000, 7125000, 5925000, 7125000, 1, 795000, 15}, + {254, 1610000, 1626500, 2483500, 2500000, 20, 496700, 100}, + {254, 1610000, 1626500, 2483500, 2500000, 2, 496700, 10}, + {255, 1626500, 1660500, 1525000, 1559000, 20, 305000, 100}, + {255, 1626500, 1660500, 1525000, 1559000, 2, 305000, 10}, + {256, 1980000, 2010000, 2170000, 2200000, 20, 434000, 100}, + {256, 1980000, 2010000, 2170000, 2200000, 2, 434000, 10}, + {257, 26500020, 29500000, 26500020, 29500000, 1, 2054166, 60}, + {257, 26500080, 29500000, 26500080, 29500000, 2, 2054167, 120}, + {258, 24250080, 27500000, 24250080, 27500000, 1, 2016667, 60}, + {258, 24250080, 27500000, 24250080, 27500000, 2, 2016667, 120}, + {260, 37000020, 40000000, 37000020, 40000000, 1, 2229166, 60}, + {260, 37000080, 40000000, 37000080, 40000000, 2, 2229167, 120}, + {261, 27500040, 28350000, 27500040, 28350000, 1, 2070833, 60}, + {261, 27500040, 28350000, 27500040, 28350000, 2, 2070833, 120}}; // synchronization raster per band tables (Rel.15) // (38.101-1 Table 5.4.3.3-1 and 38.101-2 Table 5.4.3.3-1) @@ -321,6 +325,11 @@ const sync_raster_t sync_raster[] = { {92, 0, 3584, 1, 3787}, {93, 0, 3572, 1, 3574}, {94, 0, 3584, 1, 3587}, + {254, 0, 6215, 1, 6244}, + {254, 1, 6218, 1, 6241}, + {255, 0, 3818, 1, 3892}, + {255, 1, 3824, 1, 3886}, + {256, 0, 5429, 1, 5494}, {257, 3, 22388, 1, 22558}, {257, 4, 22390, 2, 22556}, {258, 3, 22257, 1, 22443}, diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 939478f35c..1f5c22c71e 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -30,7 +30,7 @@ static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, static const uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16}; // Table 5.4.3.3-1 38-101 -static const int nr_ssb_table[54][3] = { +static const int nr_ssb_table[][3] = { {1, 15, nr_ssb_type_A}, {2, 15, nr_ssb_type_A}, {3, 15, nr_ssb_type_A}, @@ -84,7 +84,12 @@ static const int nr_ssb_table[54][3] = { {92, 15, nr_ssb_type_A}, {93, 15, nr_ssb_type_A}, {94, 15, nr_ssb_type_A}, - {96, 30, nr_ssb_type_C}}; + {96, 30, nr_ssb_type_C}, + {254, 15, nr_ssb_type_A}, + {254, 30, nr_ssb_type_C}, + {255, 15, nr_ssb_type_A}, + {255, 30, nr_ssb_type_B}, + {256, 15, nr_ssb_type_A}}; void set_Lmax(NR_DL_FRAME_PARMS *fp) { // definition of Lmax according to ts 38.213 section 4.1 diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 7baca618d1..bbab43ad7a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -345,9 +345,6 @@ static void config_common(gNB_MAC_INST *nrmac, } } - uint32_t band = *frequencyInfoDL->frequencyBandList.list.array[0]; - frequency_range = band < 100 ? FR1 : FR2; - frame_type_t frame_type = get_frame_type(*frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); nrmac->common_channels[0].frame_type = frame_type; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index cae49d3f53..006bcd36bf 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -542,7 +542,7 @@ void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig, NR_SCS_SpecificCarrier_t *scs_carrier = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]; int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - const frequency_range_t freq_range = band < 100 ? FR1 : FR2; + const frequency_range_t freq_range = band < 257 ? FR1 : FR2; const int scs = scs_carrier->subcarrierSpacing; const int bw_size = scs_carrier->carrierBandwidth; @@ -2302,7 +2302,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, } const NR_FreqBandIndicatorNR_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - frequency_range_t frequency_range = band < 100 ? FR1 : FR2; + frequency_range_t frequency_range = band > 256 ? FR2 : FR1; sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA = get_ssb_offset_to_pointA(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB, scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA, scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing, diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf new file mode 100644 index 0000000000..274f31db46 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu0.25prb.rfsim.conf @@ -0,0 +1,280 @@ +Active_gNBs = ( "5G-GOA-gNB"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "5G-GOA-gNB"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + nr_cellid = 12345678L; + + ////////// Physical parameters: + + sib1_tda = 5; + min_rxtxtime = 6; + disable_harq = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # GSCN 6221 = 497770, (GSCN 6215 - 497290) + absoluteFrequencySSB = 497770; + dl_frequencyBand = 254; + # this is 2486.9 MHz + dl_absoluteFrequencyPointA = 497380; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 0; + dl_carrierBandwidth = 25; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=25 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 0; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 254; + # this is 1613.4 MHz + ul_absoluteFrequencyPointA = 322680; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 0; + ul_carrierBandwidth = 25; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 0; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 0; +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 0; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 0; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + + #ext2 + #ntn_Config_r17 + cellSpecificKoffset_r17 = 478; //GEO + ta-Common-r17 = 29319745; + positionX-r17 = 0; + positionY-r17 = 0; + positionZ-r17 = 32433846; + velocityVX-r17 = 0; + velocityVY-r17 = 0; + velocityVZ-r17 = 0; + } + + ); + + TIMERS : + { + sr_ProhibitTimer = 0; + sr_TransMax = 64; + sr_ProhibitTimer_v1700 = 512; + t300 = 2000; + t301 = 2000; + t319 = 2000; + }; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.71.132"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + sf_extension = 0; + eNB_instances = [0]; + sdr_addrs = "type=x300"; + clock_src = "internal"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = 4043; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; + diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf new file mode 100644 index 0000000000..a84bf9c88f --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band254.ntn.mu1.24prb.rfsim.conf @@ -0,0 +1,280 @@ +Active_gNBs = ( "5G-GOA-gNB"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "5G-GOA-gNB"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + nr_cellid = 12345678L; + + ////////// Physical parameters: + + sib1_tda = 5; + min_rxtxtime = 6; + disable_harq = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # GSCN 6221 = 497770, (GSCN 6215 - 497290) + absoluteFrequencySSB = 497770; + dl_frequencyBand = 254; + # this is 2483.90 Mhz + dl_absoluteFrequencyPointA = 496780; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 24; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=25 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 254; + # this is 1610.4 MHz + ul_absoluteFrequencyPointA = 322080; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 24; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6325; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1; +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + + #ext2 + #ntn_Config_r17 + cellSpecificKoffset_r17 = 478; //GEO + ta-Common-r17 = 29319745; + positionX-r17 = 0; + positionY-r17 = 0; + positionZ-r17 = 32433846; + velocityVX-r17 = 0; + velocityVY-r17 = 0; + velocityVZ-r17 = 0; + } + + ); + + TIMERS : + { + sr_ProhibitTimer = 0; + sr_TransMax = 64; + sr_ProhibitTimer_v1700 = 512; + t300 = 2000; + t301 = 2000; + t319 = 2000; + }; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.71.132"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + sf_extension = 0; + eNB_instances = [0]; + sdr_addrs = "type=x300"; + clock_src = "internal"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = 4043; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; + diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf new file mode 100644 index 0000000000..98cd0fb66b --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band255.ntn.mu0.25prb.rfsim.conf @@ -0,0 +1,279 @@ +Active_gNBs = ( "5G-GOA-gNB"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "5G-GOA-gNB"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + nr_cellid = 12345678L; + + ////////// Physical parameters: + + sib1_tda = 5; + min_rxtxtime = 6; + disable_harq = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # GSCN 3855 - 308430 + absoluteFrequencySSB = 308430; + dl_frequencyBand = 255; + # this is 1540.35 MHz + dl_absoluteFrequencyPointA = 308070; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 0; + dl_carrierBandwidth = 25; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=25 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 0; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 255; + ul_absoluteFrequencyPointA = 328370; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 0; + ul_carrierBandwidth = 25; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 0; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 0; +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 0; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 0; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + + #ext2 + #ntn_Config_r17 + cellSpecificKoffset_r17 = 478; //GEO + ta-Common-r17 = 29319745; + positionX-r17 = 0; + positionY-r17 = 0; + positionZ-r17 = 32433846; + velocityVX-r17 = 0; + velocityVY-r17 = 0; + velocityVZ-r17 = 0; + } + + ); + + TIMERS : + { + sr_ProhibitTimer = 0; + sr_TransMax = 64; + sr_ProhibitTimer_v1700 = 512; + t300 = 2000; + t301 = 2000; + t319 = 2000; + }; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.71.132"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + sf_extension = 0; + eNB_instances = [0]; + sdr_addrs = "type=x300"; + clock_src = "internal"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = 4043; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; + diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf new file mode 100644 index 0000000000..221b6b0c89 --- /dev/null +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band256.ntn.mu0.25prb.rfsim.conf @@ -0,0 +1,279 @@ +Active_gNBs = ( "5G-GOA-gNB"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "5G-GOA-gNB"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ mcc = 208; mnc = 99; mnc_length = 2; snssaiList = ({ sst = 1, sd = 0xffffff }) }); + nr_cellid = 12345678L; + + ////////// Physical parameters: + + sib1_tda = 5; + min_rxtxtime = 6; + disable_harq = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # GSCN 5459 - 436810 + absoluteFrequencySSB = 436810; + dl_frequencyBand = 256; + # this is 2181.95 MHz + dl_absoluteFrequencyPointA = 436390; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 0; + dl_carrierBandwidth = 25; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=25 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 0; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 256; + ul_absoluteFrequencyPointA = 398390; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 0; + ul_carrierBandwidth = 25; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6600; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 0; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 0; +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; + + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 0; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 0; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + + #ext2 + #ntn_Config_r17 + cellSpecificKoffset_r17 = 478; //GEO + ta-Common-r17 = 29319745; + positionX-r17 = 0; + positionY-r17 = 0; + positionZ-r17 = 32433846; + velocityVX-r17 = 0; + velocityVY-r17 = 0; + velocityVZ-r17 = 0; + } + + ); + + TIMERS : + { + sr_ProhibitTimer = 0; + sr_TransMax = 64; + sr_ProhibitTimer_v1700 = 512; + t300 = 2000; + t301 = 2000; + t319 = 2000; + }; + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ({ ipv4 = "192.168.71.132"; }); + + NETWORK_INTERFACES : + { + GNB_IPV4_ADDRESS_FOR_NG_AMF = "192.168.71.140/26"; + GNB_IPV4_ADDRESS_FOR_NGU = "192.168.71.140/26"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 150; + pucch_TargetSNRx10 = 200; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 150; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( + { + local_rf = "yes"; + nb_tx = 1; + nb_rx = 1; + att_tx = 0; + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + sf_extension = 0; + eNB_instances = [0]; + sdr_addrs = "type=x300"; + clock_src = "internal"; + # if_freq = 3700000000L; + # if_offset = 1000000; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_DISABLE"; + } +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = 4043; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; + From 7d2b7c2ba31cad234c52e5bf75c72b0d80c54373 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 14 Nov 2024 17:23:40 +0100 Subject: [PATCH 19/36] Prevent segfault in RRC Similar to the previous commit, prevent the same segfault in RRC. --- openair2/RRC/NR/rrc_gNB.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index c018b8030a..881a6d7fee 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -915,7 +915,7 @@ static void rrc_gNB_process_RRCReestablishmentComplete(gNB_RRC_INST *rrc, gNB_RR * reestablishment, instead of re-requesting the CellGroupConfig from the DU. * Hence, add below hack; the solution would be to request the * CellGroupConfig from the DU when doing reestablishment. */ - if (cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) { + if (cellGroupConfig->spCellConfig && cellGroupConfig->spCellConfig->reconfigurationWithSync) { ASN_STRUCT_FREE(asn_DEF_NR_ReconfigurationWithSync, cellGroupConfig->spCellConfig->reconfigurationWithSync); cellGroupConfig->spCellConfig->reconfigurationWithSync = NULL; } From ca877514aaac78e5f2820c3fc325dae6eebf8814 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 22 Mar 2024 16:13:34 +0100 Subject: [PATCH 20/36] fix for going to idle: release MAC config only after resetting MAC --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 3c66515eef..80e2255aa5 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1611,8 +1611,7 @@ static void configure_timeAlignmentTimer(NR_timer_t *time_alignment_timer, NR_Ti nr_timer_start(time_alignment_timer); } -void nr_rrc_mac_config_req_reset(module_id_t module_id, - NR_UE_MAC_reset_cause_t cause) +void nr_rrc_mac_config_req_reset(module_id_t module_id, NR_UE_MAC_reset_cause_t cause) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); int ret = pthread_mutex_lock(&mac->if_mutex); @@ -1621,8 +1620,8 @@ void nr_rrc_mac_config_req_reset(module_id_t module_id, switch (cause) { case GO_TO_IDLE: reset_ra(mac, true); - release_mac_configuration(mac, cause); nr_ue_init_mac(mac); + release_mac_configuration(mac, cause); nr_ue_mac_default_configs(mac); // new sync but no target cell id -> -1 nr_ue_send_synch_request(mac, module_id, 0, &sync_req); From 2cc63bf19509dd965394d1d552d3533d29c0a6b4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 6 Jun 2024 13:06:54 +0200 Subject: [PATCH 21/36] Fixup: avoid deadlock --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 16dae866ce..3b0847feae 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -667,6 +667,7 @@ void nr_rlc_reestablish_entity(int ue_id, int lc_id) if (ue == NULL) { LOG_E(RLC, "RLC instance for the given UE was not found \n"); + nr_rlc_manager_unlock(nr_rlc_ue_manager); return; } nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id); From 7e3df5f1735fc0ab59cf5b71a3de27d03edf00cb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 17 Nov 2024 10:09:31 +0100 Subject: [PATCH 22/36] Adjust TCP threshold MIMO for AW2S 2x2 pipeline --- ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml index 5d43c89c3c..514672df66 100644 --- a/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml +++ b/ci-scripts/xml_files/container_sa_aw2s_asue_2x2.xml @@ -192,7 +192,7 @@ iperf (DL/TCP)(30 sec)(multi-ue profile) -t 30 -R amarisoft_ue_1 amarisoft_ue_2 amarisoft_ue_3 amarisoft_ue_4 amarisoft_ue_5 amarisoft_ue_6 amarisoft_ue_7 amarisoft_ue_8 amarisoft_ue_9 amarisoft_ue_10 amarisoft_ue_11 amarisoft_ue_12 amarisoft_ue_13 amarisoft_ue_14 amarisoft_ue_15 - 4 + 3.9 oc-cn5g From 0bbd446478f7464786682752896c4a9e5f95796e Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Tue, 11 Jun 2024 11:45:16 +0200 Subject: [PATCH 23/36] Add test to trigger re-establishment to RFSIM F1 CI * trigger re-establshemnt on DU: reset RLC counters on DRB 1 for OAI UE, since SRB 1 does not work for lack of periodic measurements reports * how is the re-establishment triggered? * a transmission on DRB 1 occurs * detection of a mismatch of RLC counters at the UE side * max number of RLC retransmissions reached * RLF detection * verify re-establishment on CU: we ping the core from the UE; this sends packets on DRB, and because the sequence number mismatches, will trigger a reestablishment. We accept in the ping that a couple of packets might be lost; after ping is over, reestablishment must be done as well (else the ping will already fail). --- .../xml_files/container_5g_f1_rfsim.xml | 30 +++++++++++++++++++ .../5g_f1_rfsimulator/docker-compose.yaml | 6 +++- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 13 ++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 16c02050d2..93ad2c4c94 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -34,6 +34,11 @@ 030020 030021 030022 + 040001 + 020022 + 040002 + 030021 + 030022 100021 222222 @@ -117,6 +122,31 @@ 90 + + Custom_Command + Trigger Reestablishment + cacofonix + echo ci force_reestab | nc 192.168.71.171 9090 | grep -E 'Reset RLC counters of UE RNTI [0-9a-f]{4} to trigger reestablishment' + yes + + + + Ping + Ping ext-dn from all NR-UEs + rfsim5g_ue + cacofonix + -c 20 192.168.72.135 -i0.5 -w25 + 80 + + + + Custom_Command + Verify Reestablishment + cacofonix + echo ci get_reestab_count | nc 192.168.71.150 9090 | grep -E 'UE RNTI [0-9a-f]{4} reestab 1' + yes + + Custom_Command Simulate a disruption of DL radio channel (ploss 55)(5 sec) diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index c925af1adb..4460452f11 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -87,8 +87,11 @@ services: container_name: rfsim5g-oai-cu cap_drop: - ALL - environment: + environment: USE_ADDITIONAL_OPTIONS: --log_config.global_log_options level,nocolor,time + --rfsimulator.options chanmod + --telnetsrv --telnetsrv.listenaddr 192.168.71.150 + --telnetsrv.shrmod ci ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-ext-dn @@ -113,6 +116,7 @@ services: --log_config.global_log_options level,nocolor,time --rfsimulator.options chanmod --telnetsrv --telnetsrv.listenaddr 192.168.71.171 + --telnetsrv.shrmod ci ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: - oai-cu diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 3b0847feae..2ebd18f5e7 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -1096,8 +1096,14 @@ bool nr_rlc_update_id(int from_id, int to_id) return true; } -/* This function is for testing purposes. At least on a COTS UE, it will - * trigger a reestablishment. */ +/** + * @brief This function is for testing purposes. + * Re-establishment is triggered by resetting RLC counters of the bearer, + * which leads to UE reaching maximum RLC retransmissions, RLF detection + * and RRC triggering re-sync. It is assumed that there is ongoing traffic on the bearer. + * - With COTS UEs, triggers re-establishment on SRB 1, where periodical measurement reports are sent. + * - With OAI UE, triggers re-establishment on DRB 1, assuming there is ongoing data traffic. + */ void nr_rlc_test_trigger_reestablishment(int ue_id) { nr_rlc_manager_lock(nr_rlc_ue_manager); @@ -1111,6 +1117,9 @@ void nr_rlc_test_trigger_reestablishment(int ue_id) * as the UE context is created. */ nr_rlc_entity_t *ent = ue->srb[0]; ent->reestablishment(ent); + /* Trigger re-establishment on OAI UE */ + nr_rlc_entity_t *drb = ue->drb[0]; + drb->reestablishment(drb); nr_rlc_manager_unlock(nr_rlc_ue_manager); } From fb1f2539e8eaf8ef0a435ac026a2e52157ddcacb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 16 Oct 2024 15:01:31 +0200 Subject: [PATCH 24/36] Custom_Command nc on cacofonix: cannot use -N, is openBSD --- ci-scripts/xml_files/container_5g_f1_rfsim.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 93ad2c4c94..8c925cbc5f 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -151,7 +151,7 @@ Custom_Command Simulate a disruption of DL radio channel (ploss 55)(5 sec) cacofonix - echo channelmod modify 0 ploss 55 | nc -N 192.168.71.181 8091 && sleep 5 + echo channelmod modify 0 ploss 55 | nc 192.168.71.181 8091 && sleep 5 yes @@ -159,7 +159,7 @@ Custom_Command Get UE sync state (UE ID 0) cacofonix - echo ciUE sync_state 0 | nc -N 192.168.71.181 8091 | grep -E UE_NOT_SYNC + echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_NOT_SYNC yes @@ -167,7 +167,7 @@ Custom_Command Restoration of the original DL channel conditions (ploss 0)(5 sec) cacofonix - echo channelmod modify 0 ploss 0 | nc -N 192.168.71.181 8091 && sleep 5 + echo channelmod modify 0 ploss 0 | nc 192.168.71.181 8091 && sleep 5 yes @@ -175,7 +175,7 @@ Custom_Command Get UE sync state (UE ID 0) cacofonix - echo ciUE sync_state 0 | nc -N 192.168.71.181 8091 | grep -E UE_CONNECTED && sleep 10 + echo ciUE sync_state 0 | nc 192.168.71.181 8091 | grep -E UE_CONNECTED && sleep 10 yes From 59bf54c9cd8e41a0e7b595f4a1ea367838ec21cd Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 29 Jul 2024 11:54:09 +0200 Subject: [PATCH 25/36] Make a separate function to fetch RNTI in telnet CI --- common/utils/telnetsrv/telnetsrv_ci.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 700ff73135..8fcea82fd2 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -115,10 +115,8 @@ int get_reestab_count(char *buf, int debug, telnet_printfunc_t prnt) return 0; } -int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) +int fetch_rnti(char *buf, telnet_printfunc_t prnt) { - if (!RC.nrmac) - ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n"); int rnti = -1; if (!buf) { rnti = get_single_ue_rnti_mac(); @@ -129,9 +127,15 @@ int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) if (rnti < 1 || rnti >= 0xfffe) ERROR_MSG_RET("RNTI needs to be [1,0xfffe]\n"); } + return rnti; +} +int trigger_reestab(char *buf, int debug, telnet_printfunc_t prnt) +{ + if (!RC.nrmac) + ERROR_MSG_RET("no MAC/RLC present, cannot trigger reestablishment\n"); + int rnti = fetch_rnti(buf, prnt); nr_rlc_test_trigger_reestablishment(rnti); - prnt("Reset RLC counters of UE RNTI %04x to trigger reestablishment\n", rnti); return 0; } From 60ef7f04aa485f825a42fbce8819353762279984 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 29 Jul 2024 11:54:53 +0200 Subject: [PATCH 26/36] Add new ci telnet commands to force UE release and UL failure --- common/utils/telnetsrv/telnetsrv_ci.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ci.c b/common/utils/telnetsrv/telnetsrv_ci.c index 8fcea82fd2..ba3062178f 100644 --- a/common/utils/telnetsrv/telnetsrv_ci.c +++ b/common/utils/telnetsrv/telnetsrv_ci.c @@ -37,6 +37,7 @@ #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_ue_manager.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #define TELNETSERVERCODE #include "telnetsrv.h" @@ -167,7 +168,27 @@ int rrc_gNB_trigger_f1_ho(char *buf, int debug, telnet_printfunc_t prnt) gNB_RRC_UE_t *UE = &ue->ue_context; nr_HO_F1_trigger_telnet(RC.nrrrc[0], UE->rrc_ue_id); prnt("RRC F1 handover triggered for UE %u\n", UE->rrc_ue_id); + return 0; +} +int force_ul_failure(char *buf, int debug, telnet_printfunc_t prnt) +{ + if (!RC.nrmac) + ERROR_MSG_RET("no MAC/RLC present, force_ul_failure failed\n"); + int rnti = fetch_rnti(buf, prnt); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); + nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); + return 0; +} + +int force_ue_release(char *buf, int debug, telnet_printfunc_t prnt) +{ + force_ul_failure(buf, debug, prnt); + int rnti = fetch_rnti(buf, prnt); + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[0]->UE_info, rnti); + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + sched_ctrl->ul_failure_timer = 2; + nr_mac_check_ul_failure(RC.nrmac[0], UE->rnti, sched_ctrl); return 0; } @@ -175,6 +196,8 @@ static telnetshell_cmddef_t cicmds[] = { {"get_single_rnti", "", get_single_rnti}, {"force_reestab", "[rnti(hex,opt)]", trigger_reestab}, {"get_reestab_count", "[rnti(hex,opt)]", get_reestab_count}, + {"force_ue_release", "[rnti(hex,opt)]", force_ue_release}, + {"force_ul_failure", "[rnti(hex,opt)]", force_ul_failure}, {"trigger_f1_ho", "[rrc_ue_id(int,opt)]", rrc_gNB_trigger_f1_ho}, {"", "", NULL}, }; From 1692e00d4a47990201a062040359f60c18fba6d6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 17:51:08 +0200 Subject: [PATCH 27/36] Add function to fetch RRC UE instance --- openair2/RRC/NR_UE/rrc_UE.c | 5 +++++ openair2/RRC/NR_UE/rrc_proto.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 602795bc4c..13e5965d75 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -151,6 +151,11 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc, static void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measConfig, NR_UE_Timers_Constants_t *timers); +NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance) +{ + return &NR_UE_rrc_inst[instance]; +} + static NR_RB_status_t get_DRB_status(const NR_UE_RRC_INST_t *rrc, NR_DRB_Identity_t drb_id) { AssertFatal(drb_id > 0 && drb_id < 33, "Invalid DRB ID %ld\n", drb_id); diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 28b51d5320..d1f1d3228f 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -42,7 +42,7 @@ #include "common/utils/ocp_itti/intertask_interface.h" NR_UE_RRC_INST_t *nr_rrc_init_ue(char* uecap_file, int nb_inst, int num_ant_tx); - +NR_UE_RRC_INST_t* get_NR_UE_rrc_inst(int instance); void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfig_file); void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len); From 882712ffd86824bb78d4af5fc4edd739fb5bf6fb Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 17:40:41 +0200 Subject: [PATCH 28/36] Add ciUE telnet command to force RLF --- common/utils/telnetsrv/telnetsrv_ciUE.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ciUE.c b/common/utils/telnetsrv/telnetsrv_ciUE.c index 673d904969..4cecd23272 100644 --- a/common/utils/telnetsrv/telnetsrv_ciUE.c +++ b/common/utils/telnetsrv/telnetsrv_ciUE.c @@ -36,6 +36,7 @@ #include #include "openair2/LAYER2/NR_MAC_UE/mac_defs.h" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "openair2/RRC/NR_UE/rrc_proto.h" #define TELNETSERVERCODE #include "telnetsrv.h" @@ -73,9 +74,20 @@ int get_sync_state(char *buf, int debug, telnet_printfunc_t prnt) return 0; } +/** + * Force RLF on UE + */ +int force_rlf(char *buf, int debug, telnet_printfunc_t prnt) +{ + NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(0); + handle_rlf_detection(rrc); + return 0; +} + /* Telnet shell command definitions */ static telnetshell_cmddef_t cicmds[] = { {"sync_state", "[UE_ID(int,opt)]", get_sync_state}, + {"force_rlf", "", force_rlf}, {"", "", NULL}, }; From 813690ece7b5b58a2cefe0935f06df3481c9dcc7 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 24 Jul 2024 17:51:38 +0200 Subject: [PATCH 29/36] Add ciUE command to force RRC_IDLE --- common/utils/telnetsrv/telnetsrv_ciUE.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/common/utils/telnetsrv/telnetsrv_ciUE.c b/common/utils/telnetsrv/telnetsrv_ciUE.c index 4cecd23272..dd95f8009c 100644 --- a/common/utils/telnetsrv/telnetsrv_ciUE.c +++ b/common/utils/telnetsrv/telnetsrv_ciUE.c @@ -84,10 +84,21 @@ int force_rlf(char *buf, int debug, telnet_printfunc_t prnt) return 0; } +/** + * Send UE to RRC_IDLE + */ +int force_RRC_IDLE(char *buf, int debug, telnet_printfunc_t prnt) +{ + NR_UE_RRC_INST_t *rrc = get_NR_UE_rrc_inst(0); + nr_rrc_going_to_IDLE(rrc, OTHER, NULL); + return 0; +} + /* Telnet shell command definitions */ static telnetshell_cmddef_t cicmds[] = { {"sync_state", "[UE_ID(int,opt)]", get_sync_state}, {"force_rlf", "", force_rlf}, + {"force_RRC_IDLE", "", force_RRC_IDLE}, {"", "", NULL}, }; From 4f969e41209d0469a2d6a4d334fd0bbf0588be40 Mon Sep 17 00:00:00 2001 From: francescomani Date: Fri, 26 Jul 2024 17:55:39 +0200 Subject: [PATCH 30/36] do not force initial sync BW scanning if going to IDLE, keep the previous configuration --- executables/nr-ue.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index bd64a9d361..d6c3086317 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -607,7 +607,13 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE, const UE_nr_rxtx_proc_t *proc if (UE->synch_request.received_synch_request == 1) { fapi_nr_synch_request_t *synch_req = &UE->synch_request.synch_req; UE->is_synchronized = 0; - UE->UE_scan_carrier = synch_req->ssb_bw_scan; + // if upper layers signal BW scan we do as instructed by command line parameter + // if upper layers disable BW scan we set it to false + if (UE->synch_request.synch_req.ssb_bw_scan) + UE->UE_scan_carrier = get_nrUE_params()->UE_scan_carrier; + else + UE->UE_scan_carrier = false; + UE->target_Nid_cell = UE->synch_request.synch_req.target_Nid_cell; UE->target_Nid_cell = synch_req->target_Nid_cell; uint64_t dl_bw = (12 * fp->N_RB_DL) * (15000 << fp->numerology_index); From 5bb38187f193b876a775b933da93f8c20b8210b8 Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 29 Jul 2024 15:11:28 +0200 Subject: [PATCH 31/36] triggering SR only if schedulingRequestResource is available --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 26b2f35e0f..a3be440cc7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1428,13 +1428,16 @@ static void nr_update_sr(NR_UE_MAC_INST_t *mac) // if the UL-SCH resources available for a new transmission do not meet the LCP mapping restrictions // TODO not implemented + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; + if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList) + return; // cannot schedule SR if there is no schedulingRequestResource configured + if (lc_info->sr_id < 0 || lc_info->sr_id >= NR_MAX_SR_ID) LOG_E(NR_MAC, "No SR corresponding to this LCID\n"); // TODO not sure what to do here else { nr_sr_info_t *sr = &sched_info->sr_info[lc_info->sr_id]; if (!sr->pending) { - NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; - NR_PUCCH_Config_t *pucch_Config = current_UL_BWP ? current_UL_BWP->pucch_Config : NULL; if (check_pucchres_for_pending_SR(pucch_Config, lc_info->sr_id)) { // trigger SR LOG_D(NR_MAC, "Triggering SR for ID %d\n", lc_info->sr_id); From fe671a887644e8e8379fdecbfb9055002834a7ee Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 29 Jul 2024 18:23:10 +0200 Subject: [PATCH 32/36] take into account the option to have initial pucch when scheduling UCI on PUSCH --- openair1/PHY/impl_defs_nr.h | 10 ---- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 9 +++ openair2/LAYER2/NR_MAC_UE/mac_proto.h | 2 +- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 10 +++- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 62 ++++++++++++-------- 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h index 7f9dfad719..16d5854604 100644 --- a/openair1/PHY/impl_defs_nr.h +++ b/openair1/PHY/impl_defs_nr.h @@ -487,16 +487,6 @@ typedef enum { reserved = 7 } PUCCH_MaxCodeRate_t; -typedef struct { - pucch_format_nr_t format; - uint8_t startingSymbolIndex; - uint8_t nrofSymbols; - uint16_t PRB_offset; - uint8_t nb_CS_indexes; - uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT]; -} initial_pucch_resource_t; - - /*********************************************************************** * * FUNCTIONALITY : Scheduling Request Configuration (SR) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 426d8f88d1..819cbea02f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -184,6 +184,15 @@ typedef enum { #undef UE_STATE } NR_UE_L2_STATE_t; +typedef struct { + pucch_format_nr_t format; + uint8_t startingSymbolIndex; + uint8_t nrofSymbols; + uint16_t PRB_offset; + uint8_t nb_CS_indexes; + uint8_t initial_CS_indexes[MAX_NB_CYCLIC_SHIFT]; +} initial_pucch_resource_t; + typedef enum { GO_TO_IDLE, DETACH, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 6feca8756e..c5334ed04a 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -210,7 +210,7 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, int slot); bool get_downlink_ack(NR_UE_MAC_INST_t *mac, frame_t frame, int slot, PUCCH_sched_t *pucch); - +initial_pucch_resource_t get_initial_pucch_resource(const int idx); void multiplex_pucch_resource(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int num_res); int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index bd233f2163..b853df90eb 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -1514,6 +1514,11 @@ void set_harq_status(NR_UE_MAC_INST_t *mac, current_harq->dai_cumul); } +initial_pucch_resource_t get_initial_pucch_resource(const int idx) +{ + return initial_pucch_resource[idx]; +} + int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame, @@ -1534,10 +1539,9 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, LOG_D(NR_MAC, "initial_pucch_id %d, pucch_resource %p\n", pucch->initial_pucch_id, pucch->pucch_resource); // configure pucch from Table 9.2.1-1 // only for ack/nack - if (pucch->initial_pucch_id > -1 && - pucch->pucch_resource == NULL) { + if (pucch->initial_pucch_id > -1 && pucch->pucch_resource == NULL) { const int idx = *current_UL_BWP->pucch_ConfigCommon->pucch_ResourceCommon; - const initial_pucch_resource_t pucch_resourcecommon = initial_pucch_resource[idx]; + const initial_pucch_resource_t pucch_resourcecommon = get_initial_pucch_resource(idx); pucch_pdu->format_type = pucch_resourcecommon.format; pucch_pdu->start_symbol_index = pucch_resourcecommon.startingSymbolIndex; pucch_pdu->nr_of_symbols = pucch_resourcecommon.nrofSymbols; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index a3be440cc7..d1d523a962 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2322,7 +2322,11 @@ void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac) LOG_D(NR_MAC,"Map SSB to RO done\n"); } -static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int slot_tx, const PUCCH_sched_t *pucch) +static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, + frame_t frame_tx, + int slot_tx, + const PUCCH_sched_t *pucch, + NR_UE_UL_BWP_t *current_UL_BWP) { fapi_nr_ul_config_request_pdu_t *ulcfg_pdu = lockGet_ul_iterator(mac, frame_tx, slot_tx); if (!ulcfg_pdu) @@ -2337,29 +2341,37 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, frame_t frame_tx, int s NR_PUCCH_Resource_t *pucchres = pucch->pucch_resource; int nr_of_symbols = 0; int start_symbol_index = 0; - switch(pucchres->format.present) { - case NR_PUCCH_Resource__format_PR_format0 : - nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; - start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format1 : - nr_of_symbols = pucchres->format.choice.format1->nrofSymbols; - start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format2 : - nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; - start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format3 : - nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; - start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; - break; - case NR_PUCCH_Resource__format_PR_format4 : - nr_of_symbols = pucchres->format.choice.format4->nrofSymbols; - start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex; - break; - default : - AssertFatal(false, "Undefined PUCCH format \n"); + if (pucch->initial_pucch_id > -1 && pucch->pucch_resource == NULL) { + const int idx = *current_UL_BWP->pucch_ConfigCommon->pucch_ResourceCommon; + const initial_pucch_resource_t pucch_resourcecommon = get_initial_pucch_resource(idx); + start_symbol_index = pucch_resourcecommon.startingSymbolIndex; + nr_of_symbols = pucch_resourcecommon.nrofSymbols; + } + else { + switch(pucchres->format.present) { + case NR_PUCCH_Resource__format_PR_format0 : + nr_of_symbols = pucchres->format.choice.format0->nrofSymbols; + start_symbol_index = pucchres->format.choice.format0->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format1 : + nr_of_symbols = pucchres->format.choice.format1->nrofSymbols; + start_symbol_index = pucchres->format.choice.format1->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format2 : + nr_of_symbols = pucchres->format.choice.format2->nrofSymbols; + start_symbol_index = pucchres->format.choice.format2->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format3 : + nr_of_symbols = pucchres->format.choice.format3->nrofSymbols; + start_symbol_index = pucchres->format.choice.format3->startingSymbolIndex; + break; + case NR_PUCCH_Resource__format_PR_format4 : + nr_of_symbols = pucchres->format.choice.format4->nrofSymbols; + start_symbol_index = pucchres->format.choice.format4->startingSymbolIndex; + break; + default : + AssertFatal(false, "Undefined PUCCH format \n"); + } } int final_symbol = nr_of_symbols + start_symbol_index; // PUCCH overlapping in time with PUSCH @@ -2468,7 +2480,7 @@ void nr_ue_pucch_scheduler(NR_UE_MAC_INST_t *mac, frame_t frameP, int slotP) mac->nr_ue_emul_l1.num_csi_reports = pucch[j].n_csi; // checking if we need to schedule pucch[j] on PUSCH - if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j])) + if (schedule_uci_on_pusch(mac, frameP, slotP, &pucch[j], mac->current_UL_BWP)) continue; fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frameP, slotP, FAPI_NR_UL_CONFIG_TYPE_PUCCH); From 6600e33caefb705caa28764fce26fa5383b5e80c Mon Sep 17 00:00:00 2001 From: francescomani Date: Mon, 7 Oct 2024 16:39:07 +0200 Subject: [PATCH 33/36] workaround to avoid assertion for UCI on PUSCH in re-establishment procedure --- openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 33 +++++++++++---------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index d1d523a962..3836291d61 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -2402,22 +2402,25 @@ static bool schedule_uci_on_pusch(NR_UE_MAC_INST_t *mac, // and does not transmit the PUCCH if the UE does not multiplex aperiodic or semi-persistent CSI reports in the PUSCH bool mux_done = false; if (pucch->n_harq > 0) { - pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq; - pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload; NR_PUSCH_Config_t *pusch_Config = mac->current_UL_BWP->pusch_Config; - AssertFatal(pusch_Config && pusch_Config->uci_OnPUSCH, "UCI on PUSCH need to be configured\n"); - NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup; - AssertFatal(onPusch && - onPusch->betaOffsets && - onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, - "Only semistatic beta offset is supported\n"); - NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic; - pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ? - (pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 : - *beta_offsets->betaOffsetACK_Index3) : - *beta_offsets->betaOffsetACK_Index1; - pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling; - mux_done = true; + if (pusch_Config && pusch_Config->uci_OnPUSCH) { + NR_UCI_OnPUSCH_t *onPusch = pusch_Config->uci_OnPUSCH->choice.setup; + AssertFatal(onPusch && + onPusch->betaOffsets && + onPusch->betaOffsets->present == NR_UCI_OnPUSCH__betaOffsets_PR_semiStatic, + "Only semistatic beta offset is supported\n"); + NR_BetaOffsets_t *beta_offsets = onPusch->betaOffsets->choice.semiStatic; + pusch_pdu->pusch_uci.harq_ack_bit_length = pucch->n_harq; + pusch_pdu->pusch_uci.harq_payload = pucch->ack_payload; + pusch_pdu->pusch_uci.beta_offset_harq_ack = pucch->n_harq > 2 ? + (pucch->n_harq < 12 ? *beta_offsets->betaOffsetACK_Index2 : + *beta_offsets->betaOffsetACK_Index3) : + *beta_offsets->betaOffsetACK_Index1; + pusch_pdu->pusch_uci.alpha_scaling = onPusch->scaling; + mux_done = true; + } else { + LOG_E(NR_MAC, "UCI on PUSCH need to be configured to schedule UCI on PUSCH\n"); + } } if (pusch_pdu->pusch_uci.csi_part1_bit_length == 0 && pusch_pdu->pusch_uci.csi_part2_bit_length == 0) { // To support this we would need to shift some bits into CSI part2 -> need to change the logic From 4f2fa739a12bc7540030bbef4b2ae0497e07624a Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 9 Oct 2024 11:11:38 +0200 Subject: [PATCH 34/36] Disable ASAN ODR detection to workaround double registration of log_mem_write_side variable in CU /opt/oai-gnb/bin/nr-softmodem -O /opt/oai-gnb/etc/gnb.conf --sa --log_config.global_log_options level,nocolor,time --rfsimulator.options chanmod --telnetsrv --telnetsrv.listenaddr 192.168.71.150 --telnetsrv.shrmod ci ================================================================= ==7==ERROR: AddressSanitizer: odr-violation (0x7fce78b85be0): [1] size=4 'log_mem_write_side' /oai-ran/common/utils/LOG/log.c:78:14 [2] size=4 'log_mem_write_side' /oai-ran/common/utils/LOG/log.c:78:14 These globals were registered at these points: [1]: \#0 0x7fce7b691658 in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:341 \#1 0x7fce7bd0c47d in call_init elf/dl-init.c:70 [2]: \#0 0x7fce7b691658 in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:341 \#1 0x7fce7a5e2eba in call_init ../csu/libc-start.c:145 \#2 0x7fce7a5e2eba in __libc_start_main_impl ../csu/libc-start.c:379 ==7==HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_odr_violation=0 SUMMARY: AddressSanitizer: odr-violation: global 'log_mem_write_side' at /oai-ran/common/utils/LOG/log.c:78:14 ==7==ABORTING [INFO tini (1)] Spawned child process '/opt/oai-gnb/bin/entrypoint.sh' with pid '7' [INFO tini (1)] Main child exited normally (with status '1') --- ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml index 4460452f11..df0a9f4b07 100644 --- a/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_f1_rfsimulator/docker-compose.yaml @@ -92,7 +92,7 @@ services: --rfsimulator.options chanmod --telnetsrv --telnetsrv.listenaddr 192.168.71.150 --telnetsrv.shrmod ci - ASAN_OPTIONS: detect_leaks=0 + ASAN_OPTIONS: detect_leaks=0:detect_odr_violation=0 depends_on: - oai-ext-dn networks: From 6b3f26f538f4f3d99733ca43cef1ecb942ca857c Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Wed, 16 Oct 2024 16:31:03 +0200 Subject: [PATCH 35/36] Add define to printf and fflush in telnetsrv for real-time logs --- common/utils/telnetsrv/telnetsrv.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 43208748d0..9e708efc38 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -67,6 +67,12 @@ static telnetsrv_params_t telnetparams; #define TELNETSRV_OPTNAME_STATICMOD "staticmod" #define TELNETSRV_OPTNAME_SHRMOD "shrmod" +#define TELNET_LOG(fmt, ...) \ + do { \ + printf("[TELNETSRV] " fmt __VA_OPT__(, ) __VA_ARGS__); \ + fflush(stdout); \ + } while (0) + // clang-format off paramdef_t telnetoptions[] = { /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ @@ -653,10 +659,10 @@ void run_telnetsrv(void) { using_history(); int plen=sprintf(prompt,"%s_%s> ",TELNET_PROMPT_PREFIX,get_softmodem_function(NULL)); - printf("\nInitializing telnet server...\n"); + TELNET_LOG("\nInitializing telnet server...\n"); while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) ) { - printf("[TELNETSRV] Telnet client connected....\n"); + TELNET_LOG("Telnet client connected....\n"); read_history(telnetparams.histfile); stifle_history(telnetparams.histsize); @@ -682,12 +688,12 @@ void run_telnetsrv(void) { } if(!readc) { - printf ("[TELNETSRV] Telnet Client disconnected.\n"); + TELNET_LOG("Telnet Client disconnected.\n"); break; } if (telnetparams.telnetdbg > 0) - printf("[TELNETSRV] Command received: readc %i filled %i \"%s\"\n", readc, filled,buf); + TELNET_LOG("Command received: readc %i filled %i \"%s\"\n", readc, filled, buf); if (buf[0] == '!') { if (buf[1] == '!') { @@ -720,7 +726,7 @@ void run_telnetsrv(void) { send(telnetparams.new_socket, prompt, strlen(prompt), MSG_NOSIGNAL); } else { - printf ("[TELNETSRV] Closing telnet connection...\n"); + TELNET_LOG("Closing telnet connection...\n"); break; } } @@ -728,7 +734,7 @@ void run_telnetsrv(void) { write_history(telnetparams.histfile); clear_history(); close(telnetparams.new_socket); - printf ("[TELNETSRV] Telnet server waitting for connection...\n"); + TELNET_LOG("Telnet server waiting for connection...\n"); } close(sock); @@ -927,7 +933,7 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde cmd[j].qptr = afifo; } } - printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n", i, telnetparams.CmdParsers[i].module); + TELNET_LOG("Telnet server: module %i = %s added to shell\n", i, telnetparams.CmdParsers[i].module); break; } } From 77b57bc2d61b11e049e48e63185c0721f8e49e17 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 18 Nov 2024 17:20:37 +0100 Subject: [PATCH 36/36] CI: increase UE thread pool size There seem to be randomly occurring deadlocks when running the UE in the CI. MR !3091 should fix this. While waiting for this, apply a workaround by increasing the number of worker pools in the UE to 12. --- ci-scripts/conf_files/nrue.uicc.conf | 2 ++ ci-scripts/conf_files/nrue.uicc.yaml | 2 ++ ci-scripts/conf_files/ue.sa.conf | 2 ++ 3 files changed, 6 insertions(+) diff --git a/ci-scripts/conf_files/nrue.uicc.conf b/ci-scripts/conf_files/nrue.uicc.conf index afd2c0142e..d97a271ff6 100644 --- a/ci-scripts/conf_files/nrue.uicc.conf +++ b/ci-scripts/conf_files/nrue.uicc.conf @@ -6,6 +6,8 @@ uicc0 = { nssai_sst=1; } +thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + #/* configuration for channel modelisation */ #/* To be included in main config file when */ #/* channel modelisation is used (rfsimulator with chanmod options enabled) */ diff --git a/ci-scripts/conf_files/nrue.uicc.yaml b/ci-scripts/conf_files/nrue.uicc.yaml index f2af872ba7..da3b7e7e19 100644 --- a/ci-scripts/conf_files/nrue.uicc.yaml +++ b/ci-scripts/conf_files/nrue.uicc.yaml @@ -5,6 +5,8 @@ uicc0: dnn: oai nssai_sst: 1 +thread-pool: "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1" + #/* configuration for channel modelisation */ #/* To be included in main config file when */ #/* channel modelisation is used (rfsimulator with chanmod options enabled) */ diff --git a/ci-scripts/conf_files/ue.sa.conf b/ci-scripts/conf_files/ue.sa.conf index 3e6f78f709..9101c7e8e9 100644 --- a/ci-scripts/conf_files/ue.sa.conf +++ b/ci-scripts/conf_files/ue.sa.conf @@ -6,3 +6,5 @@ uicc0 = { nssai_sst=1; nssai_sd=66051; } + +thread-pool = "-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1"