From 4602feea3b3422fd62e80584c84ac0df6e4b0454 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=BAben=20Soares=20da=20Silva?= <rsilva@allbesmart.pt>
Date: Tue, 23 Apr 2024 23:41:01 +0100
Subject: [PATCH] Fix packing/unpacking procedures for CONFIG.request

Add utility functions related to CONFIG.request
---
 nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h  |   3 +
 nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c  | 326 +++++++++++++++++
 .../nfapi/public_inc/nfapi_interface.h        |   1 +
 nfapi/open-nFAPI/nfapi/src/nfapi_p5.c         | 341 ++++++++++--------
 4 files changed, 521 insertions(+), 150 deletions(-)

diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
index d67e13eb459..15e17e7c823 100644
--- a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
+++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
@@ -65,11 +65,14 @@ void copy_vendor_extension_value(nfapi_vendor_extension_tlv_t *dst, const nfapi_
 
 bool eq_param_request(const nfapi_nr_param_request_scf_t *unpacked_req, const nfapi_nr_param_request_scf_t *req);
 bool eq_param_response(const nfapi_nr_param_response_scf_t *unpacked_req, const nfapi_nr_param_response_scf_t *req);
+bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const nfapi_nr_config_request_scf_t *req);
 
 void free_param_request(nfapi_nr_param_request_scf_t *msg);
 void free_param_response(nfapi_nr_param_response_scf_t *msg);
+void free_config_request(nfapi_nr_config_request_scf_t *msg);
 
 void copy_param_request(const nfapi_nr_param_request_scf_t *src, nfapi_nr_param_request_scf_t *dst);
 void copy_param_response(const nfapi_nr_param_response_scf_t *src, nfapi_nr_param_response_scf_t *dst);
+void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_config_request_scf_t *dst);
 
 #endif // OPENAIRINTERFACE_NR_FAPI_P5_UTILS_H
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
index fd7074ad3c2..8e4db4c695d 100644
--- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
@@ -180,6 +180,135 @@ bool eq_param_response(const nfapi_nr_param_response_scf_t *unpacked_req, const
 
   return true;
 }
