diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9b6528d7b0..7c4322f654 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2809,6 +2809,30 @@ int nr_mac_enable_ue_rrc_processing_timer(gNB_MAC_INST *mac, NR_UE_info_t *UE, b return 0; } +void nr_mac_release_ue(gNB_MAC_INST *mac, int rnti) +{ + NR_SCHED_ENSURE_LOCKED(&mac->sched_lock); + + nr_rlc_remove_ue(rnti); + mac_remove_nr_ue(mac, rnti); + + // the CU might not know such UE, e.g., because we never sent a message to + // it, so there might not be a corresponding entry for such UE in the look up + // table. This can happen, e.g., on Msg.3 with C-RNTI, where we create a UE + // MAC context, decode the PDU, find the C-RNTI MAC CE, and then throw the + // newly created context away. See also in _nr_rx_sdu() and commit 93f59a3c6e56f + if (du_exists_f1_ue_data(rnti)) { + f1_ue_data_t ue_data = du_get_f1_ue_data(rnti); + f1ap_ue_context_release_complete_t complete = { + .gNB_CU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = rnti, + }; + mac->mac_rrc.ue_context_release_complete(&complete); + + du_remove_f1_ue_data(rnti); + } +} + void nr_mac_update_timers(module_id_t module_id, frame_t frame, sub_frame_t slot) @@ -2823,8 +2847,7 @@ void nr_mac_update_timers(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; if (nr_mac_check_release(sched_ctrl, UE->rnti)) { - nr_rlc_remove_ue(UE->rnti); - mac_remove_nr_ue(mac, UE->rnti); + nr_mac_release_ue(mac, UE->rnti); // go back to examine the next UE, which is at the position the // current UE was UE--; @@ -2963,7 +2986,7 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE) void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) { // trigger 60ms - sched_ctrl->release_timer = 60 << subcarrier_spacing; + sched_ctrl->release_timer = 100 << subcarrier_spacing; } bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 9f96a0d106..e58d2c12ae 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -443,6 +443,7 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); void nr_mac_trigger_release_timer(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing); bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti); +void nr_mac_release_ue(gNB_MAC_INST *mac, 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); 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 ea0d08e152..75357ef4ae 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -466,27 +466,24 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) { /* mark UE as to be deleted after PUSCH failure */ gNB_MAC_INST *mac = RC.nrmac[0]; - pthread_mutex_lock(&mac->sched_lock); + NR_SCHED_LOCK(&mac->sched_lock); NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->gNB_DU_ue_id); + if (UE == NULL) { + LOG_E(MAC, "ERROR: unknown UE with RNTI %04x, ignoring UE Context Release Command\n", cmd->gNB_DU_ue_id); + NR_SCHED_UNLOCK(&mac->sched_lock); + return; + } + if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ - nr_rlc_remove_ue(cmd->gNB_DU_ue_id); - mac_remove_nr_ue(mac, cmd->gNB_DU_ue_id); + nr_mac_release_ue(mac, cmd->gNB_DU_ue_id); } else { /* UE is in sync: forward release message and mark to be deleted * after UL failure */ nr_rlc_srb_recv_sdu(cmd->gNB_DU_ue_id, cmd->srb_id, cmd->rrc_container, cmd->rrc_container_length); nr_mac_trigger_release_timer(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); } - pthread_mutex_unlock(&mac->sched_lock); - - f1ap_ue_context_release_complete_t complete = { - .gNB_CU_ue_id = cmd->gNB_CU_ue_id, - .gNB_DU_ue_id = cmd->gNB_DU_ue_id, - }; - mac->mac_rrc.ue_context_release_complete(&complete); - - du_remove_f1_ue_data(cmd->gNB_DU_ue_id); + NR_SCHED_UNLOCK(&mac->sched_lock); } void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)