diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 8ce2c2a8cada08297d9af2e7b3ea6dbef2bf3880..26399fae859a6cf432f76cc50cce641838659532 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -140,7 +140,8 @@ typedef struct f1ap_served_cell_info_t { f1ap_tdd_info_t tdd; }; - char *measurement_timing_information; + uint8_t *measurement_timing_config; + int measurement_timing_config_len; } f1ap_served_cell_info_t; typedef struct f1ap_gnb_du_system_info_t { diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index c44ab890188b52b06185499f19b83f579373d57a..ed8403c4928cb4f77ec6e34f4d89b54ed5b39a34 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -67,6 +67,14 @@ int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *Erro AssertFatal(1==0,"Not implemented yet\n"); } +static uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) +{ + uint8_t *buf = calloc(os->size, sizeof(*buf)); + AssertFatal(buf != NULL, "out of memory\n"); + memcpy(buf, os->buf, os->size); + *len = os->size; + return buf; +} /* F1 Setup @@ -187,6 +195,11 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present); } + /* MeasurementConfig */ + if (servedCellInformation->measurementTimingConfiguration.size > 0) + req->cell[i].info.measurement_timing_config = + cp_octet_string(&servedCellInformation->measurementTimingConfiguration, &req->cell[i].info.measurement_timing_config_len); + struct F1AP_GNB_DU_System_Information * DUsi=served_cells_item->gNB_DU_System_Information; if (DUsi != NULL) { // System Information @@ -537,6 +550,12 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present); } + /* MeasurementConfig */ + if (servedCellInformation->measurementTimingConfiguration.size > 0) + req->cell_to_add[i].info.measurement_timing_config = + cp_octet_string(&servedCellInformation->measurementTimingConfiguration, + &req->cell_to_add[i].info.measurement_timing_config_len); + struct F1AP_GNB_DU_System_Information *DUsi = served_cells_item->gNB_DU_System_Information; // System Information req->cell_to_add[i].sys_info = calloc(1, sizeof(*req->cell_to_add[i].sys_info)); @@ -648,7 +667,12 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso } else { AssertFatal(false, "unknown NR Mode info %d\n", servedCellInformation->nR_Mode_Info.present); } - // TODO: Measurement Config + + /* MeasurementConfig */ + if (servedCellInformation->measurementTimingConfiguration.size > 0) + req->cell_to_modify[i].info.measurement_timing_config = + cp_octet_string(&servedCellInformation->measurementTimingConfiguration, + &req->cell_to_modify[i].info.measurement_timing_config_len); /*gNB DU SYSTEM INFORMATION */ struct F1AP_GNB_DU_System_Information *DUsi = served_cells_item->gNB_DU_System_Information; diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 5e7c892301424149e3912ae9533735dcf71fcc9c..23af0ea3e6c048d21b0321b438de41704d51ce5d 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -196,10 +196,9 @@ static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_ } /* - measurementTimingConfiguration */ - char *measurementTimingConfiguration = c->measurement_timing_information; OCTET_STRING_fromBuf(&scell_info.measurementTimingConfiguration, - measurementTimingConfiguration, - strlen(measurementTimingConfiguration)); + (const char *)c->measurement_timing_config, + c->measurement_timing_config_len); return scell_info; } diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index a0db5ad338c48580866ea3a2fe9cff5bc98775a6..64a40e4a833cf776665bbf815487b52f1193a04a 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -82,6 +82,7 @@ #include "NR_RateMatchPatternLTE-CRS.h" #include "NR_SearchSpace.h" #include "NR_ControlResourceSet.h" +#include "NR_MeasurementTimingConfiguration.h" #include "NR_EUTRA-MBSFN-SubframeConfig.h" #include "uper_decoder.h" #include "uper_encoder.h" @@ -1168,7 +1169,16 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id, req->cell[0].info.fdd = read_fdd_config(scc); } - req->cell[0].info.measurement_timing_information = "0"; + NR_MeasurementTimingConfiguration_t *mtc = get_new_MeasurementTimingConfiguration(scc); + uint8_t buf[1024]; + int len = encode_MeasurementTimingConfiguration(mtc, buf, sizeof(buf)); + DevAssert(len <= sizeof(buf)); + free_MeasurementTimingConfiguration(mtc); + uint8_t *mtc_buf = calloc(len, sizeof(*mtc_buf)); + AssertFatal(mtc_buf != NULL, "out of memory\n"); + memcpy(mtc_buf, buf, len); + req->cell[0].info.measurement_timing_config = mtc_buf; + req->cell[0].info.measurement_timing_config_len = len; if (get_softmodem_params()->sa) { // in NSA we don't transmit SIB1, so cannot fill DU system information diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c index 9cb6613d875b4167d5b4a281a35e94cf8c015782..acef49ef5bb2708aab086fa23056f0fec2454dc5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -39,8 +39,14 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req) AssertFatal(f1ap_msg->cell[n].info.tac != NULL, "out of memory\n"); *f1ap_msg->cell[n].info.tac = *req->cell[n].info.tac; } - if (req->cell[n].info.measurement_timing_information) - f1ap_msg->cell[n].info.measurement_timing_information = strdup(req->cell[n].info.measurement_timing_information); + if (req->cell[n].info.measurement_timing_config_len > 0) { + f1ap_msg->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t)); + AssertFatal(f1ap_msg->cell[n].info.measurement_timing_config != NULL, "out of memory\n"); + memcpy(f1ap_msg->cell[n].info.measurement_timing_config, + req->cell[n].info.measurement_timing_config, + req->cell[n].info.measurement_timing_config_len); + f1ap_msg->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len; + } if (req->cell[n].sys_info) { f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info; @@ -85,9 +91,15 @@ static void gnb_du_configuration_update_direct(const f1ap_gnb_du_configuration_u AssertFatal(f1ap_msg->cell_to_modify[n].info.tac != NULL, "out of memory\n"); *f1ap_msg->cell_to_modify[n].info.tac = *upd->cell_to_modify[n].info.tac; } - if (upd->cell_to_modify[n].info.measurement_timing_information) - f1ap_msg->cell_to_modify[n].info.measurement_timing_information = - strdup(upd->cell_to_modify[n].info.measurement_timing_information); + if (upd->cell_to_modify[n].info.measurement_timing_config_len > 0) { + f1ap_msg->cell_to_modify[n].info.measurement_timing_config = + calloc(upd->cell_to_modify[n].info.measurement_timing_config_len, sizeof(uint8_t)); + AssertFatal(f1ap_msg->cell_to_modify[n].info.measurement_timing_config != NULL, "out of memory\n"); + memcpy(f1ap_msg->cell_to_modify[n].info.measurement_timing_config, + upd->cell_to_modify[n].info.measurement_timing_config, + upd->cell_to_modify[n].info.measurement_timing_config_len); + f1ap_msg->cell_to_modify[n].info.measurement_timing_config_len = upd->cell_to_modify[n].info.measurement_timing_config_len; + } if (upd->cell_to_modify[n].sys_info) { f1ap_gnb_du_system_info_t *orig_sys_info = upd->cell_to_modify[n].sys_info; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index 8cd58e696ac2168371244f4650d36ecb6c96ff6a..19beddad7a9dcb0965c9a2924691b27ad2b40ee7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -69,8 +69,14 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req) AssertFatal(f1ap_setup->cell[n].info.tac != NULL, "out of memory\n"); *f1ap_setup->cell[n].info.tac = *req->cell[n].info.tac; } - if (req->cell[n].info.measurement_timing_information) - f1ap_setup->cell[n].info.measurement_timing_information = strdup(req->cell[n].info.measurement_timing_information); + if (req->cell[n].info.measurement_timing_config_len > 0) { + f1ap_setup->cell[n].info.measurement_timing_config = calloc(req->cell[n].info.measurement_timing_config_len, sizeof(uint8_t)); + AssertFatal(f1ap_setup->cell[n].info.measurement_timing_config != NULL, "out of memory\n"); + memcpy(f1ap_setup->cell[n].info.measurement_timing_config, + req->cell[n].info.measurement_timing_config, + req->cell[n].info.measurement_timing_config_len); + f1ap_setup->cell[n].info.measurement_timing_config_len = req->cell[n].info.measurement_timing_config_len; + } if (req->cell[n].sys_info) { f1ap_gnb_du_system_info_t *orig_sys_info = req->cell[n].sys_info; diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index be1aaeec82a631c71b2048f7c492c377b16513b3..20953a20ca9f1e0915a5463a64be2cb25d13764b 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -36,6 +36,8 @@ #include "oai_asn1.h" #include "SIMULATION/TOOLS/sim.h" // for taus(); +#include "NR_MeasurementTimingConfiguration.h" + #include "uper_decoder.h" #include "uper_encoder.h" @@ -1887,6 +1889,83 @@ int encode_MIB_NR_setup(NR_MIB_t *mib, int frame, uint8_t *buf, int buf_size) return (enc_rval.encoded + 7) / 8; } +static struct NR_SSB_MTC__periodicityAndOffset get_SSB_MTC_periodicityAndOffset(long ssb_periodicityServingCell) +{ + struct NR_SSB_MTC__periodicityAndOffset po = {0}; + switch (ssb_periodicityServingCell) { + case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms5: + po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf5; + po.choice.sf5 = 0; + break; + case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms10: + po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf10; + po.choice.sf10 = 0; + break; + case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20: + po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf20; + po.choice.sf20 = 0; + break; + case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms40: + po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf40; + po.choice.sf40 = 0; + break; + case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms80: + po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf80; + po.choice.sf80 = 0; + break; + case NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms160: + po.present = NR_SSB_MTC__periodicityAndOffset_PR_sf160; + po.choice.sf160 = 0; + break; + default: + AssertFatal(false, "illegal ssb_periodicityServingCell %ld\n", ssb_periodicityServingCell); + break; + } + return po; +} + +NR_MeasurementTimingConfiguration_t *get_new_MeasurementTimingConfiguration(const NR_ServingCellConfigCommon_t *scc) +{ + NR_MeasurementTimingConfiguration_t *mtc = calloc(1, sizeof(*mtc)); + AssertFatal(mtc != NULL, "out of memory\n"); + mtc->criticalExtensions.present = NR_MeasurementTimingConfiguration__criticalExtensions_PR_c1; + mtc->criticalExtensions.choice.c1 = calloc(1, sizeof(*mtc->criticalExtensions.choice.c1)); + AssertFatal(mtc->criticalExtensions.choice.c1 != NULL, "out of memory\n"); + mtc->criticalExtensions.choice.c1->present = NR_MeasurementTimingConfiguration__criticalExtensions__c1_PR_measTimingConf; + NR_MeasurementTimingConfiguration_IEs_t *mtc_ie = calloc(1, sizeof(*mtc_ie)); + AssertFatal(mtc_ie != NULL, "out of memory\n"); + mtc->criticalExtensions.choice.c1->choice.measTimingConf = mtc_ie; + mtc_ie->measTiming = calloc(1, sizeof(*mtc_ie->measTiming)); + AssertFatal(mtc_ie->measTiming != NULL, "out of memory\n"); + + asn1cSequenceAdd(mtc_ie->measTiming->list, NR_MeasTiming_t, mt); + AssertFatal(mt != NULL, "out of memory\n"); + mt->frequencyAndTiming = calloc(1, sizeof(*mt->frequencyAndTiming)); + AssertFatal(mt->frequencyAndTiming != NULL, "out of memory\n"); + mt->frequencyAndTiming->carrierFreq = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB; + mt->frequencyAndTiming->ssbSubcarrierSpacing = *scc->ssbSubcarrierSpacing; + + NR_SSB_MTC_t *ssb_mtc = &mt->frequencyAndTiming->ssb_MeasurementTimingConfiguration; + ssb_mtc->duration = NR_SSB_MTC__duration_sf1; + ssb_mtc->periodicityAndOffset = get_SSB_MTC_periodicityAndOffset(*scc->ssb_periodicityServingCell); + + return mtc; +} + +int encode_MeasurementTimingConfiguration(const struct NR_MeasurementTimingConfiguration *mtc, uint8_t *buf, int buf_len) +{ + DevAssert(mtc != NULL); + xer_fprint(stdout, &asn_DEF_NR_MeasurementTimingConfiguration, mtc); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_MeasurementTimingConfiguration, NULL, mtc, buf, buf_len); + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); + return (enc_rval.encoded + 7) / 8; +} + +void free_MeasurementTimingConfiguration(NR_MeasurementTimingConfiguration_t *mtc) +{ + ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc); +} + NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const f1ap_plmn_t *plmn, uint64_t cellID, int tac) { AssertFatal(cellID < (1l << 36), "cellID must fit within 36 bits, but is %lu\n", cellID); diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index b18be2ff61395a1a090d09dd7cf3bdc64365f3b3..d469638fcf932d4ce3db111e9bb2a54e33cd7dea 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -57,6 +57,10 @@ void free_MIB_NR(NR_BCCH_BCH_Message_t *mib); int encode_MIB_NR(NR_BCCH_BCH_Message_t *mib, int frame, uint8_t *buf, int buf_size); int encode_MIB_NR_setup(NR_MIB_t *mib, int frame, uint8_t *buf, int buf_size); +struct NR_MeasurementTimingConfiguration; +struct NR_MeasurementTimingConfiguration *get_new_MeasurementTimingConfiguration(const NR_ServingCellConfigCommon_t *scc); +int encode_MeasurementTimingConfiguration(const struct NR_MeasurementTimingConfiguration *mtc, uint8_t *buf, int buf_len); +void free_MeasurementTimingConfiguration(struct NR_MeasurementTimingConfiguration *mtc); #define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 NR_BCCH_DL_SCH_Message_t *get_SIB1_NR(const NR_ServingCellConfigCommon_t *scc, const f1ap_plmn_t *plmn, uint64_t cellID, int tac); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index fda89f6f8a1c7b84ad138338645b7166670e9009..728640c149b048673f4abfdb55a2e24a145cc190 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -62,6 +62,7 @@ #include "NR_CellGroupConfig.h" #include "NR_ServingCellConfigCommon.h" #include "NR_EstablishmentCause.h" +#include "NR_MeasurementTimingConfiguration.h" //------------------- @@ -382,6 +383,7 @@ typedef struct nr_rrc_du_container_t { f1ap_setup_req_t *setup_req; NR_MIB_t *mib; NR_SIB1_t *sib1; + NR_MeasurementTimingConfiguration_t *mtc; } nr_rrc_du_container_t; typedef struct nr_rrc_cuup_container_t { diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index c67263a67e2115a58b0db45768ef84ed96bed156..a0d92a445a2df6c51329fbec1e368f1a5a088d7a 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -80,6 +80,30 @@ static bool extract_sys_info(const f1ap_gnb_du_system_info_t *sys_info, NR_MIB_t return true; } +static NR_MeasurementTimingConfiguration_t *extract_mtc(uint8_t *buf, int buf_len) +{ + NR_MeasurementTimingConfiguration_t *mtc = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_MeasurementTimingConfiguration, (void **)&mtc, buf, buf_len); + if (dec_rval.code != RC_OK) { + ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc); + return NULL; + } + /* verify that it has the format we need */ + if (mtc->criticalExtensions.present != NR_MeasurementTimingConfiguration__criticalExtensions_PR_c1 + || mtc->criticalExtensions.choice.c1 == NULL + || mtc->criticalExtensions.choice.c1->present != NR_MeasurementTimingConfiguration__criticalExtensions__c1_PR_measTimingConf + || mtc->criticalExtensions.choice.c1->choice.measTimingConf == NULL + || mtc->criticalExtensions.choice.c1->choice.measTimingConf->measTiming == NULL + || mtc->criticalExtensions.choice.c1->choice.measTimingConf->measTiming->list.count == 0) { + LOG_E(RRC, "error: measurementTimingConfiguration does not have expected format (at least one measTiming entry\n"); + if (LOG_DEBUGFLAG(DEBUG_ASN1)) + xer_fprint(stdout, &asn_DEF_NR_MeasurementTimingConfiguration, mtc); + ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc); + return NULL; + } + return mtc; +} + void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) { AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); @@ -142,6 +166,15 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) } } + NR_MeasurementTimingConfiguration_t *mtc = + extract_mtc(cell_info->measurement_timing_config, cell_info->measurement_timing_config_len); + if (!mtc) { + LOG_W(RRC, "cannot decode MeasurementTimingConfiguration of DU ID %ld, rejecting\n", req->gNB_DU_id); + f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; + rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + return; + } + const f1ap_gnb_du_system_info_t *sys_info = req->cell[0].sys_info; NR_MIB_t *mib = NULL; NR_SIB1_t *sib1 = NULL; @@ -151,6 +184,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) LOG_W(RRC, "rejecting DU ID %ld\n", req->gNB_DU_id); f1ap_setup_failure_t fail = {.cause = F1AP_CauseProtocol_semantic_error}; rrc->mac_rrc.f1_setup_failure(assoc_id, &fail); + ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, mtc); return; } } @@ -171,6 +205,7 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id) // MIB can be null and configured later via DU Configuration Update du->mib = mib; du->sib1 = sib1; + du->mtc = mtc; RB_INSERT(rrc_du_tree, &rrc->dus, du); rrc->num_dus++; @@ -234,6 +269,16 @@ static void update_cell_info(nr_rrc_du_container_t *du, const f1ap_served_cell_i ci->tdd = new_ci->tdd; else ci->fdd = new_ci->fdd; + + NR_MeasurementTimingConfiguration_t *new_mtc = + extract_mtc(new_ci->measurement_timing_config, new_ci->measurement_timing_config_len); + if (new_mtc != NULL) { + ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, du->mtc); + du->mtc = new_mtc; + } else { + LOG_E(RRC, "error decoding MeasurementTimingConfiguration during cell update, ignoring new config\n"); + ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, new_mtc); + } } void rrc_gNB_process_f1_du_configuration_update(f1ap_gnb_du_configuration_update_t *conf_up, sctp_assoc_t assoc_id) @@ -321,6 +366,7 @@ void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t LOG_I(RRC, "releasing DU ID %ld (%s) on assoc_id %d\n", req->gNB_DU_id, req->gNB_DU_name, assoc_id); ASN_STRUCT_FREE(asn_DEF_NR_MIB, du->mib); ASN_STRUCT_FREE(asn_DEF_NR_SIB1, du->sib1); + ASN_STRUCT_FREE(asn_DEF_NR_MeasurementTimingConfiguration, du->mtc); /* TODO: free setup request */ nr_rrc_du_container_t *removed = RB_REMOVE(rrc_du_tree, &rrc->dus, du); DevAssert(removed != NULL);