+
+bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const nfapi_nr_config_request_scf_t *req)
+{
+  EQ(unpacked_req->header.message_id, req->header.message_id);
+  EQ(unpacked_req->header.message_length, req->header.message_length);
+  EQ(unpacked_req->num_tlv, req->num_tlv);
+
+  EQ_TLV(unpacked_req->carrier_config.dl_bandwidth, req->carrier_config.dl_bandwidth);
+
+  EQ_TLV(unpacked_req->carrier_config.dl_frequency, req->carrier_config.dl_frequency);
+
+  for (int i = 0; i < 5; ++i) {
+    EQ_TLV(unpacked_req->carrier_config.dl_k0[i], req->carrier_config.dl_k0[i]);
+
+    EQ_TLV(unpacked_req->carrier_config.dl_grid_size[i], req->carrier_config.dl_grid_size[i]);
+  }
+
+  EQ_TLV(unpacked_req->carrier_config.num_tx_ant, req->carrier_config.num_tx_ant);
+
+  EQ_TLV(unpacked_req->carrier_config.uplink_bandwidth, req->carrier_config.uplink_bandwidth);
+
+  EQ_TLV(unpacked_req->carrier_config.uplink_frequency, req->carrier_config.uplink_frequency);
+
+  for (int i = 0; i < 5; ++i) {
+    EQ_TLV(unpacked_req->carrier_config.ul_k0[i], req->carrier_config.ul_k0[i]);
+
+    EQ_TLV(unpacked_req->carrier_config.ul_grid_size[i], req->carrier_config.ul_grid_size[i]);
+  }
+
+  EQ_TLV(unpacked_req->carrier_config.num_rx_ant, req->carrier_config.num_rx_ant);
+
+  EQ_TLV(unpacked_req->carrier_config.frequency_shift_7p5khz, req->carrier_config.frequency_shift_7p5khz);
+
+  EQ_TLV(unpacked_req->cell_config.phy_cell_id, req->cell_config.phy_cell_id);
+
+  EQ_TLV(unpacked_req->cell_config.frame_duplex_type, req->cell_config.frame_duplex_type);
+
+  EQ_TLV(unpacked_req->ssb_config.ss_pbch_power, req->ssb_config.ss_pbch_power);
+
+  EQ_TLV(unpacked_req->ssb_config.bch_payload, req->ssb_config.bch_payload);
+
+  EQ_TLV(unpacked_req->ssb_config.scs_common, req->ssb_config.scs_common);
+
+  EQ_TLV(unpacked_req->prach_config.prach_sequence_length, req->prach_config.prach_sequence_length);
+
+  EQ_TLV(unpacked_req->prach_config.prach_sub_c_spacing, req->prach_config.prach_sub_c_spacing);
+
+  EQ_TLV(unpacked_req->prach_config.restricted_set_config, req->prach_config.restricted_set_config);
+
+  EQ_TLV(unpacked_req->prach_config.num_prach_fd_occasions, req->prach_config.num_prach_fd_occasions);
+
+  EQ_TLV(unpacked_req->prach_config.prach_ConfigurationIndex, req->prach_config.prach_ConfigurationIndex);
+
+  for (int i = 0; i < unpacked_req->prach_config.num_prach_fd_occasions.value; i++) {
+    nfapi_nr_num_prach_fd_occasions_t unpacked_prach_fd_occasion = unpacked_req->prach_config.num_prach_fd_occasions_list[i];
+    nfapi_nr_num_prach_fd_occasions_t req_prach_fd_occasion = req->prach_config.num_prach_fd_occasions_list[i];
+
+    EQ_TLV(unpacked_prach_fd_occasion.prach_root_sequence_index, req_prach_fd_occasion.prach_root_sequence_index);
+
+    EQ_TLV(unpacked_prach_fd_occasion.num_root_sequences, req_prach_fd_occasion.num_root_sequences);
+
+    EQ_TLV(unpacked_prach_fd_occasion.k1, req_prach_fd_occasion.k1);
+
+    EQ_TLV(unpacked_prach_fd_occasion.prach_zero_corr_conf, req_prach_fd_occasion.prach_zero_corr_conf);
+
+    EQ_TLV(unpacked_prach_fd_occasion.num_unused_root_sequences, req_prach_fd_occasion.num_unused_root_sequences);
+    for (int k = 0; k < unpacked_prach_fd_occasion.num_unused_root_sequences.value; k++) {
+      EQ_TLV(unpacked_prach_fd_occasion.unused_root_sequences_list[k], req_prach_fd_occasion.unused_root_sequences_list[k]);
+    }
+  }
+
+  EQ_TLV(unpacked_req->prach_config.ssb_per_rach, req->prach_config.ssb_per_rach);
+
+  EQ_TLV(unpacked_req->prach_config.prach_multiple_carriers_in_a_band, req->prach_config.prach_multiple_carriers_in_a_band);
+
+  EQ_TLV(unpacked_req->ssb_table.ssb_offset_point_a, req->ssb_table.ssb_offset_point_a);
+
+  EQ_TLV(unpacked_req->ssb_table.ssb_period, req->ssb_table.ssb_period);
+
+  EQ_TLV(unpacked_req->ssb_table.ssb_subcarrier_offset, req->ssb_table.ssb_subcarrier_offset);
+
+  EQ_TLV(unpacked_req->ssb_table.MIB, req->ssb_table.MIB);
+
+  EQ_TLV(unpacked_req->ssb_table.ssb_mask_list[0].ssb_mask, req->ssb_table.ssb_mask_list[0].ssb_mask);
+
+  EQ_TLV(unpacked_req->ssb_table.ssb_mask_list[1].ssb_mask, req->ssb_table.ssb_mask_list[1].ssb_mask);
+
+  for (int i = 0; i < 64; i++) {
+    EQ_TLV(unpacked_req->ssb_table.ssb_beam_id_list[i].beam_id, req->ssb_table.ssb_beam_id_list[i].beam_id);
+  }
+
+  EQ_TLV(unpacked_req->tdd_table.tdd_period, req->tdd_table.tdd_period);
+
+  const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+  // Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
+  uint8_t cyclicprefix = 1;
+  bool normal_CP = cyclicprefix ? false : true;
+  // 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
+  uint8_t number_of_symbols_per_slot = normal_CP ? 14 : 12;
+
+  for (int i = 0; i < slotsperframe[unpacked_req->ssb_config.scs_common.value]; i++) {
+    for (int k = 0; k < number_of_symbols_per_slot; k++) {
+      EQ_TLV(unpacked_req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
+             req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
+    }
+  }
+
+  EQ_TLV(unpacked_req->measurement_config.rssi_measurement, req->measurement_config.rssi_measurement);
+
+  EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv4.tl.tag, req->nfapi_config.p7_vnf_address_ipv4.tl.tag);
+  for (int i = 0; i < NFAPI_IPV4_ADDRESS_LENGTH; ++i) {
+    EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv4.address[i], req->nfapi_config.p7_vnf_address_ipv4.address[i]);
+  }
+
+  EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv6.tl.tag, req->nfapi_config.p7_vnf_address_ipv6.tl.tag);
+  for (int i = 0; i < NFAPI_IPV6_ADDRESS_LENGTH; ++i) {
+    EQ(unpacked_req->nfapi_config.p7_vnf_address_ipv6.address[i], req->nfapi_config.p7_vnf_address_ipv6.address[i]);
+  }
+
+  EQ_TLV(unpacked_req->nfapi_config.p7_vnf_port, req->nfapi_config.p7_vnf_port);
+
+  EQ_TLV(unpacked_req->nfapi_config.timing_window, req->nfapi_config.timing_window);
+
+  EQ_TLV(unpacked_req->nfapi_config.timing_info_mode, req->nfapi_config.timing_info_mode);
+
+  EQ_TLV(unpacked_req->nfapi_config.timing_info_period, req->nfapi_config.timing_info_period);
+  return true;
+}
+
 void free_param_request(nfapi_nr_param_request_scf_t *msg)
 {
   if (msg->vendor_extension) {
@@ -198,6 +327,34 @@ void free_param_response(nfapi_nr_param_response_scf_t *msg)
   }
 }
 
