Commit 59803e22 authored by Guido Casati's avatar Guido Casati

Fix duplicate handover request handling

- Add early check for existing UE context by AMF UE NGAP ID at beginning of rrc_gNB_process_Handover_Request
- Add dedicated function to get UE context by AMF UE NGAP ID: rrc_gNB_get_ue_context_by_amf_ue_ngap_id()
- Send handover failure with appropriate cause if UE context already exists
- Remove redundant ho_context NULL check that could never be true for newly created UE contexts
- Prevents duplicate handover processing and resource leaks
parent 13571587
...@@ -1129,6 +1129,19 @@ void rrc_gNB_send_NGAP_HANDOVER_FAILURE(gNB_RRC_INST *rrc, ngap_handover_failure ...@@ -1129,6 +1129,19 @@ void rrc_gNB_send_NGAP_HANDOVER_FAILURE(gNB_RRC_INST *rrc, ngap_handover_failure
/** @brief Process NG Handover Request message (8.4.2.2 3GPP TS 38.413) */ /** @brief Process NG Handover Request message (8.4.2.2 3GPP TS 38.413) */
int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, ngap_handover_request_t *msg) int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, ngap_handover_request_t *msg)
{ {
// Check if UE context already exists for this AMF UE NGAP ID
rrc_gNB_ue_context_t *existing_ue_context = rrc_gNB_get_ue_context_by_amf_ue_ngap_id(rrc, msg->amf_ue_ngap_id);
if (existing_ue_context != NULL) {
LOG_E(RRC, "UE context already exists for AMF UE NGAP ID %ld, cannot process handover request\n", msg->amf_ue_ngap_id);
ngap_handover_failure_t fail = {
.amf_ue_ngap_id = msg->amf_ue_ngap_id,
.cause.type = NGAP_CAUSE_RADIO_NETWORK,
.cause.value = NGAP_CAUSE_RADIO_NETWORK_HO_FAILURE_IN_TARGET_5GC_NGRAN_NODE_OR_TARGET_SYSTEM,
};
rrc_gNB_send_NGAP_HANDOVER_FAILURE(rrc, &fail);
return -1;
}
struct nr_rrc_du_container_t *du = get_du_by_cell_id(rrc, msg->nr_cell_id); struct nr_rrc_du_container_t *du = get_du_by_cell_id(rrc, msg->nr_cell_id);
if (du == NULL) { if (du == NULL) {
/* Cell Not Found! Return HO Request Failure*/ /* Cell Not Found! Return HO Request Failure*/
...@@ -1150,10 +1163,6 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga ...@@ -1150,10 +1163,6 @@ int rrc_gNB_process_Handover_Request(gNB_RRC_INST *rrc, instance_t instance, nga
gNB_RRC_UE_t *UE = &ue_context_p->ue_context; gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
// allocate context for target // allocate context for target
if (UE->ho_context != NULL) {
LOG_E(NR_RRC, "Ongoing handover for UE %d, cannot trigger new\n", UE->rrc_ue_id);
return -1;
}
UE->ho_context = alloc_ho_ctx(HO_CTX_TARGET); UE->ho_context = alloc_ho_ctx(HO_CTX_TARGET);
UE->ho_context->target->ho_trigger = nr_rrc_trigger_n2_ho_target; UE->ho_context->target->ho_trigger = nr_rrc_trigger_n2_ho_target;
......
...@@ -122,6 +122,18 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST *rrc_in ...@@ -122,6 +122,18 @@ rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST *rrc_in
return NULL; return NULL;
} }
/** @brief Fetch UE Context by the unique AMF UE NGAP ID */
rrc_gNB_ue_context_t *rrc_gNB_get_ue_context_by_amf_ue_ngap_id(gNB_RRC_INST *rrc_instance_pP, uint64_t amf_ue_ngap_id)
{
rrc_gNB_ue_context_t *ue_context_p;
RB_FOREACH (ue_context_p, rrc_nr_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
if (ue_context_p->ue_context.amf_ue_ngap_id == amf_ue_ngap_id) {
return ue_context_p;
}
}
return NULL;
}
void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t *const ue_context_pP) void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t *const ue_context_pP)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
......
...@@ -46,6 +46,7 @@ rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance ...@@ -46,6 +46,7 @@ rrc_gNB_ue_context_t* rrc_gNB_allocate_new_ue_context(gNB_RRC_INST* rrc_instance
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue); rrc_gNB_ue_context_t* rrc_gNB_get_ue_context(gNB_RRC_INST* rrc_instance_pP, ue_id_t ue);
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP); rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti(gNB_RRC_INST* rrc_instance_pP, sctp_assoc_t assoc_id, rnti_t rntiP);
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP); rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_rnti_any_du(gNB_RRC_INST* rrc_instance_pP, rnti_t rntiP);
rrc_gNB_ue_context_t* rrc_gNB_get_ue_context_by_amf_ue_ngap_id(gNB_RRC_INST* rrc_instance_pP, uint64_t amf_ue_ngap_id);
void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP); void rrc_gNB_free_mem_ue_context(rrc_gNB_ue_context_t* const ue_context_pP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment