Merge remote-tracking branch 'origin/fix_reestablishment_after_handover' into integration_2026_w03 (!3812)

Fix reestablishment after handover
This commit is contained in:
Robert Schmidt
2026-01-13 10:01:00 +01:00
7 changed files with 97 additions and 23 deletions
+1 -9
View File
@@ -2585,17 +2585,9 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i
// nothing is to be done, we wait for confirmation to release the UE in the
// CU/DU)
if (UE->ho_context && UE->ho_context->target && UE->ho_context->source) {
nr_ho_target_cu_t *target_ctx = UE->ho_context->target;
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
ue_data.secondary_ue = target_ctx->du_ue_id;
ue_data.du_assoc_id = target_ctx->du->assoc_id;
bool success = cu_update_f1_ue_data(UE->rrc_ue_id, &ue_data);
DevAssert(success);
LOG_I(NR_RRC, "UE %d handover: update RNTI from %04x to %04x\n", UE->rrc_ue_id, UE->rnti, target_ctx->new_rnti);
nr_ho_source_cu_t *source_ctx = UE->ho_context->source;
DevAssert(source_ctx->old_rnti == UE->rnti);
UE->rnti = target_ctx->new_rnti;
UE->nr_cellid = target_ctx->du->setup_req->cell[0].info.nr_cellid;
nr_rrc_apply_target_context(UE);
}
}
+29 -4
View File
@@ -63,6 +63,34 @@ static void free_ho_ctx(nr_handover_context_t *ho_ctx)
free(ho_ctx);
}
/** @brief Apply target handover context: update F1AP associations and RNTI */
void nr_rrc_apply_target_context(gNB_RRC_UE_t *UE)
{
DevAssert(UE->ho_context);
DevAssert(UE->ho_context->target);
nr_ho_target_cu_t *target_ctx = UE->ho_context->target;
f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id);
LOG_I(NR_RRC,
"UE %d: update CU F1AP Context DU UE ID %u => %u and RNTI %04x => %04x\n",
UE->rrc_ue_id,
ue_data.secondary_ue,
target_ctx->du_ue_id,
UE->rnti,
target_ctx->new_rnti);
/* update F1 data: secondary UE association and DU association */
ue_data.secondary_ue = target_ctx->du_ue_id;
ue_data.du_assoc_id = target_ctx->du->assoc_id;
bool success = cu_update_f1_ue_data(UE->rrc_ue_id, &ue_data);
DevAssert(success);
/* update UE RNTI */
UE->rnti = target_ctx->new_rnti;
/* update UE NR cell ID */
UE->nr_cellid = target_ctx->du->setup_req->cell[0].info.nr_cellid;
}
/** @brief Fill DRB to Be Setup List in F1 UE Context Setup Request (optional list)
* @return 0 if list is empty, list size otherwise */
static int fill_drb_to_be_setup(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, f1ap_drb_to_setup_t drbs[MAX_DRBS_PER_UE])
@@ -464,10 +492,7 @@ static void nr_rrc_n2_ho_acknowledge(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE)
/* this is the callback for N2 handover after F1 UE context setup response in
* the handover case. Check that there was no associated DU, then set it */
AssertFatal(previous_data.secondary_ue == -1, "there was already a DU present\n");
previous_data.secondary_ue = UE->ho_context->target->du_ue_id;
bool success = cu_update_f1_ue_data(UE->rrc_ue_id, &previous_data);
DevAssert(success);
LOG_I(NR_RRC, "Updated CU F1AP Context for UE %d, DU Id : %u\n", UE->rrc_ue_id, UE->ho_context->target->du_ue_id);
nr_rrc_apply_target_context(UE);
byte_array_t hoCommand = rrc_gNB_encode_HandoverCommand(UE, rrc);
if (hoCommand.len < 0) {
+2
View File
@@ -110,4 +110,6 @@ void nr_rrc_trigger_n2_ho_target(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue);
byte_array_t *get_meas_timing_config(const NR_MeasurementTimingConfiguration_t *mtc, const NR_MeasConfig_t *measConfig);
void nr_rrc_apply_target_context(gNB_RRC_UE_t *UE);
#endif /* RRC_GNB_MOBILITY_H_ */
+13 -1
View File
@@ -938,8 +938,10 @@ static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc,
/* if the frequencyInfoDL is included, consider the target SpCell
to be one on the SSB frequency indicated by the frequencyInfoDL */
const NR_DownlinkConfigCommon_t *dcc = reconfigurationWithSync->spCellConfigCommon->downlinkConfigCommon;
if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB)
if (dcc && dcc->frequencyInfoDL && dcc->frequencyInfoDL->absoluteFrequencySSB) {
rrc->arfcn_ssb = *dcc->frequencyInfoDL->absoluteFrequencySSB;
LOG_I(NR_RRC, "UE %ld: updated ARFCN_SSB=%ld\n", rrc->ue_id, rrc->arfcn_ssb);
}
// consider the target SpCell to be one with a physical cell identity indicated by the physCellId
if (!reconfigurationWithSync->spCellConfigCommon->physCellId)
@@ -1767,6 +1769,15 @@ static void nr_rrc_ue_decode_NR_BCCH_BCH_Message(NR_UE_RRC_INST_t *rrc,
}
NR_BCCH_BCH_Message_t *bcch_message = NULL;
if (rrc->phyCellID != phycellid || rrc->arfcn_ssb != ssb_arfcn) {
LOG_I(NR_RRC,
"[UE %ld] BCCH update: phyCellID %d->%u, arfcn_ssb %ld->%ld\n",
rrc->ue_id,
rrc->phyCellID,
phycellid,
rrc->arfcn_ssb,
ssb_arfcn);
}
rrc->phyCellID = phycellid;
rrc->arfcn_ssb = ssb_arfcn;
@@ -2396,6 +2407,7 @@ static void nr_rrc_ue_process_rrcReestablishment(NR_UE_RRC_INST_t *rrc,
// perform the actions upon going to RRC_IDLE as specified in 5.3.11
// with release cause 'RRC connection failure', upon which the procedure ends
if (!integrity_pass) {
LOG_W(NR_RRC, "Integrity of RRCReestablishment failed, going to IDLE\n");
NR_Release_Cause_t release_cause = RRC_CONNECTION_FAILURE;
nr_rrc_going_to_IDLE(rrc, release_cause, NULL);
return;