+void free_config_request(nfapi_nr_config_request_scf_t *msg)
+{
+  if (msg->vendor_extension) {
+    free(msg->vendor_extension);
+  }
+
+  if (msg->prach_config.num_prach_fd_occasions_list) {
+    for (int i = 0; i < msg->prach_config.num_prach_fd_occasions.value; i++) {
+      nfapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &(msg->prach_config.num_prach_fd_occasions_list[i]);
+      if (prach_fd_occasion->unused_root_sequences_list) {
+        free(prach_fd_occasion->unused_root_sequences_list);
+      }
+    }
+    free(msg->prach_config.num_prach_fd_occasions_list);
+  }
+  const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+  if (msg->tdd_table.max_tdd_periodicity_list) {
+    for (int i = 0; i < slotsperframe[msg->ssb_config.scs_common.value]; i++) {
+      free(msg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list);
+    }
+    free(msg->tdd_table.max_tdd_periodicity_list);
+  }
+
+  if (msg->pmi_list.pmi_pdu) {
+    free(msg->pmi_list.pmi_pdu);
+  }
+}
+
 void copy_param_request(const nfapi_nr_param_request_scf_t *src, nfapi_nr_param_request_scf_t *dst)
 {
   dst->header.message_id = src->header.message_id;
@@ -379,3 +536,172 @@ void copy_param_response(const nfapi_nr_param_response_scf_t *src, nfapi_nr_para
 
   COPY_TLV(dst->nfapi_config.tx_data_timing_offset, src->nfapi_config.tx_data_timing_offset);
 }
+
+void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_config_request_scf_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+  if (src->vendor_extension) {
+    dst->vendor_extension = calloc(1, sizeof(nfapi_vendor_extension_tlv_t));
+    dst->vendor_extension->tag = src->vendor_extension->tag;
+    dst->vendor_extension->length = src->vendor_extension->length;
+    copy_vendor_extension_value(&dst->vendor_extension, &src->vendor_extension);
+  }
+
+  dst->num_tlv = src->num_tlv;
+
+  COPY_TLV(dst->carrier_config.dl_bandwidth, src->carrier_config.dl_bandwidth);
+
+  COPY_TLV(dst->carrier_config.dl_frequency, src->carrier_config.dl_frequency);
+
+  for (int i = 0; i < 5; ++i) {
+    COPY_TLV(dst->carrier_config.dl_k0[i], src->carrier_config.dl_k0[i]);
+
+    COPY_TLV(dst->carrier_config.dl_grid_size[i], src->carrier_config.dl_grid_size[i]);
+  }
+
+  COPY_TLV(dst->carrier_config.num_tx_ant, src->carrier_config.num_tx_ant);
+
+  COPY_TLV(dst->carrier_config.uplink_bandwidth, src->carrier_config.uplink_bandwidth);
+
+  COPY_TLV(dst->carrier_config.uplink_frequency, src->carrier_config.uplink_frequency);
+
+  COPY_TLV(dst->carrier_config.uplink_frequency, src->carrier_config.uplink_frequency);
+
+  for (int i = 0; i < 5; ++i) {
+    COPY_TLV(dst->carrier_config.ul_k0[i], src->carrier_config.ul_k0[i]);
+
+    COPY_TLV(dst->carrier_config.ul_grid_size[i], src->carrier_config.ul_grid_size[i]);
+  }
+
+  COPY_TLV(dst->carrier_config.num_rx_ant, src->carrier_config.num_rx_ant);
+
+  COPY_TLV(dst->carrier_config.frequency_shift_7p5khz, src->carrier_config.frequency_shift_7p5khz);
+
+  COPY_TLV(dst->cell_config.phy_cell_id, src->cell_config.phy_cell_id);
+
+  COPY_TLV(dst->cell_config.frame_duplex_type, src->cell_config.frame_duplex_type);
+
+  COPY_TLV(dst->ssb_config.ss_pbch_power, src->ssb_config.ss_pbch_power);
+
+  COPY_TLV(dst->ssb_config.bch_payload, src->ssb_config.bch_payload);
+
+  COPY_TLV(dst->ssb_config.scs_common, src->ssb_config.scs_common);
+
+  COPY_TLV(dst->prach_config.prach_sequence_length, src->prach_config.prach_sequence_length);
+
+  COPY_TLV(dst->prach_config.prach_sub_c_spacing, src->prach_config.prach_sub_c_spacing);
+
+  COPY_TLV(dst->prach_config.restricted_set_config, src->prach_config.restricted_set_config);
+
+  COPY_TLV(dst->prach_config.num_prach_fd_occasions, src->prach_config.num_prach_fd_occasions);
+
+  COPY_TLV(dst->prach_config.prach_ConfigurationIndex, src->prach_config.prach_ConfigurationIndex);
+
+  COPY_TLV(dst->prach_config.prach_ConfigurationIndex, src->prach_config.prach_ConfigurationIndex);
+
+  dst->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *)malloc(
+      dst->prach_config.num_prach_fd_occasions.value * sizeof(nfapi_nr_num_prach_fd_occasions_t));
+  for (int i = 0; i < dst->prach_config.num_prach_fd_occasions.value; i++) {
+    nfapi_nr_num_prach_fd_occasions_t *src_prach_fd_occasion = &(src->prach_config.num_prach_fd_occasions_list[i]);
+    nfapi_nr_num_prach_fd_occasions_t *dst_prach_fd_occasion = &(dst->prach_config.num_prach_fd_occasions_list[i]);
+
+    COPY_TLV(dst_prach_fd_occasion->prach_root_sequence_index, src_prach_fd_occasion->prach_root_sequence_index);
+
+    COPY_TLV(dst_prach_fd_occasion->num_root_sequences, src_prach_fd_occasion->num_root_sequences);
+
+    COPY_TLV(dst_prach_fd_occasion->k1, src_prach_fd_occasion->k1);
+
+    COPY_TLV(dst_prach_fd_occasion->prach_zero_corr_conf, src_prach_fd_occasion->prach_zero_corr_conf);
+
+    COPY_TLV(dst_prach_fd_occasion->num_unused_root_sequences, src_prach_fd_occasion->num_unused_root_sequences);
+
+    dst_prach_fd_occasion->unused_root_sequences_list =
+        (nfapi_uint8_tlv_t *)malloc(dst_prach_fd_occasion->num_unused_root_sequences.value * sizeof(nfapi_uint8_tlv_t));
+    for (int k = 0; k < dst_prach_fd_occasion->num_unused_root_sequences.value; k++) {
+      COPY_TLV(dst_prach_fd_occasion->unused_root_sequences_list[k], src_prach_fd_occasion->unused_root_sequences_list[k]);
+    }
+  }
+
+  COPY_TLV(dst->prach_config.ssb_per_rach, src->prach_config.ssb_per_rach);
+
+  COPY_TLV(dst->prach_config.prach_multiple_carriers_in_a_band, src->prach_config.prach_multiple_carriers_in_a_band);
+
+  COPY_TLV(dst->ssb_table.ssb_offset_point_a, src->ssb_table.ssb_offset_point_a);
+
+  COPY_TLV(dst->ssb_table.ssb_period, src->ssb_table.ssb_period);
+
+  COPY_TLV(dst->ssb_table.ssb_subcarrier_offset, src->ssb_table.ssb_subcarrier_offset);
+
+  COPY_TLV(dst->ssb_table.MIB, src->ssb_table.MIB);
+
+  COPY_TLV(dst->ssb_table.ssb_mask_list[0].ssb_mask, src->ssb_table.ssb_mask_list[0].ssb_mask);
+
+  COPY_TLV(dst->ssb_table.ssb_mask_list[1].ssb_mask, src->ssb_table.ssb_mask_list[1].ssb_mask);
+
+  for (int i = 0; i < 64; i++) {
+    COPY_TLV(dst->ssb_table.ssb_beam_id_list[i].beam_id, src->ssb_table.ssb_beam_id_list[i].beam_id);
+  }
+
+  COPY_TLV(dst->tdd_table.tdd_period, src->tdd_table.tdd_period);
+
+  const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+  // Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
+  uint8_t cyclicprefix = 1;
+  bool normal_CP = cyclicprefix ? false : true;
+  // 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
+  uint8_t number_of_symbols_per_slot = normal_CP ? 14 : 12;
+  dst->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(slotsperframe[dst->ssb_config.scs_common.value]
+                                                                                     * sizeof(nfapi_nr_max_tdd_periodicity_t));
+
+  for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) {
+    dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
+        (nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot * sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
+  }
+  for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
+    for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
+      COPY_TLV(dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
+               src->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
+    }
+  }
+
+  COPY_TLV(dst->measurement_config.rssi_measurement, src->measurement_config.rssi_measurement);
+
+  COPY_TL(dst->nfapi_config.p7_vnf_address_ipv4.tl, src->nfapi_config.p7_vnf_address_ipv4.tl);
+  memcpy(dst->nfapi_config.p7_vnf_address_ipv4.address,
+         src->nfapi_config.p7_vnf_address_ipv4.address,
+         sizeof(dst->nfapi_config.p7_vnf_address_ipv4.address));
+
+  COPY_TL(dst->nfapi_config.p7_vnf_address_ipv6.tl, src->nfapi_config.p7_vnf_address_ipv6.tl);
+  memcpy(dst->nfapi_config.p7_vnf_address_ipv6.address,
+         src->nfapi_config.p7_vnf_address_ipv6.address,
+         sizeof(dst->nfapi_config.p7_vnf_address_ipv6.address));
+
+  COPY_TLV(dst->nfapi_config.p7_vnf_port, src->nfapi_config.p7_vnf_port);
+
+  COPY_TL(dst->nfapi_config.p7_pnf_address_ipv4.tl, src->nfapi_config.p7_pnf_address_ipv4.tl);
+  memcpy(dst->nfapi_config.p7_pnf_address_ipv4.address,
+         src->nfapi_config.p7_pnf_address_ipv4.address,
+         sizeof(dst->nfapi_config.p7_pnf_address_ipv4.address));
+
+  COPY_TL(dst->nfapi_config.p7_pnf_address_ipv6.tl, src->nfapi_config.p7_pnf_address_ipv6.tl);
+  memcpy(dst->nfapi_config.p7_pnf_address_ipv6.address,
+         src->nfapi_config.p7_pnf_address_ipv6.address,
+         sizeof(dst->nfapi_config.p7_pnf_address_ipv6.address));
+
+  COPY_TLV(dst->nfapi_config.p7_pnf_port, src->nfapi_config.p7_pnf_port);
+
+  COPY_TLV(dst->nfapi_config.timing_window, src->nfapi_config.timing_window);
+
+  COPY_TLV(dst->nfapi_config.timing_info_mode, src->nfapi_config.timing_info_mode);
+
+  COPY_TLV(dst->nfapi_config.timing_info_period, src->nfapi_config.timing_info_period);
+
+  COPY_TLV(dst->nfapi_config.dl_tti_timing_offset, src->nfapi_config.dl_tti_timing_offset);
+
+  COPY_TLV(dst->nfapi_config.ul_tti_timing_offset, src->nfapi_config.ul_tti_timing_offset);
+
+  COPY_TLV(dst->nfapi_config.ul_dci_timing_offset, src->nfapi_config.ul_dci_timing_offset);
+
+  COPY_TLV(dst->nfapi_config.tx_data_timing_offset, src->nfapi_config.tx_data_timing_offset);
+}
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
index 3ec1cb7a045..7bf43056c04 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
@@ -20,6 +20,7 @@
 
 #include "stddef.h"
 #include <stdint.h>
