diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4086588660..cb3c1bf801 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -335,6 +335,9 @@ static void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, slot_t s const int lcid = c->lcid; const uint16_t rnti = UE->rnti; LOG_D(NR_MAC, "In %s: UE %x: LCID %d\n", __FUNCTION__, rnti, lcid); + memset(&sched_ctrl->rlc_status[lcid], 0, sizeof(sched_ctrl->rlc_status[lcid])); + if (c->suspended) + continue; if (lcid == DL_SCH_LCID_DTCH && nr_timer_is_active(&sched_ctrl->transm_interrupt)) continue; start_meas(&RC.nrmac[module_id]->rlc_status_ind); @@ -399,8 +402,7 @@ static bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *U // used if CORESET 0 is configured for the cell and the size of initial DL bandwidth part shall be used if CORESET 0 is not // configured for the cell. if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0 && sched_ctrl->search_space->searchSpaceType - && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common - && dl_bwp->pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) { + && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { if (sched_ctrl->coreset->controlResourceSetId == 0) { bwp_info.bwpStart = nr_mac->cset0_bwp_start; } else { @@ -1183,8 +1185,7 @@ void nr_schedule_ue_spec(module_id_t module_id, // 3GPP TS 38.214 Section 5.1.2.2.2 Downlink resource allocation type 1 uint16_t riv_bwp_size = pdsch_pdu->BWPSize; if (current_BWP->dci_format == NR_DL_DCI_FORMAT_1_0 - && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common - && pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1) { + && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { if (gNB_mac->cset0_bwp_size > 0) { riv_bwp_size = gNB_mac->cset0_bwp_size; } else { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 2e6a778163..a447d9f91c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2104,6 +2104,7 @@ NR_UE_info_t *find_ra_UE(NR_UEs_t *UEs, rnti_t rntiP) void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia) { ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); + ASN_STRUCT_FREE(asn_DEF_NR_SpCellConfig, UE->reconfigSpCellConfig); ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; seq_arr_free(&sched_ctrl->lc_config, NULL); @@ -3477,6 +3478,16 @@ static int cmp_lc_config(const void *va, const void *vb) return 1; } +nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid) +{ + nr_lc_config_t c = {.lcid = lcid}; + elm_arr_t elm = find_if(&sched_ctrl->lc_config, &c, eq_lcid_config); + if (elm.found) + return elm.it; + else + return NULL; +} + bool nr_mac_add_lcid(NR_UE_sched_ctrl_t* sched_ctrl, const nr_lc_config_t *c) { elm_arr_t elm = find_if(&sched_ctrl->lc_config, (void *) c, eq_lcid_config); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 241b6203e9..3fa16f6a51 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -78,8 +78,7 @@ static bwp_info_t get_pusch_bwp_start_size(NR_UE_info_t *UE) // case when DCI format 0_0 is decoded in any common search space in which case the size of the initial UL bandwidth part shall // be used. if (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_0 && sched_ctrl->search_space->searchSpaceType - && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common - && ul_bwp->pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1) { + && sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_common) { bwp_info.bwpSize = min(ul_bwp->BWPSize, UE->sc_info.initial_ul_BWPSize); } else { bwp_info.bwpSize = ul_bwp->BWPSize; @@ -391,10 +390,15 @@ static int nr_process_mac_pdu(instance_t module_idP, slot, lcid); - nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); + const nr_lc_config_t *srbc = nr_mac_get_lc_config(sched_ctrl, lcid); + if (!srbc || srbc->suspended) { + LOG_I(NR_MAC, "RNTI %04x LCID %d: ignoring %d bytes\n", UE->rnti, lcid, mac_len); + } else { + nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); - UE->mac_stats.ul.total_sdu_bytes += mac_len; - UE->mac_stats.ul.lc_bytes[lcid] += mac_len; + UE->mac_stats.ul.total_sdu_bytes += mac_len; + UE->mac_stats.ul.lc_bytes[lcid] += mac_len; + } break; case UL_SCH_LCID_DTCH ...(UL_SCH_LCID_DTCH + 28): @@ -407,16 +411,21 @@ static int nr_process_mac_pdu(instance_t module_idP, lcid, module_idP, mac_len); - UE->mac_stats.ul.lc_bytes[lcid] += mac_len; + const nr_lc_config_t *c = nr_mac_get_lc_config(sched_ctrl, lcid); + if (!c || c->suspended) { + LOG_I(NR_MAC, "RNTI %04x LCID %d: ignoring %d bytes\n", UE->rnti, lcid, mac_len); + } else { + UE->mac_stats.ul.lc_bytes[lcid] += mac_len; - nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); + nr_mac_rlc_data_ind(module_idP, UE->rnti, true, lcid, (char *)(pduP + mac_subheader_len), mac_len); - sdus += 1; - /* Updated estimated buffer when receiving data */ - if (sched_ctrl->estimated_ul_buffer >= mac_len) - sched_ctrl->estimated_ul_buffer -= mac_len; - else - sched_ctrl->estimated_ul_buffer = 0; + sdus += 1; + /* Updated estimated buffer when receiving data */ + if (sched_ctrl->estimated_ul_buffer >= mac_len) + sched_ctrl->estimated_ul_buffer -= mac_len; + else + sched_ctrl->estimated_ul_buffer = 0; + } break; case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY: diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a61e2f8f89..6acf4ae1d8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -453,6 +453,7 @@ void process_addmod_bearers_cellGroupConfig(NR_UE_sched_ctrl_t *sched_ctrl, const struct NR_CellGroupConfig__rlc_BearerToAddModList *addmod); bool nr_mac_add_lcid(NR_UE_sched_ctrl_t *sched_ctrl, const nr_lc_config_t *c); +nr_lc_config_t *nr_mac_get_lc_config(NR_UE_sched_ctrl_t* sched_ctrl, int lcid); bool nr_mac_remove_lcid(NR_UE_sched_ctrl_t *sched_ctrl, long lcid); bool nr_mac_get_new_rnti(NR_UEs_t *UEs, rnti_t *rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index a5999e50b1..bcb69f5824 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -782,9 +782,20 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) "RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n"); } else if (req->ReconfigComplOutcome == RRCreconf_success) { LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n"); + if (UE->reconfigSpCellConfig) { + // in case of reestablishment, the spCellConfig had to be released + // temporarily. Reapply now before doing the reconfiguration. + UE->CellGroup->spCellConfig = UE->reconfigSpCellConfig; + UE->reconfigSpCellConfig = NULL; + } // we re-configure the BWP to apply the CellGroup and to use UE specific Search Space with DCIX1 nr_mac_clean_cellgroup(UE->CellGroup); configure_UE_BWP(mac, scc, UE, false, NR_SearchSpace__searchSpaceType_PR_ue_Specific, -1, -1); + for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { + nr_lc_config_t *c = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); + c->suspended = false; + nr_rlc_reestablish_entity(req->gNB_DU_ue_id, c->lcid); + } } if (ue_cap != NULL) { @@ -949,15 +960,9 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) DevAssert(success); } - if (UE->reestablish_rlc && dl_rrc->srb_id == 1) { - // we expected a reconfiguration to re-establish RLC, and this is on DCCH. We assume this is the reconfiguration. - for (int i = 1; i < seq_arr_size(&UE->UE_sched_ctrl.lc_config); ++i) { - nr_lc_config_t *lc_config = seq_arr_at(&UE->UE_sched_ctrl.lc_config, i); - nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, lc_config->lcid); - } - UE->reestablish_rlc = false; - } + /* if we get the old-gNB-DU-UE-ID, this means there is a reestablishment + * ongoing. */ if (dl_rrc->old_gNB_DU_ue_id != NULL) { AssertFatal(*dl_rrc->old_gNB_DU_ue_id != dl_rrc->gNB_DU_ue_id, "logic bug: current and old gNB DU UE ID cannot be the same\n"); @@ -968,30 +973,30 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) NR_UE_info_t *oldUE = find_nr_UE(&mac->UE_info, *dl_rrc->old_gNB_DU_ue_id); AssertFatal(oldUE, "CU claims we should know UE %04x, but we don't\n", *dl_rrc->old_gNB_DU_ue_id); pthread_mutex_lock(&mac->sched_lock); - /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it - * from the current configuration. Also, expect the reconfiguration from - * the CU, so save the old UE's CellGroup for the new UE */ - UE->CellGroup->spCellConfig = NULL; uid_t temp_uid = UE->uid; UE->uid = oldUE->uid; oldUE->uid = temp_uid; for (int i = 1; i < seq_arr_size(&oldUE->UE_sched_ctrl.lc_config); ++i) { const nr_lc_config_t *c = seq_arr_at(&oldUE->UE_sched_ctrl.lc_config, i); - nr_mac_add_lcid(&UE->UE_sched_ctrl, c); + nr_lc_config_t new = *c; + new.suspended = true; + nr_mac_add_lcid(&UE->UE_sched_ctrl, &new); } ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup); UE->CellGroup = oldUE->CellGroup; oldUE->CellGroup = NULL; UE->mac_stats = oldUE->mac_stats; + /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it + * from the current configuration. It will be reapplied when the + * reconfiguration has succeeded (indicated by the CU) */ + UE->reconfigSpCellConfig = UE->CellGroup->spCellConfig; + UE->CellGroup->spCellConfig = NULL; mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); pthread_mutex_unlock(&mac->sched_lock); nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); nr_rlc_update_id(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); /* 38.331 clause 5.3.7.4: apply the specified configuration defined in 9.2.1 for SRB1 */ nr_rlc_reconfigure_entity(dl_rrc->gNB_DU_ue_id, 1, NULL); - /* Set flag to trigger RLC re-establishment - * for remaining RBs in next RRCReconfiguration */ - UE->reestablish_rlc = true; instance_t f1inst = get_f1_gtp_instance(); if (f1inst >= 0) // we actually use F1-U gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index e1b5d4f78b..3918e0215c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -561,6 +561,8 @@ typedef struct NR_QoS_config_s { typedef struct nr_lc_config { uint8_t lcid; + /// flag if corresponding RB is suspended + bool suspended; /// priority as specified in 38.321 int priority; /// associated NSSAI for DRB @@ -737,8 +739,9 @@ typedef struct { NR_mac_stats_t mac_stats; /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; - /// reestablishRLC has to be signaled in RRCreconfiguration - bool reestablish_rlc; + /// in case of reestablishment, old spCellConfig to apply after + /// reconfiguration + NR_SpCellConfig_t *reconfigSpCellConfig; interrupt_followup_action_t interrupt_action; NR_UE_NR_Capability_t *capability; // UE selected beam index