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);