+#include <stdbool.h>
 
 // Constants - update based on implementation
 #define NFAPI_MAX_PHY_RF_INSTANCES 2
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
index 1a54263731d..bdc8ea109e4 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
@@ -1231,16 +1231,15 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
                         end,
                         &pack_uint16_tlv_value);
   numTLVs++;
-
-  if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
-    // TLV not supported by Aerial L1
-    pack_nr_tlv(NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG,
-                &(pNfapiMsg->carrier_config.frequency_shift_7p5khz),
-                ppWritePackedMsg,
-                end,
-                &pack_uint8_tlv_value);
-    numTLVs++;
-  }
+#ifndef ENABLE_AERIAL
+  // TLV not supported by Aerial L1
+  retval &= pack_nr_tlv(NFAPI_NR_CONFIG_FREQUENCY_SHIFT_7P5KHZ_TAG,
+                        &(pNfapiMsg->carrier_config.frequency_shift_7p5khz),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint8_tlv_value);
+  numTLVs++;
+#endif
   // END Carrier Configuration
 
   // START Cell Configuration
@@ -1266,15 +1265,16 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
                         end,
                         &pack_uint32_tlv_value);
   numTLVs++;
-  if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
-    // TLV not supported by Aerial L1
-    retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG,
-                          &(pNfapiMsg->ssb_config.bch_payload),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_uint8_tlv_value);
-    numTLVs++;
-  }
+
+#ifndef ENABLE_AERIAL
+  // TLV not supported by Aerial L1
+  retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG,
+                        &(pNfapiMsg->ssb_config.bch_payload),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint8_tlv_value);
+  numTLVs++;
+#endif
 
   retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SCS_COMMON_TAG,
                         &(pNfapiMsg->ssb_config.scs_common),
