From d6fb5c2e314b7d185e9fe3fe68101725a56f1467 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 27 Apr 2023 08:44:19 +0200 Subject: [PATCH] Handle UE release request at CU, and trigger at DU at UL failure --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h | 11 ------ openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 3 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c | 5 ++- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 39 +++++++++++++++++++ .../LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c | 3 +- .../LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c | 5 ++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 14 +++---- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 4 ++ .../LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 2 +- .../LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c | 5 ++- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 3 +- openair2/RRC/NR/L2_nr_interface.c | 29 -------------- openair2/RRC/NR/rrc_gNB.c | 17 +++++++- .../ngap_gNB_context_management_procedures.c | 5 +++ 14 files changed, 85 insertions(+), 60 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 9f80475666..ccb630f63d 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -271,17 +271,6 @@ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, @returns transformPrecoding value */ long get_transformPrecoding(const NR_UE_UL_BWP_t *current_UL_BWP, nr_dci_format_t dci_format, uint8_t configuredGrant); -void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); - -void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP); - uint8_t number_of_bits_set(uint8_t buf); void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index fb78ff0d13..0b5e261c5b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -1796,8 +1796,7 @@ static void nr_generate_Msg3_dcch_dtch_response(module_id_t module_idP, configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE, 0, 0); // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE - sched_ctrl->pusch_consecutive_dtx_cnt = 0; - sched_ctrl->ul_failure = 0; + nr_mac_reset_ul_failure(sched_ctrl); } static void nr_generate_Msg4(module_id_t module_idP, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 4d3d59c12e..3f1ea001b3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -577,7 +577,7 @@ static void pf_dl(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - if (sched_ctrl->ul_failure==1) + if (sched_ctrl->ul_failure) continue; const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl; @@ -898,7 +898,8 @@ void nr_schedule_ue_spec(module_id_t module_id, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; - if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; + if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) + continue; NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch; UE->mac_stats.dl.current_bytes = 0; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9545f8feb7..e9a985b670 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -2795,6 +2795,9 @@ void nr_mac_update_timers(module_id_t module_id, continue; } + /* check if UL failure and trigger release request if necessary */ + nr_mac_check_ul_failure(RC.nrmac[module_id], UE->rnti, sched_ctrl); + if (sched_ctrl->rrc_processing_timer > 0) { sched_ctrl->rrc_processing_timer--; if (sched_ctrl->rrc_processing_timer == 0) { @@ -2970,3 +2973,39 @@ bool nr_mac_check_release(NR_UE_sched_ctrl_t *sched_ctrl, int rnti) sched_ctrl->release_timer--; return sched_ctrl->release_timer == 0; } + +void nr_mac_trigger_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl, NR_SubcarrierSpacing_t subcarrier_spacing) +{ + if (sched_ctrl->ul_failure) { + /* already running */ + return; + } + sched_ctrl->ul_failure = true; + // 30 seconds till triggering release request + sched_ctrl->ul_failure_timer = 30000 << subcarrier_spacing; +} + +void nr_mac_reset_ul_failure(NR_UE_sched_ctrl_t *sched_ctrl) +{ + sched_ctrl->ul_failure = false; + sched_ctrl->ul_failure_timer = 0; + 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) +{ + if (!sched_ctrl->ul_failure) + return; + if (sched_ctrl->ul_failure_timer > 0) + sched_ctrl->ul_failure_timer--; + /* to trigger only once: trigger when ul_failure_timer == 1, but timer will + * stop at 0 and we wait for a UE release command from upper layers */ + if (sched_ctrl->ul_failure_timer == 1) { + f1ap_ue_context_release_complete_t complete = { + .rnti = rnti, + .cause = F1AP_CAUSE_RADIO_NETWORK, + .cause_value = 12, // F1AP_CauseRadioNetwork_rl_failure_others + }; + nrmac->mac_rrc.ue_context_release_request(&complete); + } +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index 3309e1af34..c384691e87 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -260,8 +260,7 @@ void nr_schedule_srs(int module_id, frame_t frame, int slot) sched_ctrl->sched_srs.srs_scheduled = false; } - if((sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) || - sched_ctrl->rrc_processing_timer > 0) { + if ((sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) || sched_ctrl->rrc_processing_timer > 0) { continue; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index e1716458d2..e09f684d25 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -209,7 +209,7 @@ void nr_csi_meas_reporting(int Mod_idP, NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; - if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) { + if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test)) { continue; } const NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; @@ -1216,7 +1216,8 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; - if (sched_ctrl->ul_failure==1 || sched_ctrl->rrc_processing_timer>0) continue; + if (sched_ctrl->ul_failure || sched_ctrl->rrc_processing_timer > 0) + continue; NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index cf20ca5d1a..e777fa5e0f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -671,7 +671,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, if (!get_softmodem_params()->phy_test && UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt >= pusch_failure_thres) { LOG_W(NR_MAC,"Detected UL Failure on PUSCH after %d PUSCH DTX, stopping scheduling\n", UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt); - nr_mac_gNB_rrc_ul_failure(gnb_mod_idP,CC_idP,frameP,slotP,rntiP); + nr_mac_trigger_ul_failure(&UE->UE_sched_ctrl, UE->current_UL_BWP.scs); } } } else if(sduP) { @@ -755,11 +755,9 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, LOG_D(NR_MAC, "[UE %04x] PUSCH TPC %d and TA %d\n", UE_msg3_stage->rnti, UE_scheduling_control->tpc0, UE_scheduling_control->ta_update); if (ra->cfra) { LOG_A(NR_MAC, "(rnti 0x%04x) CFRA procedure succeeded!\n", ra->rnti); - nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->rnti); + nr_mac_reset_ul_failure(UE_scheduling_control); reset_dl_harq_list(UE_scheduling_control); reset_ul_harq_list(UE_scheduling_control); - UE_scheduling_control->pusch_consecutive_dtx_cnt = 0; - UE_scheduling_control->ul_failure = 0; UE_msg3_stage->ra_timer = 0; nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); process_CellGroup(ra->CellGroup, UE_scheduling_control); @@ -791,8 +789,7 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP, return; } else { // The UE identified by C-RNTI still exists at the gNB - // Reset uplink failure flags/counters/timers at RRC - nr_mac_gNB_rrc_ul_failure_reset(gnb_mod_idP, frameP, slotP, ra->crnti); + nr_mac_reset_ul_failure(&UE_C->UE_sched_ctrl); // Reset HARQ processes reset_dl_harq_list(&UE_C->UE_sched_ctrl); @@ -1636,7 +1633,7 @@ static void pf_ul(module_id_t module_id, UE_iterator(UE_list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure == 1) + if (UE->Msg4_ACKed != true || sched_ctrl->ul_failure) continue; LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti); @@ -2065,7 +2062,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot, n const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; UE_iterator( UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue; + if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test) + continue; NR_CellGroupConfig_t *cg = UE->CellGroup; NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a94a99d452..f01a47699a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -443,4 +443,8 @@ 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_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); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ 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 2cf37946ea..6e444b9816 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -153,7 +153,7 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) gNB_MAC_INST *mac = RC.nrmac[0]; pthread_mutex_lock(&mac->sched_lock); NR_UE_info_t *UE = find_nr_UE(&mac->UE_info, cmd->rnti); - if (UE->UE_sched_ctrl.ul_failure > 0 || cmd->rrc_container_length == 0) { + 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->rnti); mac_remove_nr_ue(mac, cmd->rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 5db1596a97..e13991529c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -57,7 +57,10 @@ static void ue_context_setup_response_direct(const f1ap_ue_context_setup_t *req, static void ue_context_release_request_direct(const f1ap_ue_context_release_req_t* req) { - AssertFatal(false, "not implemented\n"); + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_REQ); + f1ap_ue_context_release_req_t *f1ap_msg = &F1AP_UE_CONTEXT_RELEASE_REQ(msg); + *f1ap_msg = *req; + itti_send_msg_to_task(TASK_RRC_GNB, 0, msg); } static void ue_context_release_complete_direct(const f1ap_ue_context_release_complete_t *complete) diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 8df47be1e9..d9f3ed1188 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -591,7 +591,8 @@ typedef struct { uint8_t current_harq_pid; int pusch_consecutive_dtx_cnt; int pucch_consecutive_dtx_cnt; - int ul_failure; + bool ul_failure; + int ul_failure_timer; int release_timer; struct CSI_Report CSI_report; bool SR; diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 4e9c077afa..74b08e7dfe 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -118,32 +118,3 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, return 0; } - -void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); - - if (ue_context_p != NULL) { - LOG_D(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP); - if(ue_context_p->ue_context.ul_failure_timer == 0) - ue_context_p->ue_context.ul_failure_timer=1; - } else { - LOG_D(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); - } -} - -void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) { - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(RC.nrrrc[Mod_instP], rntiP); - if (ue_context_p != NULL) { - LOG_W(RRC,"Frame %d, Subframe %d: UE %x UL failure reset, deactivating timer\n",frameP,subframeP,rntiP); - ue_context_p->ue_context.ul_failure_timer=0; - } else { - LOG_W(RRC,"Frame %d, Subframe %d: UL failure reset: UE %x unknown \n",frameP,subframeP,rntiP); - } -} diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index b955c7147d..a7f6aabb74 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2589,6 +2589,21 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance * messages (UE capability, to be specific) */ } +static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p) +{ + const int instance = 0; + f1ap_ue_context_release_req_t *req = &F1AP_UE_CONTEXT_RELEASE_REQ(msg_p); + gNB_RRC_INST *rrc = RC.nrrrc[instance]; + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(rrc, req->rnti); + + /* TODO: marshall types correctly */ + LOG_I(NR_RRC, "received UE Context Release Request for UE %04x, forwarding to AMF\n", req->rnti); + rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_REQ(instance, + ue_context_p, + NGAP_CAUSE_RADIO_NETWORK, + NGAP_CAUSE_RADIO_NETWORK_RADIO_CONNECTION_WITH_UE_LOST); +} + static void rrc_CU_process_ue_context_release_complete(MessageDef *msg_p) { const int instance = 0; @@ -3178,7 +3193,7 @@ void *rrc_gnb_task(void *args_p) { break; case F1AP_UE_CONTEXT_RELEASE_REQ: - AssertFatal(false, "F1 UE context release request to be implemented\n"); + rrc_CU_process_ue_context_release_request(msg_p); break; case F1AP_UE_CONTEXT_RELEASE_COMPLETE: diff --git a/openair3/NGAP/ngap_gNB_context_management_procedures.c b/openair3/NGAP/ngap_gNB_context_management_procedures.c index c9db35e8c8..b05f96b899 100644 --- a/openair3/NGAP/ngap_gNB_context_management_procedures.c +++ b/openair3/NGAP/ngap_gNB_context_management_procedures.c @@ -138,6 +138,11 @@ int ngap_ue_context_release_req(instance_t instance, /* The context for this gNB ue ngap id doesn't exist in the map of gNB UEs */ NGAP_WARN("Failed to find ue context associated with gNB ue ngap id: %u\n", ue_release_req_p->gNB_ue_ngap_id); + /* send response to free the UE: we don't know it, but it should be + * released since RRC seems to know it (e.g., there is no AMF) */ + MessageDef *msg = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND); + NGAP_UE_CONTEXT_RELEASE_COMMAND(msg).gNB_ue_ngap_id = ue_release_req_p->gNB_ue_ngap_id; + itti_send_msg_to_task(TASK_RRC_GNB, ngap_gNB_instance_p->instance, msg); return -1; }