Optimize create_measgap_config to eliminate unnecessary allocation
- Replace inefficient 'allocate, extract, free' pattern with direct value extraction - Remove unused functions get_gap_config_from_smtc() and get_gap_config() - Add extract_gap_config_from_smtc() that extracts values directly without allocation - Eliminates use-after-free risk and improves performance - No allocation overhead, no memory leaks
This commit is contained in:
@@ -50,6 +50,11 @@
|
|||||||
|
|
||||||
#define NR_MAX_SUPPORTED_DL_LAYERS 4
|
#define NR_MAX_SUPPORTED_DL_LAYERS 4
|
||||||
|
|
||||||
|
/* Default values for measurement gap configuration */
|
||||||
|
#define DEFAULT_MGRP NR_GapConfig__mgrp_ms160
|
||||||
|
#define DEFAULT_MGTA NR_GapConfig__mgta_ms0dot5
|
||||||
|
#define DEFAULT_MGL NR_GapConfig__mgl_ms6
|
||||||
|
|
||||||
#define PUCCH2_SIZE 8
|
#define PUCCH2_SIZE 8
|
||||||
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
|
||||||
|
|
||||||
@@ -4211,53 +4216,6 @@ NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t u
|
|||||||
return reconfigurationWithSync;
|
return reconfigurationWithSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NR_MeasGapConfig_t *get_gap_config_from_smtc(const NR_SSB_MTC_t *ssb_mtc)
|
|
||||||
{
|
|
||||||
NR_MeasGapConfig_t *measGapConfig = calloc_or_fail(1, sizeof(*measGapConfig));
|
|
||||||
measGapConfig->ext1 = calloc_or_fail(1, sizeof(*measGapConfig->ext1));
|
|
||||||
measGapConfig->ext1->gapUE = calloc_or_fail(1, sizeof(*measGapConfig->ext1->gapUE));
|
|
||||||
measGapConfig->ext1->gapUE->present = NR_SetupRelease_GapConfig_PR_setup;
|
|
||||||
NR_GapConfig_t *gap_config = calloc_or_fail(1, sizeof(*gap_config));
|
|
||||||
measGapConfig->ext1->gapUE->choice.setup = gap_config;
|
|
||||||
|
|
||||||
// mgta = Measurement Gap Timing Advance, to provide sufficient time for the UE to re-tune its transceiver
|
|
||||||
// This allows the Measurement Gap to extend mgta ms either side of the SS/PBCH Measurement Window.
|
|
||||||
gap_config->mgta = NR_GapConfig__mgta_ms0dot5;
|
|
||||||
|
|
||||||
// mgrp = Measurement Gap Repetition Period
|
|
||||||
// gapOffset = It defines the start of the Measurement Gaps relative to the start of the radio frame with SFN = 0
|
|
||||||
// The Measurement Gaps need to be synchronized with the SS/PBCH transmissions which are to be measured
|
|
||||||
gap_config->mgrp = NR_GapConfig__mgrp_ms160;
|
|
||||||
switch (ssb_mtc->periodicityAndOffset.present) {
|
|
||||||
case NR_SSB_MTC__periodicityAndOffset_PR_sf20:
|
|
||||||
gap_config->gapOffset = ssb_mtc->periodicityAndOffset.choice.sf20;
|
|
||||||
break;
|
|
||||||
case NR_SSB_MTC__periodicityAndOffset_PR_sf40:
|
|
||||||
gap_config->gapOffset = ssb_mtc->periodicityAndOffset.choice.sf40;
|
|
||||||
break;
|
|
||||||
case NR_SSB_MTC__periodicityAndOffset_PR_sf80:
|
|
||||||
gap_config->gapOffset = ssb_mtc->periodicityAndOffset.choice.sf80;
|
|
||||||
break;
|
|
||||||
case NR_SSB_MTC__periodicityAndOffset_PR_sf160:
|
|
||||||
gap_config->gapOffset = ssb_mtc->periodicityAndOffset.choice.sf160;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_W(NR_RRC, "SMTC periodicity higher than MGRP\n");
|
|
||||||
// With this configuration, not all SSBs belong to the Measurement Gap.
|
|
||||||
if (ssb_mtc->periodicityAndOffset.present == NR_SSB_MTC__periodicityAndOffset_PR_sf5) {
|
|
||||||
gap_config->gapOffset = ssb_mtc->periodicityAndOffset.choice.sf5;
|
|
||||||
} else if (ssb_mtc->periodicityAndOffset.present == NR_SSB_MTC__periodicityAndOffset_PR_sf10) {
|
|
||||||
gap_config->gapOffset = ssb_mtc->periodicityAndOffset.choice.sf10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mgl = Measurement Gap Length
|
|
||||||
// FIXME: At least the duration of the SMTC plus 2 times the mgta should be enough,
|
|
||||||
// however, at the moment it only works by setting the maximum value
|
|
||||||
gap_config->mgl = NR_GapConfig__mgl_ms6;
|
|
||||||
|
|
||||||
return measGapConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len)
|
NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
@@ -4330,25 +4288,37 @@ static float get_mgta(long mgta)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Return Measurement Gap Configuration, from ASN.1 config */
|
/** @brief Extract gapOffset from SSB MTC periodicity */
|
||||||
const NR_GapConfig_t *get_gap_config(const NR_MeasGapConfig_t *mgc)
|
static bool extract_gap_offset_from_smtc(const NR_SSB_MTC_t *ssb_mtc, long *gapOffset)
|
||||||
{
|
{
|
||||||
if (mgc->gapFR2 && mgc->gapFR2->present == NR_SetupRelease_GapConfig_PR_setup)
|
if (!ssb_mtc)
|
||||||
return mgc->gapFR2->choice.setup;
|
return false;
|
||||||
|
|
||||||
// FR1 case
|
// Extract gapOffset based on periodicity
|
||||||
if (!mgc->ext1)
|
switch (ssb_mtc->periodicityAndOffset.present) {
|
||||||
return NULL;
|
case NR_SSB_MTC__periodicityAndOffset_PR_sf20:
|
||||||
|
*gapOffset = ssb_mtc->periodicityAndOffset.choice.sf20;
|
||||||
|
break;
|
||||||
|
case NR_SSB_MTC__periodicityAndOffset_PR_sf40:
|
||||||
|
*gapOffset = ssb_mtc->periodicityAndOffset.choice.sf40;
|
||||||
|
break;
|
||||||
|
case NR_SSB_MTC__periodicityAndOffset_PR_sf80:
|
||||||
|
*gapOffset = ssb_mtc->periodicityAndOffset.choice.sf80;
|
||||||
|
break;
|
||||||
|
case NR_SSB_MTC__periodicityAndOffset_PR_sf160:
|
||||||
|
*gapOffset = ssb_mtc->periodicityAndOffset.choice.sf160;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_W(NR_RRC, "SMTC periodicity higher than MGRP\n");
|
||||||
|
if (ssb_mtc->periodicityAndOffset.present == NR_SSB_MTC__periodicityAndOffset_PR_sf5) {
|
||||||
|
*gapOffset = ssb_mtc->periodicityAndOffset.choice.sf5;
|
||||||
|
} else if (ssb_mtc->periodicityAndOffset.present == NR_SSB_MTC__periodicityAndOffset_PR_sf10) {
|
||||||
|
*gapOffset = ssb_mtc->periodicityAndOffset.choice.sf10;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const NR_SetupRelease_GapConfig_t *gapUE = mgc->ext1->gapUE;
|
return true;
|
||||||
if (gapUE && gapUE->present == NR_SetupRelease_GapConfig_PR_setup)
|
|
||||||
return gapUE->choice.setup;
|
|
||||||
|
|
||||||
const NR_SetupRelease_GapConfig_t *gapFR1 = mgc->ext1->gapFR1;
|
|
||||||
if (gapFR1 && gapFR1->present == NR_SetupRelease_GapConfig_PR_setup)
|
|
||||||
return gapFR1->choice.setup;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime)
|
measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime)
|
||||||
@@ -4359,20 +4329,25 @@ measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t
|
|||||||
DevAssert(mt != NULL && mt->frequencyAndTiming != NULL);
|
DevAssert(mt != NULL && mt->frequencyAndTiming != NULL);
|
||||||
const struct NR_MeasTiming__frequencyAndTiming *ft = mt->frequencyAndTiming;
|
const struct NR_MeasTiming__frequencyAndTiming *ft = mt->frequencyAndTiming;
|
||||||
const NR_SSB_MTC_t *ssb_mtc = &ft->ssb_MeasurementTimingConfiguration;
|
const NR_SSB_MTC_t *ssb_mtc = &ft->ssb_MeasurementTimingConfiguration;
|
||||||
NR_MeasGapConfig_t *measGapConfig = get_gap_config_from_smtc(ssb_mtc);
|
|
||||||
const NR_GapConfig_t *gap_config = get_gap_config(measGapConfig);
|
// Initialize with defaults
|
||||||
if (!gap_config) {
|
long mgrp = DEFAULT_MGRP;
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_MeasGapConfig, measGapConfig);
|
long gapOffset = 0;
|
||||||
|
long mgta = DEFAULT_MGTA;
|
||||||
|
long mgl = DEFAULT_MGL;
|
||||||
|
|
||||||
|
// Extract gapOffset from SSB MTC periodicity
|
||||||
|
if (!extract_gap_offset_from_smtc(ssb_mtc, &gapOffset)) {
|
||||||
return mgc;
|
return mgc;
|
||||||
}
|
}
|
||||||
|
|
||||||
mgc.mgrp_ms = get_mgrp(gap_config->mgrp);
|
mgc.mgrp_ms = get_mgrp(mgrp);
|
||||||
DevAssert(mgc.mgrp_ms != -1);
|
DevAssert(mgc.mgrp_ms != -1);
|
||||||
mgc.mgrp = gap_config->mgrp;
|
mgc.mgrp = mgrp;
|
||||||
|
|
||||||
mgc.gapOffset = gap_config->gapOffset;
|
mgc.gapOffset = gapOffset;
|
||||||
mgc.mgta = gap_config->mgta;
|
mgc.mgta = mgta;
|
||||||
mgc.n_slots_mgta = ((int)(10 * get_mgta(gap_config->mgta)) << scs) / 10;
|
mgc.n_slots_mgta = ((int)(10 * get_mgta(mgta)) << scs) / 10;
|
||||||
|
|
||||||
// We start the timer K2 slots earlier to avoid scheduling feedback PUCCHs inside measGap
|
// We start the timer K2 slots earlier to avoid scheduling feedback PUCCHs inside measGap
|
||||||
// or depending on the current min_rxtxtime earlier
|
// or depending on the current min_rxtxtime earlier
|
||||||
@@ -4381,16 +4356,13 @@ measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t
|
|||||||
|
|
||||||
mgc.n_slots_advance = mgc.n_slots_mgta + max_k2;
|
mgc.n_slots_advance = mgc.n_slots_mgta + max_k2;
|
||||||
|
|
||||||
mgc.mgl_ms = get_mgl(gap_config->mgl);
|
mgc.mgl_ms = get_mgl(mgl);
|
||||||
DevAssert(mgc.mgl_ms != -1);
|
DevAssert(mgc.mgl_ms != -1);
|
||||||
mgc.mgl = gap_config->mgl;
|
mgc.mgl = mgl;
|
||||||
mgc.mgl_slots = ((int)(10 * (mgc.mgl_ms + max_k2)) << scs) / 10;
|
mgc.mgl_slots = ((int)(10 * (mgc.mgl_ms + max_k2)) << scs) / 10;
|
||||||
|
|
||||||
mgc.enable = true;
|
mgc.enable = true;
|
||||||
|
|
||||||
// Free the allocated measGapConfig structure after we're done using gap_config
|
|
||||||
ASN_STRUCT_FREE(asn_DEF_NR_MeasGapConfig, measGapConfig);
|
|
||||||
|
|
||||||
return mgc;
|
return mgc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user