@@ -1355,12 +1355,11 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
     numTLVs++;
     for (int k = 0; k < prach_fd_occasion.num_unused_root_sequences.value; k++) {
       prach_fd_occasion.unused_root_sequences_list[k].tl.tag = NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG;
-      prach_fd_occasion.unused_root_sequences_list[k].value = 0;
-      pack_nr_tlv(NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG,
-                  &(prach_fd_occasion.unused_root_sequences_list[k]),
-                  ppWritePackedMsg,
-                  end,
-                  &pack_uint16_tlv_value);
+      retval &= pack_nr_tlv(NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG,
+                            &(prach_fd_occasion.unused_root_sequences_list[k]),
+                            ppWritePackedMsg,
+                            end,
+                            &pack_uint16_tlv_value);
       numTLVs++;
     }
   }
@@ -1372,24 +1371,23 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
                         &pack_uint8_tlv_value);
   numTLVs++;
   pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.tl.tag = NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG;
-  pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band.value = 0;
-  pack_nr_tlv(NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG,
-              &(pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band),
-              ppWritePackedMsg,
-              end,
-              &pack_uint8_tlv_value);
+  retval &= pack_nr_tlv(NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG,
+                        &(pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint8_tlv_value);
   numTLVs++;
   // END PRACH Configuration
   // START SSB Table
-  if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
-    // TLV not supported by Aerial L1
-    retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,
-                          &(pNfapiMsg->ssb_table.ssb_offset_point_a),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_uint16_tlv_value);
-    numTLVs++;
-  }
+#ifndef ENABLE_AERIAL
+  // TLV not supported by Aerial L1
+  retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG,
+                        &(pNfapiMsg->ssb_table.ssb_offset_point_a),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint16_tlv_value);
+  numTLVs++;
+#endif
   retval &=
       pack_nr_tlv(NFAPI_NR_CONFIG_SSB_PERIOD_TAG, &(pNfapiMsg->ssb_table.ssb_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
   numTLVs++;
@@ -1402,7 +1400,7 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
   numTLVs++;
   /* was unused */
   pNfapiMsg->ssb_table.MIB.tl.tag = NFAPI_NR_CONFIG_MIB_TAG;
-  pack_nr_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value);
+  retval &= pack_nr_tlv(NFAPI_NR_CONFIG_MIB_TAG, &(pNfapiMsg->ssb_table.MIB), ppWritePackedMsg, end, &pack_uint32_tlv_value);
   numTLVs++;
   // SCF222.10.02 Table 3-25 : If included there must be two instances of this TLV
   retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SSB_MASK_TAG,
@@ -1418,47 +1416,51 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
                         end,
                         &pack_uint32_tlv_value);
   numTLVs++;
-  if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
-    // TLV not supported by Aerial L1
-    for (int i = 0; i < 64; i++) {
-      // SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV
-      retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG,
-                            &(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id),
-                            ppWritePackedMsg,
-                            end,
-                            &pack_uint8_tlv_value);
-      numTLVs++;
-    }
-
-    // END SSB Table
-    // START TDD Table
-    retval &= pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG,
-                          &(pNfapiMsg->tdd_table.tdd_period),
+#ifndef ENABLE_AERIAL
+  // TLV not supported by Aerial L1
+  for (int i = 0; i < 64; i++) {
+    // SCF222.10.02 Table 3-25 : If included there must be 64 instances of this TLV
+    retval &= pack_nr_tlv(NFAPI_NR_CONFIG_BEAM_ID_TAG,
+                          &(pNfapiMsg->ssb_table.ssb_beam_id_list[i].beam_id),
                           ppWritePackedMsg,
                           end,
                           &pack_uint8_tlv_value);
     numTLVs++;
-    // END TDD Table
-    for (int i = 0; i < 40; i++) {
-      for (int k = 0; k < 14; k++) {
-        pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
-                    &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config),
-                    ppWritePackedMsg,
-                    end,
-                    &pack_uint8_tlv_value);
-        numTLVs++;
-      }
+  }
+
+  // END SSB Table
+  // START TDD Table
+  retval &=
+      pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
+  numTLVs++;
+  const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+  // Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
+  uint8_t cyclicprefix = 1;
+  bool normal_CP = cyclicprefix ? false : true;
+  // 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
+  uint8_t number_of_symbols_per_slot = normal_CP ? 14 : 12;
+  for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
+    for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
+      retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
+                            &pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
+                            ppWritePackedMsg,
+                            end,
+                            &pack_uint8_tlv_value);
+      numTLVs++;
     }
   }
