Merge remote-tracking branch 'origin/NR_fix_ssbpos_ho' into integration_2026_w10 (!3929)

UE: Fix if target cell during handover has SSB at a different offset as in source cell

These changes fixed these observed issues:
- If target cell has a different SSB position compared to source cell during
  ho - sync was not successful.
- RAR does not get decoded if SSB position has changed on the target cell
  compared to source cell.
This commit is contained in:
Jaroslava Fiedlerova
2026-03-04 21:15:46 +01:00
8 changed files with 102 additions and 60 deletions
+5 -9
View File
@@ -24,6 +24,7 @@
#include "common/utils/LOG/log.h"
#include "executables/softmodem-common.h"
#include "PHY/MODULATION/nr_modulation.h"
#include "PHY/nr_phy_common/inc/nr_phy_common.h"
/// Subcarrier spacings in Hz indexed by numerology index
static const uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
@@ -421,16 +422,11 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fapi_nr_config_request_t* conf
fp->samples_per_frame = 10 * fp->samples_per_subframe;
fp->freq_range = get_freq_range_from_freq(fp->dl_CarrierFreq);
uint8_t sco = 0;
if (((fp->freq_range == FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) ||
((fp->freq_range == FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) {
if (fp->freq_range == FR1)
sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common;
else
sco = config->ssb_table.ssb_subcarrier_offset;
}
fp->ssb_start_subcarrier = nr_get_ssb_start_sc(config->ssb_config.scs_common,
config->ssb_table.ssb_offset_point_a,
config->ssb_table.ssb_subcarrier_offset,
fp->freq_range);
fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
set_Lmax(fp);
fp->L_ssb = (((uint64_t) config->ssb_table.ssb_mask_list[0].ssb_mask)<<32) | config->ssb_table.ssb_mask_list[1].ssb_mask;
@@ -389,4 +389,9 @@ void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms,
const uint8_t cdm_type,
c16_t **dataF);
int nr_get_ssb_start_sc(int scs,
int ssb_offset_point_a,
int ssb_sco,
frequency_range_t freq_range);
#endif
@@ -481,3 +481,26 @@ void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, con
mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14);
#endif
}
/*!
* Setting the first subcarrier
* 3GPP TS 38.211 sections 7.4.3.1 and 4.4.4.2
* for FR1 offsetToPointA and k_SSB are expressed in terms of 15 kHz SCS
* for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the SCS provided
* by the higher-layer parameter subCarrierSpacingCommon
*/
int nr_get_ssb_start_sc(int scs, int ssb_offset_point_a, int ssb_sco, frequency_range_t freq_range)
{
const int prb_offset =
(freq_range == FR1) ? ssb_offset_point_a >> scs : ssb_offset_point_a >> (scs - 2);
const int sc_offset =
(freq_range == FR1) ? ssb_sco >> scs : ssb_sco;
int ssb_start_subcarrier = (12 * prb_offset + sc_offset);
LOG_D(NR_PHY, "prb_offset:%d, ssb_subcarrier_offset:%d,scs :%d, Fr:%d, ssb_start_subcarrier:%d\n",
prb_offset, ssb_sco, scs, freq_range, ssb_start_subcarrier);
return ssb_start_subcarrier;
}
+4 -12
View File
@@ -118,9 +118,10 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
// by the higher-layer parameter subCarrierSpacingCommon
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
const int scs = cfg->ssb_config.scs_common.value;
const int prb_offset = (fp->freq_range == FR1) ? pdu->ssbOffsetPointA >> scs : pdu->ssbOffsetPointA >> (scs - 2);
const int sc_offset = (fp->freq_range == FR1) ? pdu->SsbSubcarrierOffset >> scs : pdu->SsbSubcarrierOffset;
fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset);
fp->ssb_start_subcarrier = nr_get_ssb_start_sc(scs,
pdu->ssbOffsetPointA,
pdu->SsbSubcarrierOffset,
fp->freq_range);
if (fp->print_ue_help_cmdline_log && IS_SA_MODE(get_softmodem_params())) {
fp->print_ue_help_cmdline_log = false;
@@ -142,15 +143,6 @@ void nr_common_signal_procedures(PHY_VARS_gNB *gNB, int frame, int slot, const n
fp->ssb_start_subcarrier,
fp->threequarter_fs ? "-E" : "");
}
LOG_D(PHY,
"ssbOffsetPointA %d SSB SsbSubcarrierOffset %d prb_offset %d sc_offset %d scs %d ssb_start_subcarrier %d\n",
pdu->ssbOffsetPointA,
pdu->SsbSubcarrierOffset,
prb_offset,
sc_offset,
scs,
fp->ssb_start_subcarrier);
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n", frame, slot, ssb_start_symbol);
const nfapi_nr_tx_precoding_and_beamforming_t *pb = &pdu->precoding_and_beamforming;
c16_t ***txdataF = gNB->common_vars.txdataF;