From c3ef6df44bf9e3460701b68f0046e73a1851c060 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 8 Oct 2024 10:53:56 +0200 Subject: [PATCH] Bugfix: request release in case of failed RA Prior to this commit, after RA failure, the DU would send a UE context release complete, without actually requesting one. This could lead to inconsistent state between DU and CU, because the CU might just discard this (unrequested) message, and not actually trigger a release [1]. Thus, refactor the release request into a function, and use it to request release of a UE for which RA has not been completed. If the CU does not know the UE, release the UE immediately. [1] One possibility would be that during reestablishment, the CU would request to look up an old DU UE ID when it has been released, resulting in Assertion (oldUE) failed! In dl_rrc_message_transfer() /home/oaicicd/robert/openairinterface5g/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c:860 CU claims we should know UE bc7f, but we don't --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 5 +-- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 33 ++++++++++++++----- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 3 +- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index e43123b55c..3e738db42a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -2435,8 +2435,9 @@ void nr_schedule_RA(module_id_t module_idP, ra->contention_resolution_timer--; if (ra->contention_resolution_timer < 0) { LOG_W(NR_MAC, "(%d.%d) RA Contention Resolution timer expired for UE 0x%04x, RA procedure failed...\n", frameP, slotP, ra->rnti); - nr_mac_release_ue(mac, ra->rnti); - nr_mac_trigger_release_complete(mac, ra->rnti); + bool requested = nr_mac_request_release_ue(mac, ra->rnti); + if (!requested) + nr_mac_release_ue(mac, ra->rnti); nr_clear_ra_proc(ra); continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 7ac6d28fb8..5930ef7f44 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -3302,7 +3302,27 @@ void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl) sched_ctrl->pusch_consecutive_dtx_cnt = 0; } -void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl) +/* \brief trigger a release request towards the CU. + * \returns true if release was requested, else false (in which case the CU + * does not know the UE, and we can safely remove it). */ +bool nr_mac_request_release_ue(const gNB_MAC_INST *nrmac, int rnti) +{ + if (!du_exists_f1_ue_data(rnti)) { + LOG_W(NR_MAC, "UE %04x: no CU-UE ID stored, cannot request release\n", rnti); + return false; + } + f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); + f1ap_ue_context_release_req_t request = { + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = rnti, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = F1AP_CauseRadioNetwork_rl_failure_others, + }; + nrmac->mac_rrc.ue_context_release_request(&request); + return true; +} + +void nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl) { if (!sched_ctrl->ul_failure) return; @@ -3312,14 +3332,9 @@ void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ct * stop at 0 and we wait for a UE release command from upper layers */ if (sched_ctrl->ul_failure_timer == 1) { LOG_W(MAC, "UE %04x: request release after UL failure timer expiry\n", rnti); - f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); - f1ap_ue_context_release_req_t request = { - .gNB_CU_ue_id = ue_data.secondary_ue, - .gNB_DU_ue_id = rnti, - .cause = F1AP_CAUSE_RADIO_NETWORK, - .cause_value = F1AP_CauseRadioNetwork_rl_failure_others, - }; - nrmac->mac_rrc.ue_context_release_request(&request); + bool requested = nr_mac_request_release_ue(nrmac, rnti); + if (!requested) + nr_mac_release_ue(nrmac, rnti); } } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a75b9c0f60..c5df1782fd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -464,10 +464,11 @@ void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierS bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); void nr_mac_trigger_release_complete(gNB_MAC_INST *mac, int rnti); void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti); +bool nr_mac_request_release_ue(const gNB_MAC_INST *nrmac, int rnti); void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl); -void nr_mac_check_ul_failure(const gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); +void nr_mac_check_ul_failure(gNB_MAC_INST *nrmac, int rnti, NR_UE_sched_ctrl_t *sched_ctrl); void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, const NR_UE_info_t *UE);