+
+  // END TDD Table
+#endif
   // START Measurement Config
   // SCF222.10.02 Table 3-27 : Contains only one TLV and is currently unused
   pNfapiMsg->measurement_config.rssi_measurement.tl.tag = NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG;
   pNfapiMsg->measurement_config.rssi_measurement.value = 1;
-  pack_nr_tlv(NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG,
-              &(pNfapiMsg->measurement_config.rssi_measurement),
-              ppWritePackedMsg,
-              end,
-              &pack_uint8_tlv_value);
+  retval &= pack_nr_tlv(NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG,
+                        &(pNfapiMsg->measurement_config.rssi_measurement),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint8_tlv_value);
   numTLVs++;
   // END Measurement Config
 
@@ -1469,57 +1471,57 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
   // START Precoding Matrix (PM) PDU
   // Struct in nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h nfapi_nr_pm_pdu_t, currently unused, tag to use for AERIAL
   // is 0xA011 END Precoding Matrix (PM) PDU
-  if (NFAPI_MODE != NFAPI_MODE_AERIAL) {
-    // START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
-    retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,
-                          &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_ipv4_address_value);
-    numTLVs++;
+#ifndef ENABLE_AERIAL
+  // START nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
+  retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG,
+                        &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_ipv4_address_value);
+  numTLVs++;
 
-    retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,
-                          &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_ipv6_address_value);
-    numTLVs++;
+  retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG,
+                        &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_ipv6_address_value);
+  numTLVs++;
 
-    retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,
-                          &(pNfapiMsg->nfapi_config.p7_vnf_port),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_uint16_tlv_value);
-    numTLVs++;
+  retval &= pack_nr_tlv(NFAPI_NR_NFAPI_P7_VNF_PORT_TAG,
+                        &(pNfapiMsg->nfapi_config.p7_vnf_port),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint16_tlv_value);
+  numTLVs++;
 
-    retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
-                          &(pNfapiMsg->nfapi_config.timing_window),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_uint8_tlv_value);
-    numTLVs++;
+  retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_WINDOW_TAG,
+                        &(pNfapiMsg->nfapi_config.timing_window),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint8_tlv_value);
+  numTLVs++;
 
-    retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,
-                          &(pNfapiMsg->nfapi_config.timing_info_mode),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_uint8_tlv_value);
-    numTLVs++;
+  retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG,
+                        &(pNfapiMsg->nfapi_config.timing_info_mode),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint8_tlv_value);
+  numTLVs++;
 
-    retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,
-                          &(pNfapiMsg->nfapi_config.timing_info_period),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_uint8_tlv_value);
-    numTLVs++;
-    // END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
+  retval &= pack_nr_tlv(NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG,
+                        &(pNfapiMsg->nfapi_config.timing_info_period),
+                        ppWritePackedMsg,
+                        end,
+                        &pack_uint8_tlv_value);
+  numTLVs++;
+  // END nFAPI TLVs included in CONFIG.request for IDLE and CONFIGURED states
 
-    if (pNfapiMsg->vendor_extension != 0 && config != 0) {
-      retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
-      NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag);
-      numTLVs++;
-    }
+  if (pNfapiMsg->vendor_extension != 0 && config != 0) {
+    retval &= pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config);
+    NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing CONFIG.request vendor_extension_tlv %d\n", pNfapiMsg->vendor_extension->tag);
+    numTLVs++;
   }
+#endif
   pNfapiMsg->num_tlv = numTLVs;
   retval &= push8(pNfapiMsg->num_tlv, &pNumTLVFields, end);
   return retval;
@@ -2494,16 +2496,6 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
   int tdd_periodicity_idx = 0;
   int symbol_per_slot_idx = 0;
   nfapi_nr_config_request_scf_t *pNfapiMsg = (nfapi_nr_config_request_scf_t *)msg;
