From c26a12e6b74583e4a7db50d9f5b96ff4ed09e9c1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 07:59:21 +0200 Subject: [PATCH 01/10] Correctly free ASN.1 memory for unused dedicated BWPs prepare_scd() sets up memory for possible dedicated BWPs to be set up. If they are not used, they are freed in fix_scd(). [1] There are two problems: 1. in prepare_scd(), multiple structures are allocated once (for multiple elements), but inserted once. When trying to free those, the logic of ASN.1 is to free list elements individually, but then we try to call free() on each element of the list that has been allocated in one go. Fix this by doing multiple allocations to be in line with ASN.1 logic. 2. in fix_scd(), free recursively all data structures, not only the sequence element itself. [1] this is horrible. We should only allocate memory if we actually need it, but let's fix the more urgent problem of memory leaks first. Fixing the logic problem would be more involved. --- openair2/GNB_APP/gnb_config.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a43812ebdb..3eb43e21a0 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -636,14 +636,14 @@ void prepare_scd(NR_ServingCellConfig_t *scd) { calloc_or_fail(1, sizeof(*NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup)); NR_PTRS_DownlinkConfig_t *NR_PTRS_DownlinkCfg = NR_DMRS_DownlinkCfg->phaseTrackingRS->choice.setup; NR_PTRS_DownlinkCfg->frequencyDensity = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->frequencyDensity)); - long *dl_rbs = calloc_or_fail(2, sizeof(*dl_rbs)); for (int i=0;i<2;i++) { - asn1cSeqAdd(&NR_PTRS_DownlinkCfg->frequencyDensity->list, &dl_rbs[i]); + long *a = calloc_or_fail(1, sizeof(*a)); + asn1cSeqAdd(&NR_PTRS_DownlinkCfg->frequencyDensity->list, a); } NR_PTRS_DownlinkCfg->timeDensity = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->timeDensity)); - long *dl_mcs = calloc_or_fail(3, sizeof(*dl_mcs)); for (int i=0;i<3;i++) { - asn1cSeqAdd(&NR_PTRS_DownlinkCfg->timeDensity->list, &dl_mcs[i]); + long *dl_mcs = calloc_or_fail(1, sizeof(*dl_mcs)); + asn1cSeqAdd(&NR_PTRS_DownlinkCfg->timeDensity->list, dl_mcs); } NR_PTRS_DownlinkCfg->epre_Ratio = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->epre_Ratio)); NR_PTRS_DownlinkCfg->resourceElementOffset = calloc_or_fail(1, sizeof(*NR_PTRS_DownlinkCfg->resourceElementOffset)); @@ -668,15 +668,15 @@ void prepare_scd(NR_ServingCellConfig_t *scd) { NR_PTRS_UplinkConfig->transformPrecoderDisabled = calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled)); NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity = calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity)); - long *n_rbs = calloc_or_fail(2, sizeof(*n_rbs)); for (int i=0;i<2;i++) { - asn1cSeqAdd(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity->list, &n_rbs[i]); + long *n_rbs = calloc_or_fail(1, sizeof(*n_rbs)); + asn1cSeqAdd(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->frequencyDensity->list, n_rbs); } NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity = calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity)); - long *ptrs_mcs = calloc_or_fail(3, sizeof(*ptrs_mcs)); for (int i = 0; i < 3; i++) { - asn1cSeqAdd(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity->list, &ptrs_mcs[i]); + long *ptrs_mcs = calloc_or_fail(1, sizeof(*ptrs_mcs)); + asn1cSeqAdd(&NR_PTRS_UplinkConfig->transformPrecoderDisabled->timeDensity->list, ptrs_mcs); } NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset = calloc_or_fail(1, sizeof(*NR_PTRS_UplinkConfig->transformPrecoderDisabled->resourceElementOffset)); @@ -703,6 +703,7 @@ void fix_scd(NR_ServingCellConfig_t *scd) { int b = 0; while (bdownlinkBWP_ToAddModList->list.count) { if (scd->downlinkBWP_ToAddModList->list.array[b]->bwp_Common->genericParameters.locationAndBandwidth == 0) { + ASN_STRUCT_FREE(asn_DEF_NR_BWP_Downlink, scd->downlinkBWP_ToAddModList->list.array[b]); asn_sequence_del(&scd->downlinkBWP_ToAddModList->list,b,1); } else { b++; @@ -712,6 +713,7 @@ void fix_scd(NR_ServingCellConfig_t *scd) { b = 0; while (buplinkConfig->uplinkBWP_ToAddModList->list.count) { if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[b]->bwp_Common->genericParameters.locationAndBandwidth == 0) { + ASN_STRUCT_FREE(asn_DEF_NR_BWP_Uplink, scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[b]); asn_sequence_del(&scd->uplinkConfig->uplinkBWP_ToAddModList->list,b,1); } else { b++; From b18fff6ae22d6c60a54c3a265797826cc76e9ef6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 08:56:07 +0200 Subject: [PATCH 02/10] Correctly deep-copy memory structures on SIB1 creation --- openair2/RRC/NR/nr_rrc_config.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 3527958008..9e834309a7 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -2471,6 +2471,14 @@ static bool is_ntn_band(int band) return false; } +static BIT_STRING_t bit_string_clone(const BIT_STRING_t *orig) +{ + BIT_STRING_t bs = {.size = orig->size, .bits_unused = orig->bits_unused}; + bs.buf = malloc_or_fail(bs.size * sizeof(*bs.buf)); + memcpy(bs.buf, orig->buf, bs.size); + return bs; +} + NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const plmn_id_t *plmn, uint64_t cellID, @@ -2548,8 +2556,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, asn1cSequenceAdd(ServCellCom->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list, struct NR_NR_MultiBandInfo, nrMultiBandInfo); - nrMultiBandInfo->freqBandIndicatorNR = - frequencyInfoDL->frequencyBandList.list.array[i]; + asn1cCallocOne(nrMultiBandInfo->freqBandIndicatorNR, *frequencyInfoDL->frequencyBandList.list.array[i]); } const NR_FreqBandIndicatorNR_t band = *frequencyInfoDL->frequencyBandList.list.array[0]; @@ -2564,8 +2571,11 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, (int)sib1->servingCellConfigCommon->downlinkConfigCommon.frequencyInfoDL.offsetToPointA); for (int i = 0; i < frequencyInfoDL->scs_SpecificCarrierList.list.count; i++) { - asn1cSeqAdd(&ServCellCom->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list, - frequencyInfoDL->scs_SpecificCarrierList.list.array[i]); + const NR_SCS_SpecificCarrier_t *orig = frequencyInfoDL->scs_SpecificCarrierList.list.array[i]; + NR_SCS_SpecificCarrier_t *new = NULL; + const int copy_result = asn_copy(&asn_DEF_NR_SCS_SpecificCarrier, (void **)&new, orig); + AssertFatal(copy_result == 0, "unable to copy NR_SCS_SpecificCarrier from scc to SIB1 structure\n"); + asn1cSeqAdd(&ServCellCom->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list, new); } initialDownlinkBWP->pdcch_ConfigCommon = clone_pdcch_configcommon(scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon); @@ -2598,7 +2608,11 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, asn_set_empty(&UL->frequencyInfoUL.scs_SpecificCarrierList.list); const NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL; for (int i = 0; i < frequencyInfoUL->scs_SpecificCarrierList.list.count; i++) { - asn1cSeqAdd(&UL->frequencyInfoUL.scs_SpecificCarrierList.list, frequencyInfoUL->scs_SpecificCarrierList.list.array[i]); + const NR_SCS_SpecificCarrier_t *orig = frequencyInfoUL->scs_SpecificCarrierList.list.array[i]; + NR_SCS_SpecificCarrier_t *new = NULL; + const int copy_result = asn_copy(&asn_DEF_NR_SCS_SpecificCarrier, (void **)&new, orig); + AssertFatal(copy_result == 0, "unable to copy NR_SCS_SpecificCarrier from scc to SIB1 structure\n"); + asn1cSeqAdd(&UL->frequencyInfoUL.scs_SpecificCarrierList.list, new); } asn1cCallocOne(UL->frequencyInfoUL.p_Max, *frequencyInfoUL->p_Max); @@ -2616,7 +2630,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, AssertFatal(UL->frequencyInfoUL.frequencyBandList != NULL, "out of memory\n"); for (int i = 0; i < frequencyInfoUL->frequencyBandList->list.count; i++) { asn1cSequenceAdd(UL->frequencyInfoUL.frequencyBandList->list, struct NR_NR_MultiBandInfo, nrMultiBandInfo); - nrMultiBandInfo->freqBandIndicatorNR = frequencyInfoUL->frequencyBandList->list.array[i]; + asn1cCallocOne(nrMultiBandInfo->freqBandIndicatorNR, *frequencyInfoUL->frequencyBandList->list.array[i]); } } @@ -2643,14 +2657,13 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, ServCellCom->n_TimingAdvanceOffset = scc->n_TimingAdvanceOffset; - ServCellCom->ssb_PositionsInBurst.inOneGroup.buf = calloc(1, sizeof(uint8_t)); uint8_t bitmap8,temp_bitmap=0; switch (scc->ssb_PositionsInBurst->present) { case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_shortBitmap: - ServCellCom->ssb_PositionsInBurst.inOneGroup = scc->ssb_PositionsInBurst->choice.shortBitmap; + ServCellCom->ssb_PositionsInBurst.inOneGroup = bit_string_clone(&scc->ssb_PositionsInBurst->choice.shortBitmap); break; case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap: - ServCellCom->ssb_PositionsInBurst.inOneGroup = scc->ssb_PositionsInBurst->choice.mediumBitmap; + ServCellCom->ssb_PositionsInBurst.inOneGroup = bit_string_clone(&scc->ssb_PositionsInBurst->choice.mediumBitmap); break; /* * groupPresence: This field is present when maximum number of SS/PBCH blocks per half frame equals to 64 as defined in @@ -2664,6 +2677,7 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, * transmitted. */ case NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_longBitmap: + ServCellCom->ssb_PositionsInBurst.inOneGroup.buf = calloc_or_fail(1, sizeof(uint8_t)); ServCellCom->ssb_PositionsInBurst.inOneGroup.size = 1; ServCellCom->ssb_PositionsInBurst.inOneGroup.bits_unused = 0; ServCellCom->ssb_PositionsInBurst.groupPresence = calloc(1, sizeof(BIT_STRING_t)); From 6afc0dee50fec85eda9abca10eba0d4787ef1c6e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 09:00:51 +0200 Subject: [PATCH 03/10] Correctly free 2-step RA/MsgA structures in fix_scc() --- openair2/GNB_APP/gnb_config.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 3eb43e21a0..a300a182ae 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -548,8 +548,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) && (int)scc->uplinkConfigCommon->initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup->msgA_PUSCH_Config_r16 ->msgA_PUSCH_ResourceGroupA_r16->msgA_PUSCH_TimeDomainOffset_r16 == 0) { - free(scc->uplinkConfigCommon->initialUplinkBWP->ext1); - scc->uplinkConfigCommon->initialUplinkBWP->ext1 = NULL; + NR_BWP_UplinkCommon_t *ulcc = scc->uplinkConfigCommon->initialUplinkBWP; + ASN_STRUCT_FREE(asn_DEF_NR_SetupRelease_MsgA_ConfigCommon_r16, ulcc->ext1->msgA_ConfigCommon_r16); + free(ulcc->ext1); + ulcc->ext1 = NULL; } if ((int)*scc->n_TimingAdvanceOffset == -1) { From 8ee0b8efdfbdda30047f0fdc059ca96dca68b2c3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 09:27:02 +0200 Subject: [PATCH 04/10] Introduce mac_top_destroy_gNB(): free MAC memory --- executables/nr-softmodem.c | 5 +++++ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 3 +++ openair2/LAYER2/NR_MAC_gNB/main.c | 13 +++++++++++++ 3 files changed, 21 insertions(+) diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 24df549243..5a8464b60c 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -758,6 +758,11 @@ int main( int argc, char **argv ) { if (RC.nb_nr_L1_inst > 0 || RC.nb_RU > 0) stop_L1(0); + if (RC.nb_nr_macrlc_inst > 0) { + DevAssert(RC.nb_nr_macrlc_inst == 1); + mac_top_destroy_gNB(RC.nrmac[0]); + } + pthread_cond_destroy(&sync_cond); pthread_mutex_destroy(&sync_mutex); pthread_cond_destroy(&nfapi_sync_cond); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index dad0eb570c..8b403f9e86 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -47,10 +47,13 @@ int get_full_ul_slots_per_period(const frame_structure_t *fs); int get_full_dl_slots_per_period(const frame_structure_t *fs); int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed); +void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia); + void mac_top_init_gNB(ngran_node_t node_type, NR_ServingCellConfigCommon_t *scc, NR_ServingCellConfig_t *scd, const nr_mac_config_t *conf); +void mac_top_destroy_gNB(gNB_MAC_INST *mac); void nr_mac_send_f1_setup_req(void); void nr_mac_config_scc(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *mac_config); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index acf0658e4c..099cb725e1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -346,6 +346,19 @@ void mac_top_init_gNB(ngran_node_t node_type, srand48(0); } +void mac_top_destroy_gNB(gNB_MAC_INST *mac) +{ + NR_COMMON_channels_t *cc = &mac->common_channels[0]; + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, cc->mib); + ASN_STRUCT_FREE(asn_DEF_NR_BCCH_DL_SCH_Message, cc->sib1); + ASN_STRUCT_FREE(asn_DEF_NR_ServingCellConfig, cc->pre_ServingCellConfig); + ASN_STRUCT_FREE(asn_DEF_NR_ServingCellConfigCommon, cc->ServingCellConfigCommon); + NR_UEs_t *UE_info = &mac->UE_info; + for (int i = 0; i < sizeofArray(UE_info->list); ++i) + if (UE_info->list[i]) + delete_nr_ue_data(UE_info->list[i], cc, &UE_info->uid_allocator); +} + void nr_mac_send_f1_setup_req(void) { gNB_MAC_INST *mac = RC.nrmac[0]; From de35a0a59c9cdd0a3e4bca4142e1e393d0238a11 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 09:31:12 +0200 Subject: [PATCH 05/10] Fix memory leak: fix_tdd_pattern() allocates pattern1.ext --- openair2/GNB_APP/gnb_config.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a300a182ae..a303db46d7 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -437,12 +437,11 @@ static void fix_tdd_pattern(NR_ServingCellConfigCommon_t *scc) int pattern_ext = pattern1->dl_UL_TransmissionPeriodicity - 8; // Check if the pattern1 extension is configured and set the value accordingly if (pattern_ext >= 0) { - pattern1->ext1 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern__ext1)); - pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530 = - calloc_or_fail(1, sizeof(*pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530)); *pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530 = pattern_ext; pattern1->dl_UL_TransmissionPeriodicity = 5; } else { + free(pattern1->ext1->dl_UL_TransmissionPeriodicity_v1530); + free(pattern1->ext1); pattern1->ext1 = NULL; } struct NR_TDD_UL_DL_Pattern *pattern2 = scc->tdd_UL_DL_ConfigurationCommon->pattern2; From a57e4cd65552ec9a7b641aaef7ea2e7a56f58c2b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 09:37:40 +0200 Subject: [PATCH 06/10] Fix direct memory leak --- openair2/GNB_APP/gnb_config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a303db46d7..6a9f605a91 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -521,8 +521,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc, uint64_t ssbmap) } // default value for msg3 precoder is NULL (0 means enabled) - if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0) + if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0) { + free(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder); scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NULL; + } frame_type_t frame_type = get_frame_type((int)*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing); From d41e7a95dfe8962100d169fe2849d910e3ddb252 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 09:43:31 +0200 Subject: [PATCH 07/10] Fix direct memory leak --- openair2/GNB_APP/gnb_config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 6a9f605a91..b5e33c5253 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -811,11 +811,13 @@ void fix_scd(NR_ServingCellConfig_t *scd) { } if (scd->downlinkBWP_ToAddModList->list.count == 0) { + free(scd->downlinkBWP_ToAddModList->list.array); free(scd->downlinkBWP_ToAddModList); scd->downlinkBWP_ToAddModList = NULL; } if (scd->uplinkConfig->uplinkBWP_ToAddModList->list.count == 0) { + free(scd->uplinkConfig->uplinkBWP_ToAddModList->list.array); free(scd->uplinkConfig->uplinkBWP_ToAddModList); scd->uplinkConfig->uplinkBWP_ToAddModList = NULL; } From d785187f287b1c2afa10c98735065c7b9477bb91 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 12:59:02 +0200 Subject: [PATCH 08/10] Make deep copy for TDD_UL_DL_ConfigCommon instead of stealing pointer --- openair2/RRC/NR/nr_rrc_config.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 9e834309a7..32f0ccae40 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -2708,14 +2708,8 @@ NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, ServCellCom->ssb_PeriodicityServingCell = *scc->ssb_periodicityServingCell; if (scc->tdd_UL_DL_ConfigurationCommon) { - ServCellCom->tdd_UL_DL_ConfigurationCommon = CALLOC(1,sizeof(struct NR_TDD_UL_DL_ConfigCommon)); - AssertFatal(ServCellCom->tdd_UL_DL_ConfigurationCommon != NULL, "out of memory\n"); - ServCellCom->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing = scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing; - ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern1 = scc->tdd_UL_DL_ConfigurationCommon->pattern1; - if (scc->tdd_UL_DL_ConfigurationCommon->pattern2) { - ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern2 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern)); - *ServCellCom->tdd_UL_DL_ConfigurationCommon->pattern2 = *scc->tdd_UL_DL_ConfigurationCommon->pattern2; - } + int copy_result = asn_copy(&asn_DEF_NR_TDD_UL_DL_ConfigCommon, (void **)&ServCellCom->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon); + AssertFatal(copy_result == 0, "Was unable to copy tdd_UL_DL_ConfigurationCommon from scc to SIB19 structure\n"); } ServCellCom->ss_PBCH_BlockPower = scc->ss_PBCH_BlockPower; From 83dc33d3bfc671d84d0942f1cafe61a862bd0d27 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 13:04:21 +0200 Subject: [PATCH 09/10] Avoid memory leaks: ext1 directly overwritten by p2 --- openair2/GNB_APP/gnb_config.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index b5e33c5253..22d9ed6f8a 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1131,12 +1131,8 @@ static NR_ServingCellConfigCommon_t *get_scc_config(configmodule_interface_t *cf if (is_pattern2) { LOG_I(GNB_APP, "tdd->pattern2 present\n"); - // allocate memory struct NR_TDD_UL_DL_ConfigCommon *tdd = scc->tdd_UL_DL_ConfigurationCommon; tdd->pattern2 = calloc_or_fail(1, sizeof(*tdd->pattern2)); - tdd->pattern2->ext1 = calloc_or_fail(1, sizeof(struct NR_TDD_UL_DL_Pattern__ext1)); - tdd->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530 = calloc_or_fail(1, sizeof(*tdd->pattern2->ext1->dl_UL_TransmissionPeriodicity_v1530)); - // fill in scc *scc->tdd_UL_DL_ConfigurationCommon->pattern2 = p2; AssertFatal(p2.nrofUplinkSlots ^ scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots, "UL slots in pattern1 (%ld) and pattern2 (%ld) are mutually exclusive (e.g. DDDFUU DDDD, DDDD DDDFUU)\n", From f9224e1fc8998000ae483a6948ee692c608afa65 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 14 Apr 2025 17:54:42 +0200 Subject: [PATCH 10/10] File-based stats: abort writing if we can't write There might be a number of reasons, such as read-only write system, erros, etc. Still gracefully continue instead of aborting the operation. --- executables/nr-gnb.c | 8 +++++--- openair2/LAYER2/NR_MAC_gNB/main.c | 5 ++++- openair2/RRC/NR/rrc_gNB.c | 15 +++++++++------ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 74a95c2794..9f20e6f409 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -267,9 +267,11 @@ void *nrL1_stats_thread(void *param) { char output[L1STATSSTRLEN]; memset(output,0,L1STATSSTRLEN); wait_sync("L1_stats_thread"); - FILE *fd; - fd=fopen("nrL1_stats.log","w"); - AssertFatal(fd!=NULL,"Cannot open nrL1_stats.log\n"); + FILE *fd=fopen("nrL1_stats.log","w"); + if (!fd) { + LOG_W(NR_PHY, "Cannot open nrL1_stats.log: %d, %s\n", errno, strerror(errno)); + return NULL; + } reset_meas(&gNB->phy_proc_tx); reset_meas(&gNB->dlsch_encoding_stats); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 099cb725e1..0e0442d77a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -79,7 +79,10 @@ void *nrmac_stats_thread(void *arg) { char output[MACSTATSSTRLEN] = {0}; const char *end = output + MACSTATSSTRLEN; FILE *file = fopen("nrMAC_stats.log","w"); - AssertFatal(file!=NULL,"Cannot open nrMAC_stats.log, error %s\n",strerror(errno)); + if (!file) { + LOG_W(NR_MAC, "Cannot open nrMAC_stats.log: %d, %s\n", errno, strerror(errno)); + return NULL; + } while (oai_exit == 0) { char *p = output; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index f3686cfc1e..824cd701fb 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2481,13 +2481,13 @@ static const char *get_pdusession_status_text(pdu_session_status_t status) return "illegal"; } -static void write_rrc_stats(const gNB_RRC_INST *rrc) +static bool write_rrc_stats(const gNB_RRC_INST *rrc) { const char *filename = "nrRRC_stats.log"; FILE *f = fopen(filename, "w"); if (f == NULL) { - LOG_E(NR_RRC, "cannot open %s for writing\n", filename); - return; + LOG_W(NR_RRC, "cannot open %s for writing: %d, %s\n", filename, errno, strerror(errno)); + return false; } time_t now = time(NULL); @@ -2538,6 +2538,7 @@ static void write_rrc_stats(const gNB_RRC_INST *rrc) dump_du_info(rrc, f); fclose(f); + return true; } void *rrc_gnb_task(void *args_p) { @@ -2576,10 +2577,12 @@ void *rrc_gnb_task(void *args_p) { break; case TIMER_HAS_EXPIRED: - if (TIMER_HAS_EXPIRED(msg_p).timer_id == stats_timer_id) - write_rrc_stats(RC.nrrrc[0]); - else + if (TIMER_HAS_EXPIRED(msg_p).timer_id == stats_timer_id) { + if (!write_rrc_stats(RC.nrrrc[0])) + timer_remove(stats_timer_id); + } else { itti_send_msg_to_task(TASK_RRC_GNB, 0, TIMER_HAS_EXPIRED(msg_p).arg); /* see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() */ + } break; case F1AP_INITIAL_UL_RRC_MESSAGE: