From 273018ea4870cbbd8d6e10ef782506fb09e365bc Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 27 Jun 2024 11:13:42 +0200 Subject: [PATCH 1/3] returning instead of asserting for invalid K2 in aperiodic CSI --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index fcc5eb4d50..38f3a0660c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -527,7 +527,10 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac, if (dci->ulsch_indicator == 0) { // in case of CSI on PUSCH and no ULSCH we need to use reportSlotOffset in trigger state - AssertFatal(csi_K2 > 0, "Invalid CSI K2 value %ld\n", csi_K2); + if (csi_K2 <= 0) { + LOG_E(MAC, "Invalid CSI K2 value %ld\n", csi_K2); + return -1; + } tda_info.k2 = csi_K2; } From caa45af1977cbb9a562bb67b1f9ff463ce2708bc Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 27 Jun 2024 11:16:16 +0200 Subject: [PATCH 2/3] making aperiodic SRS feedback time dependent on what set in config at gNB (to avoid UE assertion) --- openair2/RRC/NR/nr_rrc_config.c | 45 +++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 9bbd4f38b7..de660f1765 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -655,6 +655,7 @@ static NR_SetupRelease_SRS_Config_t *get_config_srs(const NR_ServingCellConfigCo const int uid, const int res_id, const long maxMIMO_Layers, + const int minRXTXTIME, int do_srs) { NR_SetupRelease_SRS_Config_t *setup_release_srs_Config = calloc(1,sizeof(*setup_release_srs_Config)); @@ -679,10 +680,10 @@ static NR_SetupRelease_SRS_Config_t *get_config_srs(const NR_ServingCellConfigCo } else { srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_aperiodic; srs_resset0->resourceType.choice.aperiodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic)); - srs_resset0->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger=1; - srs_resset0->resourceType.choice.aperiodic->csi_RS=NULL; + srs_resset0->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger = 1; + srs_resset0->resourceType.choice.aperiodic->csi_RS = NULL; srs_resset0->resourceType.choice.aperiodic->slotOffset = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic->slotOffset)); - *srs_resset0->resourceType.choice.aperiodic->slotOffset = 2; + *srs_resset0->resourceType.choice.aperiodic->slotOffset = minRXTXTIME; srs_resset0->resourceType.choice.aperiodic->ext1 = NULL; } srs_resset0->usage=NR_SRS_ResourceSet__usage_codebook; @@ -1487,7 +1488,14 @@ static void config_uplinkBWP(NR_BWP_Uplink_t *ubwp, && servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers ? *servingcellconfigdedicated->uplinkConfig->pusch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers : 1; - ubwp->bwp_Dedicated->srs_Config = get_config_srs(scc, NULL, curr_bwp, uid, bwp_loop + 1, maxMIMO_Layers, configuration->do_SRS); + ubwp->bwp_Dedicated->srs_Config = get_config_srs(scc, + NULL, + curr_bwp, + uid, + bwp_loop + 1, + maxMIMO_Layers, + configuration->minRXTXTIME, + configuration->do_SRS); ubwp->bwp_Dedicated->configuredGrantConfig = NULL; ubwp->bwp_Dedicated->beamFailureRecoveryConfig = NULL; @@ -2633,7 +2641,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid, : 1; // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 - initialUplinkBWP->srs_Config = get_config_srs(scc, NULL, curr_bwp, uid, 0, maxMIMO_Layers, 0); + initialUplinkBWP->srs_Config = get_config_srs(scc, NULL, curr_bwp, uid, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0); scheduling_request_config(scc, pucch_Config, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing); @@ -2937,7 +2945,14 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, // UL and SRS configuration if (configuration->do_SRS && uplinkConfig && uplinkConfig->initialUplinkBWP) { ASN_STRUCT_FREE(asn_DEF_NR_SetupRelease_SRS_Config, uplinkConfig->initialUplinkBWP->srs_Config); - uplinkConfig->initialUplinkBWP->srs_Config = get_config_srs(scc, uecap, curr_bwp, uid, 0, maxMIMO_Layers, configuration->do_SRS); + uplinkConfig->initialUplinkBWP->srs_Config = get_config_srs(scc, + uecap, + curr_bwp, + uid, + 0, + maxMIMO_Layers, + configuration->minRXTXTIME, + configuration->do_SRS); } // Set DL MCS table @@ -2974,7 +2989,14 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, } ASN_STRUCT_FREE(asn_DEF_NR_SetupRelease_SRS_Config, ul_bwp->bwp_Dedicated->srs_Config); - ul_bwp->bwp_Dedicated->srs_Config = get_config_srs(scc, uecap, bwp_size, uid, i + 1, maxMIMO_Layers, configuration->do_SRS); + ul_bwp->bwp_Dedicated->srs_Config = get_config_srs(scc, + uecap, + bwp_size, + uid, + i + 1, + maxMIMO_Layers, + configuration->minRXTXTIME, + configuration->do_SRS); } } update_cqitables(bwp_Dedicated->pdsch_Config, csi_MeasConfig); @@ -3172,7 +3194,14 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC int curr_bwp = NRRIV2BW(servingcellconfigcommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - initialUplinkBWP->srs_Config = get_config_srs(servingcellconfigcommon, NULL, curr_bwp, uid, 0, maxMIMO_Layers, configuration->do_SRS); + initialUplinkBWP->srs_Config = get_config_srs(servingcellconfigcommon, + NULL, + curr_bwp, + uid, + 0, + maxMIMO_Layers, + configuration->minRXTXTIME, + configuration->do_SRS); // Downlink BWPs int n_dl_bwp = 1; From 2dcfabb6de8cc2a032ad277c89d1121efe26e695 Mon Sep 17 00:00:00 2001 From: francescomani Date: Thu, 27 Jun 2024 12:33:14 +0200 Subject: [PATCH 3/3] avoid TDA index assertion by rejecting the DCI with invalid parameter --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 1 + openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 22 +++++++++++++++++-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 19 ++++++++++------ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 4 ++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 3 +++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 11 +++++----- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 4 ++++ 7 files changed, 49 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index c8d8232382..14e69e0276 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -614,6 +614,7 @@ typedef struct NR_tda_info { int startSymbolIndex; int nrOfSymbols; long k2; + bool valid_tda; } NR_tda_info_t; #endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index d612a6dcc6..1f043728a1 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -467,7 +467,11 @@ NR_tda_info_t get_ul_tda_info(const NR_UE_UL_BWP_t *ul_bwp, AssertFatal(scs >= 0 && scs < 5, "Subcarrier spacing indicatior %d invalid value\n", scs); int j = scs == 0 ? 1 : scs; if (tdalist) { - AssertFatal(tda_index < tdalist->list.count, "TDA index from DCI %d exceeds TDA list array size %d\n", tda_index, tdalist->list.count); + tda_info.valid_tda = tda_index < tdalist->list.count; + if (!tda_info.valid_tda) { + LOG_E(NR_MAC, "TDA index from DCI %d exceeds TDA list array size %d\n", tda_index, tdalist->list.count); + return tda_info; + } NR_PUSCH_TimeDomainResourceAllocation_t *tda = tdalist->list.array[tda_index]; tda_info.mapping_type = tda->mappingType; // As described in 38.331, when the field is absent the UE applies the value 1 when PUSCH SCS is 15/30KHz @@ -479,6 +483,11 @@ NR_tda_info_t get_ul_tda_info(const NR_UE_UL_BWP_t *ul_bwp, tda_info.nrOfSymbols = L; } else { bool normal_CP = ul_bwp->cyclicprefix ? false : true; + tda_info.valid_tda = tda_index < 16; + if (!tda_info.valid_tda) { + LOG_E(NR_MAC, "TDA index from DCI %d exceeds default TDA list array size %d\n", tda_index, 16); + return tda_info; + } if (normal_CP) { tda_info.mapping_type = table_6_1_2_1_1_2[tda_index][0]; tda_info.k2 = table_6_1_2_1_1_2[tda_index][1] + j; @@ -500,6 +509,11 @@ NR_tda_info_t get_info_from_tda_tables(default_table_type_t table_type, int normal_CP) { NR_tda_info_t tda_info = {0}; + tda_info.valid_tda = tda < 16; + if (!tda_info.valid_tda) { + LOG_E(NR_MAC, "TDA index from DCI %d exceeds default TDA list array size %d\n", tda, 16); + return tda_info; + } bool is_mapping_typeA; int k0 = 0; switch(table_type){ @@ -586,7 +600,11 @@ default_table_type_t get_default_table_type(int mux_pattern) NR_tda_info_t set_tda_info_from_list(NR_PDSCH_TimeDomainResourceAllocationList_t *tdalist, int tda_index) { NR_tda_info_t tda_info = {0}; - AssertFatal(tda_index < tdalist->list.count, "TDA index from DCI %d exceeds TDA list array size %d\n", tda_index, tdalist->list.count); + tda_info.valid_tda = tda_index < tdalist->list.count; + if (!tda_info.valid_tda) { + LOG_E(NR_MAC, "TDA index from DCI %d exceeds TDA list array size %d\n", tda_index, tdalist->list.count); + return tda_info; + } NR_PDSCH_TimeDomainResourceAllocation_t *tda = tdalist->list.array[tda_index]; tda_info.mapping_type = tda->mappingType; int S, L; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 38f3a0660c..82e7a541d5 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -435,11 +435,12 @@ static int nr_ue_process_dci_ul_00(NR_UE_MAC_INST_t *mac, dci_ind->ss_type, get_rnti_type(mac, dci_ind->rnti), dci->time_domain_assignment.val); - frame_t frame_tx; - int slot_tx; - if (tda_info.nrOfSymbols == 0) + + if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) return -1; + frame_t frame_tx; + int slot_tx; if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2)) { LOG_E(MAC, "Cannot schedule PUSCH\n"); return -1; @@ -525,6 +526,9 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac, get_rnti_type(mac, dci_ind->rnti), dci->time_domain_assignment.val); + if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) + return -1; + if (dci->ulsch_indicator == 0) { // in case of CSI on PUSCH and no ULSCH we need to use reportSlotOffset in trigger state if (csi_K2 <= 0) { @@ -534,9 +538,6 @@ static int nr_ue_process_dci_ul_01(NR_UE_MAC_INST_t *mac, tda_info.k2 = csi_K2; } - if (tda_info.nrOfSymbols == 0) - return -1; - if (-1 == nr_ue_pusch_scheduler(mac, 0, frame, slot, &frame_tx, &slot_tx, tda_info.k2)) { LOG_E(MAC, "Cannot schedule PUSCH\n"); return -1; @@ -682,6 +683,8 @@ static int nr_ue_process_dci_dl_10(NR_UE_MAC_INST_t *mac, rnti_type, coreset_type, mac->get_sib1); + if (!tda_info.valid_tda) + return -1; dlsch_pdu->number_symbols = tda_info.nrOfSymbols; dlsch_pdu->start_symbol = tda_info.startSymbolIndex; @@ -993,6 +996,8 @@ static int nr_ue_process_dci_dl_11(NR_UE_MAC_INST_t *mac, rnti_type, coreset_type, false); + if (!tda_info.valid_tda) + return -1; dlsch_pdu->number_symbols = tda_info.nrOfSymbols; dlsch_pdu->start_symbol = tda_info.startSymbolIndex; @@ -3952,7 +3957,7 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d pdcch_config->ra_SS->searchSpaceType->present, TYPE_RA_RNTI_, rar_grant.Msg3_t_alloc); - if (tda_info.nrOfSymbols == 0) { + if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) { LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n"); return; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 3f752dae23..9daabdddaf 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1271,6 +1271,8 @@ static void nr_generate_Msg2(module_id_t module_idP, TYPE_RA_RNTI_, coresetid, false); + if (!tda_info.valid_tda) + return; uint16_t *vrb_map = cc[CC_id].vrb_map; for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) { @@ -1804,6 +1806,8 @@ static void nr_generate_Msg4(module_id_t module_idP, TYPE_TC_RNTI_, coreset->controlResourceSetId, false); + if (!msg4_tda.valid_tda) + return; NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, dl_bwp, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 29b5fbe713..95832f5158 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -455,6 +455,8 @@ static bool allocate_dl_retransmission(module_id_t module_id, TYPE_C_RNTI_, coresetid, false); + if (!temp_tda.valid_tda) + return false; bool reuse_old_tda = (retInfo->tda_info.startSymbolIndex == temp_tda.startSymbolIndex) && (retInfo->tda_info.nrOfSymbols <= temp_tda.nrOfSymbols); LOG_D(NR_MAC, "[UE %x] %s old TDA, %s number of layers\n", @@ -775,6 +777,7 @@ static void pf_dl(module_id_t module_id, TYPE_C_RNTI_, coresetid, false); + AssertFatal(sched_pdsch->tda_info.valid_tda, "Invalid TDA from get_dl_tda_info\n"); NR_tda_info_t *tda_info = &sched_pdsch->tda_info; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 6d6c6a2047..db04417150 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -75,6 +75,8 @@ void nr_preprocessor_phytest(module_id_t module_id, TYPE_C_RNTI_, sched_ctrl->coreset->controlResourceSetId, false); + if(!tda_info.valid_tda) + return; sched_ctrl->sched_pdsch.tda_info = tda_info; sched_ctrl->sched_pdsch.time_domain_allocation = tda; @@ -271,18 +273,15 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ sched_ctrl->search_space->searchSpaceType->present, TYPE_C_RNTI_, tda); + if (!tda_info.valid_tda) + return false; sched_ctrl->sched_pusch.tda_info = tda_info; const int buffer_index = ul_buffer_index(sched_frame, sched_slot, mu, nr_mac->vrb_map_UL_size); uint16_t *vrb_map_UL = &nr_mac->common_channels[CC_id].vrb_map_UL[buffer_index * MAX_BWP_SIZE]; for (int i = rbStart; i < rbStart + rbSize; ++i) { if ((vrb_map_UL[i+BWPStart] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) != 0) { - LOG_E(MAC, - "%s(): %4d.%2d RB %d is already reserved, cannot schedule UE\n", - __func__, - frame, - slot, - i); + LOG_E(MAC, "%4d.%2d RB %d is already reserved, cannot schedule UE\n", frame, slot, i); return false; } } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 820eba2b5b..612cbc0eab 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1601,6 +1601,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, sched_ctrl->search_space->searchSpaceType->present, TYPE_C_RNTI_, tda); + if (!tda_info.valid_tda) + return false; bool reuse_old_tda = (retInfo->tda_info.startSymbolIndex == tda_info.startSymbolIndex) && (retInfo->tda_info.nrOfSymbols <= tda_info.nrOfSymbols); if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) { /* Check the resource is enough for retransmission */ @@ -1844,6 +1846,7 @@ static void pf_ul(module_id_t module_id, sched_ctrl->search_space->searchSpaceType->present, TYPE_C_RNTI_, sched_pusch->time_domain_allocation); + AssertFatal(sched_pusch->tda_info.valid_tda, "Invalid TDA from get_ul_tda_info\n"); sched_pusch->dmrs_info = get_ul_dmrs_params(scc, current_BWP, &sched_pusch->tda_info, @@ -1967,6 +1970,7 @@ static void pf_ul(module_id_t module_id, sched_ctrl->search_space->searchSpaceType->present, TYPE_C_RNTI_, sched_pusch->time_domain_allocation); + AssertFatal(sched_pusch->tda_info.valid_tda, "Invalid TDA from get_ul_tda_info\n"); sched_pusch->dmrs_info = get_ul_dmrs_params(scc, current_BWP, &sched_pusch->tda_info,