-  // Memory allocations
-  pNfapiMsg->tdd_table.max_tdd_periodicity_list =
-      (nfapi_nr_max_tdd_periodicity_t *)malloc(40 * sizeof(nfapi_nr_max_tdd_periodicity_t));
-
-  for (int i = 0; i < 40; i++) {
-    pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
-        (nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(14 * sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
-  }
-  pNfapiMsg->prach_config.num_prach_fd_occasions_list =
-      (nfapi_nr_num_prach_fd_occasions_t *)malloc(sizeof(nfapi_nr_num_prach_fd_occasions_t));
   // unpack TLVs
 
   unpack_tlv_t unpack_fns[] = {
@@ -2528,22 +2520,12 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
       {NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG, &(pNfapiMsg->prach_config.restricted_set_config), &unpack_uint8_tlv_value},
       {NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions), &unpack_uint8_tlv_value},
       {NFAPI_NR_CONFIG_PRACH_CONFIG_INDEX_TAG, &(pNfapiMsg->prach_config.prach_ConfigurationIndex), &unpack_uint8_tlv_value},
-      {NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG,
-       &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_root_sequence_index),
-       &unpack_uint16_tlv_value},
-      {NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG,
-       &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_root_sequences),
-       &unpack_uint8_tlv_value},
-      {NFAPI_NR_CONFIG_K1_TAG, &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].k1), &unpack_uint16_tlv_value},
-      {NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG,
-       &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].prach_zero_corr_conf),
-       &unpack_uint8_tlv_value},
-      {NFAPI_NR_CONFIG_NUM_UNUSED_ROOT_SEQUENCES_TAG,
-       &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].num_unused_root_sequences),
-       &unpack_uint16_tlv_value},
-      {NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG,
-       &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[0].unused_root_sequences_list[0]),
-       &unpack_uint16_tlv_value},
+      {NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG, NULL, &unpack_uint16_tlv_value},
+      {NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG, NULL, &unpack_uint8_tlv_value},
+      {NFAPI_NR_CONFIG_K1_TAG, NULL, &unpack_uint16_tlv_value},
+      {NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG, NULL, &unpack_uint8_tlv_value},
+      {NFAPI_NR_CONFIG_NUM_UNUSED_ROOT_SEQUENCES_TAG, NULL, &unpack_uint16_tlv_value},
+      {NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG, NULL, &unpack_uint16_tlv_value},
       {NFAPI_NR_CONFIG_SSB_PER_RACH_TAG, &(pNfapiMsg->prach_config.ssb_per_rach), &unpack_uint8_tlv_value},
       {NFAPI_NR_CONFIG_PRACH_MULTIPLE_CARRIERS_IN_A_BAND_TAG,
        &(pNfapiMsg->prach_config.prach_multiple_carriers_in_a_band),
@@ -2562,9 +2544,7 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
        &(pNfapiMsg->ssb_table.multiple_cells_ss_pbch_in_a_carrier),
        &unpack_uint8_tlv_value},
       {NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), &unpack_uint8_tlv_value},
-      {NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
-       &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[0].max_num_of_symbol_per_slot_list[0].slot_config),
-       &unpack_uint8_tlv_value},
+      {NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, NULL, &unpack_uint8_tlv_value},
       {NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, &(pNfapiMsg->measurement_config.rssi_measurement), &unpack_uint8_tlv_value},
       {NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv4), &unpack_ipv4_address_value},
       {NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG, &(pNfapiMsg->nfapi_config.p7_vnf_address_ipv6), &unpack_ipv6_address_value},
@@ -2592,11 +2572,43 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
         pStartOfValue = *ppReadPackedMsg;
         tagMatch = 1;
         nfapi_tl_t *tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
-        tl->tag = generic_tl.tag;
-        tl->length = generic_tl.length;
+        if (tl) {
+          tl->tag = generic_tl.tag;
+          tl->length = generic_tl.length;
+        }
         int result = 0;
         switch (generic_tl.tag) {
+          case NFAPI_NR_CONFIG_NUM_PRACH_FD_OCCASIONS_TAG:
+            pNfapiMsg->prach_config.num_prach_fd_occasions.tl.tag = generic_tl.tag;
+            pNfapiMsg->prach_config.num_prach_fd_occasions.tl.length = generic_tl.length;
+            result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->prach_config.num_prach_fd_occasions, ppReadPackedMsg, end);
+            pNfapiMsg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *)malloc(
+                pNfapiMsg->prach_config.num_prach_fd_occasions.value * sizeof(nfapi_nr_num_prach_fd_occasions_t));
+            prach_root_seq_idx = 0;
+            break;
+          case NFAPI_NR_CONFIG_SCS_COMMON_TAG:
+            pNfapiMsg->ssb_config.scs_common.tl.tag = generic_tl.tag;
+            pNfapiMsg->ssb_config.scs_common.tl.length = generic_tl.length;
+            result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->ssb_config.scs_common, ppReadPackedMsg, end);
+            const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
+            // Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
+            uint8_t cyclicprefix = 1;
+            bool normal_CP = cyclicprefix ? false : true;
+            // 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
+            uint8_t number_of_symbols_per_slot = normal_CP ? 14 : 12;
+
+            pNfapiMsg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(
+                slotsperframe[pNfapiMsg->ssb_config.scs_common.value] * sizeof(nfapi_nr_max_tdd_periodicity_t));
+
+            for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) {
+              pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
+                  (nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot
+                                                                  * sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
+            }
+            break;
           case NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG:
+            unpack_fns[idx].tlv =
+                &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].prach_root_sequence_index);
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].prach_root_sequence_index.tl.tag =
                 generic_tl.tag;
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].prach_root_sequence_index.tl.length =
@@ -2605,9 +2617,9 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
                 &pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].prach_root_sequence_index,
                 ppReadPackedMsg,
                 end);
-            prach_root_seq_idx++;
             break;
           case NFAPI_NR_CONFIG_K1_TAG:
+            unpack_fns[idx].tlv = &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].k1);
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].k1.tl.tag = generic_tl.tag;
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].k1.tl.length = generic_tl.length;
             result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].k1,
@@ -2615,6 +2627,7 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
                                                     end);
             break;
           case NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG:
