Merge remote-tracking branch 'origin/fix_reestablishment_after_handover' into integration_2026_w03 (!3812)
Fix reestablishment after handover
This commit is contained in:
@@ -514,6 +514,15 @@ static int handle_sync_req_from_mac(PHY_VARS_NR_UE *UE)
|
||||
uint64_t dl_CarrierFreq = get_carrier_frequency(fp->N_RB_DL, fp->numerology_index, cfg->dl_frequency);
|
||||
uint64_t ul_CarrierFreq = get_carrier_frequency(fp->N_RB_UL, fp->numerology_index, cfg->uplink_frequency);
|
||||
if (dl_CarrierFreq != fp->dl_CarrierFreq || ul_CarrierFreq != fp->ul_CarrierFreq) {
|
||||
LOG_I(NR_PHY,
|
||||
"[UE %d] RF frequency change: dl %lu->%lu Hz, ul %lu->%lu Hz (from dl_frequency=%u kHz, target_Nid_cell=%d)\n",
|
||||
UE->Mod_id,
|
||||
fp->dl_CarrierFreq,
|
||||
dl_CarrierFreq,
|
||||
fp->ul_CarrierFreq,
|
||||
ul_CarrierFreq,
|
||||
cfg->dl_frequency,
|
||||
UE->target_Nid_cell);
|
||||
fp->dl_CarrierFreq = dl_CarrierFreq;
|
||||
fp->ul_CarrierFreq = ul_CarrierFreq;
|
||||
nr_rf_card_config_freq(&UE->openair0_cfg[UE->rf_map.card], ul_CarrierFreq, dl_CarrierFreq, 0);
|
||||
|
||||
@@ -142,9 +142,21 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo
|
||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||
cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||
|
||||
uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) *
|
||||
(15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
|
||||
cfg->carrier_config.dl_frequency = (downlink_frequency[cc_idP][0]/1000) - (dl_bw_khz>>1);
|
||||
/** Only set frequency if not already initialized (e.g., from handover reconfigurationWithSync)
|
||||
* MAC maintains its own frequency state, don't overwrite it with command-line parameter which
|
||||
* is related to the initial cell selection. */
|
||||
if (cfg->carrier_config.dl_frequency == 0) {
|
||||
// Initial cell selection: derive from command-line parameter
|
||||
uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) *
|
||||
(15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
|
||||
cfg->carrier_config.dl_frequency = (downlink_frequency[cc_idP][0]/1000) - (dl_bw_khz>>1);
|
||||
LOG_I(NR_MAC,
|
||||
"[UE %d] Initial cell selection: dl_frequency=%u kHz (from command-line, band=%d, scs=%ld)\n",
|
||||
mac->ue_id,
|
||||
cfg->carrier_config.dl_frequency,
|
||||
mac->nr_band,
|
||||
frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
|
||||
@@ -165,10 +177,21 @@ static void config_common_ue_sa(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommo
|
||||
frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
|
||||
cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
|
||||
|
||||
if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
|
||||
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
|
||||
else
|
||||
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency + (uplink_frequency_offset[cc_idP][0] / 1000);
|
||||
/** Only set UL frequency if not already initialized (e.g., from handover reconfigurationWithSync)
|
||||
* MAC maintains its own frequency state, don't overwrite it with command-line parameter which
|
||||
* is related to the initial cell selection. */
|
||||
if (cfg->carrier_config.uplink_frequency == 0) {
|
||||
// Initial cell selection: derive from DL frequency
|
||||
LOG_I(NR_MAC,
|
||||
"Initial cell selection: uplink_frequency=%u kHz (from dl_frequency=%u kHz, uplink_frequency_offset=%u kHz)\n",
|
||||
cfg->carrier_config.uplink_frequency,
|
||||
cfg->carrier_config.dl_frequency,
|
||||
uplink_frequency_offset[cc_idP][0]);
|
||||
if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
|
||||
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
|
||||
else
|
||||
cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency + (uplink_frequency_offset[cc_idP][0] / 1000);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
|
||||
@@ -437,6 +460,13 @@ static void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t
|
||||
*scc->ssbSubcarrierSpacing,
|
||||
frequencyInfoDL->absoluteFrequencyPointA)
|
||||
/ 1000; // freq in kHz
|
||||
LOG_I(NR_MAC,
|
||||
"[UE %d] Set dl_frequency=%u kHz (from absoluteFrequencyPointA=%ld, band=%d, scs=%ld)\n",
|
||||
mac->ue_id,
|
||||
cfg->carrier_config.dl_frequency,
|
||||
frequencyInfoDL->absoluteFrequencyPointA,
|
||||
mac->nr_band,
|
||||
*scc->ssbSubcarrierSpacing);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
|
||||
|
||||
@@ -1114,9 +1114,9 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
|
||||
RA_config_t *ra = &mac->ra;
|
||||
|
||||
if (ra->cfra) {
|
||||
LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CFRA: RAR successfully received.\n", mac->ue_id, frame, slot);
|
||||
LOG_A(NR_MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CFRA: RAR successfully received.\n", mac->ue_id, frame, slot);
|
||||
} else {
|
||||
LOG_A(MAC,
|
||||
LOG_A(NR_MAC,
|
||||
"[UE %d][%d.%d][RAPROC] %d-Step RA procedure succeeded. CBRA: Contention Resolution is successful.\n",
|
||||
mac->ue_id,
|
||||
frame,
|
||||
@@ -1127,6 +1127,10 @@ void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame
|
||||
nr_timer_stop(&ra->contention_resolution_timer);
|
||||
}
|
||||
|
||||
// rach-ConfigDedicated is one shot configuration to be used only for a specific instance of reconfiguration with sync
|
||||
if (ra->rach_ConfigDedicated)
|
||||
asn1cFreeStruc(asn_DEF_NR_RACH_ConfigDedicated, ra->rach_ConfigDedicated);
|
||||
|
||||
ra->RA_active = false;
|
||||
mac->msg3_C_RNTI = false;
|
||||
ra->ra_state = nrRA_SUCCEEDED;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user