From a2da391e70034ea22aac0eb3e8ceb2d459ca7629 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 4 Oct 2024 19:46:00 +0200 Subject: [PATCH] Handle successful HO after reconfigurationComplete The HO is completed (from a pure RAN perspective) when receiving reconfiguration complete. In that case, remove the HO context, and signal successful handover through the callback. For the F1 handover, this means releasing the UE at the source DU. Co-authored-by: batuhanduyuler Co-authored-by: rmagueta --- openair2/RRC/NR/rrc_gNB.c | 8 ++++++++ openair2/RRC/NR/rrc_gNB_mobility.c | 26 +++++++++++++++++++++++++- openair2/RRC/NR/rrc_gNB_mobility.h | 1 + 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3335116a21..0ab53e0bf7 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1558,6 +1558,14 @@ static void handle_rrcReconfigurationComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *U LOG_I(RRC, "UE %d: transaction %d still ongoing for action %d\n", UE->rrc_ue_id, i, UE->xids[i]); } } + + if (UE->ho_context != NULL) { + LOG_A(NR_RRC, "handover for UE %d/RNTI %04x complete!\n", UE->rrc_ue_id, UE->rnti); + DevAssert(UE->ho_context->target != NULL); + + UE->ho_context->target->ho_success(rrc, UE); + nr_rrc_finalize_ho(UE); + } } static void rrc_gNB_generate_UECapabilityEnquiry(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue) diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c index c423e400f4..6f6a034aa3 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.c +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -272,6 +272,24 @@ static void nr_rrc_f1_ho_acknowledge(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_ } } +static void nr_rrc_f1_ho_complete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE) +{ + DevAssert(UE->ho_context != NULL); + nr_ho_source_cu_t *source_ctx = UE->ho_context->source; + DevAssert(source_ctx != NULL); + RETURN_IF_INVALID_ASSOC_ID(source_ctx->du->assoc_id); + f1ap_ue_context_release_cmd_t cmd = { + .gNB_CU_ue_id = UE->rrc_ue_id, + .gNB_DU_ue_id = source_ctx->du_ue_id, + .cause = F1AP_CAUSE_RADIO_NETWORK, // better + .cause_value = 5, // 5 = F1AP_CauseRadioNetwork_interaction_with_other_procedure + .srb_id = DCCH, + }; + rrc->mac_rrc.ue_context_release_command(source_ctx->du->assoc_id, &cmd); + LOG_I(NR_RRC, "UE %d Handover: trigger release on DU assoc_id %d\n", UE->rrc_ue_id, source_ctx->du->assoc_id); +} + + void nr_rrc_trigger_f1_ho(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, nr_rrc_du_container_t *source_du, nr_rrc_du_container_t *target_du) { DevAssert(rrc != NULL); @@ -287,11 +305,17 @@ void nr_rrc_trigger_f1_ho(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, nr_rrc_du_contain // and therefore also the PDU sessions. Orig RRC reconfiguration should be in // handover preparation information ho_req_ack_t ack = nr_rrc_f1_ho_acknowledge; - ho_success_t success = NULL; + ho_success_t success = nr_rrc_f1_ho_complete; ho_cancel_t cancel = NULL; nr_initiate_handover(rrc, ue, source_du, target_du, buf, size, ack, success, cancel); } +void nr_rrc_finalize_ho(gNB_RRC_UE_t *ue) +{ + free_ho_ctx(ue->ho_context); + ue->ho_context = NULL; +} + void nr_HO_F1_trigger_telnet(gNB_RRC_INST *rrc, uint32_t rrc_ue_id) { rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, rrc_ue_id); diff --git a/openair2/RRC/NR/rrc_gNB_mobility.h b/openair2/RRC/NR/rrc_gNB_mobility.h index 5811804009..1078cffe4e 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.h +++ b/openair2/RRC/NR/rrc_gNB_mobility.h @@ -67,5 +67,6 @@ typedef struct nr_handover_context_s { } nr_handover_context_t; void nr_rrc_trigger_f1_ho(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, nr_rrc_du_container_t *source_du, nr_rrc_du_container_t *target_du); +void nr_rrc_finalize_ho(gNB_RRC_UE_t *ue); #endif /* RRC_GNB_MOBILITY_H_ */