+            unpack_fns[idx].tlv = &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].prach_zero_corr_conf);
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].prach_zero_corr_conf.tl.tag = generic_tl.tag;
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].prach_zero_corr_conf.tl.length =
                 generic_tl.length;
@@ -2624,6 +2637,7 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
                 end);
             break;
           case NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG:
+            unpack_fns[idx].tlv = &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_root_sequences);
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_root_sequences.tl.tag = generic_tl.tag;
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_root_sequences.tl.length =
                 generic_tl.length;
@@ -2633,6 +2647,8 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
                 end);
             break;
           case NFAPI_NR_CONFIG_NUM_UNUSED_ROOT_SEQUENCES_TAG:
+            unpack_fns[idx].tlv =
+                &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_unused_root_sequences);
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_unused_root_sequences.tl.tag =
                 generic_tl.tag;
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_unused_root_sequences.tl.length =
@@ -2641,8 +2657,15 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
                 &pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_unused_root_sequences,
                 ppReadPackedMsg,
                 end);
+            pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].unused_root_sequences_list =
+                (nfapi_uint8_tlv_t *)malloc(
+                    pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_unused_root_sequences.value
+                    * sizeof(nfapi_uint8_tlv_t));
+            unused_root_seq_idx = 0;
             break;
           case NFAPI_NR_CONFIG_UNUSED_ROOT_SEQUENCES_TAG:
+            unpack_fns[idx].tlv = &(pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx]
+                                        .unused_root_sequences_list[unused_root_seq_idx]);
             pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx]
                 .unused_root_sequences_list[unused_root_seq_idx]
                 .tl.tag = generic_tl.tag;
@@ -2654,6 +2677,12 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
                                                     ppReadPackedMsg,
                                                     end);
             unused_root_seq_idx++;
+            // last tlv of the list
+            if (unused_root_seq_idx
+                >= pNfapiMsg->prach_config.num_prach_fd_occasions_list[prach_root_seq_idx].num_unused_root_sequences.value) {
+              prach_root_seq_idx++;
+              unused_root_seq_idx = 0;
+            }
             break;
           case NFAPI_NR_CONFIG_SSB_MASK_TAG:
             pNfapiMsg->ssb_table.ssb_mask_list[ssb_mask_idx].ssb_mask.tl.tag = generic_tl.tag;
@@ -2663,21 +2692,25 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
             break;
           case NFAPI_NR_CONFIG_DL_GRID_SIZE_TAG:
             for (int i = 0; i < 5; i++) {
+              pNfapiMsg->carrier_config.dl_grid_size[i].tl.tag = generic_tl.tag;
               result = unpack_uint16_tlv_value(&pNfapiMsg->carrier_config.dl_grid_size[i], ppReadPackedMsg, end);
             }
             break;
           case NFAPI_NR_CONFIG_DL_K0_TAG:
             for (int i = 0; i < 5; i++) {
+              pNfapiMsg->carrier_config.dl_k0[i].tl.tag = generic_tl.tag;
               result = unpack_uint16_tlv_value(&pNfapiMsg->carrier_config.dl_k0[i], ppReadPackedMsg, end);
             }
             break;
           case NFAPI_NR_CONFIG_UL_GRID_SIZE_TAG:
             for (int i = 0; i < 5; i++) {
+              pNfapiMsg->carrier_config.ul_grid_size[i].tl.tag = generic_tl.tag;
               result = unpack_uint16_tlv_value(&pNfapiMsg->carrier_config.ul_grid_size[i], ppReadPackedMsg, end);
             }
             break;
           case NFAPI_NR_CONFIG_UL_K0_TAG:
             for (int i = 0; i < 5; i++) {
+              pNfapiMsg->carrier_config.ul_k0[i].tl.tag = generic_tl.tag;
               result = unpack_uint16_tlv_value(&pNfapiMsg->carrier_config.ul_k0[i], ppReadPackedMsg, end);
             }
             break;
@@ -2690,6 +2723,9 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
             config_beam_idx++;
             break;
           case NFAPI_NR_CONFIG_SLOT_CONFIG_TAG:
+            unpack_fns[idx].tlv = &(pNfapiMsg->tdd_table.max_tdd_periodicity_list[tdd_periodicity_idx]
+                                        .max_num_of_symbol_per_slot_list[symbol_per_slot_idx]
+                                        .slot_config);
             pNfapiMsg->tdd_table.max_tdd_periodicity_list[tdd_periodicity_idx]
                 .max_num_of_symbol_per_slot_list[symbol_per_slot_idx]
                 .slot_config.tl.tag = generic_tl.tag;
@@ -2701,7 +2737,7 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
                                                          .slot_config,
                                                     ppReadPackedMsg,
                                                     end);
-            symbol_per_slot_idx = (symbol_per_slot_idx + 1) % 14;
+            symbol_per_slot_idx = (symbol_per_slot_idx + 1) % number_of_symbols_per_slot;
             if (symbol_per_slot_idx == 0) {
               tdd_periodicity_idx++;
             }
@@ -2710,7 +2746,12 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
             result = (*unpack_fns[idx].unpack_func)(tl, ppReadPackedMsg, end);
             break;
         }
-
+        // update tl pointer with updated value, if it was set in the switch (it was inside lists)
+        if (!tl) {
+          tl = (nfapi_tl_t *)(unpack_fns[idx].tlv);
+          tl->tag = generic_tl.tag;
+          tl->length = generic_tl.length;
+        }
         if (result == 0)
           return 0;
 
-- 
GitLab