diff --git a/CMakeLists.txt b/CMakeLists.txt
index 351c40d89a65817756a90a9ae02ac9a2d445e910..e3741d1f9b06db7cad30d425de5043d2d930f4ec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -723,7 +723,7 @@ set(NFAPI_SRC
 )
 add_library(NFAPI_LIB ${NFAPI_SRC})
 target_link_libraries(NFAPI_LIB PUBLIC nfapi_common)
-target_link_libraries(NFAPI_LIB PUBLIC nr_fapi_p5)
+target_link_libraries(NFAPI_LIB PUBLIC nr_fapi_p5 nr_fapi_p7)
 
 include_directories(${NFAPI_DIR}/nfapi/public_inc)
 include_directories(${NFAPI_DIR}/nfapi/inc)
@@ -748,7 +748,7 @@ set(NFAPI_VNF_SRC
 )
 add_library(NFAPI_VNF_LIB ${NFAPI_VNF_SRC})
 target_link_libraries(NFAPI_VNF_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
-target_link_libraries(NFAPI_VNF_LIB PRIVATE nr_fapi_p5)
+target_link_libraries(NFAPI_VNF_LIB PRIVATE nr_fapi_p5 nr_fapi_p7)
 if(OAI_AERIAL)
   target_compile_definitions(NFAPI_VNF_LIB PRIVATE ENABLE_AERIAL)
 endif()
@@ -765,6 +765,7 @@ set(NFAPI_USER_SRC
 )
 add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC})
 target_link_libraries(NFAPI_USER_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
+target_link_libraries(NFAPI_USER_LIB PRIVATE nr_fapi_p7)
 include_directories(${NFAPI_USER_DIR})
 
 # Layer 1
diff --git a/executables/lte-softmodem.c b/executables/lte-softmodem.c
index 552de278d13c56828d229fee055a8f3cecd79bfc..223d0c92f356e96c381eb6f4ca12d2bd8a2cde8e 100644
--- a/executables/lte-softmodem.c
+++ b/executables/lte-softmodem.c
@@ -193,6 +193,16 @@ bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP,
   abort();
 }
 
+/* hack: nfapi code is common for 4G/5G, so some function calls are hardcoded.
+ * Provide body for 5G function not used in 4G code */
+void handle_nr_srs_measurements(const module_id_t module_id,
+                                const frame_t frame,
+                                const sub_frame_t slot,
+                                nfapi_nr_srs_indication_pdu_t *srs_ind)
+{
+  return;
+}
+
 /* forward declarations */
 void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
 
diff --git a/nfapi/oai_integration/aerial/CMakeLists.txt b/nfapi/oai_integration/aerial/CMakeLists.txt
index 80d4cd77c601ea7a2331d68bdabd4b2380967a6c..74b1ad9fbf20241ea99c0621ac4c903f84589279 100644
--- a/nfapi/oai_integration/aerial/CMakeLists.txt
+++ b/nfapi/oai_integration/aerial/CMakeLists.txt
@@ -21,7 +21,7 @@ if (OAI_AERIAL)
     endif ()
     target_compile_definitions(aerial_lib PUBLIC ENABLE_L2_SLT_RSP)
     target_link_libraries(aerial_lib PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
-    target_link_libraries(aerial_lib PRIVATE nr_fapi_p5)
+    target_link_libraries(aerial_lib PRIVATE nr_fapi_p5 nr_fapi_p7)
     target_link_libraries(aerial_lib PRIVATE "${NVLOG_LIB}" "${NVIPC_LIB}")
 else ()
     message(STATUS "No Support for Aerial")
diff --git a/nfapi/oai_integration/aerial/fapi_nvIPC.c b/nfapi/oai_integration/aerial/fapi_nvIPC.c
index ca8cd163815a62fa9bcd6e52301576803f071661..ed087204b09c81e8a59c5a57b9965c0406ef81eb 100644
--- a/nfapi/oai_integration/aerial/fapi_nvIPC.c
+++ b/nfapi/oai_integration/aerial/fapi_nvIPC.c
@@ -250,9 +250,14 @@ static int ipc_handle_rx_msg(nv_ipc_t *ipc, nv_ipc_msg_t *msg)
       }
 
       case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: {
+        uint8_t *pReadData = msg->data_buf;
+        int dataBufLen = msg->data_len;
+        uint8_t *data_end = msg->data_buf + dataBufLen;
         nfapi_nr_srs_indication_t ind;
         aerial_unpack_nr_srs_indication(&pReadPackedMessage,
                                         end,
+                                        &pReadData,
+                                        data_end,
                                         &ind,
                                         &((vnf_p7_t *)((vnf_info *)vnf_config->user_data)->p7_vnfs->config)->_public.codec_config);
         if (((vnf_info *)vnf_config->user_data)->p7_vnfs->config->nr_srs_indication) {
@@ -288,7 +293,7 @@ int8_t buf[1024];
 
 nv_ipc_config_t nv_ipc_config;
 
-int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header)
+int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p4_p5_message_header_t *header)
 {
   if (ipc == NULL) {
     return -1;
@@ -334,12 +339,12 @@ int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_me
 
   memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
   LOG_D(NFAPI_VNF,
-         "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
-         send_msg.cell_id,
-         send_msg.msg_id,
-         send_msg.msg_len,
-         send_msg.data_len,
-         send_msg.data_pool);
+        "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
+        send_msg.cell_id,
+        send_msg.msg_id,
+        send_msg.msg_len,
+        send_msg.data_len,
+        send_msg.data_pool);
   // Send the message
   int send_retval = ipc->tx_send_msg(ipc, &send_msg);
   if (send_retval < 0) {
@@ -352,7 +357,7 @@ int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_me
   return 0;
 }
 
-int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header)
+int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p7_message_header_t *header)
 {
   if (ipc == NULL) {
     return -1;
@@ -421,12 +426,12 @@ int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_messa
 
   memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
   LOG_D(NFAPI_VNF,
-         "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
-         send_msg.cell_id,
-         send_msg.msg_id,
-         send_msg.msg_len,
-         send_msg.data_len,
-         send_msg.data_pool);
+        "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
+        send_msg.cell_id,
+        send_msg.msg_id,
+        send_msg.msg_len,
+        send_msg.data_len,
+        send_msg.data_pool);
   // Send the message
   int send_retval = ipc->tx_send_msg(ipc, &send_msg);
   if (send_retval < 0) {
@@ -440,10 +445,10 @@ int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_messa
 }
 
 int aerial_send_P7_msg_with_data(void *packedBuf,
-                                      uint32_t packedMsgLength,
-                                      void *dataBuf,
-                                      uint32_t dataLength,
-                                      nfapi_p7_message_header_t *header)
+                                 uint32_t packedMsgLength,
+                                 void *dataBuf,
+                                 uint32_t dataLength,
+                                 nfapi_nr_p7_message_header_t *header)
 {
   if (ipc == NULL) {
     return -1;
@@ -511,12 +516,12 @@ int aerial_send_P7_msg_with_data(void *packedBuf,
   memcpy(send_msg.msg_buf, packedBuf, send_msg.msg_len);
   memcpy(send_msg.data_buf, dataBuf, send_msg.data_len);
   LOG_D(NFAPI_VNF,
-         "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
-         send_msg.cell_id,
-         send_msg.msg_id,
-         send_msg.msg_len,
-         send_msg.data_len,
-         send_msg.data_pool);
+        "send: cell_id=%d msg_id=0x%02X msg_len=%d data_len=%d data_pool=%d\n",
+        send_msg.cell_id,
+        send_msg.msg_id,
+        send_msg.msg_len,
+        send_msg.data_len,
+        send_msg.data_pool);
   // Send the message
   int send_retval = ipc->tx_send_msg(ipc, &send_msg);
   if (send_retval != 0) {
diff --git a/nfapi/oai_integration/aerial/fapi_nvIPC.h b/nfapi/oai_integration/aerial/fapi_nvIPC.h
index 3d88937f606797f453f80b71d599a666dbbaf453..5b8b9959642d2145a661f5f8c005d57e4f024929 100644
--- a/nfapi/oai_integration/aerial/fapi_nvIPC.h
+++ b/nfapi/oai_integration/aerial/fapi_nvIPC.h
@@ -47,13 +47,13 @@ typedef struct {
   uint32_t message_length;
 } fapi_phy_api_msg;
 
-int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p4_p5_message_header_t *header);
-int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_p7_message_header_t *header);
+int aerial_send_P5_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p4_p5_message_header_t *header);
+int aerial_send_P7_msg(void *packedBuf, uint32_t packedMsgLength, nfapi_nr_p7_message_header_t *header);
 int aerial_send_P7_msg_with_data(void *packedBuf,
-                                      uint32_t packedMsgLength,
-                                      void *dataBuf,
-                                      uint32_t dataLength,
-                                      nfapi_p7_message_header_t *header);
+                                 uint32_t packedMsgLength,
+                                 void *dataBuf,
+                                 uint32_t dataLength,
+                                 nfapi_nr_p7_message_header_t *header);
 void set_config(nfapi_vnf_config_t *conf);
 int nvIPC_Init(nvipc_params_t nvipc_params_s);
 
diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p5.c b/nfapi/oai_integration/aerial/fapi_vnf_p5.c
index 951a734ddd241e0e27f5dc67bea7deb75576521c..1128559b1df2997122654d753796db46e702cb8c 100644
--- a/nfapi/oai_integration/aerial/fapi_vnf_p5.c
+++ b/nfapi/oai_integration/aerial/fapi_vnf_p5.c
@@ -299,7 +299,6 @@ int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx)
   req->header.phy_id = phy->id;
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Send NFAPI_CONFIG_REQUEST\n");
 
-
   vnf_t *_this = (vnf_t *)(config);
 
   nfapi_vnf_phy_info_t *vnf_phy = nfapi_vnf_phy_info_list_find(config, req->header.phy_id);
@@ -309,7 +308,7 @@ int aerial_nr_send_config_request(nfapi_vnf_config_t *config, int p5_idx)
     return -1;
   }
 
-  nfapi_p4_p5_message_header_t *msg = &req->header;
+  nfapi_nr_p4_p5_message_header_t *msg = &req->header;
   uint16_t msg_len = sizeof(nfapi_nr_config_request_scf_t);
   uint8_t tx_messagebufferFAPI[sizeof(_this->tx_message_buffer)];
   int packedMessageLengthFAPI = -1;
@@ -346,19 +345,19 @@ int aerial_nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_sta
   return 0;
 }
 
-int aerial_vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg)
+int aerial_vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, void *msg)
 {
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__);
 
-  switch (msg->message_id) {
+  switch (((nfapi_nr_p4_p5_message_header_t *)msg)->message_id) {
     case P5_VENDOR_EXT_RSP: {
       vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg;
       NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
       // send the start request
-      nfapi_pnf_start_request_t req;
+      nfapi_nr_pnf_start_request_t req;
       memset(&req, 0, sizeof(req));
       req.header.message_id = NFAPI_PNF_START_REQUEST;
-      nfapi_vnf_pnf_start_req(config, p5_idx, &req);
+      nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
     } break;
   }
 
@@ -392,12 +391,12 @@ int aerial_vnf_pack_vendor_extension_tlv(void *vext, uint8_t **ppWritePackedMsg,
   return -1;
 }
 
-int aerial_vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
+int aerial_vnf_unpack_p4_p5_vendor_extension(void *header,
                                              uint8_t **ppReadPackedMessage,
                                              uint8_t *end,
                                              nfapi_p4_p5_codec_config_t *codec)
 {
-  if (header->message_id == P5_VENDOR_EXT_RSP) {
+  if (((nfapi_nr_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_RSP) {
     vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header);
     return (!pull16(ppReadPackedMessage, &req->error_code, end));
   }
@@ -405,12 +404,12 @@ int aerial_vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *heade
   return 0;
 }
 
-int aerial_vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
+int aerial_vnf_pack_p4_p5_vendor_extension(void *header,
                                            uint8_t **ppWritePackedMsg,
                                            uint8_t *end,
                                            nfapi_p4_p5_codec_config_t *codec)
 {
-  if (header->message_id == P5_VENDOR_EXT_REQ) {
+  if (((nfapi_nr_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_REQ) {
     vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
     return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)));
   }
@@ -418,17 +417,17 @@ int aerial_vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header,
   return 0;
 }
 
-nfapi_p4_p5_message_header_t *aerial_vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+void *aerial_vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
 {
   if (message_id == P5_VENDOR_EXT_RSP) {
     *msg_size = sizeof(vendor_ext_p5_rsp);
-    return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp));
+    return malloc(sizeof(vendor_ext_p5_rsp));
   }
 
   return 0;
 }
 
-void aerial_vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header)
+void aerial_vnf_deallocate_p4_p5_vendor_ext(void *header)
 {
   free(header);
 }
diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p7.c b/nfapi/oai_integration/aerial/fapi_vnf_p7.c
index 2f8d001d5072945a05c4353dd788b681b80a4544..25508f833bc79369f042745eab4bb6c2f30b6ad3 100644
--- a/nfapi/oai_integration/aerial/fapi_vnf_p7.c
+++ b/nfapi/oai_integration/aerial/fapi_vnf_p7.c
@@ -32,6 +32,8 @@
 
 #include "fapi_vnf_p7.h"
 #include "nr_nfapi_p7.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
 
 #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" // for handle_nr_srs_measurements()
 
@@ -42,38 +44,10 @@ extern int nfapi_sync_var;
 int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind)
 {
   nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind));
-  crc_ind->header.message_id = ind->header.message_id;
-  crc_ind->number_crcs = ind->number_crcs;
-  crc_ind->sfn = ind->sfn;
-  crc_ind->slot = ind->slot;
-  if (ind->number_crcs > 0) {
-    crc_ind->crc_list = CALLOC(NFAPI_NR_CRC_IND_MAX_PDU, sizeof(nfapi_nr_crc_t));
-    AssertFatal(crc_ind->crc_list != NULL, "Memory not allocated for crc_ind->crc_list in phy_nr_crc_indication.");
-  }
-  for (int j = 0; j < ind->number_crcs; j++) {
-    crc_ind->crc_list[j].handle = ind->crc_list[j].handle;
-    crc_ind->crc_list[j].rnti = ind->crc_list[j].rnti;
-    crc_ind->crc_list[j].harq_id = ind->crc_list[j].harq_id;
-    crc_ind->crc_list[j].tb_crc_status = ind->crc_list[j].tb_crc_status;
-    crc_ind->crc_list[j].num_cb = ind->crc_list[j].num_cb;
-    crc_ind->crc_list[j].cb_crc_status = ind->crc_list[j].cb_crc_status;
-    crc_ind->crc_list[j].ul_cqi = ind->crc_list[j].ul_cqi;
-    crc_ind->crc_list[j].timing_advance = ind->crc_list[j].timing_advance;
-    crc_ind->crc_list[j].rssi = ind->crc_list[j].rssi;
-    if (crc_ind->crc_list[j].tb_crc_status != 0) {
-      LOG_D(NR_MAC,
-            "Received crc_ind.harq_id %d status %d for index %d SFN SLot %u %u with rnti %04x\n",
-            crc_ind->crc_list[j].harq_id,
-            crc_ind->crc_list[j].tb_crc_status,
-            j,
-            crc_ind->sfn,
-            crc_ind->slot,
-            crc_ind->crc_list[j].rnti);
-    }
-  }
+  copy_crc_indication(ind, crc_ind);
   if (!put_queue(&gnb_crc_ind_queue, crc_ind)) {
     LOG_E(NR_MAC, "Put_queue failed for crc_ind\n");
-    free(crc_ind->crc_list);
+    free_crc_indication(crc_ind);
     free(crc_ind);
   }
   return 1;
@@ -82,40 +56,10 @@ int aerial_phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind)
 int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind)
 {
   nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind));
-  rx_ind->header.message_id = ind->header.message_id;
-  rx_ind->sfn = ind->sfn;
-  rx_ind->slot = ind->slot;
-  rx_ind->number_of_pdus = ind->number_of_pdus;
-
-  if (ind->number_of_pdus > 0) {
-    rx_ind->pdu_list = CALLOC(NFAPI_NR_RX_DATA_IND_MAX_PDU, sizeof(nfapi_nr_rx_data_pdu_t));
-    AssertFatal(rx_ind->pdu_list != NULL, "Memory not allocated for rx_ind->pdu_list in phy_nr_rx_data_indication.");
-  }
-  for (int j = 0; j < ind->number_of_pdus; j++) {
-    rx_ind->pdu_list[j].handle = ind->pdu_list[j].handle;
-    rx_ind->pdu_list[j].rnti = ind->pdu_list[j].rnti;
-    rx_ind->pdu_list[j].harq_id = ind->pdu_list[j].harq_id;
-    rx_ind->pdu_list[j].pdu_length = ind->pdu_list[j].pdu_length;
-    rx_ind->pdu_list[j].ul_cqi = ind->pdu_list[j].ul_cqi;
-    rx_ind->pdu_list[j].timing_advance = ind->pdu_list[j].timing_advance;
-    rx_ind->pdu_list[j].rssi = ind->pdu_list[j].rssi;
-    // Only copy PDU data if there's any to copy
-    if (rx_ind->pdu_list[j].pdu_length > 0) {
-      rx_ind->pdu_list[j].pdu = calloc(rx_ind->pdu_list[j].pdu_length, sizeof(uint8_t));
-      memcpy(rx_ind->pdu_list[j].pdu, ind->pdu_list[j].pdu, ind->pdu_list[j].pdu_length);
-    }
-    LOG_D(NR_MAC,
-          "(%d.%d) Handle %d for index %d, RNTI, %04x, HARQID %d\n",
-          ind->sfn,
-          ind->slot,
-          ind->pdu_list[j].handle,
-          j,
-          ind->pdu_list[j].rnti,
-          ind->pdu_list[j].harq_id);
-  }
+  copy_rx_data_indication(ind, rx_ind);
   if (!put_queue(&gnb_rx_ind_queue, rx_ind)) {
     LOG_E(NR_MAC, "Put_queue failed for rx_ind\n");
-    free(rx_ind->pdu_list);
+    free_rx_data_indication(rx_ind);
     free(rx_ind);
   }
   return 1;
@@ -124,29 +68,10 @@ int aerial_phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind)
 int aerial_phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind)
 {
   nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind));
-  rach_ind->header.message_id = ind->header.message_id;
-  rach_ind->sfn = ind->sfn;
-  rach_ind->slot = ind->slot;
-  rach_ind->number_of_pdus = ind->number_of_pdus;
-  rach_ind->pdu_list = CALLOC(rach_ind->number_of_pdus, sizeof(*rach_ind->pdu_list));
-  AssertFatal(rach_ind->pdu_list != NULL, "Memory not allocated for rach_ind->pdu_list in phy_nr_rach_indication.");
-  for (int i = 0; i < ind->number_of_pdus; i++) {
-    rach_ind->pdu_list[i].phy_cell_id = ind->pdu_list[i].phy_cell_id;
-    rach_ind->pdu_list[i].symbol_index = ind->pdu_list[i].symbol_index;
-    rach_ind->pdu_list[i].slot_index = ind->pdu_list[i].slot_index;
-    rach_ind->pdu_list[i].freq_index = ind->pdu_list[i].freq_index;
-    rach_ind->pdu_list[i].avg_rssi = ind->pdu_list[i].avg_rssi;
-    rach_ind->pdu_list[i].avg_snr = ind->pdu_list[i].avg_snr;
-    rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble;
-    for (int j = 0; j < ind->pdu_list[i].num_preamble; j++) {
-      rach_ind->pdu_list[i].preamble_list[j].preamble_index = ind->pdu_list[i].preamble_list[j].preamble_index;
-      rach_ind->pdu_list[i].preamble_list[j].timing_advance = ind->pdu_list[i].preamble_list[j].timing_advance;
-      rach_ind->pdu_list[i].preamble_list[j].preamble_pwr = ind->pdu_list[i].preamble_list[j].preamble_pwr;
-    }
-  }
+  copy_rach_indication(ind, rach_ind);
   if (!put_queue(&gnb_rach_ind_queue, rach_ind)) {
     LOG_E(NR_MAC, "Put_queue failed for rach_ind\n");
-    free(rach_ind->pdu_list);
+    free_rach_indication(rach_ind);
     free(rach_ind);
   } else {
     LOG_I(NR_MAC, "RACH.indication put_queue successfull\n");
@@ -158,99 +83,10 @@ int aerial_phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
 {
   nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind));
   AssertFatal(uci_ind, "Memory not allocated for uci_ind in phy_nr_uci_indication.");
-  *uci_ind = *ind;
-
-  uci_ind->uci_list = CALLOC(NFAPI_NR_UCI_IND_MAX_PDU, sizeof(nfapi_nr_uci_t));
-  AssertFatal(uci_ind->uci_list != NULL, "Memory not allocated for uci_ind->uci_list in phy_nr_uci_indication.");
-  for (int i = 0; i < ind->num_ucis; i++) {
-    uci_ind->uci_list[i] = ind->uci_list[i];
-
-    switch (uci_ind->uci_list[i].pdu_type) {
-      case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
-        LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
-        break;
-
-      case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
-//          nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1;
-//          nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1;
-//          if (ind_pdu->sr) {
-//            uci_ind_pdu->sr = CALLOC(1, sizeof(*uci_ind_pdu->sr));
-//            AssertFatal(uci_ind_pdu->sr != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication.");
-//            *uci_ind_pdu->sr = *ind_pdu->sr;
-//          }
-//          if (ind_pdu->harq) {
-//            uci_ind_pdu->harq = CALLOC(1, sizeof(*uci_ind_pdu->harq));
-//            AssertFatal(uci_ind_pdu->harq != NULL, "Memory not allocated for uci_ind_pdu->harq in phy_nr_uci_indication.");
-//
-//            *uci_ind_pdu->harq = *ind_pdu->harq;
-//            uci_ind_pdu->harq->harq_list = CALLOC(uci_ind_pdu->harq->num_harq, sizeof(*uci_ind_pdu->harq->harq_list));
-//            AssertFatal(uci_ind_pdu->harq->harq_list != NULL,
-//                        "Memory not allocated for uci_ind_pdu->harq->harq_list in phy_nr_uci_indication.");
-//            for (int j = 0; j < uci_ind_pdu->harq->num_harq; j++)
-//              uci_ind_pdu->harq->harq_list[j].harq_value = ind_pdu->harq->harq_list[j].harq_value;
-//          }
-        break;
-      }
-
-      case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
-        nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4;
-        nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4;
-        *uci_ind_pdu = *ind_pdu;
-        if (ind_pdu->harq.harq_payload) {
-          uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload));
-          AssertFatal(uci_ind_pdu->harq.harq_payload != NULL,
-                      "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication.");
-          *uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload;
-        }
-        if (ind_pdu->sr.sr_payload) {
-          uci_ind_pdu->sr.sr_payload = CALLOC(1, sizeof(*uci_ind_pdu->sr.sr_payload));
-          AssertFatal(uci_ind_pdu->sr.sr_payload != NULL,
-                      "Memory not allocated for uci_ind_pdu->sr.sr_payload in phy_nr_uci_indication.");
-          //SCF222.10.02 sr_bit_len values from 1 to 8, payload always just one byte
-          uci_ind_pdu->sr.sr_payload[0] = ind_pdu->sr.sr_payload[0];
-        }
-        if (ind_pdu->csi_part1.csi_part1_payload) {
-          uint8_t byte_len = (ind_pdu->csi_part1.csi_part1_bit_len / 8) + 1;
-          uci_ind_pdu->csi_part1.csi_part1_payload = calloc(byte_len, sizeof(uint8_t));
-          AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL,
-                      "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication.");
-          memcpy(uci_ind_pdu->csi_part1.csi_part1_payload,ind_pdu->csi_part1.csi_part1_payload,byte_len);
-        }
-        if (ind_pdu->csi_part2.csi_part2_payload) {
-          uint8_t byte_len = (ind_pdu->csi_part2.csi_part2_bit_len / 8) + 1;
-          uci_ind_pdu->csi_part2.csi_part2_payload = calloc(byte_len, sizeof(uint8_t));
-          AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL,
-                      "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication.");
-          memcpy(uci_ind_pdu->csi_part2.csi_part2_payload,ind_pdu->csi_part2.csi_part2_payload,byte_len);
-        }
-        break;
-      }
-    }
-  }
-
+  copy_uci_indication(ind, uci_ind);
   if (!put_queue(&gnb_uci_ind_queue, uci_ind)) {
     LOG_E(NR_MAC, "Put_queue failed for uci_ind\n");
-    for (int i = 0; i < ind->num_ucis; i++) {
-      if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE) {
-//          if (uci_ind->uci_list[i].pucch_pdu_format_0_1.harq) {
-//            free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list);
-//            uci_ind->uci_list[i].pucch_pdu_format_0_1.harq->harq_list = NULL;
-//            free(uci_ind->uci_list[i].pucch_pdu_format_0_1.harq);
-//            uci_ind->uci_list[i].pucch_pdu_format_0_1.harq = NULL;
-//          }
-//          if (uci_ind->uci_list[i].pucch_pdu_format_0_1.sr) {
-//            free(uci_ind->uci_list[i].pucch_pdu_format_0_1.sr);
-//            uci_ind->uci_list[i].pucch_pdu_format_0_1.sr = NULL;
-//          }
-      }
-      if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE) {
-        free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload);
-        free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload);
-        free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload);
-      }
-    }
-    free(uci_ind->uci_list);
-    uci_ind->uci_list = NULL;
+    free_uci_indication(uci_ind);
     free(uci_ind);
     uci_ind = NULL;
   }
@@ -333,25 +169,25 @@ void aerial_vnf_deallocate(void *ptr)
   free(ptr);
 }
 
-int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg)
+int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, void *msg)
 {
-  if (msg->message_id == P7_VENDOR_EXT_IND) {
+  if (((nfapi_nr_p7_message_header_t *)msg)->message_id == P7_VENDOR_EXT_IND) {
     // vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg;
     // NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] vendor_ext (error_code:%d)\n", ind->error_code);
   } else {
-    NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] unknown %02x\n", msg->message_id);
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] unknown %02x\n", ((nfapi_nr_p7_message_header_t *)msg)->message_id);
   }
 
   return 0;
 }
 
-int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header,
+int aerial_phy_unpack_p7_vendor_extension(void *header,
                                           uint8_t **ppReadPackedMessage,
                                           uint8_t *end,
                                           nfapi_p7_codec_config_t *config)
 {
   // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if (header->message_id == P7_VENDOR_EXT_IND) {
+  if (((nfapi_nr_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_IND) {
     vendor_ext_p7_ind *req = (vendor_ext_p7_ind *)(header);
 
     if (!pull16(ppReadPackedMessage, &req->error_code, end))
@@ -361,13 +197,10 @@ int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header,
   return 1;
 }
 
-int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header,
-                                        uint8_t **ppWritePackedMsg,
-                                        uint8_t *end,
-                                        nfapi_p7_codec_config_t *config)
+int aerial_phy_pack_p7_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
 {
   // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if (header->message_id == P7_VENDOR_EXT_REQ) {
+  if (((nfapi_nr_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_REQ) {
     // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
     vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header);
 
@@ -412,17 +245,17 @@ int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, u
   }
 }
 
-nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+void *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size)
 {
   if (message_id == P7_VENDOR_EXT_IND) {
     *msg_size = sizeof(vendor_ext_p7_ind);
-    return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind));
+    return (nfapi_nr_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind));
   }
 
   return 0;
 }
 
-void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header)
+void aerial_phy_deallocate_p7_vendor_ext(void *header)
 {
   free(header);
 }
@@ -504,9 +337,25 @@ uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end,
   return unpack_nr_uci_indication(ppReadPackedMsg, end, msg, config);
 }
 
-uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg,
+                                        uint8_t *end,
+                                        uint8_t **pDataMsg,
+                                        uint8_t *data_end,
+                                        void *msg,
+                                        nfapi_p7_codec_config_t *config)
 {
-  return unpack_nr_srs_indication(ppReadPackedMsg, end, msg, config);
+  uint8_t retval = unpack_nr_srs_indication(ppReadPackedMsg, end, msg, config);
+  nfapi_nr_srs_indication_t *srs_ind = (nfapi_nr_srs_indication_t *)msg;
+  for (uint8_t pdu_idx = 0; pdu_idx < srs_ind->number_of_pdus; pdu_idx++) {
+    nfapi_nr_srs_indication_pdu_t *pdu = &srs_ind->pdu_list[pdu_idx];
+    nfapi_srs_report_tlv_t *report_tlv = &pdu->report_tlv;
+    for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
+      if (!pull32(pDataMsg, &report_tlv->value[i], data_end)) {
+        return 0;
+      }
+    }
+  }
+  return retval;
 }
 
 uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
@@ -530,7 +379,7 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
     return -1;
   }
 
-  nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
+  nfapi_nr_p7_message_header_t *pMessageHeader = pMessageBuf;
   uint8_t *end = pPackedBuf + packedBufLen;
   uint8_t *data_end = pDataBuf + dataBufLen;
   uint8_t *pWritePackedMessage = pPackedBuf;
@@ -569,8 +418,7 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
     // recalculate PDU_Length for Aerial (leave only the size occupied in the payload buffer afterward)
     // assuming there is only 1 TLV present
     value->PDU_length = value->TLVs[0].length;
-    if (!(push32(value->PDU_length, ppWriteBody, end)
-          && // cuBB expects TX_DATA.request PDUSize to be 32 bit
+    if (!(push32(value->PDU_length, ppWriteBody, end) && // cuBB expects TX_DATA.request PDUSize to be 32 bit
           push16(value->PDU_index, ppWriteBody, end) && push32(value->num_TLV, ppWriteBody, end))) {
       return 0;
     }
@@ -589,7 +437,7 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
     }
   }
 
-  //Actual payloads are packed in a separate buffer
+  // Actual payloads are packed in a separate buffer
   for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
     nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)&pNfapiMsg->pdu_list[i];
 
@@ -626,12 +474,11 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
           }
         }
       } else {
-        LOG_E(NR_MAC,"value->TLVs[i].length was 0! (%d.%d) \n", pNfapiMsg->SFN, pNfapiMsg->Slot);
+        LOG_E(NR_MAC, "value->TLVs[i].length was 0! (%d.%d) \n", pNfapiMsg->SFN, pNfapiMsg->Slot);
       }
     }
   }
 
-
   // calculate data_len
   uintptr_t dataHead = (uintptr_t)pPackedDataFieldStart;
   uintptr_t dataEnd = (uintptr_t)pPackedDataField;
@@ -659,155 +506,8 @@ static int32_t aerial_pack_tx_data_request(void *pMessageBuf,
   return (packedMsgLen16);
 }
 
-int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config)
-{
-  if (pMessageBuf == NULL || pPackedBuf == NULL) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
-    return -1;
-  }
-
-  nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
-  uint8_t *end = pPackedBuf + packedBufLen;
-  uint8_t *pWritePackedMessage = pPackedBuf;
-  uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
-  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-  uint8_t *pPacketBodyField = &pWritePackedMessage[8];
-  uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
-
-  // PHY API message header
-  // Number of messages [0]
-  // Opaque handle [1]
-  // PHY API Message structure
-  // Message type ID [2,3]
-  // Message Length [4,5,6,7]
-  // Message Body [8,...]
-  if (!(push8(1, &pWritePackedMessage, pPackMessageEnd) && push8(0, &pWritePackedMessage, pPackMessageEnd)
-        && push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd))) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
-    return -1;
-  }
-
-  // look for the specific message
-  uint8_t result = 0;
-  switch (pMessageHeader->message_id) {
-    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-      result = pack_dl_tti_request(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-      result = pack_ul_tti_request(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-      // TX_DATA.request already handled by aerial_pack_tx_data_request
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-      result = pack_ul_dci_request(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_UE_RELEASE_REQUEST:
-      result = pack_ue_release_request(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_UE_RELEASE_RESPONSE:
-      result = pack_ue_release_response(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
-      result = pack_nr_slot_indication(pMessageHeader, &pPacketBodyField, end, config);
-
-    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
-      result = pack_nr_rx_data_indication(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
-      result = pack_nr_crc_indication(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
-      result = pack_nr_uci_indication(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
-      result = pack_nr_srs_indication(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
-      result = pack_nr_rach_indication(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-      result = pack_nr_dl_node_sync(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
-      result = pack_nr_ul_node_sync(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case NFAPI_TIMING_INFO:
-      result = pack_nr_timing_info(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    case 0x8f:
-      result = pack_nr_slot_indication(pMessageHeader, &pPacketBodyField, end, config);
-      break;
-
-    default: {
-      if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
-        if (config && config->pack_p7_vendor_extension) {
-          result = (config->pack_p7_vendor_extension)(pMessageHeader, &pPacketBodyField, end, config);
-        } else {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR,
-                      "%s VE NFAPI message ID %d. No ve ecoder provided\n",
-                      __FUNCTION__,
-                      pMessageHeader->message_id);
-        }
-      } else {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-      }
-    } break;
-  }
-
-  if (result == 0) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
-    return -1;
-  }
-
-  // check for a valid message length
-  uintptr_t msgHead = (uintptr_t)pPacketBodyFieldStart;
-  uintptr_t msgEnd = (uintptr_t)pPacketBodyField;
-  uint32_t packedMsgLen = msgEnd - msgHead;
-  uint16_t packedMsgLen16;
-  if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
-    return -1;
-  } else {
-    packedMsgLen16 = (uint16_t)packedMsgLen;
-  }
-
-  // Update the message length in the header
-  pMessageHeader->message_length = packedMsgLen16;
-
-  // Update the message length in the header
-  if (!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
-    return -1;
-
-  if (1) {
-    // quick test
-    if (pMessageHeader->message_length != packedMsgLen) {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR,
-                  "nfapi packedMsgLen(%d) != message_length(%d) id %d\n",
-                  packedMsgLen,
-                  pMessageHeader->message_length,
-                  pMessageHeader->message_id);
-    }
-  }
-
-  return (packedMsgLen16);
-}
 
-int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header)
+int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_nr_p7_message_header_t *header)
 {
   uint8_t FAPI_buffer[1024 * 64];
   // Check if TX_DATA request, if true, need to pack to data_buf
@@ -817,7 +517,7 @@ int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t
     for (int i = 0; i < pNfapiMsg->Number_of_PDUs; ++i) {
       size += pNfapiMsg->pdu_list[i].PDU_length;
     }
-    AssertFatal(size <= 1024 * 1024 * 2, "Message data larger than available buffer, tried to pack %"PRId64 ,size);
+    AssertFatal(size <= 1024 * 1024 * 2, "Message data larger than available buffer, tried to pack %" PRId64, size);
     uint8_t FAPI_data_buffer[1024 * 1024 * 2]; // 2MB
     uint32_t data_len = 0;
     int32_t len_FAPI = aerial_pack_tx_data_request(header,
diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p7.h b/nfapi/oai_integration/aerial/fapi_vnf_p7.h
index 404df347cc9b485cb18cfac01800f75aa45a91b7..ca75b022760cc110767deb4b31a035dc486d06b5 100644
--- a/nfapi/oai_integration/aerial/fapi_vnf_p7.h
+++ b/nfapi/oai_integration/aerial/fapi_vnf_p7.h
@@ -187,23 +187,20 @@ int aerial_phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind);
 int aerial_phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind);
 void *aerial_vnf_allocate(size_t size);
 void aerial_vnf_deallocate(void *ptr);
-int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg);
-int aerial_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header,
+int aerial_phy_vendor_ext(struct nfapi_vnf_p7_config *config, void *msg);
+int aerial_phy_unpack_p7_vendor_extension(void *header,
                                           uint8_t **ppReadPackedMessage,
                                           uint8_t *end,
                                           nfapi_p7_codec_config_t *config);
-int aerial_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header,
-                                        uint8_t **ppWritePackedMsg,
-                                        uint8_t *end,
-                                        nfapi_p7_codec_config_t *config);
+int aerial_phy_pack_p7_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
 int aerial_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
                                            uint8_t **ppReadPackedMessage,
                                            uint8_t *end,
                                            void **ve,
                                            nfapi_p7_codec_config_t *codec);
 int aerial_phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec);
-nfapi_p7_message_header_t *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size);
-void aerial_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header);
+void *aerial_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size);
+void aerial_phy_deallocate_p7_vendor_ext(void *header);
 
 uint8_t aerial_unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
                                          uint8_t *end,
@@ -220,12 +217,17 @@ uint8_t aerial_unpack_nr_crc_indication(uint8_t **ppReadPackedMsg,
                                         nfapi_nr_crc_indication_t *msg,
                                         nfapi_p7_codec_config_t *config);
 uint8_t aerial_unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
-uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg,
+                                        uint8_t *end,
+                                        uint8_t **pDataMsg,
+                                        uint8_t *data_end,
+                                        void *msg,
+                                        nfapi_p7_codec_config_t *config);
 uint8_t aerial_unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
                                          uint8_t *end,
                                          nfapi_nr_rach_indication_t *msg,
                                          nfapi_p7_codec_config_t *config);
 
 // int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
-int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_p7_message_header_t *header);
+int fapi_nr_pack_and_send_p7_message(vnf_p7_t *vnf_p7, nfapi_nr_p7_message_header_t *header);
 #endif // OPENAIRINTERFACE_FAPI_VNF_P7_H
diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index a933aba614815deac44748548ab3a36bc17d9f6a..c96acd9fba4c51fe11062d151e60a05d9c8e714d 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -1076,8 +1076,9 @@ int nr_config_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, n
   return 0;
 }
 
-nfapi_p7_message_header_t *pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) {
-  if(message_id == P7_VENDOR_EXT_REQ) {
+void *pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+{
+  if (message_id == P7_VENDOR_EXT_REQ) {
     (*msg_size) = sizeof(vendor_ext_p7_req);
     return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_req));
   }
@@ -1085,7 +1086,23 @@ nfapi_p7_message_header_t *pnf_phy_allocate_p7_vendor_ext(uint16_t message_id, u
   return 0;
 }
 
-void pnf_phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
+void *pnf_nr_phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+{
+  if (message_id == P7_VENDOR_EXT_REQ) {
+    (*msg_size) = sizeof(vendor_ext_p7_req);
+    return (nfapi_nr_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_req));
+  }
+
+  return 0;
+}
+
+void pnf_phy_deallocate_p7_vendor_ext(void *header)
+{
+  free(header);
+}
+
+void pnf_nr_phy_deallocate_p7_vendor_ext(void *header)
+{
   free(header);
 }
 
@@ -1522,10 +1539,23 @@ int pnf_phy_ue_release_req(nfapi_pnf_p7_config_t* config, nfapi_ue_release_reque
   return 0;
 }
 
-int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t *config, nfapi_p7_message_header_t *msg) {
-  if(msg->message_id == P7_VENDOR_EXT_REQ) {
-    //vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg;
-    //printf("[PNF] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2);
+int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t *config, void *msg)
+{
+  if (((nfapi_p7_message_header_t *)msg)->message_id == P7_VENDOR_EXT_REQ) {
+    // vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg;
+    // printf("[PNF] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2);
+  } else {
+    printf("[PNF] unknown vendor ext\n");
+  }
+
+  return 0;
+}
+
+int pnf_nr_phy_vendor_ext(nfapi_pnf_p7_config_t *config, void *msg)
+{
+  if (((nfapi_nr_p7_message_header_t *)msg)->message_id == P7_VENDOR_EXT_REQ) {
+    // vendor_ext_p7_req* req = (vendor_ext_p7_req*)msg;
+    // printf("[PNF] vendor request (1:%d 2:%d)\n", req->dummy1, req->dummy2);
   } else {
     printf("[PNF] unknown vendor ext\n");
   }
@@ -1533,9 +1563,9 @@ int pnf_phy_vendor_ext(nfapi_pnf_p7_config_t *config, nfapi_p7_message_header_t
   return 0;
 }
 
-int pnf_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codex) {
+int pnf_phy_pack_p7_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codex) {
   //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if(header->message_id == P7_VENDOR_EXT_IND) {
+  if(((nfapi_p7_message_header_t*)header)->message_id == P7_VENDOR_EXT_IND) {
     vendor_ext_p7_ind *ind = (vendor_ext_p7_ind *)(header);
 
     if(!push16(ind->error_code, ppWritePackedMsg, end))
@@ -1547,13 +1577,43 @@ int pnf_phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t
   return -1;
 }
 
-int pnf_phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *codec) {
-  if(header->message_id == P7_VENDOR_EXT_REQ) {
-    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+int pnf_phy_unpack_p7_vendor_extension(void *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *codec)
+{
+  if (((nfapi_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_REQ) {
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+    vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header);
+
+    if (!(pull16(ppReadPackedMessage, &req->dummy1, end) && pull16(ppReadPackedMessage, &req->dummy2, end)))
+      return 0;
+
+    return 1;
+  }
+
+  return -1;
+}
+
+int pnf_nr_phy_pack_p7_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codex)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_nr_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_IND) {
+    vendor_ext_p7_ind *ind = (vendor_ext_p7_ind *)(header);
+
+    if (!push16(ind->error_code, ppWritePackedMsg, end))
+      return 0;
+
+    return 1;
+  }
+
+  return -1;
+}
+
+int pnf_nr_phy_unpack_p7_vendor_extension(void *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *codec)
+{
+  if (((nfapi_nr_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_REQ) {
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
     vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header);
 
-    if(!(pull16(ppReadPackedMessage, &req->dummy1, end) &&
-         pull16(ppReadPackedMessage, &req->dummy2, end)))
+    if (!(pull16(ppReadPackedMessage, &req->dummy1, end) && pull16(ppReadPackedMessage, &req->dummy2, end)))
       return 0;
 
     return 1;
@@ -1585,6 +1645,34 @@ int pnf_phy_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint
   return -1;
 }
 
+int pnf_nr_phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
+                                           uint8_t **ppReadPackedMessage,
+                                           uint8_t *end,
+                                           void **ve,
+                                           nfapi_p7_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_phy_unpack_vendor_extension_tlv\n");
+  switch (tl->tag) {
+    case VENDOR_EXT_TLV_1_TAG:
+      *ve = malloc(sizeof(vendor_ext_tlv_1));
+
+      if (!pull32(ppReadPackedMessage, &((vendor_ext_tlv_1 *)(*ve))->dummy, end))
+        return 0;
+
+      return 1;
+      break;
+  }
+
+  return -1;
+}
+
+int pnf_nr_phy_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  // printf("%s\n", __FUNCTION__);
+  (void)ve;
+  (void)ppWritePackedMsg;
+  return -1;
+}
 int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *config) {
   //NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_unpack_vendor_extension_tlv\n");
   switch(tl->tag) {
@@ -1601,6 +1689,27 @@ int pnf_sim_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMe
   return -1;
 }
 
+int pnf_nr_sim_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
+                                           uint8_t **ppReadPackedMessage,
+                                           uint8_t *end,
+                                           void **ve,
+                                           nfapi_p4_p5_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "pnf_sim_unpack_vendor_extension_tlv\n");
+  switch (tl->tag) {
+    case VENDOR_EXT_TLV_2_TAG:
+      *ve = malloc(sizeof(vendor_ext_tlv_2));
+
+      if (!pull32(ppReadPackedMessage, &((vendor_ext_tlv_2 *)(*ve))->dummy, end))
+        return 0;
+
+      return 1;
+      break;
+  }
+
+  return -1;
+}
+
 int pnf_sim_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
   //printf("%s\n", __FUNCTION__);
   (void)ve;
@@ -1609,11 +1718,18 @@ int pnf_sim_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint
   return -1;
 }
 
+int pnf_nr_sim_pack_vendor_extention_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config)
+{
+  // printf("%s\n", __FUNCTION__);
+  (void)ve;
+  (void)ppWritePackedMsg;
+
+  return -1;
+}
+
 nfapi_dl_config_request_t dummy_dl_config_req;
 nfapi_tx_request_t dummy_tx_req;
 
-nfapi_pnf_p7_subframe_buffer_t dummy_subframe;
-
 int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_start_request_t *req) {
   printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id);
   pnf_info *pnf = (pnf_info *)(config->user_data);
@@ -1674,12 +1790,8 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi
   memset(&dummy_tx_req, 0, sizeof(dummy_tx_req));
   dummy_tx_req.tx_request_body.number_of_pdus=0;
   dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG;
-  dummy_subframe.dl_config_req = &dummy_dl_config_req;
-  dummy_subframe.tx_req = 0;//&dummy_tx_req;
-  dummy_subframe.ul_config_req=0;
-  dummy_subframe.hi_dci0_req=0;
-  dummy_subframe.lbt_dl_config_req=0;
-  p7_config->dummy_subframe = dummy_subframe;
+  memset(&p7_config->dummy_subframe, 0, sizeof(p7_config->dummy_subframe));
+  p7_config->dummy_subframe.dl_config_req = &dummy_dl_config_req;
   p7_config->vendor_ext = &pnf_phy_vendor_ext;
   p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext;
   p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext;
@@ -1732,7 +1844,8 @@ int start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi
   return 0;
 }
 
-int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy,  nfapi_nr_start_request_scf_t *req) {
+int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nfapi_nr_start_request_scf_t *req)
+{
   printf("[PNF] Received NFAPI_START_REQ phy_id:%d\n", req->header.phy_id);
   pnf_info *pnf = (pnf_info *)(config->user_data);
   phy_info *phy_info = pnf->phys;
@@ -1743,7 +1856,11 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy,  n
 
   p7_config->local_p7_port = phy_info->udp.rx_port;
   p7_config->local_p7_addr = phy_info->local_addr;
-  printf("[PNF] P7 remote:%s:%d local:%s:%d\n", p7_config->remote_p7_addr, p7_config->remote_p7_port, p7_config->local_p7_addr, p7_config->local_p7_port);
+  printf("[PNF] P7 remote:%s:%d local:%s:%d\n",
+         p7_config->remote_p7_addr,
+         p7_config->remote_p7_port,
+         p7_config->local_p7_addr,
+         p7_config->local_p7_port);
   p7_config->user_data = phy_info;
   p7_config->malloc = &pnf_allocate;
   p7_config->free = &pnf_deallocate;
@@ -1755,19 +1872,19 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy,  n
   p7_config->slot_buffer_size = phy_info->timing_window; // TODO: check if correct for NR
   printf("subframe_buffer_size configured using phy_info->timing_window:%d\n", phy_info->timing_window);
 
-  if(phy_info->timing_info_mode & 0x1) {
+  if (phy_info->timing_info_mode & 0x1) {
     p7_config->timing_info_mode_periodic = 1;
     p7_config->timing_info_period = phy_info->timing_info_period;
   }
 
-  if(phy_info->timing_info_mode & 0x2) {
+  if (phy_info->timing_info_mode & 0x2) {
     p7_config->timing_info_mode_aperiodic = 1;
   }
 
   // NR
-  p7_config->dl_tti_req_fn  = &pnf_phy_dl_tti_req;
-  p7_config->ul_tti_req_fn  = &pnf_phy_ul_tti_req;
-  p7_config->ul_dci_req_fn  = &pnf_phy_ul_dci_req;
+  p7_config->dl_tti_req_fn = &pnf_phy_dl_tti_req;
+  p7_config->ul_tti_req_fn = &pnf_phy_ul_tti_req;
+  p7_config->ul_dci_req_fn = &pnf_phy_ul_dci_req;
   p7_config->tx_data_req_fn = &pnf_phy_tx_data_req;
 
   // LTE
@@ -1777,7 +1894,7 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy,  n
   p7_config->tx_req = &pnf_phy_tx_req;
   p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req;
   p7_config->ue_release_req = &pnf_phy_ue_release_req;
-  if (NFAPI_MODE==NFAPI_UE_STUB_PNF) {
+  if (NFAPI_MODE == NFAPI_UE_STUB_PNF) {
     p7_config->dl_config_req = NULL;
     p7_config->ul_config_req = NULL;
     p7_config->hi_dci0_req = NULL;
@@ -1791,29 +1908,25 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy,  n
 
   p7_config->lbt_dl_config_req = &pnf_phy_lbt_dl_config_req;
   memset(&dummy_dl_config_req, 0, sizeof(dummy_dl_config_req));
-  dummy_dl_config_req.dl_config_request_body.tl.tag=NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
-  dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols=1;
-  dummy_dl_config_req.dl_config_request_body.number_dci=0;
-  dummy_dl_config_req.dl_config_request_body.number_pdu=0;
-  dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti=0;
-  dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich=6000;
-  dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list=0;
+  dummy_dl_config_req.dl_config_request_body.tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+  dummy_dl_config_req.dl_config_request_body.number_pdcch_ofdm_symbols = 1;
+  dummy_dl_config_req.dl_config_request_body.number_dci = 0;
+  dummy_dl_config_req.dl_config_request_body.number_pdu = 0;
+  dummy_dl_config_req.dl_config_request_body.number_pdsch_rnti = 0;
+  dummy_dl_config_req.dl_config_request_body.transmission_power_pcfich = 6000;
+  dummy_dl_config_req.dl_config_request_body.dl_config_pdu_list = 0;
   memset(&dummy_tx_req, 0, sizeof(dummy_tx_req));
-  dummy_tx_req.tx_request_body.number_of_pdus=0;
-  dummy_tx_req.tx_request_body.tl.tag=NFAPI_TX_REQUEST_BODY_TAG;
-  dummy_subframe.dl_config_req = &dummy_dl_config_req;
-  dummy_subframe.tx_req = 0;//&dummy_tx_req;
-  dummy_subframe.ul_config_req=0;
-  dummy_subframe.hi_dci0_req=0;
-  dummy_subframe.lbt_dl_config_req=0;
-  p7_config->dummy_subframe = dummy_subframe;
-  p7_config->vendor_ext = &pnf_phy_vendor_ext;
-  p7_config->allocate_p7_vendor_ext = &pnf_phy_allocate_p7_vendor_ext;
-  p7_config->deallocate_p7_vendor_ext = &pnf_phy_deallocate_p7_vendor_ext;
-  p7_config->codec_config.unpack_p7_vendor_extension = &pnf_phy_unpack_p7_vendor_extension;
-  p7_config->codec_config.pack_p7_vendor_extension = &pnf_phy_pack_p7_vendor_extension;
-  p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_phy_unpack_vendor_extension_tlv;
-  p7_config->codec_config.pack_vendor_extension_tlv = &pnf_phy_pack_vendor_extention_tlv;
+  dummy_tx_req.tx_request_body.number_of_pdus = 0;
+  dummy_tx_req.tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
+  memset(&p7_config->dummy_subframe, 0, sizeof(p7_config->dummy_subframe));
+  p7_config->dummy_subframe.dl_config_req = &dummy_dl_config_req;
+  p7_config->vendor_ext = &pnf_nr_phy_vendor_ext;
+  p7_config->allocate_p7_vendor_ext = &pnf_nr_phy_allocate_p7_vendor_ext;
+  p7_config->deallocate_p7_vendor_ext = &pnf_nr_phy_deallocate_p7_vendor_ext;
+  p7_config->codec_config.unpack_p7_vendor_extension = &pnf_nr_phy_unpack_p7_vendor_extension;
+  p7_config->codec_config.pack_p7_vendor_extension = &pnf_nr_phy_pack_p7_vendor_extension;
+  p7_config->codec_config.unpack_vendor_extension_tlv = &pnf_nr_phy_unpack_vendor_extension_tlv;
+  p7_config->codec_config.pack_vendor_extension_tlv = &pnf_nr_phy_pack_vendor_extention_tlv;
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating P7 thread %s\n", __FUNCTION__);
   pthread_t p7_thread;
   threadCreate(&p7_thread, &pnf_nr_p7_thread_start, p7_config, "pnf_p7_thread", -1, OAI_PRIORITY_RT);
@@ -1823,24 +1936,24 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy,  n
   p7_config_g = p7_config;
 
   // Need to wait for main thread to create RU structures
-  while(config_sync_var<0) {
+  while (config_sync_var < 0) {
     usleep(5000000);
     printf("[PNF] waiting for OAI to be configured (eNB/RU)\n");
   }
 
   printf("[PNF] OAI eNB/RU configured\n");
-  //printf("[PNF] About to call phy_init_RU() for RC.ru[0]:%p\n", RC.ru[0]);
-  //phy_init_RU(RC.ru[0]);
+  // printf("[PNF] About to call phy_init_RU() for RC.ru[0]:%p\n", RC.ru[0]);
+  // phy_init_RU(RC.ru[0]);
   printf("[PNF] About to call init_eNB_afterRU()\n");
 
-  if (NFAPI_MODE!=NFAPI_UE_STUB_PNF) {
+  if (NFAPI_MODE != NFAPI_UE_STUB_PNF) {
     init_eNB_afterRU();
   }
 
   // Signal to main thread that it can carry on - otherwise RU will startup too quickly and it is not initialised
   {
     pthread_mutex_lock(&nfapi_sync_mutex);
-    nfapi_sync_var=0;
+    nfapi_sync_var = 0;
     pthread_cond_broadcast(&nfapi_sync_cond);
     pthread_mutex_unlock(&nfapi_sync_mutex);
   }
@@ -1860,8 +1973,7 @@ int nr_start_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy,  n
   nfapi_pnf_p7_subframe_ind(p7_config, p7_config->phy_id, 0); // SFN_SF set to zero - correct???
   printf("[PNF] Sent first P7 subframe ind\n");
 #endif
-  
-  
+
   return 0;
 }
 
@@ -2052,10 +2164,11 @@ int nmm_stop_request(nfapi_pnf_config_t *config, nfapi_pnf_phy_config_t *phy, nf
   return 0;
 }
 
-int vendor_ext(nfapi_pnf_config_t *config, nfapi_p4_p5_message_header_t *msg) {
+int vendor_ext(nfapi_pnf_config_t *config, void *msg)
+{
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 %s %p\n", __FUNCTION__, msg);
 
-  switch(msg->message_id) {
+  switch (((nfapi_p4_p5_message_header_t *)msg)->message_id) {
     case P5_VENDOR_EXT_REQ: {
       vendor_ext_p5_req *req = (vendor_ext_p5_req *)msg;
       NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2);
@@ -2065,15 +2178,35 @@ int vendor_ext(nfapi_pnf_config_t *config, nfapi_p4_p5_message_header_t *msg) {
       rsp.header.message_id = P5_VENDOR_EXT_RSP;
       rsp.error_code = NFAPI_MSG_OK;
       nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp));
-    }
-    break;
+    } break;
+  }
+
+  return 0;
+}
+
+int nr_vendor_ext(nfapi_pnf_config_t *config, void *msg)
+{
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 %s %p\n", __FUNCTION__, msg);
+
+  switch (((nfapi_nr_p4_p5_message_header_t *)msg)->message_id) {
+    case P5_VENDOR_EXT_REQ: {
+      vendor_ext_p5_req *req = (vendor_ext_p5_req *)msg;
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] P5 Vendor Ext Req (%d %d)\n", req->dummy1, req->dummy2);
+      // send back the P5_VENDOR_EXT_RSP
+      vendor_ext_p5_rsp rsp;
+      memset(&rsp, 0, sizeof(rsp));
+      rsp.header.message_id = P5_VENDOR_EXT_RSP;
+      rsp.error_code = NFAPI_MSG_OK;
+      nfapi_pnf_vendor_extension(config, &rsp.header, sizeof(vendor_ext_p5_rsp));
+    } break;
   }
 
   return 0;
 }
 
-nfapi_p4_p5_message_header_t *pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size) {
-  if(message_id == P5_VENDOR_EXT_REQ) {
+void *pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+{
+  if (message_id == P5_VENDOR_EXT_REQ) {
     (*msg_size) = sizeof(vendor_ext_p5_req);
     return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_req));
   }
@@ -2081,13 +2214,30 @@ nfapi_p4_p5_message_header_t *pnf_sim_allocate_p4_p5_vendor_ext(uint16_t message
   return 0;
 }
 
-void pnf_sim_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) {
+void *pnf_nr_sim_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+{
+  if (message_id == P5_VENDOR_EXT_REQ) {
+    (*msg_size) = sizeof(vendor_ext_p5_req);
+    return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_req));
+  }
+
+  return 0;
+}
+
+void pnf_sim_deallocate_p4_p5_vendor_ext(void *header)
+{
   free(header);
 }
 
-int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config) {
-  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if(header->message_id == P5_VENDOR_EXT_RSP) {
+void pnf_nr_sim_deallocate_p4_p5_vendor_ext(void *header)
+{
+  free(header);
+}
+
+int pnf_sim_pack_p4_p5_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_RSP) {
     vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)(header);
     return (!push16(rsp->error_code, ppWritePackedMsg, end));
   }
@@ -2095,13 +2245,45 @@ int pnf_sim_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, ui
   return 0;
 }
 
-int pnf_sim_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) {
-  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if(header->message_id == P5_VENDOR_EXT_REQ) {
+int pnf_nr_sim_pack_p4_p5_vendor_extension(void *header,
+                                           uint8_t **ppWritePackedMsg,
+                                           uint8_t *end,
+                                           nfapi_p4_p5_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_nr_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_RSP) {
+    vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)(header);
+    return (!push16(rsp->error_code, ppWritePackedMsg, end));
+  }
+
+  return 0;
+}
+
+int pnf_sim_unpack_p4_p5_vendor_extension(void *header,
+                                          uint8_t **ppReadPackedMessage,
+                                          uint8_t *end,
+                                          nfapi_p4_p5_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_REQ) {
+    vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
+    return (!(pull16(ppReadPackedMessage, &req->dummy1, end) && pull16(ppReadPackedMessage, &req->dummy2, end)));
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2);
+  }
+
+  return 0;
+}
+
+int pnf_nr_sim_unpack_p4_p5_vendor_extension(void *header,
+                                             uint8_t **ppReadPackedMessage,
+                                             uint8_t *end,
+                                             nfapi_p4_p5_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_nr_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_REQ) {
     vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
-    return (!(pull16(ppReadPackedMessage, &req->dummy1, end) &&
-              pull16(ppReadPackedMessage, &req->dummy2, end)));
-    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2);
+    return (!(pull16(ppReadPackedMessage, &req->dummy1, end) && pull16(ppReadPackedMessage, &req->dummy2, end)));
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s (%d %d)\n", __FUNCTION__, req->dummy1, req->dummy2);
   }
 
   return 0;
@@ -2128,9 +2310,10 @@ void *pnf_nr_start_thread(void *ptr) {
   return (void *)0;
 }
 
-void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) {
+void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port)
+{
   printf("%s() PNF\n\n\n\n\n\n", __FUNCTION__);
-    nfapi_setmode(NFAPI_MODE_PNF);  // PNF!
+  nfapi_setmode(NFAPI_MODE_PNF); // PNF!
 
   nfapi_pnf_config_t *config = nfapi_pnf_config_create();
   config->vnf_ip_addr = vnf_ip_addr;
@@ -2149,9 +2332,8 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
          pnf.phys[0].udp.tx_port,
          pnf.phys[0].udp.rx_port);
   config->cell_search_req = &cell_search_request;
-         
-    
-  //config->pnf_nr_param_req = &pnf_nr_param_request;
+
+  // config->pnf_nr_param_req = &pnf_nr_param_request;
   config->pnf_nr_param_req = &pnf_nr_param_request;
   config->pnf_nr_config_req = &pnf_nr_config_request;
   config->pnf_nr_start_req = &pnf_nr_start_request;
@@ -2159,22 +2341,21 @@ void configure_nr_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_add
   config->nr_param_req = &nr_param_request;
   config->nr_config_req = &nr_config_request;
   config->nr_start_req = &nr_start_request;
-  config->measurement_req = &measurement_request;
   config->rssi_req = &rssi_request;
   config->broadcast_detect_req = &broadcast_detect_request;
   config->system_information_schedule_req = &system_information_schedule_request;
   config->system_information_req = &system_information_request;
   config->nmm_stop_req = &nmm_stop_request;
-  config->vendor_ext = &vendor_ext;
+  config->vendor_ext = &nr_vendor_ext;
   config->trace = &pnf_nfapi_trace;
   config->user_data = &pnf;
   // To allow custom vendor extentions to be added to nfapi
-  config->codec_config.unpack_vendor_extension_tlv = &pnf_sim_unpack_vendor_extension_tlv;
-  config->codec_config.pack_vendor_extension_tlv = &pnf_sim_pack_vendor_extention_tlv;
-  config->allocate_p4_p5_vendor_ext = &pnf_sim_allocate_p4_p5_vendor_ext;
-  config->deallocate_p4_p5_vendor_ext = &pnf_sim_deallocate_p4_p5_vendor_ext;
-  config->codec_config.unpack_p4_p5_vendor_extension = &pnf_sim_unpack_p4_p5_vendor_extension;
-  config->codec_config.pack_p4_p5_vendor_extension = &pnf_sim_pack_p4_p5_vendor_extension;
+  config->codec_config.unpack_vendor_extension_tlv = &pnf_nr_sim_unpack_vendor_extension_tlv;
+  config->codec_config.pack_vendor_extension_tlv = &pnf_nr_sim_pack_vendor_extention_tlv;
+  config->allocate_p4_p5_vendor_ext = &pnf_nr_sim_allocate_p4_p5_vendor_ext;
+  config->deallocate_p4_p5_vendor_ext = &pnf_nr_sim_deallocate_p4_p5_vendor_ext;
+  config->codec_config.unpack_p4_p5_vendor_extension = &pnf_nr_sim_unpack_p4_p5_vendor_extension;
+  config->codec_config.pack_p4_p5_vendor_extension = &pnf_nr_sim_pack_p4_p5_vendor_extension;
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[PNF] Creating PNF NFAPI start thread %s\n", __FUNCTION__);
   pthread_create(&pnf_start_pthread, NULL, &pnf_nr_start_thread, config);
   pthread_setname_np(pnf_start_pthread, "NFAPI_PNF");
diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
index c742a7088a609b23de6fb74318249d9f41cdbd95..76542d3587e3efeb9abd9998fceb9f0f10460076 100644
--- a/nfapi/oai_integration/nfapi_vnf.c
+++ b/nfapi/oai_integration/nfapi_vnf.c
@@ -47,6 +47,9 @@
 #include "common/ran_context.h"
 #include "openair2/PHY_INTERFACE/queue_t.h"
 #include "gnb_ind_vars.h"
+#include "nr_fapi_p7_utils.h"
+#include <NR_MAC_gNB/mac_proto.h>
+
 
 #define TEST
 
@@ -195,9 +198,36 @@ int vnf_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t
   return -1;
 }
 
+int vnf_nr_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "vnf_pack_vendor_extension_tlv\n");
+  nfapi_tl_t *tlv = (nfapi_tl_t *)ve;
+
+  switch (tlv->tag) {
+    case VENDOR_EXT_TLV_2_TAG: {
+      // NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_2\n");
+      vendor_ext_tlv_2 *ve = (vendor_ext_tlv_2 *)tlv;
+
+      if (!push32(ve->dummy, ppWritePackedMsg, end))
+        return 0;
+
+      return 1;
+    } break;
+  }
+
+  return -1;
+}
 int vnf_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessage, uint8_t *end, void **ve, nfapi_p4_p5_codec_config_t *codec) {
   return -1;
 }
+int vnf_nr_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
+                                       uint8_t **ppReadPackedMessage,
+                                       uint8_t *end,
+                                       void **ve,
+                                       nfapi_p4_p5_codec_config_t *codec)
+{
+  return -1;
+}
 void install_nr_schedule_handlers(NR_IF_Module_t *if_inst);
 void install_schedule_handlers(IF_Module_t *if_inst);
 extern uint16_t sf_ahead;
@@ -718,35 +748,15 @@ int phy_rach_indication(struct nfapi_vnf_p7_config *config, nfapi_rach_indicatio
 
 int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind)
 {
-  if(NFAPI_MODE == NFAPI_MODE_VNF)
-  {
+  if (NFAPI_MODE == NFAPI_MODE_VNF) {
     nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind));
-    rach_ind->header.message_id = ind->header.message_id;
-    rach_ind->number_of_pdus = ind->number_of_pdus;
-    rach_ind->sfn = ind->sfn;
-    rach_ind->slot = ind->slot;
-    rach_ind->pdu_list = CALLOC(rach_ind->number_of_pdus, sizeof(*rach_ind->pdu_list));
-    AssertFatal(rach_ind->pdu_list != NULL, "Memory not allocated for rach_ind->pdu_list in phy_nr_rach_indication.");
-    for (int i = 0; i < ind->number_of_pdus; i++)
-    {
-      rach_ind->pdu_list[i].num_preamble = ind->pdu_list[i].num_preamble;
-      rach_ind->pdu_list[i].freq_index = ind->pdu_list[i].freq_index;
-      rach_ind->pdu_list[i].symbol_index = ind->pdu_list[i].symbol_index;
-      AssertFatal(rach_ind->pdu_list[i].preamble_list != NULL, "Memory not allocated for rach_ind->pdu_list[i].preamble_list  in phy_nr_rach_indication.");
-      for (int j = 0; j < ind->number_of_pdus; j++)
-      {
-        rach_ind->pdu_list[i].preamble_list[j].preamble_index = ind->pdu_list[i].preamble_list[j].preamble_index;
-        rach_ind->pdu_list[i].preamble_list[j].timing_advance = ind->pdu_list[i].preamble_list[j].timing_advance;
-      }
-    }
-    if (!put_queue(&gnb_rach_ind_queue, rach_ind))
-    {
+    copy_rach_indication(ind, rach_ind);
+    if (!put_queue(&gnb_rach_ind_queue, rach_ind)) {
       LOG_E(NR_MAC, "Put_queue failed for rach_ind\n");
-      free(rach_ind->pdu_list);
+      free_rach_indication(rach_ind);
       free(rach_ind);
     }
-  }
-  else {
+  } else {
     LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode());
   }
   return 1;
@@ -754,84 +764,18 @@ int phy_nr_rach_indication(nfapi_nr_rach_indication_t *ind)
 
 int phy_nr_uci_indication(nfapi_nr_uci_indication_t *ind)
 {
-
-  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n",
-          __FUNCTION__,ind->sfn, ind->slot, ind->num_ucis);
-  if(NFAPI_MODE == NFAPI_MODE_VNF)
-  {
+  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n", __FUNCTION__, ind->sfn, ind->slot, ind->num_ucis);
+  if (NFAPI_MODE == NFAPI_MODE_VNF) {
     nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind));
     AssertFatal(uci_ind, "Memory not allocated for uci_ind in phy_nr_uci_indication.");
-    *uci_ind = *ind;
-
-    uci_ind->uci_list = CALLOC(NFAPI_NR_UCI_IND_MAX_PDU, sizeof(nfapi_nr_uci_t));
-    AssertFatal(uci_ind->uci_list != NULL, "Memory not allocated for uci_ind->uci_list in phy_nr_uci_indication.");
-    for (int i = 0; i < ind->num_ucis; i++)
-    {
-      uci_ind->uci_list[i] = ind->uci_list[i];
-
-      switch (uci_ind->uci_list[i].pdu_type) {
-        case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
-          LOG_E(MAC, "%s(): unhandled NFAPI_NR_UCI_PUSCH_PDU_TYPE\n", __func__);
-          break;
-
-        case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
-          //nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_0_1;
-          //nfapi_nr_uci_pucch_pdu_format_0_1_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_0_1;
-          //Unused
-          break;
-        }
-
-        case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
-          nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_ind_pdu = &uci_ind->uci_list[i].pucch_pdu_format_2_3_4;
-          nfapi_nr_uci_pucch_pdu_format_2_3_4_t *ind_pdu = &ind->uci_list[i].pucch_pdu_format_2_3_4;
-          *uci_ind_pdu = *ind_pdu;
-          if (ind_pdu->harq.harq_payload) {
-            uci_ind_pdu->harq.harq_payload = CALLOC(1, sizeof(*uci_ind_pdu->harq.harq_payload));
-            AssertFatal(uci_ind_pdu->harq.harq_payload != NULL, "Memory not allocated for uci_ind_pdu->harq.harq_payload in phy_nr_uci_indication.");
-            *uci_ind_pdu->harq.harq_payload = *ind_pdu->harq.harq_payload;
-          }
-          if (ind_pdu->sr.sr_payload) {
-            uci_ind_pdu->sr.sr_payload = CALLOC(1, sizeof(*uci_ind_pdu->sr.sr_payload));
-            AssertFatal(uci_ind_pdu->sr.sr_payload != NULL, "Memory not allocated for uci_ind_pdu->sr.sr_payload in phy_nr_uci_indication.");
-            *uci_ind_pdu->sr.sr_payload = *ind_pdu->sr.sr_payload;
-          }
-          if (ind_pdu->csi_part1.csi_part1_payload) {
-            uci_ind_pdu->csi_part1.csi_part1_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part1.csi_part1_payload));
-            AssertFatal(uci_ind_pdu->csi_part1.csi_part1_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part1.csi_part1_payload in phy_nr_uci_indication.");
-            *uci_ind_pdu->csi_part1.csi_part1_payload = *ind_pdu->csi_part1.csi_part1_payload;
-          }
-          if (ind_pdu->csi_part2.csi_part2_payload) {
-            uci_ind_pdu->csi_part2.csi_part2_payload = CALLOC(1, sizeof(*uci_ind_pdu->csi_part2.csi_part2_payload));
-            AssertFatal(uci_ind_pdu->csi_part2.csi_part2_payload != NULL, "Memory not allocated for uci_ind_pdu->csi_part2.csi_part2_payload in phy_nr_uci_indication.");
-            *uci_ind_pdu->csi_part2.csi_part2_payload = *ind_pdu->csi_part2.csi_part2_payload;
-          }
-          break;
-        }
-      }
-    }
-
-    if (!put_queue(&gnb_uci_ind_queue, uci_ind))
-    {
+    copy_uci_indication(ind, uci_ind);
+    if (!put_queue(&gnb_uci_ind_queue, uci_ind)) {
       LOG_E(NR_MAC, "Put_queue failed for uci_ind\n");
-      for (int i = 0; i < ind->num_ucis; i++)
-      {
-          if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE)
-          {
-          }
-          if (uci_ind->uci_list[i].pdu_type == NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE)
-          {
-            free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.harq.harq_payload);
-            free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part1.csi_part1_payload);
-            free(uci_ind->uci_list[i].pucch_pdu_format_2_3_4.csi_part2.csi_part2_payload);
-          }
-      }
-      free(uci_ind->uci_list);
-      uci_ind->uci_list = NULL;
+      free_uci_indication(uci_ind);
       free(uci_ind);
       uci_ind = NULL;
     }
-  }
-  else {
+  } else {
     LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode());
   }
   return 1;
@@ -922,43 +866,19 @@ int phy_crc_indication(struct nfapi_vnf_p7_config *config, nfapi_crc_indication_
   return 1;
 }
 
-int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind) {
-
-  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n",
-          __FUNCTION__,ind->sfn, ind->slot, ind->number_crcs);
+int phy_nr_crc_indication(nfapi_nr_crc_indication_t *ind)
+{
+  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u\n", __FUNCTION__, ind->sfn, ind->slot, ind->number_crcs);
 
-  if(NFAPI_MODE == NFAPI_MODE_VNF)
-  {
+  if (NFAPI_MODE == NFAPI_MODE_VNF) {
     nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind));
-    crc_ind->header.message_id = ind->header.message_id;
-    crc_ind->number_crcs = ind->number_crcs;
-    crc_ind->sfn = ind->sfn;
-    crc_ind->slot = ind->slot;
-    if (ind->number_crcs > 0) {
-      crc_ind->crc_list = CALLOC(NFAPI_NR_CRC_IND_MAX_PDU, sizeof(nfapi_nr_crc_t));
-      AssertFatal(crc_ind->crc_list != NULL, "Memory not allocated for crc_ind->crc_list in phy_nr_crc_indication.");
-    }
-    for (int j = 0; j < ind->number_crcs; j++)
-    {
-      crc_ind->crc_list[j].handle = ind->crc_list[j].handle;
-      crc_ind->crc_list[j].harq_id = ind->crc_list[j].harq_id;
-      crc_ind->crc_list[j].num_cb = ind->crc_list[j].num_cb;
-      crc_ind->crc_list[j].rnti = ind->crc_list[j].rnti;
-      crc_ind->crc_list[j].tb_crc_status = ind->crc_list[j].tb_crc_status;
-      crc_ind->crc_list[j].timing_advance = ind->crc_list[j].timing_advance;
-      crc_ind->crc_list[j].ul_cqi = ind->crc_list[j].ul_cqi;
-      LOG_D(NR_MAC, "Received crc_ind.harq_id = %d for %d index SFN SLot %u %u with rnti %x\n",
-                    ind->crc_list[j].harq_id, j, ind->sfn, ind->slot, ind->crc_list[j].rnti);
-    }
-    if (!put_queue(&gnb_crc_ind_queue, crc_ind))
-    {
+    copy_crc_indication(ind, crc_ind);
+    if (!put_queue(&gnb_crc_ind_queue, crc_ind)) {
       LOG_E(NR_MAC, "Put_queue failed for crc_ind\n");
-      free(crc_ind->crc_list);
+      free_crc_indication(crc_ind);
       free(crc_ind);
     }
-  }
-  else
-  {
+  } else {
     LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode());
   }
   return 1;
@@ -1041,43 +961,25 @@ int phy_rx_indication(struct nfapi_vnf_p7_config *config, nfapi_rx_indication_t
   return 1;
 }
 
-int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind) {
-
-  LOG_D(NR_MAC, "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u, and pdu %p\n",
-          __FUNCTION__,ind->sfn, ind->slot, ind->number_of_pdus, ind->pdu_list[0].pdu);
+int phy_nr_rx_data_indication(nfapi_nr_rx_data_indication_t *ind)
+{
+  LOG_D(NR_MAC,
+        "In %s() NFAPI SFN/SF: %d/%d number_of_pdus :%u, and pdu %p\n",
+        __FUNCTION__,
+        ind->sfn,
+        ind->slot,
+        ind->number_of_pdus,
+        ind->pdu_list[0].pdu);
 
-  if(NFAPI_MODE == NFAPI_MODE_VNF)
-  {
+  if (NFAPI_MODE == NFAPI_MODE_VNF) {
     nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind));
-    rx_ind->header.message_id = ind->header.message_id;
-    rx_ind->sfn = ind->sfn;
-    rx_ind->slot = ind->slot;
-    rx_ind->number_of_pdus = ind->number_of_pdus;
-
-    if (ind->number_of_pdus > 0) {
-      rx_ind->pdu_list = CALLOC(NFAPI_NR_RX_DATA_IND_MAX_PDU, sizeof(nfapi_nr_rx_data_pdu_t));
-      AssertFatal(rx_ind->pdu_list != NULL, "Memory not allocated for rx_ind->pdu_list in phy_nr_rx_data_indication.");
-    }
-    for (int j = 0; j < ind->number_of_pdus; j++)
-    {
-      rx_ind->pdu_list[j].handle = ind->pdu_list[j].handle;
-      rx_ind->pdu_list[j].harq_id = ind->pdu_list[j].harq_id;
-      rx_ind->pdu_list[j].pdu = ind->pdu_list[j].pdu;
-      rx_ind->pdu_list[j].pdu_length = ind->pdu_list[j].pdu_length;
-      rx_ind->pdu_list[j].rnti = ind->pdu_list[j].rnti;
-      rx_ind->pdu_list[j].timing_advance = ind->pdu_list[j].timing_advance;
-      rx_ind->pdu_list[j].ul_cqi = ind->pdu_list[j].ul_cqi;
-      rx_ind->pdu_list[j].rssi = ind->pdu_list[j].rssi;
-    }
-    if (!put_queue(&gnb_rx_ind_queue, rx_ind))
-    {
+    copy_rx_data_indication(ind, rx_ind);
+    if (!put_queue(&gnb_rx_ind_queue, rx_ind)) {
       LOG_E(NR_MAC, "Put_queue failed for rx_ind\n");
-      free(rx_ind->pdu_list);
+      free_rx_data_indication(rx_ind);
       free(rx_ind);
     }
-  }
-  else
-  {
+  } else {
     LOG_E(NR_MAC, "NFAPI_MODE = %d not NFAPI_MODE_VNF(2)\n", nfapi_getmode());
   }
   return 1;
@@ -1238,24 +1140,10 @@ int phy_nr_slot_indication(nfapi_nr_slot_indication_scf_t *ind) {
   return 1;
 }
 
-
-int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind) {
-  struct PHY_VARS_gNB_s *gNB = RC.gNB[0];
-
-  gNB->UL_INFO.srs_ind = *ind;
-
-  if (ind->number_of_pdus > 0)
-    gNB->UL_INFO.srs_ind.pdu_list = malloc(sizeof(nfapi_nr_srs_indication_pdu_t)*ind->number_of_pdus);
-
-  for (int i=0; i<ind->number_of_pdus; i++) {
-    memcpy(&gNB->UL_INFO.srs_ind.pdu_list[i], &ind->pdu_list[i], sizeof(ind->pdu_list[0]));
-
-    LOG_D(MAC, "%s() NFAPI SFN/Slot:%d.%d SRS_IND:number_of_pdus:%d UL_INFO:pdus:%d\n",
-        __FUNCTION__,
-        ind->sfn,ind->slot, ind->number_of_pdus, gNB->UL_INFO.srs_ind.number_of_pdus
-        );
-  }
-
+int phy_nr_srs_indication(nfapi_nr_srs_indication_t *ind)
+{
+  for (int i = 0; i < ind->number_of_pdus; ++i)
+    handle_nr_srs_measurements(0, ind->sfn, ind->slot, &ind->pdu_list[i]);
   return 1;
 }
 //end NR phy indication
@@ -1288,6 +1176,17 @@ void vnf_deallocate(void *ptr) {
   free(ptr);
 }
 
+void *vnf_nr_allocate(size_t size)
+{
+  // return (void*)memory_pool::allocate(size);
+  return (void *)malloc(size);
+}
+
+void vnf_nr_deallocate(void *ptr)
+{
+  // memory_pool::deallocate((uint8_t*)ptr);
+  free(ptr);
+}
 
 void vnf_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) {
   va_list args;
@@ -1296,18 +1195,31 @@ void vnf_trace(nfapi_trace_level_t nfapi_level, const char *message, ...) {
   va_end(args);
 }
 
-int phy_vendor_ext(struct nfapi_vnf_p7_config *config, nfapi_p7_message_header_t *msg) {
-  if(msg->message_id == P7_VENDOR_EXT_IND) {
-    //vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg;
-    //NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] vendor_ext (error_code:%d)\n", ind->error_code);
+int phy_vendor_ext(struct nfapi_vnf_p7_config *config, void *msg)
+{
+  if (((nfapi_p7_message_header_t *)msg)->message_id == P7_VENDOR_EXT_IND) {
+    // vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg;
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] vendor_ext (error_code:%d)\n", ind->error_code);
+  } else {
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] unknown %02x\n", ((nfapi_p7_message_header_t *)msg)->message_id);
+  }
+
+  return 0;
+}
+
+int phy_nr_vendor_ext(struct nfapi_vnf_p7_config *config, void *msg)
+{
+  if (((nfapi_nr_p7_message_header_t *)msg)->message_id == P7_VENDOR_EXT_IND) {
+    // vendor_ext_p7_ind* ind = (vendor_ext_p7_ind*)msg;
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] vendor_ext (error_code:%d)\n", ind->error_code);
   } else {
-    NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] unknown %02x\n", msg->message_id);
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] unknown %02x\n", ((nfapi_nr_p7_message_header_t *)msg)->message_id);
   }
 
   return 0;
 }
 
-nfapi_p7_message_header_t *phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) {
+void *phy_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size) {
   if(message_id == P7_VENDOR_EXT_IND) {
     *msg_size = sizeof(vendor_ext_p7_ind);
     return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind));
@@ -1316,7 +1228,23 @@ nfapi_p7_message_header_t *phy_allocate_p7_vendor_ext(uint16_t message_id, uint1
   return 0;
 }
 
-void phy_deallocate_p7_vendor_ext(nfapi_p7_message_header_t *header) {
+void phy_deallocate_p7_vendor_ext(void *header)
+{
+  free(header);
+}
+
+void *phy_nr_allocate_p7_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+{
+  if (message_id == P7_VENDOR_EXT_IND) {
+    *msg_size = sizeof(vendor_ext_p7_ind);
+    return (nfapi_p7_message_header_t *)malloc(sizeof(vendor_ext_p7_ind));
+  }
+
+  return 0;
+}
+
+void phy_nr_deallocate_p7_vendor_ext(void *header)
+{
   free(header);
 }
 
@@ -1327,6 +1255,18 @@ int phy_unpack_vendor_extension_tlv(nfapi_tl_t *tl, uint8_t **ppReadPackedMessag
   return -1;
 }
 
+int phy_nr_unpack_vendor_extension_tlv(nfapi_tl_t *tl,
+                                       uint8_t **ppReadPackedMessage,
+                                       uint8_t *end,
+                                       void **ve,
+                                       nfapi_p7_codec_config_t *codec)
+{
+  (void)tl;
+  (void)ppReadPackedMessage;
+  (void)ve;
+  return -1;
+}
+
 int phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec) {
   //NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n");
   nfapi_tl_t *tlv = (nfapi_tl_t *)ve;
@@ -1349,39 +1289,100 @@ int phy_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t
   }
 }
 
-int phy_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *config) {
-  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if(header->message_id == P7_VENDOR_EXT_IND) {
+int phy_nr_pack_vendor_extension_tlv(void *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "phy_pack_vendor_extension_tlv\n");
+  nfapi_tl_t *tlv = (nfapi_tl_t *)ve;
+
+  switch (tlv->tag) {
+    case VENDOR_EXT_TLV_1_TAG: {
+      // NFAPI_TRACE(NFAPI_TRACE_INFO, "Packing VENDOR_EXT_TLV_1\n");
+      vendor_ext_tlv_1 *ve = (vendor_ext_tlv_1 *)tlv;
+
+      if (!push32(ve->dummy, ppWritePackedMsg, end))
+        return 0;
+
+      return 1;
+    } break;
+
+    default:
+      return -1;
+      break;
+  }
+}
+int phy_unpack_p7_vendor_extension(void *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_IND) {
+    vendor_ext_p7_ind *req = (vendor_ext_p7_ind *)(header);
+
+    if (!pull16(ppReadPackedMessage, &req->error_code, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+int phy_nr_unpack_p7_vendor_extension(void *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_nr_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_IND) {
     vendor_ext_p7_ind *req = (vendor_ext_p7_ind *)(header);
 
-    if(!pull16(ppReadPackedMessage, &req->error_code, end))
+    if (!pull16(ppReadPackedMessage, &req->error_code, end))
       return 0;
   }
 
   return 1;
 }
 
-int phy_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
-  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if(header->message_id == P7_VENDOR_EXT_REQ) {
-    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+int phy_pack_p7_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_REQ) {
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
     vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header);
 
-    if(!(push16(req->dummy1, ppWritePackedMsg, end) &&
-         push16(req->dummy2, ppWritePackedMsg, end)))
+    if (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)))
       return 0;
   }
 
   return 1;
 }
 
-int vnf_pack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) {
-  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if(header->message_id == P5_VENDOR_EXT_REQ) {
+int phy_nr_pack_p7_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_nr_p7_message_header_t *)header)->message_id == P7_VENDOR_EXT_REQ) {
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+    vendor_ext_p7_req *req = (vendor_ext_p7_req *)(header);
+
+    if (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)))
+      return 0;
+  }
+
+  return 1;
+}
+
+int vnf_pack_p4_p5_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_REQ) {
+    vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2);
+    return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)));
+  }
+
+  return 0;
+}
+
+int vnf_nr_pack_p4_p5_vendor_extension(void *header, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_nr_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_REQ) {
     vendor_ext_p5_req *req = (vendor_ext_p5_req *)(header);
-    //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2);
-    return (!(push16(req->dummy1, ppWritePackedMsg, end) &&
-              push16(req->dummy2, ppWritePackedMsg, end)));
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s %d %d\n", __FUNCTION__, req->dummy1, req->dummy2);
+    return (!(push16(req->dummy1, ppWritePackedMsg, end) && push16(req->dummy2, ppWritePackedMsg, end)));
   }
 
   return 0;
@@ -1406,7 +1407,8 @@ void *vnf_p7_start_thread(void *ptr) {
   return config;
 }
 
-void *vnf_nr_p7_thread_start(void *ptr) {
+void *vnf_nr_p7_thread_start(void *ptr)
+{
   init_queue(&gnb_rach_ind_queue);
   init_queue(&gnb_rx_ind_queue);
   init_queue(&gnb_crc_ind_queue);
@@ -1432,17 +1434,17 @@ void *vnf_nr_p7_thread_start(void *ptr) {
   p7_vnf->config->nr_srs_indication = &phy_nr_srs_indication;
   p7_vnf->config->malloc = &vnf_allocate;
   p7_vnf->config->free = &vnf_deallocate;
-  p7_vnf->config->vendor_ext = &phy_vendor_ext;
+  p7_vnf->config->vendor_ext = &phy_nr_vendor_ext;
   p7_vnf->config->user_data = p7_vnf;
   p7_vnf->mac->user_data = p7_vnf;
-  p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_unpack_p7_vendor_extension;
-  p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_pack_p7_vendor_extension;
-  p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_unpack_vendor_extension_tlv;
-  p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_pack_vendor_extension_tlv;
+  p7_vnf->config->codec_config.unpack_p7_vendor_extension = &phy_nr_unpack_p7_vendor_extension;
+  p7_vnf->config->codec_config.pack_p7_vendor_extension = &phy_nr_pack_p7_vendor_extension;
+  p7_vnf->config->codec_config.unpack_vendor_extension_tlv = &phy_nr_unpack_vendor_extension_tlv;
+  p7_vnf->config->codec_config.pack_vendor_extension_tlv = &phy_nr_pack_vendor_extension_tlv;
   p7_vnf->config->codec_config.allocate = &vnf_allocate;
   p7_vnf->config->codec_config.deallocate = &vnf_deallocate;
-  p7_vnf->config->allocate_p7_vendor_ext = &phy_allocate_p7_vendor_ext;
-  p7_vnf->config->deallocate_p7_vendor_ext = &phy_deallocate_p7_vendor_ext;
+  p7_vnf->config->allocate_p7_vendor_ext = &phy_nr_allocate_p7_vendor_ext;
+  p7_vnf->config->deallocate_p7_vendor_ext = &phy_nr_deallocate_p7_vendor_ext;
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI P7 start thread %s\n", __FUNCTION__);
   pthread_create(&vnf_p7_start_pthread, NULL, &vnf_nr_p7_start_thread, p7_vnf->config);
   return 0;
@@ -1696,10 +1698,11 @@ int nr_start_resp_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_nr_start_resp
   return 0;
 }
 
-int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_header_t *msg) {
+int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, void *msg)
+{
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__);
 
-  switch(msg->message_id) {
+  switch (((nfapi_p4_p5_message_header_t *)msg)->message_id) {
     case P5_VENDOR_EXT_RSP: {
       vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg;
       NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
@@ -1708,25 +1711,58 @@ int vendor_ext_cb(nfapi_vnf_config_t *config, int p5_idx, nfapi_p4_p5_message_he
       memset(&req, 0, sizeof(req));
       req.header.message_id = NFAPI_PNF_START_REQUEST;
       nfapi_vnf_pnf_start_req(config, p5_idx, &req);
-    }
-    break;
+    } break;
+  }
+
+  return 0;
+}
+
+int vendor_nr_ext_cb(nfapi_vnf_config_t *config, int p5_idx, void *msg)
+{
+  NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s\n", __FUNCTION__);
+
+  switch (((nfapi_nr_p4_p5_message_header_t *)msg)->message_id) {
+    case P5_VENDOR_EXT_RSP: {
+      vendor_ext_p5_rsp *rsp = (vendor_ext_p5_rsp *)msg;
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] P5_VENDOR_EXT_RSP error_code:%d\n", rsp->error_code);
+      // send the start request
+      nfapi_nr_pnf_start_request_t req = {0};
+      req.header.message_id = NFAPI_PNF_START_REQUEST;
+      nfapi_nr_vnf_pnf_start_req(config, p5_idx, &req);
+    } break;
   }
 
   return 0;
 }
 
-int vnf_unpack_p4_p5_vendor_extension(nfapi_p4_p5_message_header_t *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t *codec) {
-  //NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
-  if(header->message_id == P5_VENDOR_EXT_RSP) {
+int vnf_unpack_p4_p5_vendor_extension(void *header, uint8_t **ppReadPackedMessage, uint8_t *end, nfapi_p4_p5_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_RSP) {
     vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header);
-    return(!pull16(ppReadPackedMessage, &req->error_code, end));
+    return (!pull16(ppReadPackedMessage, &req->error_code, end));
   }
 
   return 0;
 }
 
-nfapi_p4_p5_message_header_t *vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size) {
-  if(message_id == P5_VENDOR_EXT_RSP) {
+int vnf_nr_unpack_p4_p5_vendor_extension(void *header,
+                                         uint8_t **ppReadPackedMessage,
+                                         uint8_t *end,
+                                         nfapi_p4_p5_codec_config_t *codec)
+{
+  // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
+  if (((nfapi_nr_p4_p5_message_header_t *)header)->message_id == P5_VENDOR_EXT_RSP) {
+    vendor_ext_p5_rsp *req = (vendor_ext_p5_rsp *)(header);
+    return (!pull16(ppReadPackedMessage, &req->error_code, end));
+  }
+
+  return 0;
+}
+
+void *vnf_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+{
+  if (message_id == P5_VENDOR_EXT_RSP) {
     *msg_size = sizeof(vendor_ext_p5_rsp);
     return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp));
   }
@@ -1734,10 +1770,26 @@ nfapi_p4_p5_message_header_t *vnf_allocate_p4_p5_vendor_ext(uint16_t message_id,
   return 0;
 }
 
-void vnf_deallocate_p4_p5_vendor_ext(nfapi_p4_p5_message_header_t *header) {
+void vnf_deallocate_p4_p5_vendor_ext(void *header)
+{
   free(header);
 }
 
+void *vnf_nr_allocate_p4_p5_vendor_ext(uint16_t message_id, uint16_t *msg_size)
+{
+  if (message_id == P5_VENDOR_EXT_RSP) {
+    *msg_size = sizeof(vendor_ext_p5_rsp);
+    return (nfapi_p4_p5_message_header_t *)malloc(sizeof(vendor_ext_p5_rsp));
+  }
+
+  return 0;
+}
+
+void vnf_nr_deallocate_p4_p5_vendor_ext(void *header) {
+  free(header);
+}
+
+
 nfapi_vnf_config_t *config = 0;
 
 void vnf_nr_start_thread(void *ptr) {
@@ -1756,7 +1808,8 @@ void vnf_start_thread(void *ptr) {
 
 static vnf_info vnf;
 
-void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port) {
+void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port)
+{
   nfapi_setmode(NFAPI_MODE_VNF);
   memset(&vnf, 0, sizeof(vnf));
   memset(vnf.p7_vnfs, 0, sizeof(vnf.p7_vnfs));
@@ -1765,7 +1818,12 @@ void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr,
   vnf.p7_vnfs[0].aperiodic_timing_enabled = 0;
   vnf.p7_vnfs[0].periodic_timing_period = 10;
   vnf.p7_vnfs[0].config = nfapi_vnf_p7_config_create();
-  NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n", __FUNCTION__, vnf.p7_vnfs[0].config, vnf_addr, vnf_p5_port);
+  NFAPI_TRACE(NFAPI_TRACE_INFO,
+              "[VNF] %s() vnf.p7_vnfs[0].config:%p VNF ADDRESS:%s:%d\n",
+              __FUNCTION__,
+              vnf.p7_vnfs[0].config,
+              vnf_addr,
+              vnf_p5_port);
   strcpy(vnf.p7_vnfs[0].local_addr, vnf_addr);
   vnf.p7_vnfs[0].local_port = vnf_p7_port;
   vnf.p7_vnfs[0].mac = (mac_t *)malloc(sizeof(mac_t));
@@ -1787,18 +1845,18 @@ void configure_nr_nfapi_vnf(char *vnf_addr, int vnf_p5_port, char *pnf_ip_addr,
   config->nr_param_resp = &nr_param_resp_cb;
   config->nr_config_resp = &nr_config_resp_cb;
   config->nr_start_resp = &nr_start_resp_cb;
-  config->vendor_ext = &vendor_ext_cb;
+  config->vendor_ext = &vendor_nr_ext_cb;
   config->user_data = &vnf;
   // To allow custom vendor extentions to be added to nfapi
-  config->codec_config.unpack_vendor_extension_tlv = &vnf_unpack_vendor_extension_tlv;
-  config->codec_config.pack_vendor_extension_tlv = &vnf_pack_vendor_extension_tlv;
-  config->codec_config.unpack_p4_p5_vendor_extension = &vnf_unpack_p4_p5_vendor_extension;
-  config->codec_config.pack_p4_p5_vendor_extension = &vnf_pack_p4_p5_vendor_extension;
-  config->allocate_p4_p5_vendor_ext = &vnf_allocate_p4_p5_vendor_ext;
-  config->deallocate_p4_p5_vendor_ext = &vnf_deallocate_p4_p5_vendor_ext;
-  config->codec_config.allocate = &vnf_allocate;
-  config->codec_config.deallocate = &vnf_deallocate;
-  memset(&UL_RCC_INFO,0,sizeof(UL_RCC_IND_t));
+  config->codec_config.unpack_vendor_extension_tlv = &vnf_nr_unpack_vendor_extension_tlv;
+  config->codec_config.pack_vendor_extension_tlv = &vnf_nr_pack_vendor_extension_tlv;
+  config->codec_config.unpack_p4_p5_vendor_extension = &vnf_nr_unpack_p4_p5_vendor_extension;
+  config->codec_config.pack_p4_p5_vendor_extension = &vnf_nr_pack_p4_p5_vendor_extension;
+  config->allocate_p4_p5_vendor_ext = &vnf_nr_allocate_p4_p5_vendor_ext;
+  config->deallocate_p4_p5_vendor_ext = &vnf_nr_deallocate_p4_p5_vendor_ext;
+  config->codec_config.allocate = &vnf_nr_allocate;
+  config->codec_config.deallocate = &vnf_nr_deallocate;
+  memset(&UL_RCC_INFO, 0, sizeof(UL_RCC_IND_t));
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Creating VNF NFAPI start thread %s\n", __FUNCTION__);
   pthread_create(&vnf_start_pthread, NULL, (void *)&vnf_nr_start_thread, config);
   NFAPI_TRACE(NFAPI_TRACE_INFO, "[VNF] Created VNF NFAPI start thread %s\n", __FUNCTION__);
diff --git a/nfapi/open-nFAPI/fapi/CMakeLists.txt b/nfapi/open-nFAPI/fapi/CMakeLists.txt
index 1e2208172f284526cf1cf97a1bab3bed81e4e6f9..b332ef6a8e1f87c923038cdeecf2e8575b3bc914 100644
--- a/nfapi/open-nFAPI/fapi/CMakeLists.txt
+++ b/nfapi/open-nFAPI/fapi/CMakeLists.txt
@@ -1,9 +1,24 @@
+add_library(nr_fapi_common
+        src/nr_fapi.c
+)
+target_include_directories(nr_fapi_common PUBLIC inc)
+target_link_libraries(nr_fapi_common PUBLIC nfapi_common)
+
 add_library(nr_fapi_p5
         src/nr_fapi_p5.c
         src/nr_fapi_p5_utils.c
 )
 target_include_directories(nr_fapi_p5 PUBLIC inc)
-target_link_libraries(nr_fapi_p5 PUBLIC nfapi_common)
-if(OAI_AERIAL)
+target_link_libraries(nr_fapi_p5 PUBLIC nr_fapi_common)
+
+add_library(nr_fapi_p7
+        src/nr_fapi_p7.c
+        src/nr_fapi_p7_utils.c
+)
+target_include_directories(nr_fapi_p7 PUBLIC inc)
+target_link_libraries(nr_fapi_p7 PUBLIC nr_fapi_common)
+
+if (OAI_AERIAL)
     target_compile_definitions(nr_fapi_p5 PRIVATE ENABLE_AERIAL)
-endif()
+    target_compile_definitions(nr_fapi_p7 PRIVATE ENABLE_AERIAL)
+endif ()
diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi.h
index 322c09b59c5d5175a673cd22d4aa9715454e06d3..f90fafebebc393f8c8ae620ee85eaae52cdfd1a4 100644
--- a/nfapi/open-nFAPI/fapi/inc/nr_fapi.h
+++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi.h
@@ -18,16 +18,6 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/open-nFAPI/fapi/inc/nr_fapi.h
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 
 #ifndef OPENAIRINTERFACE_NR_FAPI_H
 #define OPENAIRINTERFACE_NR_FAPI_H
@@ -42,6 +32,32 @@
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include "assertions.h"
+#include "debug.h"
+
+#define EQ_TLV(_tlv_a, _tlv_b)        \
+  do {                                \
+    EQ(_tlv_a.tl.tag, _tlv_b.tl.tag); \
+    EQ(_tlv_a.value, _tlv_b.value);   \
+  } while (0)
+
+#define EQ(_a, _b)      \
+  do {                  \
+    if ((_a) != (_b)) { \
+      return false;     \
+    }                   \
+  } while (0)
+
+#define COPY_TL(_dst_tl, _src_tl)    \
+  do {                               \
+    _dst_tl.tag = _src_tl.tag;       \
+    _dst_tl.length = _src_tl.length; \
+  } while (0)
+
+#define COPY_TLV(_dst, _src)   \
+  do {                         \
+    COPY_TL(_dst.tl, _src.tl); \
+    _dst.value = _src.value;   \
+  } while (0)
 
 typedef struct {
   uint8_t num_msg;
@@ -50,23 +66,16 @@ typedef struct {
   uint32_t message_length;
 } fapi_message_header_t;
 
-int fapi_nr_p5_message_header_unpack(uint8_t **pMessageBuf,
-                                     uint32_t messageBufLen,
-                                     void *pUnpackedBuf,
-                                     uint32_t unpackedBufLen,
-                                     nfapi_p4_p5_codec_config_t *config);
-
-int fapi_nr_p5_message_pack(void *pMessageBuf,
-                            uint32_t messageBufLen,
-                            void *pPackedBuf,
-                            uint32_t packedBufLen,
-                            nfapi_p4_p5_codec_config_t *config);
+void copy_vendor_extension_value(nfapi_vendor_extension_tlv_t *dst, const nfapi_vendor_extension_tlv_t *src);
 
-int fapi_nr_p5_message_unpack(void *pMessageBuf,
-                              uint32_t messageBufLen,
-                              void *pUnpackedBuf,
-                              uint32_t unpackedBufLen,
-                              nfapi_p4_p5_codec_config_t *config);
+bool isFAPIMessageIDValid(uint16_t id);
 
 int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen);
+
+int fapi_nr_message_header_unpack(uint8_t **pMessageBuf,
+                                  uint32_t messageBufLen,
+                                  void *pUnpackedBuf,
+                                  uint32_t unpackedBufLen,
+                                  nfapi_p4_p5_codec_config_t *config);
+
 #endif // OPENAIRINTERFACE_NR_FAPI_H
diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5.h
index feade4015b125e9ff16890a726a95fa3e846f02e..307b5bad27afc61248adc03a087958f090040d24 100644
--- a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5.h
+++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5.h
@@ -18,22 +18,24 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/open-nFAPI/fapi/inc/nr_fapi_p5.h
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 
 #ifndef OPENAIRINTERFACE_NR_FAPI_P5_H
 #define OPENAIRINTERFACE_NR_FAPI_P5_H
 #include "stdint.h"
 #include "nfapi_interface.h"
 
+int fapi_nr_p5_message_pack(void *pMessageBuf,
+                            uint32_t messageBufLen,
+                            void *pPackedBuf,
+                            uint32_t packedBufLen,
+                            nfapi_p4_p5_codec_config_t *config);
+
+int fapi_nr_p5_message_unpack(void *pMessageBuf,
+                              uint32_t messageBufLen,
+                              void *pUnpackedBuf,
+                              uint32_t unpackedBufLen,
+                              nfapi_p4_p5_codec_config_t *config);
+
 uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
 uint8_t unpack_nr_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
 uint8_t pack_nr_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
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 36d327a850a8cc65d292780f9067e3e8958e7007..edd75df6775a63fbe927f9d813ed3dd4a1e239c0 100644
--- a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
+++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
@@ -18,16 +18,6 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 
 #ifndef OPENAIRINTERFACE_NR_FAPI_P5_UTILS_H
 #define OPENAIRINTERFACE_NR_FAPI_P5_UTILS_H
@@ -36,33 +26,6 @@
 #include "nr_fapi.h"
 #include "nfapi/oai_integration/vendor_ext.h"
 
-#define EQ_TLV(_tlv_a, _tlv_b)        \
-  do {                                \
-    EQ(_tlv_a.tl.tag, _tlv_b.tl.tag); \
-    EQ(_tlv_a.value, _tlv_b.value);   \
-  } while (0)
-
-#define EQ(_a, _b)      \
-  do {                  \
-    if ((_a) != (_b)) { \
-      return false;     \
-    }                   \
-  } while (0)
-
-#define COPY_TL(_dst_tl, _src_tl)    \
-  do {                               \
-    _dst_tl.tag = _src_tl.tag;       \
-    _dst_tl.length = _src_tl.length; \
-  } while (0)
-
-#define COPY_TLV(_dst, _src)   \
-  do {                         \
-    COPY_TL(_dst.tl, _src.tl); \
-    _dst.value = _src.value;   \
-  } while (0)
-
-void copy_vendor_extension_value(nfapi_vendor_extension_tlv_t *dst, const nfapi_vendor_extension_tlv_t *src);
-
 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);
diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h
new file mode 100644
index 0000000000000000000000000000000000000000..76e2043f2d69aa38d5487ead15c2095d520bf39c
--- /dev/null
+++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#ifndef OPENAIRINTERFACE_NR_FAPI_P7_H
+#define OPENAIRINTERFACE_NR_FAPI_P7_H
+
+int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config);
+
+int fapi_nr_p7_message_unpack(void *pMessageBuf,
+                              uint32_t messageBufLen,
+                              void *pUnpackedBuf,
+                              uint32_t unpackedBufLen,
+                              nfapi_p7_codec_config_t *config);
+
+uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
+                                  uint8_t *end,
+                                  nfapi_nr_slot_indication_scf_t *msg,
+                                  nfapi_p7_codec_config_t *config);
+uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
+uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
+#endif // OPENAIRINTERFACE_NR_FAPI_P7_H
diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7_utils.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0682dbb44e88eda2d27ff926eac4d3645393f2e
--- /dev/null
+++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7_utils.h
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+/*! \file nfapi/open-nFAPI/fapi/inc/p5/nr_fapi_p5_utils.h
+ * \brief
+ * \author Ruben S. Silva
+ * \date 2024
+ * \version 0.1
+ * \company OpenAirInterface Software Alliance
+ * \email: contact@openairinterface.org, rsilva@allbesmart.pt
+ * \note
+ * \warning
+ */
+
+#ifndef OPENAIRINTERFACE_NR_FAPI_P7_UTILS_H
+#define OPENAIRINTERFACE_NR_FAPI_P7_UTILS_H
+#include "stdio.h"
+#include "stdint.h"
+#include "nr_fapi.h"
+
+bool eq_dl_tti_request(const nfapi_nr_dl_tti_request_t *a, const nfapi_nr_dl_tti_request_t *b);
+bool eq_ul_tti_request(const nfapi_nr_ul_tti_request_t *a, const nfapi_nr_ul_tti_request_t *b);
+bool eq_slot_indication(const nfapi_nr_slot_indication_scf_t *a, const nfapi_nr_slot_indication_scf_t *b);
+bool eq_ul_dci_request(const nfapi_nr_ul_dci_request_t *a, const nfapi_nr_ul_dci_request_t *b);
+bool eq_tx_data_request(const nfapi_nr_tx_data_request_t *a, const nfapi_nr_tx_data_request_t *b);
+bool eq_rx_data_indication(const nfapi_nr_rx_data_indication_t *a, const nfapi_nr_rx_data_indication_t *b);
+bool eq_crc_indication(const nfapi_nr_crc_indication_t *a, const nfapi_nr_crc_indication_t *b);
+bool eq_uci_indication(const nfapi_nr_uci_indication_t *a, const nfapi_nr_uci_indication_t *b);
+bool eq_srs_indication(const nfapi_nr_srs_indication_t *a, const nfapi_nr_srs_indication_t *b);
+bool eq_rach_indication(const nfapi_nr_rach_indication_t *a, const nfapi_nr_rach_indication_t *b);
+
+void free_dl_tti_request(nfapi_nr_dl_tti_request_t *msg);
+void free_ul_tti_request(nfapi_nr_ul_tti_request_t *msg);
+void free_slot_indication(nfapi_nr_slot_indication_scf_t *msg);
+void free_ul_dci_request(nfapi_nr_ul_dci_request_t *msg);
+void free_tx_data_request(nfapi_nr_tx_data_request_t *msg);
+void free_rx_data_indication(nfapi_nr_rx_data_indication_t *msg);
+void free_crc_indication(nfapi_nr_crc_indication_t *msg);
+void free_uci_indication(nfapi_nr_uci_indication_t *msg);
+void free_srs_indication(nfapi_nr_srs_indication_t *msg);
+void free_rach_indication(nfapi_nr_rach_indication_t *msg);
+
+void copy_dl_tti_request(const nfapi_nr_dl_tti_request_t *src, nfapi_nr_dl_tti_request_t *dst);
+void copy_ul_tti_request(const nfapi_nr_ul_tti_request_t *src, nfapi_nr_ul_tti_request_t *dst);
+void copy_slot_indication(const nfapi_nr_slot_indication_scf_t *src, nfapi_nr_slot_indication_scf_t *dst);
+void copy_ul_dci_request(const nfapi_nr_ul_dci_request_t *src, nfapi_nr_ul_dci_request_t *dst);
+void copy_tx_data_request(const nfapi_nr_tx_data_request_t *src, nfapi_nr_tx_data_request_t *dst);
+void copy_rx_data_indication(const nfapi_nr_rx_data_indication_t *src, nfapi_nr_rx_data_indication_t *dst);
+void copy_crc_indication(const nfapi_nr_crc_indication_t *src, nfapi_nr_crc_indication_t *dst);
+void copy_uci_indication(const nfapi_nr_uci_indication_t *src, nfapi_nr_uci_indication_t *dst);
+void copy_srs_indication(const nfapi_nr_srs_indication_t *src, nfapi_nr_srs_indication_t *dst);
+void copy_rach_indication(const nfapi_nr_rach_indication_t *src, nfapi_nr_rach_indication_t *dst);
+
+
+size_t get_tx_data_request_size(const nfapi_nr_tx_data_request_t *msg);
+size_t get_rx_data_indication_size(const nfapi_nr_rx_data_indication_t *msg);
+size_t get_crc_indication_size(const nfapi_nr_crc_indication_t *msg);
+size_t get_uci_indication_size(const nfapi_nr_uci_indication_t *msg);
+size_t get_srs_indication_size(const nfapi_nr_srs_indication_t *msg);
+size_t get_rach_indication_size(nfapi_nr_rach_indication_t *msg);
+#endif // OPENAIRINTERFACE_NR_FAPI_P7_UTILS_H
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi.c b/nfapi/open-nFAPI/fapi/src/nr_fapi.c
new file mode 100644
index 0000000000000000000000000000000000000000..c36fff4b349c927d9a5a69b822681b7046bbfff5
--- /dev/null
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi.c
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "nr_fapi.h"
+
+void copy_vendor_extension_value(nfapi_vendor_extension_tlv_t *dst, const nfapi_vendor_extension_tlv_t *src)
+{
+  nfapi_tl_t *dst_tlv = (nfapi_tl_t *)dst;
+  nfapi_tl_t *src_tlv = (nfapi_tl_t *)src;
+
+  switch (dst_tlv->tag) {
+    case VENDOR_EXT_TLV_2_TAG: {
+      vendor_ext_tlv_2 *dst_ve = (vendor_ext_tlv_2 *)dst_tlv;
+      vendor_ext_tlv_2 *src_ve = (vendor_ext_tlv_2 *)src_tlv;
+
+      dst_ve->dummy = src_ve->dummy;
+    } break;
+    case VENDOR_EXT_TLV_1_TAG: {
+      vendor_ext_tlv_1 *dst_ve = (vendor_ext_tlv_1 *)dst_tlv;
+      vendor_ext_tlv_1 *src_ve = (vendor_ext_tlv_1 *)src_tlv;
+
+      dst_ve->dummy = src_ve->dummy;
+    } break;
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown Vendor Extension tag %d\n", dst_tlv->tag);
+  }
+}
+
+bool isFAPIMessageIDValid(const uint16_t id)
+{
+  // SCF 222.10.04 Table 3-5 PHY API message types
+  return (id >= NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST && id <= 0xFF) || id == NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE
+         || id == NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC || id == NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC
+         || id == NFAPI_NR_PHY_MSG_TYPE_TIMING_INFO;
+}
+
+int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen)
+{
+  int retLen = 0;
+
+  // check for size of nFAPI struct without the nFAPI specific parameters
+  switch (msgId) {
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_param_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
+        retLen = sizeof(fapi_message_header_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_param_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t) - sizeof(nfapi_nr_nfapi_t))
+        retLen = sizeof(nfapi_nr_param_request_scf_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_config_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t) - sizeof(nfapi_nr_nfapi_t))
+        retLen = sizeof(nfapi_nr_config_request_scf_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_config_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
+        retLen = sizeof(nfapi_nr_config_response_scf_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_start_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
+        retLen = sizeof(fapi_message_header_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
+        retLen = sizeof(fapi_message_header_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_stop_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
+        retLen = sizeof(fapi_message_header_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nr_stop_indication_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
+        retLen = sizeof(fapi_message_header_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nr_error_indication_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
+        retLen = sizeof(fapi_message_header_t);
+
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_dl_tti_request_t))
+        retLen = sizeof(nfapi_nr_dl_tti_request_t);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_ul_tti_request_t))
+        retLen = sizeof(nfapi_nr_ul_tti_request_t);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
+    case NFAPI_NR_PHY_MSG_TYPE_VENDOR_EXT_SLOT_RESPONSE:
+      if (unpackedBufLen >= sizeof(nfapi_nr_slot_indication_scf_t))
+        retLen = sizeof(nfapi_nr_slot_indication_scf_t);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_ul_dci_request_t))
+        retLen = sizeof(nfapi_nr_ul_dci_request_t);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t))
+        retLen = sizeof(nfapi_nr_tx_data_request_t);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nr_rx_data_indication_t))
+        retLen = sizeof(nfapi_nr_rx_data_indication_t);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nr_crc_indication_t))
+        retLen = sizeof(nfapi_nr_crc_indication_t);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nr_rach_indication_t))
+        retLen = sizeof(nfapi_nr_rach_indication_t);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nr_uci_indication_t))
+        retLen = sizeof(nfapi_nr_uci_indication_t);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
+      if (unpackedBufLen >= sizeof(nfapi_nr_srs_indication_t))
+        retLen = sizeof(nfapi_nr_srs_indication_t);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+      if (unpackedBufLen >= sizeof(nfapi_nr_dl_node_sync_t))
+        retLen = sizeof(nfapi_nr_dl_node_sync_t);
+      break;
+
+    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+      if (unpackedBufLen >= sizeof(nfapi_nr_ul_node_sync_t))
+        retLen = sizeof(nfapi_nr_ul_node_sync_t);
+      break;
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
+      break;
+  }
+
+  return retLen;
+}
+
+int fapi_nr_message_header_unpack(uint8_t **pMessageBuf,
+                                  uint32_t messageBufLen,
+                                  void *pUnpackedBuf,
+                                  uint32_t unpackedBufLen,
+                                  nfapi_p4_p5_codec_config_t *config)
+{
+  uint8_t **pReadPackedMessage = pMessageBuf;
+  nfapi_nr_p4_p5_message_header_t *header = pUnpackedBuf;
+  fapi_message_header_t fapi_msg = {0};
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL || messageBufLen < NFAPI_HEADER_LENGTH
+      || unpackedBufLen < sizeof(fapi_message_header_t)) {
+    return -1;
+  }
+  uint8_t *end = *pMessageBuf + messageBufLen;
+  // process the header
+  int result =
+      (pull8(pReadPackedMessage, &fapi_msg.num_msg, end) && pull8(pReadPackedMessage, &fapi_msg.opaque_handle, end)
+       && pull16(pReadPackedMessage, &header->message_id, end) && pull32(pReadPackedMessage, &header->message_length, end));
+  return (result);
+}
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c
index 295cca7a4876dd3ce2069dc5fcdd3ddd890c5e5c..b5ff0a24900d4c4e711be375dadb587b124dd6f1 100644
--- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c
@@ -18,53 +18,11 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/open-nFAPI/fapi/src/nr_fapi_p5.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nr_fapi.h"
 #include "nr_fapi_p5.h"
-#include "nr_fapi_p5_utils.h"
 #include "debug.h"
 
-bool isFAPIMessageIDValid(uint16_t id)
-{
-  // SCF 222.10.04 Table 3-5 PHY API message types
-  return (id >= NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST && id <= 0xFF) || id == NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE
-         || id == NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC || id == NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC
-         || id == NFAPI_NR_PHY_MSG_TYPE_TIMING_INFO;
-}
-
-int fapi_nr_p5_message_header_unpack(uint8_t **pMessageBuf,
-                                     uint32_t messageBufLen,
-                                     void *pUnpackedBuf,
-                                     uint32_t unpackedBufLen,
-                                     nfapi_p4_p5_codec_config_t *config)
-{
-  uint8_t **pReadPackedMessage = pMessageBuf;
-  nfapi_p4_p5_message_header_t *header = pUnpackedBuf;
-  fapi_message_header_t fapi_msg;
-
-  if(pMessageBuf == NULL || pUnpackedBuf == NULL || messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)){
-    return -1;
-  }
-  uint8_t *end = *pMessageBuf + messageBufLen;
-  // process the header
-  int result =
-      (pull8(pReadPackedMessage, &fapi_msg.num_msg, end) && pull8(pReadPackedMessage, &fapi_msg.opaque_handle, end)
-       && pull16(pReadPackedMessage, &header->message_id, end) && pull32(pReadPackedMessage, &fapi_msg.message_length, end));
-  DevAssert(fapi_msg.message_length <= 0xFFFF);
-  header->message_length = fapi_msg.message_length;
-  return (result);
-}
-
-uint8_t fapi_nr_p5_message_body_pack(nfapi_p4_p5_message_header_t *header,
+uint8_t fapi_nr_p5_message_body_pack(nfapi_nr_p4_p5_message_header_t *header,
                                      uint8_t **ppWritePackedMsg,
                                      uint8_t *end,
                                      nfapi_p4_p5_codec_config_t *config)
@@ -74,7 +32,7 @@ uint8_t fapi_nr_p5_message_body_pack(nfapi_p4_p5_message_header_t *header,
   // look for the specific message
   switch (header->message_id) {
     case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
-      result = 0;
+      result = 1;
       break;
 
     case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
@@ -110,7 +68,7 @@ uint8_t fapi_nr_p5_message_body_pack(nfapi_p4_p5_message_header_t *header,
       break;
 
     default: {
-      AssertFatal(header->message_id >= 0x00 && header->message_id <= 0xFF,
+      AssertFatal(header->message_id <= 0xFF,
                   "FAPI message IDs are defined between 0x00 and 0xFF the message provided 0x%02x, which is not a FAPI message",
                   header->message_id);
       break;
@@ -122,17 +80,14 @@ uint8_t fapi_nr_p5_message_body_pack(nfapi_p4_p5_message_header_t *header,
 int fapi_nr_p5_message_pack(void *pMessageBuf,
                             uint32_t messageBufLen,
                             void *pPackedBuf,
-                            uint32_t packedBufLen,
+                            const uint32_t packedBufLen,
                             nfapi_p4_p5_codec_config_t *config)
 {
-  nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
+  nfapi_nr_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
   uint8_t *pWritePackedMessage = pPackedBuf;
   AssertFatal(isFAPIMessageIDValid(pMessageHeader->message_id),
               "FAPI message IDs are defined between 0x00 and 0xFF the message provided 0x%02x, which is not a FAPI message",
               pMessageHeader->message_id);
-  uint32_t packedMsgLen;
-  uint32_t packedBodyLen;
-  uint16_t packedMsgLen16;
   AssertFatal(pMessageBuf != NULL && pPackedBuf != NULL, "P5 Pack supplied pointers are null");
 
   uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
@@ -140,8 +95,8 @@ int fapi_nr_p5_message_pack(void *pMessageBuf,
   uint8_t *pPacketBodyField = &pWritePackedMessage[8];
   uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
 
-  uint8_t res = fapi_nr_p5_message_body_pack(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
-  AssertFatal(res >= 0, "fapi_nr_p5_message_body_pack error packing message body %d\n", res);
+  const uint8_t res = fapi_nr_p5_message_body_pack(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
+  AssertFatal(res > 0, "fapi_nr_p5_message_body_pack error packing message body %d\n", res);
 
   // PHY API message header
   push8(1, &pWritePackedMessage, pPackMessageEnd); // Number of messages
@@ -151,9 +106,8 @@ int fapi_nr_p5_message_pack(void *pMessageBuf,
   push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd); // Message type ID
 
   // check for a valid message length
-  packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pPacketBodyField);
-  packedBodyLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
-  packedMsgLen16 = (uint16_t)packedBodyLen;
+  const uint32_t packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pPacketBodyField);
+  uint16_t packedMsgLen16 = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
   if (pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST
       || pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_START_REQUEST
       || pMessageHeader->message_id == NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST
@@ -171,13 +125,13 @@ int fapi_nr_p5_message_pack(void *pMessageBuf,
     return -1;
 
   // return the packed length
-  return (int)(packedMsgLen);
+  return packedMsgLen;
 }
 
 int fapi_nr_p5_message_unpack(void *pMessageBuf,
-                              uint32_t messageBufLen,
+                              const uint32_t messageBufLen,
                               void *pUnpackedBuf,
-                              uint32_t unpackedBufLen,
+                              const uint32_t unpackedBufLen,
                               nfapi_p4_p5_codec_config_t *config)
 {
   fapi_message_header_t *pMessageHeader = pUnpackedBuf;
@@ -191,7 +145,7 @@ int fapi_nr_p5_message_unpack(void *pMessageBuf,
               unpackedBufLen);
   // clean the supplied buffer for - tag value blanking
   (void)memset(pUnpackedBuf, 0, unpackedBufLen);
-  if (fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, pMessageHeader, sizeof(fapi_message_header_t), 0)
+  if (fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, pMessageHeader, sizeof(fapi_message_header_t), 0)
       < 0) {
     // failed to read the header
     return -1;
@@ -259,73 +213,6 @@ int fapi_nr_p5_message_unpack(void *pMessageBuf,
   return result;
 }
 
-int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen)
-{
-  int retLen = 0;
-  /**  NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST=  0x00,
-    NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE= 0x01,
-    NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST= 0x02,
-    NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE=0X03,
-    NFAPI_NR_PHY_MSG_TYPE_START_REQUEST=  0X04,
-    NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST=   0X05,
-    NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION=0X06,
-    NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION=0X07
-    */
-  // check for size of nFAPI struct without the nFAPI specific parameters
-  switch (msgId) {
-    case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
-      if (unpackedBufLen >= sizeof(nfapi_nr_param_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
-        retLen = sizeof(fapi_message_header_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
-      if (unpackedBufLen >= sizeof(nfapi_nr_param_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t) - sizeof(nfapi_nr_nfapi_t))
-        retLen = sizeof(nfapi_nr_param_request_scf_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
-      if (unpackedBufLen >= sizeof(nfapi_nr_config_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t) - sizeof(nfapi_nr_nfapi_t))
-        retLen = sizeof(nfapi_nr_config_request_scf_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
-      if (unpackedBufLen >= sizeof(nfapi_nr_config_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
-        retLen = sizeof(nfapi_nr_config_response_scf_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
-      if (unpackedBufLen >= sizeof(nfapi_nr_start_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
-        retLen = sizeof(fapi_message_header_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
-      if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
-        retLen = sizeof(fapi_message_header_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
-      if (unpackedBufLen >= sizeof(nfapi_nr_stop_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
-        retLen = sizeof(fapi_message_header_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION:
-      if (unpackedBufLen >= sizeof(nfapi_nr_stop_indication_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
-        retLen = sizeof(fapi_message_header_t);
-
-      break;
-    case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION:
-      if (unpackedBufLen >= sizeof(nfapi_nr_error_indication_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
-        retLen = sizeof(fapi_message_header_t);
-
-      break;
-    default:
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
-      break;
-  }
-
-  return retLen;
-}
-
 uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config)
 {
   nfapi_nr_param_request_scf_t *pNfapiMsg = (nfapi_nr_param_request_scf_t *)msg;
@@ -370,12 +257,7 @@ uint8_t pack_nr_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
                            &pack_uint16_tlv_value);
 
   for (int i = 0; i < pNfapiMsg->cell_param.num_config_tlvs_to_report.value; ++i) {
-    /*retval &= pack_nr_tlv(pNfapiMsg->cell_param.config_tlvs_to_report_list[i].tl.tag,
-                          &(pNfapiMsg->cell_param.config_tlvs_to_report_list[i]),
-                          ppWritePackedMsg,
-                          end,
-                          &pack_uint8_tlv_value);*/
-    retval &= push16(pNfapiMsg->cell_param.config_tlvs_to_report_list[i].tl.tag, ppWritePackedMsg, end);
+    retval &= push16(pNfapiMsg->cell_param.config_tlvs_to_report_list[i].tl.tag, ppWritePackedMsg, end) != 0;
     retval &= push8(pNfapiMsg->cell_param.config_tlvs_to_report_list[i].tl.length, ppWritePackedMsg, end);
     retval &= push8(pNfapiMsg->cell_param.config_tlvs_to_report_list[i].value, ppWritePackedMsg, end);
     // Add padding that ensures multiple of 4 bytes (SCF 225 Section 2.3.2.1)
@@ -1141,9 +1023,8 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
   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;
+  uint8_t number_of_symbols_per_slot = cyclicprefix ? 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,
@@ -1362,9 +1243,8 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
             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;
+            uint8_t number_of_symbols_per_slot = cyclicprefix ? 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));
@@ -1709,8 +1589,8 @@ uint8_t unpack_nr_stop_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void
 uint8_t pack_nr_error_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config)
 {
   nfapi_nr_error_indication_scf_t *pNfapiMsg = (nfapi_nr_error_indication_scf_t *)msg;
-  uint8_t retval = push16(pNfapiMsg->sfn, ppWritePackedMsg, end);
-  retval &= push16(pNfapiMsg->slot, ppWritePackedMsg, end);
+  uint8_t retval = push16(pNfapiMsg->sfn, ppWritePackedMsg, end) != 0;
+  retval &= push16(pNfapiMsg->slot, ppWritePackedMsg, end) != 0;
   retval &= push8(pNfapiMsg->message_id, ppWritePackedMsg, end);
   retval &= push8(pNfapiMsg->error_code, ppWritePackedMsg, end);
 
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 abcbc3e9717a6578810fb8175f2085961076b137..6450fadb44dc903fb8c4ee0ff6068236ad4a3b46 100644
--- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
@@ -18,39 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nr_fapi_p5_utils.h"
 
-void copy_vendor_extension_value(nfapi_vendor_extension_tlv_t *dst, const nfapi_vendor_extension_tlv_t *src)
-{
-  nfapi_tl_t *dst_tlv = (nfapi_tl_t *)dst;
-  nfapi_tl_t *src_tlv = (nfapi_tl_t *)src;
-
-  switch (dst_tlv->tag) {
-    case VENDOR_EXT_TLV_2_TAG: {
-      vendor_ext_tlv_2 *dst_ve = (vendor_ext_tlv_2 *)dst_tlv;
-      vendor_ext_tlv_2 *src_ve = (vendor_ext_tlv_2 *)src_tlv;
-
-      dst_ve->dummy = src_ve->dummy;
-    } break;
-    case VENDOR_EXT_TLV_1_TAG: {
-      vendor_ext_tlv_1 *dst_ve = (vendor_ext_tlv_1 *)dst_tlv;
-      vendor_ext_tlv_1 *src_ve = (vendor_ext_tlv_1 *)src_tlv;
-
-      dst_ve->dummy = src_ve->dummy;
-    } break;
-  }
-}
-
 bool eq_param_request(const nfapi_nr_param_request_scf_t *unpacked_req, const nfapi_nr_param_request_scf_t *req)
 {
   EQ(unpacked_req->header.message_id, req->header.message_id);
@@ -276,9 +245,8 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const
   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;
+  uint8_t number_of_symbols_per_slot = cyclicprefix ? 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++) {
@@ -805,9 +773,8 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf
   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;
+  uint8_t number_of_symbols_per_slot = cyclicprefix ? 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));
 
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e58e5117876d25de2c88088d3f1d136a9dc2f20
--- /dev/null
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c
@@ -0,0 +1,2413 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "nr_fapi.h"
+#include "nr_fapi_p7.h"
+#include "nr_nfapi_p7.h"
+#include "debug.h"
+
+uint8_t fapi_nr_p7_message_body_pack(nfapi_nr_p7_message_header_t *header,
+                                     uint8_t **ppWritePackedMsg,
+                                     uint8_t *end,
+                                     nfapi_p7_codec_config_t *config)
+{
+  // look for the specific message
+  uint8_t result = 0;
+  switch (header->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      result = pack_dl_tti_request(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      result = pack_ul_tti_request(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
+      result = pack_nr_slot_indication(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      result = pack_ul_dci_request(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      result = pack_tx_data_request(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
+      result = pack_nr_rx_data_indication(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
+      result = pack_nr_crc_indication(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
+      result = pack_nr_uci_indication(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
+      result = pack_nr_srs_indication(header, ppWritePackedMsg, end, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
+      result = pack_nr_rach_indication(header, ppWritePackedMsg, end, config);
+    break;
+#ifdef ENABLE_AERIAL
+    case NFAPI_NR_PHY_MSG_TYPE_VENDOR_EXT_SLOT_RESPONSE:
+      result = pack_nr_slot_indication(header, ppWritePackedMsg, end, config);
+    break;
+#endif
+    default: {
+      if (header->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if (config && config->pack_p7_vendor_extension) {
+          result = (config->pack_p7_vendor_extension)(header, ppWritePackedMsg, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, header->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, header->message_id);
+      }
+    } break;
+  }
+
+  if (result == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
+  }
+  return result;
+}
+
+int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config)
+{
+  if (pMessageBuf == NULL || pPackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
+    return -1;
+  }
+
+  nfapi_nr_p7_message_header_t *pMessageHeader = pMessageBuf;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
+  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
+  uint8_t *pPacketBodyField = &pWritePackedMessage[8];
+  uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
+
+  const uint8_t result = fapi_nr_p7_message_body_pack(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config);
+  AssertFatal(result > 0, "fapi_nr_p7_message_body_pack error packing message body %d\n", result);
+
+  // PHY API message header
+  // Number of messages [0]
+  // Opaque handle [1]
+  // PHY API Message structure
+  // Message type ID [2,3]
+  // Message Length [4,5,6,7]
+  // Message Body [8,...]
+  if (!(push8(1, &pWritePackedMessage, pPackMessageEnd) && push8(0, &pWritePackedMessage, pPackMessageEnd)
+        && push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
+    return -1;
+  }
+
+  // check for a valid message length
+  uintptr_t msgHead = (uintptr_t)pPacketBodyFieldStart;
+  uintptr_t msgEnd = (uintptr_t)pPacketBodyField;
+  uint32_t packedMsgLen = msgEnd - msgHead;
+  if (packedMsgLen > packedBufLen) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+    return -1;
+  }
+
+  // Update the message length in the header
+  pMessageHeader->message_length = packedMsgLen;
+
+  // Update the message length in the header
+  if (!push32(packedMsgLen, &pPackedLengthField, pPackMessageEnd))
+    return -1;
+
+  return packedMsgLen;
+}
+
+int fapi_nr_p7_message_unpack(void *pMessageBuf,
+                              uint32_t messageBufLen,
+                              void *pUnpackedBuf,
+                              uint32_t unpackedBufLen,
+                              nfapi_p7_codec_config_t *config)
+{
+  int result = 0;
+  nfapi_nr_p7_message_header_t *pMessageHeader = (nfapi_nr_p7_message_header_t *)pUnpackedBuf;
+  fapi_message_header_t fapi_hdr;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+
+  AssertFatal(pMessageBuf != NULL && pUnpackedBuf != NULL, "P7 unpack supplied pointers are null");
+  uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
+  AssertFatal(messageBufLen >= NFAPI_HEADER_LENGTH && unpackedBufLen >= sizeof(fapi_message_header_t),
+              "P5 unpack supplied message buffer is too small %d, %d\n",
+              messageBufLen,
+              unpackedBufLen);
+
+
+  if (fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &fapi_hdr, sizeof(fapi_message_header_t), 0) < 0) {
+    // failed to read the header
+    return -1;
+  }
+  pMessageHeader->message_length = fapi_hdr.message_length;
+  pMessageHeader->message_id = fapi_hdr.message_id;
+  if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
+    return -1;
+  }
+
+  // look for the specific message
+  switch (pMessageHeader->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
+        result = unpack_dl_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
+        result = unpack_ul_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION, unpackedBufLen)) {
+        nfapi_nr_slot_indication_scf_t *msg = (nfapi_nr_slot_indication_scf_t *)pMessageHeader;
+        result = unpack_nr_slot_indication(&pReadPackedMessage, end, msg, config);
+      }
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
+        result = unpack_ul_dci_request(&pReadPackedMessage, end, pMessageHeader, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
+        result = unpack_tx_data_request(&pReadPackedMessage, end, pMessageHeader, config);
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_rx_data_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      }
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_crc_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      }
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_uci_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      }
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_srs_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      }
+    break;
+    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_rach_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      }
+    break;
+    default:
+
+      if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if (config && config->unpack_p7_vendor_extension) {
+          result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR,
+                      "%s VE NFAPI message ID %d. No ve decoder provided\n",
+                      __FUNCTION__,
+                      pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+      break;
+  }
+
+  if (result == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Unpack failed to unpack message\n");
+    return -1;
+  }
+  return 0;
+}
+
+static uint8_t pack_nr_tx_beamforming_pdu(const nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu,
+                                          uint8_t **ppWritePackedMsg,
+                                          uint8_t *end)
+{ // Pack RX Beamforming PDU
+  if (!(push16(beamforming_pdu->num_prgs, ppWritePackedMsg, end) && push16(beamforming_pdu->prg_size, ppWritePackedMsg, end)
+        && push8(beamforming_pdu->dig_bf_interfaces, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
+    if (!push16(beamforming_pdu->prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
+      return 0;
+    }
+    for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) {
+      if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) {
+        return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
+  if (!(push16(value->bwp_size, ppWritePackedMsg, end) && push16(value->bwp_start, ppWritePackedMsg, end)
+        && push8(value->subcarrier_spacing, ppWritePackedMsg, end) && push8(value->cyclic_prefix, ppWritePackedMsg, end)
+        && push16(value->start_rb, ppWritePackedMsg, end) && push16(value->nr_of_rbs, ppWritePackedMsg, end)
+        && push8(value->csi_type, ppWritePackedMsg, end) && push8(value->row, ppWritePackedMsg, end)
+        && push16(value->freq_domain, ppWritePackedMsg, end) && push8(value->symb_l0, ppWritePackedMsg, end)
+        && push8(value->symb_l1, ppWritePackedMsg, end) && push8(value->cdm_type, ppWritePackedMsg, end)
+        && push8(value->freq_density, ppWritePackedMsg, end) && push16(value->scramb_id, ppWritePackedMsg, end)
+        && push8(value->power_control_offset, ppWritePackedMsg, end)
+        && push8(value->power_control_offset_ss, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  // Precoding and beamforming
+  if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) {
+    return 0;
+  }
+  return 1;
+}
+
+static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
+
+  if (!(push16(value->BWPSize, ppWritePackedMsg, end) && push16(value->BWPStart, ppWritePackedMsg, end)
+        && push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && push8(value->CyclicPrefix, ppWritePackedMsg, end)
+        && push8(value->StartSymbolIndex, ppWritePackedMsg, end) && push8(value->DurationSymbols, ppWritePackedMsg, end)
+        && pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end)
+        && push8(value->CceRegMappingType, ppWritePackedMsg, end) && push8(value->RegBundleSize, ppWritePackedMsg, end)
+        && push8(value->InterleaverSize, ppWritePackedMsg, end) && push8(value->CoreSetType, ppWritePackedMsg, end)
+        && push16(value->ShiftIndex, ppWritePackedMsg, end) && push8(value->precoderGranularity, ppWritePackedMsg, end)
+        && push16(value->numDlDci, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  for (uint16_t i = 0; i < value->numDlDci; ++i) {
+    if (!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end)
+          && push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end)
+          && push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end)
+          && push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) {
+      return 0;
+    }
+    // Precoding and beamforming
+    if(!pack_nr_tx_beamforming_pdu(&value->dci_pdu[i].precodingAndBeamforming,ppWritePackedMsg, end)) {
+      return 0;
+    }
+    // TX Power info
+    if (!(push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end)
+          && push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
+          // DCI Payload fields
+          push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
+          // Pack DCI Payload
+          pack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
+
+  if (!(push16(value->pduBitmap, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
+        && push16(value->pduIndex, ppWritePackedMsg, end) && push16(value->BWPSize, ppWritePackedMsg, end)
+        && push16(value->BWPStart, ppWritePackedMsg, end) && push8(value->SubcarrierSpacing, ppWritePackedMsg, end)
+        && push8(value->CyclicPrefix, ppWritePackedMsg, end) && push8(value->NrOfCodewords, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  for (int i = 0; i < value->NrOfCodewords; ++i) {
+    if (!(push16(value->targetCodeRate[i], ppWritePackedMsg, end) && push8(value->qamModOrder[i], ppWritePackedMsg, end)
+          && push8(value->mcsIndex[i], ppWritePackedMsg, end) && push8(value->mcsTable[i], ppWritePackedMsg, end)
+          && push8(value->rvIndex[i], ppWritePackedMsg, end) && push32(value->TBSize[i], ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+
+  if (!(push16(value->dataScramblingId, ppWritePackedMsg, end) && push8(value->nrOfLayers, ppWritePackedMsg, end)
+        && push8(value->transmissionScheme, ppWritePackedMsg, end) && push8(value->refPoint, ppWritePackedMsg, end)
+        && push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && push8(value->dmrsConfigType, ppWritePackedMsg, end)
+        && push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && push8(value->SCID, ppWritePackedMsg, end)
+        && push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && push16(value->dmrsPorts, ppWritePackedMsg, end)
+        && push8(value->resourceAlloc, ppWritePackedMsg, end) && (int)pusharray8(value->rbBitmap, 36, 36, ppWritePackedMsg, end)
+        && push16(value->rbStart, ppWritePackedMsg, end) && push16(value->rbSize, ppWritePackedMsg, end)
+        && push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && push8(value->StartSymbolIndex, ppWritePackedMsg, end)
+        && push8(value->NrOfSymbols, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  // Check pduBitMap bit 0 to add or not PTRS parameters
+  if (value->pduBitmap & 0b1) {
+    if (!(push8(value->PTRSPortIndex, ppWritePackedMsg, end) && push8(value->PTRSTimeDensity, ppWritePackedMsg, end)
+          && push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && push8(value->PTRSReOffset, ppWritePackedMsg, end)
+          && push8(value->nEpreRatioOfPDSCHToPTRS, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+
+  // Precoding and beamforming
+  if(!pack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming,ppWritePackedMsg, end)) {
+    return 0;
+  }
+
+  if (!(push8(value->powerControlOffset, ppWritePackedMsg, end) && push8(value->powerControlOffsetSS, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  // Check pduBitMap bit 1 to add or not CBG parameters
+  if (value->pduBitmap & 0b10) {
+    if (!(push8(value->isLastCbPresent, ppWritePackedMsg, end) && push8(value->isInlineTbCrc, ppWritePackedMsg, end)
+          && push32(value->dlTbCrc, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+#ifndef ENABLE_AERIAL
+  if (!push8(value->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end)
+      || !push32(value->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end))
+    return 0;
+#endif
+  return 1;
+}
+
+static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n");
+  nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
+
+  if (!(push16(value->PhysCellId, ppWritePackedMsg, end) && push8(value->BetaPss, ppWritePackedMsg, end)
+        && push8(value->SsbBlockIndex, ppWritePackedMsg, end) && push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end)
+        && push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end)
+        && push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end)
+        && push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end)
+        && push8(0, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  // Precoding and beamforming
+  if(!pack_nr_tx_beamforming_pdu(&value->precoding_and_beamforming,ppWritePackedMsg, end)) {
+    return 0;
+  }
+  return 1;
+}
+
+static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)tlv;
+  uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
+  if (!push16(value->PDUType, ppWritePackedMsg, end))
+    return 0;
+  uint8_t *pPackedLengthField = *ppWritePackedMsg;
+  if (!push16(value->PDUSize, ppWritePackedMsg, end))
+    return 0;
+
+  // first match the pdu type, then call the respective function
+  switch (value->PDUType) {
+    case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
+      if (!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppWritePackedMsg, end)))
+        return 0;
+    } break;
+
+    case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
+      if (!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppWritePackedMsg, end)))
+        return 0;
+    } break;
+
+    case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
+      if (!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppWritePackedMsg, end)))
+        return 0;
+    } break;
+
+    case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
+      if (!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppWritePackedMsg, end)))
+        return 0;
+    } break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType);
+    } break;
+  }
+  // pack proper size
+  uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
+  uint16_t packedMsgLen = msgEnd - msgHead;
+  value->PDUSize = packedMsgLen;
+  return push16(value->PDUSize, &pPackedLengthField, end);
+}
+
+uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
+
+  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
+        && push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end)
+        && push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
+    if (!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i], ppWritePackedMsg, end)) {
+      return 0;
+    }
+  }
+
+  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
+    if (!push8(pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end))
+      return 0;
+    for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
+      if (!(push32(pNfapiMsg->dl_tti_request_body.PduIdx[i][j], ppWritePackedMsg, end))) {
+        return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+static uint8_t unpack_nr_tx_beamforming_pdu(nfapi_nr_tx_precoding_and_beamforming_t *beamforming_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
+{ // Unpack RX Beamforming PDU
+  if (!(pull16(ppReadPackedMsg, &beamforming_pdu->num_prgs, end) && pull16(ppReadPackedMsg, &beamforming_pdu->prg_size, end)
+        && pull8(ppReadPackedMsg, &beamforming_pdu->dig_bf_interfaces, end))) {
+    return 0;
+  }
+  for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
+    if (!(pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].pm_idx, end))) {
+      return 0;
+    }
+    for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interfaces; digBFInterface++) {
+      if (!pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) {
+        return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
+
+  if (!(pull16(ppReadPackedMsg, &value->BWPSize, end) && pull16(ppReadPackedMsg, &value->BWPStart, end)
+        && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && pull8(ppReadPackedMsg, &value->CyclicPrefix, end)
+        && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && pull8(ppReadPackedMsg, &value->DurationSymbols, end)
+        && pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end)
+        && pull8(ppReadPackedMsg, &value->CceRegMappingType, end) && pull8(ppReadPackedMsg, &value->RegBundleSize, end)
+        && pull8(ppReadPackedMsg, &value->InterleaverSize, end) && pull8(ppReadPackedMsg, &value->CoreSetType, end)
+        && pull16(ppReadPackedMsg, &value->ShiftIndex, end) && pull8(ppReadPackedMsg, &value->precoderGranularity, end)
+        && pull16(ppReadPackedMsg, &value->numDlDci, end))) {
+    return 0;
+  }
+
+  for (uint16_t i = 0; i < value->numDlDci; ++i) {
+    if (!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end)
+          && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end)
+          && pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end)
+          && pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end))) {
+      return 0;
+    }
+
+    // Preocding and Beamforming
+    if(!unpack_nr_tx_beamforming_pdu(&value->dci_pdu[i].precodingAndBeamforming, ppReadPackedMsg, end)) {
+      return 0;
+    }
+
+    if (!(pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end)
+          && pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end)
+          && pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end)
+          && unpack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppReadPackedMsg, end))) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
+
+  if (!(pull16(ppReadPackedMsg, &value->pduBitmap, end) && pull16(ppReadPackedMsg, &value->rnti, end)
+        && pull16(ppReadPackedMsg, &value->pduIndex, end) && pull16(ppReadPackedMsg, &value->BWPSize, end)
+        && pull16(ppReadPackedMsg, &value->BWPStart, end) && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end)
+        && pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && pull8(ppReadPackedMsg, &value->NrOfCodewords, end))) {
+    return 0;
+  }
+  for (int i = 0; i < value->NrOfCodewords; ++i) {
+    if (!(pull16(ppReadPackedMsg, &value->targetCodeRate[i], end) && pull8(ppReadPackedMsg, &value->qamModOrder[i], end)
+          && pull8(ppReadPackedMsg, &value->mcsIndex[i], end) && pull8(ppReadPackedMsg, &value->mcsTable[i], end)
+          && pull8(ppReadPackedMsg, &value->rvIndex[i], end) && pull32(ppReadPackedMsg, &value->TBSize[i], end))) {
+      return 0;
+    }
+  }
+
+  if (!(pull16(ppReadPackedMsg, &value->dataScramblingId, end) && pull8(ppReadPackedMsg, &value->nrOfLayers, end)
+        && pull8(ppReadPackedMsg, &value->transmissionScheme, end) && pull8(ppReadPackedMsg, &value->refPoint, end)
+        && pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) && pull8(ppReadPackedMsg, &value->dmrsConfigType, end)
+        && pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) && pull8(ppReadPackedMsg, &value->SCID, end)
+        && pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) && pull16(ppReadPackedMsg, &value->dmrsPorts, end)
+        && pull8(ppReadPackedMsg, &value->resourceAlloc, end) && pullarray8(ppReadPackedMsg, &value->rbBitmap[0], 36, 36, end)
+        && pull16(ppReadPackedMsg, &value->rbStart, end) && pull16(ppReadPackedMsg, &value->rbSize, end)
+        && pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end)
+        && pull8(ppReadPackedMsg, &value->NrOfSymbols, end))) {
+    return 0;
+  }
+  // Check pduBitMap bit 0 to pull PTRS parameters or not
+  if (value->pduBitmap & 0b1) {
+    if (!(pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) && pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end)
+          && pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) && pull8(ppReadPackedMsg, &value->PTRSReOffset, end)
+          && pull8(ppReadPackedMsg, &value->nEpreRatioOfPDSCHToPTRS, end))) {
+      return 0;
+    }
+  }
+
+  // Preocding and Beamforming
+  if(!unpack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming, ppReadPackedMsg, end)) {
+    return 0;
+  }
+
+  // Tx power info
+  if (!(pull8(ppReadPackedMsg, &value->powerControlOffset, end) && pull8(ppReadPackedMsg, &value->powerControlOffsetSS, end))) {
+    return 0;
+  }
+
+  // Check pduBitMap bit 1 to pull CBG parameters or not
+  if (value->pduBitmap & 0b10) {
+    if (!(pull8(ppReadPackedMsg, &value->isLastCbPresent, end) && pull8(ppReadPackedMsg, &value->isInlineTbCrc, end)
+          && pull32(ppReadPackedMsg, &value->dlTbCrc, end))) {
+      return 0;
+    }
+  }
+#ifndef ENABLE_AERIAL
+  if (!pull8(ppReadPackedMsg, &value->maintenance_parms_v3.ldpcBaseGraph, end)
+      || !pull32(ppReadPackedMsg, &value->maintenance_parms_v3.tbSizeLbrmBytes, end))
+    return 0;
+#endif
+  return 1;
+}
+
+static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
+  if (!(pull16(ppReadPackedMsg, &value->bwp_size, end) && pull16(ppReadPackedMsg, &value->bwp_start, end)
+        && pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &value->cyclic_prefix, end)
+        && pull16(ppReadPackedMsg, &value->start_rb, end) && pull16(ppReadPackedMsg, &value->nr_of_rbs, end)
+        && pull8(ppReadPackedMsg, &value->csi_type, end) && pull8(ppReadPackedMsg, &value->row, end)
+        && pull16(ppReadPackedMsg, &value->freq_domain, end) && pull8(ppReadPackedMsg, &value->symb_l0, end)
+        && pull8(ppReadPackedMsg, &value->symb_l1, end) && pull8(ppReadPackedMsg, &value->cdm_type, end)
+        && pull8(ppReadPackedMsg, &value->freq_density, end) && pull16(ppReadPackedMsg, &value->scramb_id, end)
+        && pull8(ppReadPackedMsg, &value->power_control_offset, end)
+        && pull8(ppReadPackedMsg, &value->power_control_offset_ss, end))) {
+    return 0;
+  }
+
+  // Preocding and Beamforming
+  if(!unpack_nr_tx_beamforming_pdu(&value->precodingAndBeamforming, ppReadPackedMsg, end)) {
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Unpacking ssb. \n");
+  uint8_t byte3, byte2, byte1, byte0;
+  nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
+
+  if (!(pull16(ppReadPackedMsg, &value->PhysCellId, end) && pull8(ppReadPackedMsg, &value->BetaPss, end)
+        && pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) && pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end)
+        && pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && pull8(ppReadPackedMsg, &value->bchPayloadFlag, end)
+        && pull8(ppReadPackedMsg, &byte3, end) && pull8(ppReadPackedMsg, &byte2, end) && pull8(ppReadPackedMsg, &byte1, end)
+        && pull8(ppReadPackedMsg, &byte0, end))) { // this should be always 0, bchpayload is 24 bits
+    return 0;
+  }
+  // rebuild the bchPayload
+  value->bchPayload = byte3 << 16 | byte2 << 8 | byte1;
+
+  // Preocding and Beamforming
+  if(!unpack_nr_tx_beamforming_pdu(&value->precoding_and_beamforming, ppReadPackedMsg, end)) {
+    return 0;
+  }
+  return 1;
+}
+
+static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+  nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, (uint16_t *)&value->PDUSize, end)))
+    return 0;
+
+  // first match the pdu type, then call the respective function
+  switch (value->PDUType) {
+    case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
+      if (!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppReadPackedMsg, end)))
+        return 0;
+    } break;
+
+    case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
+      if (!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppReadPackedMsg, end)))
+        return 0;
+    } break;
+
+    case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
+      if (!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppReadPackedMsg, end)))
+        return 0;
+    } break;
+
+    case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
+      if (!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppReadPackedMsg, end)))
+        return 0;
+    } break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType);
+    } break;
+  }
+
+  return 1;
+}
+
+uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
+  pNfapiMsg->vendor_extension = NULL;
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
+        && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end)
+        && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end))) {
+    return 0;
+  }
+  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
+    if (!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
+      return 0;
+  }
+
+  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
+    if (!pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nUe[i], end)) {
+      return 0;
+    }
+    for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
+      if (!pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.PduIdx[i][j], end)) {
+        return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+
+// Pack fns for ul_tti PDUS
+
+static uint8_t pack_nr_rx_beamforming_pdu(const nfapi_nr_ul_beamforming_t *beamforming_pdu,
+                                          uint8_t **ppWritePackedMsg,
+                                          uint8_t *end)
+{ // Pack RX Beamforming PDU
+  if (!(push8(beamforming_pdu->trp_scheme, ppWritePackedMsg, end) && push16(beamforming_pdu->num_prgs, ppWritePackedMsg, end)
+        && push16(beamforming_pdu->prg_size, ppWritePackedMsg, end)
+        && push8(beamforming_pdu->dig_bf_interface, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
+    for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interface; digBFInterface++) {
+      if (!push16(beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) {
+        return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+static uint8_t pack_ul_tti_request_prach_pdu(const nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  if (!(push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) && push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end)
+        && push8(prach_pdu->prach_format, ppWritePackedMsg, end) && push8(prach_pdu->num_ra, ppWritePackedMsg, end)
+        && push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) && push16(prach_pdu->num_cs, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  return pack_nr_rx_beamforming_pdu(&prach_pdu->beamforming, ppWritePackedMsg, end);
+}
+
+static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  if (!(push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) && push16(pusch_pdu->rnti, ppWritePackedMsg, end)
+        && push32(pusch_pdu->handle, ppWritePackedMsg, end) && push16(pusch_pdu->bwp_size, ppWritePackedMsg, end)
+        && push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) && push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end)
+        && push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) && push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end)
+        && push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_index, ppWritePackedMsg, end)
+        && push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end)
+        && push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end)
+        && push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end)
+        && push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end)
+        && push16(pusch_pdu->pusch_identity, ppWritePackedMsg, end) && push8(pusch_pdu->scid, ppWritePackedMsg, end)
+        && push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end)
+        && push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) && push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end)
+        && pusharray8(pusch_pdu->rb_bitmap, 36, 36, ppWritePackedMsg, end) && push16(pusch_pdu->rb_start, ppWritePackedMsg, end)
+        && push16(pusch_pdu->rb_size, ppWritePackedMsg, end) && push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end)
+        && push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end)
+        && push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end)
+        && push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end)
+        && push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) && push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  // Pack Optional Data only included if indicated in pduBitmap
+  // Check if PUSCH_PDU_BITMAP_PUSCH_DATA bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
+    // pack optional TLVs
+    if (!(push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_data.new_data_indicator, ppWritePackedMsg, end)
+          && push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end)
+          && push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end))) {
+      return 0;
+    }
+    const uint16_t cb_len = (pusch_pdu->pusch_data.num_cb + 7) / 8;
+    if (!pusharray8(pusch_pdu->pusch_data.cb_present_and_position, cb_len, cb_len, ppWritePackedMsg, end)) {
+      return 0;
+    }
+  }
+
+  // Check if PUSCH_PDU_BITMAP_PUSCH_UCI bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
+    if (!(push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end)
+          && push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end)
+          && push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+
+  // Check if PUSCH_PDU_BITMAP_PUSCH_PTRS bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+    if (!push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end)) {
+      return 0;
+    }
+    for (int i = 0; i < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++i) {
+      if (!(push16(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_port_index, ppWritePackedMsg, end)
+            && push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_dmrs_port, ppWritePackedMsg, end)
+            && push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_re_offset, ppWritePackedMsg, end))) {
+        return 0;
+      }
+    }
+
+    if (!(push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end)
+          && push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+
+  // Check if PUSCH_PDU_BITMAP_DFTS_OFDM bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
+    if (!(push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end)
+          && push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end)
+          && push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end)
+          && push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+
+  // Pack RX Beamforming PDU
+  if (!(pack_nr_rx_beamforming_pdu(&pusch_pdu->beamforming, ppWritePackedMsg, end))) {
+    return 0;
+  }
+#ifndef ENABLE_AERIAL
+  if (!(push8(pusch_pdu->maintenance_parms_v3.ldpcBaseGraph, ppWritePackedMsg, end)
+        && push32(pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes, ppWritePackedMsg, end)))
+    return 0;
+#endif
+  return 1;
+}
+
+static uint8_t pack_ul_tti_request_pucch_pdu(const nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  if (!(push16(pucch_pdu->rnti, ppWritePackedMsg, end) && push32(pucch_pdu->handle, ppWritePackedMsg, end)
+        && push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) && push16(pucch_pdu->bwp_start, ppWritePackedMsg, end)
+        && push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end)
+        && push8(pucch_pdu->format_type, ppWritePackedMsg, end) && push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end)
+        && push8(pucch_pdu->pi_2bpsk, ppWritePackedMsg, end) && push16(pucch_pdu->prb_start, ppWritePackedMsg, end)
+        && push16(pucch_pdu->prb_size, ppWritePackedMsg, end) && push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end)
+        && push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) && push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end)
+        && push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) && push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end)
+        && push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) && push16(pucch_pdu->hopping_id, ppWritePackedMsg, end)
+        && push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end)
+        && push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end)
+        && push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) && push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end)
+        && push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) && push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end)
+        && push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end)
+        && push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) && push8(pucch_pdu->sr_flag, ppWritePackedMsg, end)
+        && push16(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) && push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end)
+        && push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  return pack_nr_rx_beamforming_pdu(&pucch_pdu->beamforming, ppWritePackedMsg, end);
+}
+
+static uint8_t pack_ul_tti_request_srs_parameters_v4(nfapi_v4_srs_parameters_t *srsParameters,
+                                                     const uint8_t num_symbols,
+                                                     uint8_t **ppWritePackedMsg,
+                                                     uint8_t *end)
+{
+  if (!(push16(srsParameters->srs_bandwidth_size, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
+    const nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
+    if (!(push16(symbol->srs_bandwidth_start, ppWritePackedMsg, end) && push8(symbol->sequence_group, ppWritePackedMsg, end)
+          && push8(symbol->sequence_number, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+#ifdef ENABLE_AERIAL
+  // For Aerial, we always pack/unpack the 4 reported symbols, not only the ones indicated by num_symbols
+  for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
+    if (!(push16(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+#endif // ENABLE_AERIAL
+  const uint8_t nUsage = __builtin_popcount(srsParameters->usage);
+  if (!(push32(srsParameters->usage, ppWritePackedMsg, end)
+        && pusharray8(srsParameters->report_type, 4, nUsage, ppWritePackedMsg, end)
+        && push8(srsParameters->singular_Value_representation, ppWritePackedMsg, end)
+        && push8(srsParameters->iq_representation, ppWritePackedMsg, end) && push16(srsParameters->prg_size, ppWritePackedMsg, end)
+        && push8(srsParameters->num_total_ue_antennas, ppWritePackedMsg, end)
+        && push32(srsParameters->ue_antennas_in_this_srs_resource_set, ppWritePackedMsg, end)
+        && push32(srsParameters->sampled_ue_antennas, ppWritePackedMsg, end)
+        && push8(srsParameters->report_scope, ppWritePackedMsg, end)
+        && push8(srsParameters->num_ul_spatial_streams_ports, ppWritePackedMsg, end)
+        && pusharray8(srsParameters->Ul_spatial_stream_ports,
+                      256,
+                      srsParameters->num_ul_spatial_streams_ports,
+                      ppWritePackedMsg,
+                      end))) {
+    return 0;
+  }
+  return 1;
+}
+
+static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  if (!(push16(srs_pdu->rnti, ppWritePackedMsg, end) && push32(srs_pdu->handle, ppWritePackedMsg, end)
+        && push16(srs_pdu->bwp_size, ppWritePackedMsg, end) && push16(srs_pdu->bwp_start, ppWritePackedMsg, end)
+        && push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end)
+        && push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) && push8(srs_pdu->num_symbols, ppWritePackedMsg, end)
+        && push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) && push8(srs_pdu->time_start_position, ppWritePackedMsg, end)
+        && push8(srs_pdu->config_index, ppWritePackedMsg, end) && push16(srs_pdu->sequence_id, ppWritePackedMsg, end)
+        && push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) && push8(srs_pdu->comb_size, ppWritePackedMsg, end)
+        && push8(srs_pdu->comb_offset, ppWritePackedMsg, end) && push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end)
+        && push8(srs_pdu->frequency_position, ppWritePackedMsg, end) && push16(srs_pdu->frequency_shift, ppWritePackedMsg, end)
+        && push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end)
+        && push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) && push8(srs_pdu->resource_type, ppWritePackedMsg, end)
+        && push16(srs_pdu->t_srs, ppWritePackedMsg, end) && push16(srs_pdu->t_offset, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  if(!(pack_nr_rx_beamforming_pdu(&srs_pdu->beamforming, ppWritePackedMsg, end))){
+    return 0;
+  }
+
+  if(!(pack_ul_tti_request_srs_parameters_v4(&srs_pdu->srs_parameters_v4, 1 << srs_pdu->num_symbols, ppWritePackedMsg, end))){
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_ul_tti_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_ul_tti_request_number_of_pdus_t *value = (nfapi_nr_ul_tti_request_number_of_pdus_t *)tlv;
+  uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
+  if (!push16(value->pdu_type, ppWritePackedMsg, end)) {
+    return 0;
+  }
+  uint8_t *pPackedLengthField = *ppWritePackedMsg;
+
+  if (!push16(value->pdu_size, ppWritePackedMsg, end))
+    return 0;
+  // pack PDUs
+  //  first match the pdu type, then call the respective function
+  switch (value->pdu_type) {
+    case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
+      if (!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
+        return 0;
+    } break;
+
+    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
+      if (!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
+        return 0;
+    } break;
+
+    case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
+      if (!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
+        return 0;
+    } break;
+
+    case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
+      if (!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
+        return 0;
+    } break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type);
+    } break;
+  }
+
+  // pack proper size
+  uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
+  uint16_t packedMsgLen = msgEnd - msgHead;
+  value->pdu_size = packedMsgLen;
+  return push16(value->pdu_size, &pPackedLengthField, end);
+}
+
+static uint8_t pack_ul_tti_groups_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_ul_tti_request_number_of_groups_t *value = (nfapi_nr_ul_tti_request_number_of_groups_t *)tlv;
+
+  if (!push8(value->n_ue, ppWritePackedMsg, end))
+    return 0;
+
+  for (int i = 0; i < value->n_ue; i++) {
+    if (!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
+  pNfapiMsg->n_ulcch = 0;
+  pNfapiMsg->n_ulsch = 0;
+  for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
+    switch (pNfapiMsg->pdus_list[i].pdu_type) {
+      case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
+        pNfapiMsg->n_ulcch++;
+      } break;
+      case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
+        pNfapiMsg->n_ulsch++;
+      } break;
+      default:
+        break;
+    }
+  }
+  if (!push16(pNfapiMsg->SFN, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(pNfapiMsg->Slot, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->rach_present, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(pNfapiMsg->n_group, ppWritePackedMsg, end))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
+    if (!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  for (int i = 0; i < pNfapiMsg->n_group; i++) {
+    if (!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_rx_beamforming_pdu(nfapi_nr_ul_beamforming_t *beamforming_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
+{ // Unpack RX Beamforming PDU
+  if (!(pull8(ppReadPackedMsg, &beamforming_pdu->trp_scheme, end) && pull16(ppReadPackedMsg, &beamforming_pdu->num_prgs, end)
+        && pull16(ppReadPackedMsg, &beamforming_pdu->prg_size, end)
+        && pull8(ppReadPackedMsg, &beamforming_pdu->dig_bf_interface, end))) {
+    return 0;
+  }
+  for (int prg = 0; prg < beamforming_pdu->num_prgs; prg++) {
+    for (int digBFInterface = 0; digBFInterface < beamforming_pdu->dig_bf_interface; digBFInterface++) {
+      if (!pull16(ppReadPackedMsg, &beamforming_pdu->prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) {
+        return 0;
+      }
+    }
+  }
+  return 1;
+}
+
+static uint8_t unpack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  if (!(pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) && pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end)
+        && pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) && pull8(ppReadPackedMsg, &prach_pdu->num_ra, end)
+        && pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) && pull16(ppReadPackedMsg, &prach_pdu->num_cs, end))) {
+    return 0;
+  }
+
+  return unpack_nr_rx_beamforming_pdu(&prach_pdu->beamforming, ppReadPackedMsg, end);
+}
+
+static uint8_t unpack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  if (!(pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) && pull16(ppReadPackedMsg, &pusch_pdu->rnti, end)
+        && pull32(ppReadPackedMsg, &pusch_pdu->handle, end) && pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) && pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end)
+        && pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) && pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end)
+        && pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end)
+        && pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->pusch_identity, end) && pull8(ppReadPackedMsg, &pusch_pdu->scid, end)
+        && pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) && pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end)
+        && pullarray8(ppReadPackedMsg, pusch_pdu->rb_bitmap, 36, 36, end) && pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end) && pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end)
+        && pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end)
+        && pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end)
+        && pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end)
+        && pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) && pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)))
+    return 0;
+
+  // Unpack Optional Data only included if indicated in pduBitmap
+  // Check if PUSCH_PDU_BITMAP_PUSCH_DATA bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
+    // pack optional TLVs
+    if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.new_data_indicator, end)
+          && pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end)
+          && pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end))) {
+      return 0;
+    }
+    const uint8_t cb_len = (pusch_pdu->pusch_data.num_cb + 7) / 8;
+    if (!pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position, cb_len, cb_len, end)) {
+      return 0;
+    }
+  }
+  // Check if PUSCH_PDU_BITMAP_PUSCH_UCI bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
+    if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end)
+          && pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end)
+          && pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end))) {
+      return 0;
+    }
+  }
+
+  // Check if PUSCH_PDU_BITMAP_PUSCH_PTRS bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+    if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end))) {
+      return 0;
+    }
+    pusch_pdu->pusch_ptrs.ptrs_ports_list = calloc(pusch_pdu->pusch_ptrs.num_ptrs_ports, sizeof(nfapi_nr_ptrs_ports_t));
+    for (int ptrs_port = 0; ptrs_port < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++ptrs_port) {
+      if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_port_index, end)
+            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_dmrs_port, end)
+            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list[ptrs_port].ptrs_re_offset, end))) {
+        return 0;
+      }
+    }
+    if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end))) {
+      return 0;
+    }
+  }
+
+  // Check if PUSCH_PDU_BITMAP_DFTS_OFDM bit is set
+  if (pusch_pdu->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
+    if (!(pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end)
+          && pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end)
+          && pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end))) {
+      return 0;
+    }
+  }
+
+  if (!(unpack_nr_rx_beamforming_pdu(&pusch_pdu->beamforming, ppReadPackedMsg, end))) {
+    return 0;
+  }
+#ifndef ENABLE_AERIAL
+  if (!(pull8(ppReadPackedMsg, &pusch_pdu->maintenance_parms_v3.ldpcBaseGraph, end)
+        && pull32(ppReadPackedMsg, &pusch_pdu->maintenance_parms_v3.tbSizeLbrmBytes, end)))
+    return 0;
+#endif
+  return 1;
+}
+
+static uint8_t unpack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  if (!(pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) && pull32(ppReadPackedMsg, &pucch_pdu->handle, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->format_type, end) && pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->pi_2bpsk, end) && pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end) && pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end) && pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end) && pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end) && pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end) && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end) && pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end)
+        && pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) && pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end)
+        && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end))) {
+    return 0;
+  }
+  return unpack_nr_rx_beamforming_pdu(&pucch_pdu->beamforming, ppReadPackedMsg, end);
+}
+
+static uint8_t unpack_ul_tti_request_srs_parameters_v4(nfapi_v4_srs_parameters_t *srsParameters,
+                                                       const uint8_t num_symbols,
+                                                       uint8_t **ppReadPackedMsg,
+                                                       uint8_t *end)
+{
+  if (!(pull16(ppReadPackedMsg, &srsParameters->srs_bandwidth_size, end))) {
+    return 0;
+  }
+
+  for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
+    nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
+    if (!(pull16(ppReadPackedMsg, &symbol->srs_bandwidth_start, end) && pull8(ppReadPackedMsg, &symbol->sequence_group, end)
+          && pull8(ppReadPackedMsg, &symbol->sequence_number, end))) {
+      return 0;
+    }
+  }
+#ifdef ENABLE_AERIAL
+  // For Aerial, we always pack/unpack the 4 reported symbols, not only the ones indicated by num_symbols
+  for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
+    nfapi_v4_srs_parameters_symbols_t *symbol = &srsParameters->symbol_list[symbol_idx];
+    if (!(pull16(ppReadPackedMsg, &symbol->srs_bandwidth_start, end) && pull8(ppReadPackedMsg, &symbol->sequence_group, end)
+          && pull8(ppReadPackedMsg, &symbol->sequence_number, end))) {
+      return 0;
+    }
+  }
+#endif // ENABLE_AERIAL
+
+  if (!(pull32(ppReadPackedMsg, &srsParameters->usage, end))) {
+    return 0;
+  }
+  const uint8_t nUsage = __builtin_popcount(srsParameters->usage);
+  if (!(pullarray8(ppReadPackedMsg, &srsParameters->report_type[0], 4, nUsage, end)
+        && pull8(ppReadPackedMsg, &srsParameters->singular_Value_representation, end)
+        && pull8(ppReadPackedMsg, &srsParameters->iq_representation, end) && pull16(ppReadPackedMsg, &srsParameters->prg_size, end)
+        && pull8(ppReadPackedMsg, &srsParameters->num_total_ue_antennas, end)
+        && pull32(ppReadPackedMsg, &srsParameters->ue_antennas_in_this_srs_resource_set, end)
+        && pull32(ppReadPackedMsg, &srsParameters->sampled_ue_antennas, end)
+        && pull8(ppReadPackedMsg, &srsParameters->report_scope, end)
+        && pull8(ppReadPackedMsg, &srsParameters->num_ul_spatial_streams_ports, end)
+        && pullarray8(ppReadPackedMsg,
+                      &srsParameters->Ul_spatial_stream_ports[0],
+                      256,
+                      srsParameters->num_ul_spatial_streams_ports,
+                      end))) {
+    return 0;
+  }
+  return 1;
+}
+
+static uint8_t unpack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  if (!(pull16(ppReadPackedMsg, &srs_pdu->rnti, end) && pull32(ppReadPackedMsg, &srs_pdu->handle, end)
+        && pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) && pull8(ppReadPackedMsg, &srs_pdu->num_symbols, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) && pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->config_index, end) && pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) && pull8(ppReadPackedMsg, &srs_pdu->comb_size, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) && pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) && pull16(ppReadPackedMsg, &srs_pdu->frequency_shift, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end)
+        && pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) && pull8(ppReadPackedMsg, &srs_pdu->resource_type, end)
+        && pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) && pull16(ppReadPackedMsg, &srs_pdu->t_offset, end))) {
+    return 0;
+  }
+
+  if (!(unpack_nr_rx_beamforming_pdu(&srs_pdu->beamforming, ppReadPackedMsg, end))) {
+    return 0;
+  }
+
+  if (!(unpack_ul_tti_request_srs_parameters_v4(&srs_pdu->srs_parameters_v4, 1 << srs_pdu->num_symbols, ppReadPackedMsg, end))) {
+    return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+  nfapi_nr_ul_tti_request_number_of_pdus_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) && pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end)))
+    return 0;
+
+  // first natch the pdu type, then call the respective function
+  switch (pNfapiMsg->pdu_type) {
+    case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
+      if (!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end))
+        return 0;
+    } break;
+
+    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
+      if (!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end))
+        return 0;
+    } break;
+
+    case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
+      if (!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end))
+        return 0;
+    } break;
+
+    case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
+      if (!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end))
+        return 0;
+    } break;
+
+    default: {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type);
+    } break;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+  nfapi_nr_ul_tti_request_number_of_groups_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t *)msg;
+
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->n_ue; i++) {
+    if (!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
+
+  if (!pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end))
+    return 0;
+  for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
+    if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
+      return 0;
+  }
+
+  for (int i = 0; i < pNfapiMsg->n_group; i++) {
+    if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
+      return 0;
+  }
+
+  return 1;
+}
+
+uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
+
+  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)))
+    return 0;
+
+  return 1;
+}
+
+uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
+                                  uint8_t *end,
+                                  nfapi_nr_slot_indication_scf_t *msg,
+                                  nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)))
+    return 0;
+
+  return 1;
+}
+
+static uint8_t pack_ul_dci_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)tlv;
+  uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
+  if (!push16(value->PDUType, ppWritePackedMsg, end)) {
+    return 0;
+  }
+  uint8_t *pPackedLengthField = *ppWritePackedMsg;
+  if (!(push16(value->PDUSize, ppWritePackedMsg, end) && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end)
+        && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end)
+        && pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end)
+        && push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end)
+        && push8(value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, ppWritePackedMsg, end)
+        && push16(value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  for (int i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
+    nfapi_nr_dl_dci_pdu_t *dci_pdu = &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i];
+    if (!(push16(dci_pdu->RNTI, ppWritePackedMsg, end) && push16(dci_pdu->ScramblingId, ppWritePackedMsg, end)
+          && push16(dci_pdu->ScramblingRNTI, ppWritePackedMsg, end) && push8(dci_pdu->CceIndex, ppWritePackedMsg, end)
+          && push8(dci_pdu->AggregationLevel, ppWritePackedMsg, end))) {
+      return 0;
+    }
+    // Precoding and Beamforming
+    nfapi_nr_tx_precoding_and_beamforming_t *beamforming = &dci_pdu->precodingAndBeamforming;
+    if (!(push16(beamforming->num_prgs, ppWritePackedMsg, end) && push16(beamforming->prg_size, ppWritePackedMsg, end)
+          && push8(beamforming->dig_bf_interfaces, ppWritePackedMsg, end))) {
+      return 0;
+    }
+    for (int prg = 0; prg < beamforming->num_prgs; prg++) {
+      if (!push16(beamforming->prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
+        return 0;
+      }
+      for (int digInt = 0; digInt < beamforming->dig_bf_interfaces; digInt++) {
+        if (!push16(beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, ppWritePackedMsg, end)) {
+          return 0;
+        }
+      }
+    }
+    if (!(push8(dci_pdu->beta_PDCCH_1_0, ppWritePackedMsg, end) && push8(dci_pdu->powerControlOffsetSS, ppWritePackedMsg, end) &&
+          // DCI Payload fields
+          push16(dci_pdu->PayloadSizeBits, ppWritePackedMsg, end) &&
+          // Pack DCI Payload
+          pack_dci_payload(dci_pdu->Payload, dci_pdu->PayloadSizeBits, ppWritePackedMsg, end))) {
+      return 0;
+    }
+  }
+
+  // pack proper size
+  uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
+  uint16_t packedMsgLen = msgEnd - msgHead;
+  value->PDUSize = packedMsgLen;
+  return push16(value->PDUSize, &pPackedLengthField, end);
+}
+
+uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
+
+  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
+        && push8(pNfapiMsg->numPdus, ppWritePackedMsg, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->numPdus; i++) {
+    if (!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+  nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, &value->PDUSize, end)
+        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end)
+        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end)
+        && pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end)
+        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end)
+        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end)
+        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end))) {
+    return 0;
+  }
+
+  for (uint16_t i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
+    nfapi_nr_dl_dci_pdu_t *dci_pdu = &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i];
+    if (!(pull16(ppReadPackedMsg, &dci_pdu->RNTI, end) && pull16(ppReadPackedMsg, &dci_pdu->ScramblingId, end)
+          && pull16(ppReadPackedMsg, &dci_pdu->ScramblingRNTI, end) && pull8(ppReadPackedMsg, &dci_pdu->CceIndex, end)
+          && pull8(ppReadPackedMsg, &dci_pdu->AggregationLevel, end))) {
+      return 0;
+    }
+    // Precoding and Beamforming
+    nfapi_nr_tx_precoding_and_beamforming_t *beamforming = &dci_pdu->precodingAndBeamforming;
+    if (!(pull16(ppReadPackedMsg, &beamforming->num_prgs, end) && pull16(ppReadPackedMsg, &beamforming->prg_size, end)
+          && pull8(ppReadPackedMsg, &beamforming->dig_bf_interfaces, end))) {
+      return 0;
+    }
+
+    for (int prg = 0; prg < beamforming->num_prgs; prg++) {
+      if (!pull16(ppReadPackedMsg, &beamforming->prgs_list[prg].pm_idx, end)) {
+        return 0;
+      }
+      for (int digInt = 0; digInt < beamforming->dig_bf_interfaces; digInt++) {
+        if (!pull16(ppReadPackedMsg, &beamforming->prgs_list[prg].dig_bf_interface_list[digInt].beam_idx, end)) {
+          return 0;
+        }
+      }
+    }
+    if (!(pull8(ppReadPackedMsg, &dci_pdu->beta_PDCCH_1_0, end) && pull8(ppReadPackedMsg, &dci_pdu->powerControlOffsetSS, end)
+          && pull16(ppReadPackedMsg, &dci_pdu->PayloadSizeBits, end)
+          && unpack_dci_payload(dci_pdu->Payload, dci_pdu->PayloadSizeBits, ppReadPackedMsg, end))) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
+        && pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->numPdus; i++) {
+    if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i]))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
+  if (!(push32(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
+        && push32(value->num_TLV, ppWritePackedMsg, end)))
+    return 0;
+
+  for (int i = 0; i < value->num_TLV; ++i) {
+    if (!(push16(value->TLVs[i].tag, ppWritePackedMsg, end) && push32(value->TLVs[i].length, ppWritePackedMsg, end)))
+      return 0;
+    const uint32_t byte_len = (value->TLVs[i].length + 3) / 4;
+    switch (value->TLVs[i].tag) {
+      case 0: {
+        if (!pusharray32(value->TLVs[i].value.direct, byte_len, byte_len, ppWritePackedMsg, end)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
+          return 0;
+        }
+        break;
+      }
+
+      case 1: {
+        if (!pusharray32(value->TLVs[i].value.ptr, byte_len, byte_len, ppWritePackedMsg, end)) {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
+          return 0;
+        }
+
+        break;
+      }
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag);
+        break;
+      }
+    }
+  }
+
+  return 1;
+}
+
+uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
+
+  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
+        && push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
+    if (!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end)) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR,
+                  "%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
+                  __FUNCTION__,
+                  __LINE__,
+                  i,
+                  pNfapiMsg->pdu_list[i].PDU_length,
+                  pNfapiMsg->pdu_list[i].PDU_index);
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
+{
+  nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
+
+  if (!(pull32(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) && pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end)
+        && pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->num_TLV; ++i) {
+    if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end) && pull32(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end)))
+      return 0;
+    const uint32_t byte_len = (pNfapiMsg->TLVs[i].length + 3) / 4;
+    if (pNfapiMsg->TLVs[i].tag == 1) {
+      pNfapiMsg->TLVs[i].value.ptr = calloc(byte_len, sizeof(uint32_t));
+    }
+    switch (pNfapiMsg->TLVs[i].tag) {
+      case 0: {
+        if (!pullarray32(ppReadPackedMsg,
+                         pNfapiMsg->TLVs[i].value.direct,
+                         sizeof(pNfapiMsg->TLVs[i].value.direct) / sizeof(uint32_t),
+                         byte_len,
+                         end))
+          return 0;
+
+        break;
+      }
+
+      case 1: {
+        if (!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.ptr, byte_len, byte_len, end))
+          return 0;
+
+        break;
+      }
+
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag);
+        return 0;
+      }
+    }
+  }
+
+  return 1;
+}
+
+uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
+        && pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
+    if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_rx_data_indication_body(const nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
+        && push8(value->harq_id, ppWritePackedMsg, end) && push32(value->pdu_length, ppWritePackedMsg, end)
+        && push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
+        && push16(value->rssi, ppWritePackedMsg, end)))
+    return 0;
+
+  if (pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
+    return 0;
+
+  return 1;
+}
+
+uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
+
+  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
+        && push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
+    if (!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
+                                                 uint8_t **ppReadPackedMsg,
+                                                 uint8_t *end,
+                                                 nfapi_p7_codec_config_t *config)
+{
+  if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
+        && pull8(ppReadPackedMsg, &value->harq_id, end) && pull32(ppReadPackedMsg, &value->pdu_length, end)
+        && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
+        && pull16(ppReadPackedMsg, &value->rssi, end)))
+    return 0;
+
+  const uint32_t length = value->pdu_length;
+  value->pdu = calloc(length, sizeof(*value->pdu));
+  if (pullarray8(ppReadPackedMsg, value->pdu, length, length, end) == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
+    return 0;
+  }
+  return 1;
+}
+
+uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
+        && pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end)))
+    return 0;
+
+  if (pNfapiMsg->number_of_pdus > 0) {
+    pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
+  }
+
+  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
+    if (!unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_crc_indication_body(const nfapi_nr_crc_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
+        && push8(value->harq_id, ppWritePackedMsg, end) && push8(value->tb_crc_status, ppWritePackedMsg, end)
+        && push16(value->num_cb, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  if (value->num_cb != 0) {
+    const uint16_t cb_len = (value->num_cb / 8) + 1; // length is ceil(NumCb/8)
+    if (!pusharray8(value->cb_crc_status, cb_len, cb_len, ppWritePackedMsg,
+                    end)) {
+      return 0;
+    }
+  }
+  if (!(push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
+        && push16(value->rssi, ppWritePackedMsg, end))) {
+    return 0;
+  }
+  return 1;
+}
+
+uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
+
+  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
+        && push16(pNfapiMsg->number_crcs, ppWritePackedMsg, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
+    if (!pack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+uint8_t unpack_nr_crc_indication_body(nfapi_nr_crc_t *value, uint8_t **ppReadPackedMsg, uint8_t *end)
+{
+  if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
+        && pull8(ppReadPackedMsg, &value->harq_id, end) && pull8(ppReadPackedMsg, &value->tb_crc_status, end)
+        && pull16(ppReadPackedMsg, &value->num_cb, end))) {
+    return 0;
+  }
+  if (value->num_cb != 0) {
+    const uint16_t cb_len = (value->num_cb / 8) + 1; // length is ceil(NumCb/8)
+    value->cb_crc_status = calloc(cb_len, sizeof(uint8_t));
+    if (!pullarray8(ppReadPackedMsg, value->cb_crc_status, cb_len, cb_len, end)) {
+      return 0;
+    }
+  }
+  if (!(pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
+        && pull16(ppReadPackedMsg, &value->rssi, end))) {
+    return 0;
+  }
+
+  return 1;
+}
+
+uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
+        && pull16(ppReadPackedMsg, &pNfapiMsg->number_crcs, end)))
+    return 0;
+
+  if (pNfapiMsg->number_crcs > 0) {
+    pNfapiMsg->crc_list = calloc(pNfapiMsg->number_crcs, sizeof(*pNfapiMsg->crc_list));
+  }
+
+  for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
+    if (!unpack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppReadPackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_uci_pusch(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_uci_pusch_pdu_t *value = (nfapi_nr_uci_pusch_pdu_t *)tlv;
+
+  if (!push8(value->pduBitmap, ppWritePackedMsg, end))
+    return 0;
+  if (!push32(value->handle, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->rnti, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(value->ul_cqi, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->timing_advance, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->rssi, ppWritePackedMsg, end))
+    return 0;
+
+  // Bit 0 not used in PUSCH PDU
+  if ((value->pduBitmap >> 1) & 0x01) { // HARQ
+    if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
+      return 0;
+    if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
+      return 0;
+    const uint16_t harq_len = (value->harq.harq_bit_len / 8) + 1;
+    if (!pusharray8(value->harq.harq_payload, harq_len, harq_len, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
+    if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
+      return 0;
+    if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
+    if (!pusharray8(value->csi_part1.csi_part1_payload, csi_len, csi_len, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
+    if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
+      return 0;
+    if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
+    if (!pusharray8(value->csi_part2.csi_part2_payload, csi_len, csi_len, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_uci_pucch_0_1(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_uci_pucch_pdu_format_0_1_t *value = (nfapi_nr_uci_pucch_pdu_format_0_1_t *)tlv;
+
+  if (!push8(value->pduBitmap, ppWritePackedMsg, end))
+    return 0;
+  if (!push32(value->handle, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->rnti, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(value->pucch_format, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(value->ul_cqi, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->timing_advance, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->rssi, ppWritePackedMsg, end))
+    return 0;
+  if (value->pduBitmap & 0x01) { // SR
+    if (!push8(value->sr.sr_indication, ppWritePackedMsg, end))
+      return 0;
+    if (!push8(value->sr.sr_confidence_level, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
+    if (!push8(value->harq.num_harq, ppWritePackedMsg, end))
+      return 0;
+    if (!push8(value->harq.harq_confidence_level, ppWritePackedMsg, end))
+      return 0;
+    for (int i = 0; i < value->harq.num_harq; i++) {
+      if (!push8(value->harq.harq_list[i].harq_value, ppWritePackedMsg, end))
+        return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_uci_pucch_2_3_4(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_uci_pucch_pdu_format_2_3_4_t *value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t *)tlv;
+
+  if (!push8(value->pduBitmap, ppWritePackedMsg, end))
+    return 0;
+  if (!push32(value->handle, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->rnti, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(value->pucch_format, ppWritePackedMsg, end))
+    return 0;
+  if (!push8(value->ul_cqi, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->timing_advance, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->rssi, ppWritePackedMsg, end))
+    return 0;
+
+  if (value->pduBitmap & 0x01) { // SR
+    if (!push16(value->sr.sr_bit_len, ppWritePackedMsg, end))
+      return 0;
+    const uint16_t sr_len = value->sr.sr_bit_len / 8 + 1;
+    if (!pusharray8(value->sr.sr_payload, sr_len, sr_len, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 1) & 0x01) { // HARQ
+    if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
+      return 0;
+    if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
+      return 0;
+    const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
+    if (!pusharray8(value->harq.harq_payload, harq_len, harq_len, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
+    if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
+      return 0;
+    if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
+    if (!pusharray8(value->csi_part1.csi_part1_payload, csi_len, csi_len, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
+    if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
+      return 0;
+    if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
+    if (!pusharray8(value->csi_part2.csi_part2_payload, csi_len, csi_len, ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_uci_indication_body(nfapi_nr_uci_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  if (!push16(value->pdu_type, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(value->pdu_size, ppWritePackedMsg, end))
+    return 0;
+
+  switch (value->pdu_type) {
+    case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
+      if (!pack_nr_uci_pusch(&value->pusch_pdu, ppWritePackedMsg, end)) {
+        return 0;
+      }
+      break;
+
+    case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
+      if (!pack_nr_uci_pucch_0_1(&value->pucch_pdu_format_0_1, ppWritePackedMsg, end)) {
+        return 0;
+      }
+      break;
+
+    case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
+      if (!pack_nr_uci_pucch_2_3_4(&value->pucch_pdu_format_2_3_4, ppWritePackedMsg, end)) {
+        return 0;
+      }
+      break;
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected UCI.indication PDU type %d\n", value->pdu_type);
+      return 0;
+  }
+
+  return 1;
+}
+
+uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
+
+  if (!push16(pNfapiMsg->sfn, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(pNfapiMsg->slot, ppWritePackedMsg, end))
+    return 0;
+  if (!push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
+    if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_uci_pusch(nfapi_nr_uci_pusch_pdu_t *value,
+                                   uint8_t **ppReadPackedMsg,
+                                   uint8_t *end,
+                                   nfapi_p7_codec_config_t *config)
+{
+  if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
+    return 0;
+  if (!pull32(ppReadPackedMsg, &value->handle, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &value->rnti, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &value->rssi, end))
+    return 0;
+
+  // Bit 0 not used in PUSCH PDU
+  if ((value->pduBitmap >> 1) & 0x01) { // HARQ
+    if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
+      return 0;
+    if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
+      return 0;
+    const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
+    value->harq.harq_payload = calloc(harq_len, sizeof(*value->harq.harq_payload));
+
+    if (value->harq.harq_payload == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
+      return 0;
+    }
+
+    if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload, harq_len, harq_len, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
+    if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
+      return 0;
+    if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
+    value->csi_part1.csi_part1_payload = calloc(csi_len, sizeof(*value->csi_part1.csi_part1_payload));
+
+    if (value->csi_part1.csi_part1_payload == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
+      return 0;
+    }
+
+    if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload, csi_len, csi_len, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
+    if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
+      return 0;
+    if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
+    value->csi_part2.csi_part2_payload = calloc(csi_len, sizeof(*value->csi_part2.csi_part2_payload));
+
+    if (value->csi_part2.csi_part2_payload == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
+      return 0;
+    }
+
+    if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload, csi_len, csi_len, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *value,
+                                       uint8_t **ppReadPackedMsg,
+                                       uint8_t *end,
+                                       nfapi_p7_codec_config_t *config)
+{
+  if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end)
+        && pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->pucch_format, end)
+        && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
+        && pull16(ppReadPackedMsg, &value->rssi, end)))
+    return 0;
+  if (value->pduBitmap & 0x01) { // SR
+    if (!(pull8(ppReadPackedMsg, &value->sr.sr_indication, end) && pull8(ppReadPackedMsg, &value->sr.sr_confidence_level, end)))
+      return 0;
+  }
+
+  if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
+
+    if (!(pull8(ppReadPackedMsg, &value->harq.num_harq, end) && pull8(ppReadPackedMsg, &value->harq.harq_confidence_level, end)))
+      return 0;
+    if (value->harq.num_harq > 0) {
+      for (int i = 0; i < value->harq.num_harq; i++) {
+        if (!pull8(ppReadPackedMsg, &value->harq.harq_list[i].harq_value, end)) {
+          return 0;
+        }
+      }
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t *value,
+                                         uint8_t **ppReadPackedMsg,
+                                         uint8_t *end,
+                                         nfapi_p7_codec_config_t *config)
+{
+  if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
+    return 0;
+  if (!pull32(ppReadPackedMsg, &value->handle, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &value->rnti, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &value->pucch_format, end))
+    return 0;
+  if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &value->rssi, end))
+    return 0;
+
+  if (value->pduBitmap & 0x01) { // SR
+    if (!pull16(ppReadPackedMsg, &value->sr.sr_bit_len, end))
+      return 0;
+    const uint16_t sr_len = value->sr.sr_bit_len / 8 + 1;
+    value->sr.sr_payload = calloc(sr_len, sizeof(*value->sr.sr_payload));
+
+    if (value->sr.sr_payload == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->sr.sr_payload\n", __FUNCTION__);
+      return 0;
+    }
+
+    if (!pullarray8(ppReadPackedMsg, value->sr.sr_payload, sr_len, sr_len, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 1) & 0x01) { // HARQ
+    if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
+      return 0;
+    if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
+      return 0;
+    const uint16_t harq_len = value->harq.harq_bit_len / 8 + 1;
+    value->harq.harq_payload = calloc(harq_len, sizeof(*value->harq.harq_payload));
+
+    if (value->harq.harq_payload == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
+      return 0;
+    }
+
+    if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload, harq_len, harq_len, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
+    if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
+      return 0;
+    if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part1.csi_part1_bit_len / 8 + 1;
+    value->csi_part1.csi_part1_payload = calloc(csi_len, sizeof(*value->csi_part1.csi_part1_payload));
+
+    if (value->csi_part1.csi_part1_payload == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
+      return 0;
+    }
+
+    if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload, csi_len, csi_len, end))
+      return 0;
+  }
+
+  if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
+    if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
+      return 0;
+    if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
+      return 0;
+    const uint16_t csi_len = value->csi_part2.csi_part2_bit_len / 8 + 1;
+    value->csi_part2.csi_part2_payload = calloc(csi_len, sizeof(*value->csi_part2.csi_part2_payload));
+
+    if (value->csi_part2.csi_part2_payload == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
+      return 0;
+    }
+
+    if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload, csi_len, csi_len, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value,
+                                             uint8_t **ppReadPackedMsg,
+                                             uint8_t *end,
+                                             nfapi_p7_codec_config_t *config)
+{
+  if (!pull16(ppReadPackedMsg, &value->pdu_type, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &value->pdu_size, end))
+    return 0;
+
+  switch (value->pdu_type) {
+    case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
+      nfapi_nr_uci_pusch_pdu_t *uci_pdu = &value->pusch_pdu;
+      if (!unpack_nr_uci_pusch(uci_pdu, ppReadPackedMsg, end, config))
+        return 0;
+      break;
+    }
+    case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
+      nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1;
+      if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config))
+        return 0;
+      break;
+    }
+    case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
+      nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4;
+      if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config))
+        return 0;
+      break;
+    }
+    default:
+      NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected UCI.indication PDU type %d\n", value->pdu_type);
+      break;
+  }
+
+  return 1;
+}
+
+uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
+
+  if (!pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &pNfapiMsg->slot, end))
+    return 0;
+  if (!pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end))
+    return 0;
+
+  pNfapiMsg->uci_list = calloc(pNfapiMsg->num_ucis, sizeof(*pNfapiMsg->uci_list));
+  for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
+    if (!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_srs_report_tlv(const nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+
+  if(!(push16(report_tlv->tag, ppWritePackedMsg, end) &&
+        push32(report_tlv->length, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
+    if (!push32(report_tlv->value[i], ppWritePackedMsg, end)) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_srs_indication_body(const nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) {
+
+  if(!(push32(value->handle, ppWritePackedMsg, end) &&
+        push16(value->rnti, ppWritePackedMsg, end) &&
+        push16(value->timing_advance_offset, ppWritePackedMsg, end) &&
+        pushs16(value->timing_advance_offset_nsec, ppWritePackedMsg, end) &&
+        push8(value->srs_usage, ppWritePackedMsg, end) &&
+        push8(value->report_type, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  if (!pack_nr_srs_report_tlv(&value->report_tlv, ppWritePackedMsg, end)) {
+    return 0;
+  }
+
+  return 1;
+}
+
+uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t *)msg;
+
+  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
+        && push16(pNfapiMsg->control_length, ppWritePackedMsg, end) && push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end))) {
+    return 0;
+  }
+
+  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
+    if (!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end)) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
+
+  if(!(pull16(ppReadPackedMsg, &report_tlv->tag, end) &&
+        pull32(ppReadPackedMsg, &report_tlv->length, end))) {
+    return 0;
+  }
+#ifndef ENABLE_AERIAL
+  for (int i = 0; i < (report_tlv->length + 3) / 4; i++) {
+    if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
+      return 0;
+    }
+  }
+#endif
+  return 1;
+}
+
+static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppReadPackedMsg, uint8_t *end) {
+
+  if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
+        pull16(ppReadPackedMsg, &value->rnti, end) &&
+        pull16(ppReadPackedMsg, &value->timing_advance_offset, end) &&
+        pulls16(ppReadPackedMsg, &value->timing_advance_offset_nsec, end) &&
+        pull8(ppReadPackedMsg, &value->srs_usage, end) &&
+        pull8(ppReadPackedMsg, &value->report_type, end))) {
+    return 0;
+  }
+
+  if (!unpack_nr_srs_report_tlv(&value->report_tlv, ppReadPackedMsg, end)) {
+    return 0;
+  }
+
+  return 1;
+}
+
+uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t *)msg;
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
+        && pull16(ppReadPackedMsg, &pNfapiMsg->control_length, end) && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
+    return 0;
+  }
+  pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
+  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
+    if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end)) {
+      return 0;
+    }
+  }
+
+  return 1;
+}
+
+static uint8_t pack_nr_rach_indication_body(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
+{
+  nfapi_nr_prach_indication_pdu_t *value = (nfapi_nr_prach_indication_pdu_t *)tlv;
+
+  if (!(push16(value->phy_cell_id, ppWritePackedMsg, end) && push8(value->symbol_index, ppWritePackedMsg, end)
+        && push8(value->slot_index, ppWritePackedMsg, end) && push8(value->freq_index, ppWritePackedMsg, end)
+        && push8(value->avg_rssi, ppWritePackedMsg, end) && push8(value->avg_snr, ppWritePackedMsg, end)
+        && push8(value->num_preamble, ppWritePackedMsg, end)))
+    return 0;
+  for (int i = 0; i < value->num_preamble; i++) {
+    if (!(push8(value->preamble_list[i].preamble_index, ppWritePackedMsg, end)
+          && push16(value->preamble_list[i].timing_advance, ppWritePackedMsg, end)
+          && push32(value->preamble_list[i].preamble_pwr, ppWritePackedMsg, end)))
+      return 0;
+  }
+  return 1;
+}
+
+uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
+
+  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
+        && push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
+    return 0;
+
+  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
+    if (!pack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
+      return 0;
+  }
+
+  return 1;
+}
+
+static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t *value,
+                                              uint8_t **ppReadPackedMsg,
+                                              uint8_t *end,
+                                              nfapi_p7_codec_config_t *config)
+{
+  if (!(pull16(ppReadPackedMsg, &value->phy_cell_id, end) && pull8(ppReadPackedMsg, &value->symbol_index, end)
+        && pull8(ppReadPackedMsg, &value->slot_index, end) && pull8(ppReadPackedMsg, &value->freq_index, end)
+        && pull8(ppReadPackedMsg, &value->avg_rssi, end) && pull8(ppReadPackedMsg, &value->avg_snr, end)
+        && pull8(ppReadPackedMsg, &value->num_preamble, end))) {
+    return 0;
+  }
+
+  for (int i = 0; i < value->num_preamble; i++) {
+    nfapi_nr_prach_indication_preamble_t *preamble = &(value->preamble_list[i]);
+    if (!(pull8(ppReadPackedMsg, &preamble->preamble_index, end) && pull16(ppReadPackedMsg, &preamble->timing_advance, end)
+          && pull32(ppReadPackedMsg, &preamble->preamble_pwr, end))) {
+      return 0;
+    }
+  }
+  return 1;
+}
+
+uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
+
+  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
+        && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
+    return 0;
+  }
+
+  if (pNfapiMsg->number_of_pdus > 0) {
+    pNfapiMsg->pdu_list = calloc(pNfapiMsg->number_of_pdus, sizeof(*pNfapiMsg->pdu_list));
+    for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
+      if (!unpack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppReadPackedMsg, end, config))
+        return 0;
+    }
+  }
+  return 1;
+}
diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..395cb29fe1d741efe67c07284e3b75f124022927
--- /dev/null
+++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c
@@ -0,0 +1,2003 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "nr_fapi_p7_utils.h"
+
+#include <malloc.h>
+
+static bool eq_dl_tti_beamforming(const nfapi_nr_tx_precoding_and_beamforming_t *a,
+                                  const nfapi_nr_tx_precoding_and_beamforming_t *b)
+{
+  EQ(a->num_prgs, b->num_prgs);
+  EQ(a->prg_size, b->prg_size);
+  EQ(a->dig_bf_interfaces, b->dig_bf_interfaces);
+  for (int prg = 0; prg < a->num_prgs; ++prg) {
+    EQ(a->prgs_list[prg].pm_idx, b->prgs_list[prg].pm_idx);
+    for (int dbf_if = 0; dbf_if < a->dig_bf_interfaces; ++dbf_if) {
+      EQ(a->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx, b->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx);
+    }
+  }
+
+  return true;
+}
+
+static bool eq_dl_tti_request_pdcch_pdu(const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *a, const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *b)
+{
+  EQ(a->BWPSize, b->BWPSize);
+  EQ(a->BWPStart, b->BWPStart);
+  EQ(a->SubcarrierSpacing, b->SubcarrierSpacing);
+  EQ(a->CyclicPrefix, b->CyclicPrefix);
+  EQ(a->StartSymbolIndex, b->StartSymbolIndex);
+  EQ(a->DurationSymbols, b->DurationSymbols);
+  for (int fdr_idx = 0; fdr_idx < 6; ++fdr_idx) {
+    EQ(a->FreqDomainResource[fdr_idx], b->FreqDomainResource[fdr_idx]);
+  }
+  EQ(a->CceRegMappingType, b->CceRegMappingType);
+  EQ(a->RegBundleSize, b->RegBundleSize);
+  EQ(a->InterleaverSize, b->InterleaverSize);
+  EQ(a->CoreSetType, b->CoreSetType);
+  EQ(a->ShiftIndex, b->ShiftIndex);
+  EQ(a->precoderGranularity, b->precoderGranularity);
+  EQ(a->numDlDci, b->numDlDci);
+  for (int dl_dci = 0; dl_dci < a->numDlDci; ++dl_dci) {
+    const nfapi_nr_dl_dci_pdu_t *a_dci_pdu = &a->dci_pdu[dl_dci];
+    const nfapi_nr_dl_dci_pdu_t *b_dci_pdu = &b->dci_pdu[dl_dci];
+    EQ(a_dci_pdu->RNTI, b_dci_pdu->RNTI);
+    EQ(a_dci_pdu->ScramblingId, b_dci_pdu->ScramblingId);
+    EQ(a_dci_pdu->ScramblingRNTI, b_dci_pdu->ScramblingRNTI);
+    EQ(a_dci_pdu->CceIndex, b_dci_pdu->CceIndex);
+    EQ(a_dci_pdu->AggregationLevel, b_dci_pdu->AggregationLevel);
+    EQ(eq_dl_tti_beamforming(&a_dci_pdu->precodingAndBeamforming, &b_dci_pdu->precodingAndBeamforming), true);
+    EQ(a_dci_pdu->beta_PDCCH_1_0, b_dci_pdu->beta_PDCCH_1_0);
+    EQ(a_dci_pdu->powerControlOffsetSS, b_dci_pdu->powerControlOffsetSS);
+    EQ(a_dci_pdu->PayloadSizeBits, b_dci_pdu->PayloadSizeBits);
+    for (int i = 0; i < 8; ++i) {
+      // The parameter itself always has 8 positions, no need to calculate how many bytes the payload actually occupies
+      EQ(a_dci_pdu->Payload[i], b_dci_pdu->Payload[i]);
+    }
+  }
+  return true;
+}
+
+static bool eq_dl_tti_request_pdsch_pdu(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *a, const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *b)
+{
+  EQ(a->pduBitmap, b->pduBitmap);
+  EQ(a->rnti, b->rnti);
+  EQ(a->pduIndex, b->pduIndex);
+  EQ(a->BWPSize, b->BWPSize);
+  EQ(a->BWPStart, b->BWPStart);
+  EQ(a->SubcarrierSpacing, b->SubcarrierSpacing);
+  EQ(a->CyclicPrefix, b->CyclicPrefix);
+  EQ(a->NrOfCodewords, b->NrOfCodewords);
+  for (int cw = 0; cw < a->NrOfCodewords; ++cw) {
+    EQ(a->targetCodeRate[cw], b->targetCodeRate[cw]);
+    EQ(a->qamModOrder[cw], b->qamModOrder[cw]);
+    EQ(a->mcsIndex[cw], b->mcsIndex[cw]);
+    EQ(a->mcsTable[cw], b->mcsTable[cw]);
+    EQ(a->rvIndex[cw], b->rvIndex[cw]);
+    EQ(a->TBSize[cw], b->TBSize[cw]);
+  }
+  EQ(a->dataScramblingId, b->dataScramblingId);
+  EQ(a->nrOfLayers, b->nrOfLayers);
+  EQ(a->transmissionScheme, b->transmissionScheme);
+  EQ(a->refPoint, b->refPoint);
+  EQ(a->dlDmrsSymbPos, b->dlDmrsSymbPos);
+  EQ(a->dmrsConfigType, b->dmrsConfigType);
+  EQ(a->dlDmrsScramblingId, b->dlDmrsScramblingId);
+  EQ(a->SCID, b->SCID);
+  EQ(a->numDmrsCdmGrpsNoData, b->numDmrsCdmGrpsNoData);
+  EQ(a->dmrsPorts, b->dmrsPorts);
+  EQ(a->resourceAlloc, b->resourceAlloc);
+  for (int i = 0; i < 36; ++i) {
+    EQ(a->rbBitmap[i], b->rbBitmap[i]);
+  }
+  EQ(a->rbStart, b->rbStart);
+  EQ(a->rbSize, b->rbSize);
+  EQ(a->VRBtoPRBMapping, b->VRBtoPRBMapping);
+  EQ(a->StartSymbolIndex, b->StartSymbolIndex);
+  EQ(a->NrOfSymbols, b->NrOfSymbols);
+  EQ(a->PTRSPortIndex, b->PTRSPortIndex);
+  EQ(a->PTRSTimeDensity, b->PTRSTimeDensity);
+  EQ(a->PTRSFreqDensity, b->PTRSFreqDensity);
+  EQ(a->PTRSReOffset, b->PTRSReOffset);
+  EQ(a->nEpreRatioOfPDSCHToPTRS, b->nEpreRatioOfPDSCHToPTRS);
+  EQ(eq_dl_tti_beamforming(&a->precodingAndBeamforming, &b->precodingAndBeamforming), true);
+  EQ(a->powerControlOffset, b->powerControlOffset);
+  EQ(a->powerControlOffsetSS, b->powerControlOffsetSS);
+  EQ(a->isLastCbPresent, b->isLastCbPresent);
+  EQ(a->isInlineTbCrc, b->isInlineTbCrc);
+  EQ(a->dlTbCrc, b->dlTbCrc);
+  EQ(a->maintenance_parms_v3.ldpcBaseGraph, b->maintenance_parms_v3.ldpcBaseGraph);
+  EQ(a->maintenance_parms_v3.tbSizeLbrmBytes, b->maintenance_parms_v3.tbSizeLbrmBytes);
+  return true;
+}
+
+static bool eq_dl_tti_request_csi_rs_pdu(const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *a, const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *b)
+{
+  EQ(a->bwp_size, b->bwp_size);
+  EQ(a->bwp_start, b->bwp_start);
+  EQ(a->subcarrier_spacing, b->subcarrier_spacing);
+  EQ(a->cyclic_prefix, b->cyclic_prefix);
+  EQ(a->start_rb, b->start_rb);
+  EQ(a->nr_of_rbs, b->nr_of_rbs);
+  EQ(a->csi_type, b->csi_type);
+  EQ(a->row, b->row);
+  EQ(a->freq_domain, b->freq_domain);
+  EQ(a->symb_l0, b->symb_l0);
+  EQ(a->symb_l1, b->symb_l1);
+  EQ(a->cdm_type, b->cdm_type);
+  EQ(a->freq_density, b->freq_density);
+  EQ(a->scramb_id, b->scramb_id);
+  EQ(a->power_control_offset, b->power_control_offset);
+  EQ(a->power_control_offset_ss, b->power_control_offset_ss);
+  EQ(eq_dl_tti_beamforming(&a->precodingAndBeamforming, &b->precodingAndBeamforming), true);
+  return true;
+}
+
+static bool eq_dl_tti_request_ssb_pdu(const nfapi_nr_dl_tti_ssb_pdu_rel15_t *a, const nfapi_nr_dl_tti_ssb_pdu_rel15_t *b)
+{
+  EQ(a->PhysCellId, b->PhysCellId);
+  EQ(a->BetaPss, b->BetaPss);
+  EQ(a->SsbBlockIndex, b->SsbBlockIndex);
+  EQ(a->SsbSubcarrierOffset, b->SsbSubcarrierOffset);
+  EQ(a->ssbOffsetPointA, b->ssbOffsetPointA);
+  EQ(a->bchPayloadFlag, b->bchPayloadFlag);
+  EQ(a->bchPayload, b->bchPayload);
+  EQ(a->ssbRsrp, b->ssbRsrp);
+  EQ(eq_dl_tti_beamforming(&a->precoding_and_beamforming, &b->precoding_and_beamforming), true);
+  return true;
+}
+
+bool eq_dl_tti_request(const nfapi_nr_dl_tti_request_t *a, const nfapi_nr_dl_tti_request_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+
+  EQ(a->SFN, b->SFN);
+  EQ(a->Slot, b->Slot);
+  EQ(a->dl_tti_request_body.nPDUs, b->dl_tti_request_body.nPDUs);
+  EQ(a->dl_tti_request_body.nGroup, b->dl_tti_request_body.nGroup);
+
+  for (int PDU = 0; PDU < a->dl_tti_request_body.nPDUs; ++PDU) {
+    // take the PDU at the start of loops
+    const nfapi_nr_dl_tti_request_pdu_t *a_dl_pdu = &a->dl_tti_request_body.dl_tti_pdu_list[PDU];
+    const nfapi_nr_dl_tti_request_pdu_t *b_dl_pdu = &b->dl_tti_request_body.dl_tti_pdu_list[PDU];
+
+    EQ(a_dl_pdu->PDUType, b_dl_pdu->PDUType);
+    EQ(a_dl_pdu->PDUSize, b_dl_pdu->PDUSize);
+
+    switch (a_dl_pdu->PDUType) {
+      case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
+        EQ(eq_dl_tti_request_pdcch_pdu(&a_dl_pdu->pdcch_pdu.pdcch_pdu_rel15, &b_dl_pdu->pdcch_pdu.pdcch_pdu_rel15), true);
+        break;
+      case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
+        EQ(eq_dl_tti_request_pdsch_pdu(&a_dl_pdu->pdsch_pdu.pdsch_pdu_rel15, &b_dl_pdu->pdsch_pdu.pdsch_pdu_rel15), true);
+        break;
+      case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
+        EQ(eq_dl_tti_request_csi_rs_pdu(&a_dl_pdu->csi_rs_pdu.csi_rs_pdu_rel15, &b_dl_pdu->csi_rs_pdu.csi_rs_pdu_rel15), true);
+        break;
+      case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
+        EQ(eq_dl_tti_request_ssb_pdu(&a_dl_pdu->ssb_pdu.ssb_pdu_rel15, &b_dl_pdu->ssb_pdu.ssb_pdu_rel15), true);
+        break;
+      default:
+        // PDU Type is not any known value
+        return false;
+    }
+  }
+
+  for (int nGroup = 0; nGroup < a->dl_tti_request_body.nGroup; ++nGroup) {
+    EQ(a->dl_tti_request_body.nUe[nGroup], b->dl_tti_request_body.nUe[nGroup]);
+    for (int UE = 0; UE < a->dl_tti_request_body.nUe[nGroup]; ++UE) {
+      EQ(a->dl_tti_request_body.PduIdx[nGroup][UE], b->dl_tti_request_body.PduIdx[nGroup][UE]);
+    }
+  }
+
+  return true;
+}
+
+static bool eq_ul_tti_beamforming(const nfapi_nr_ul_beamforming_t *a, const nfapi_nr_ul_beamforming_t *b)
+{
+  EQ(a->trp_scheme, b->trp_scheme);
+  EQ(a->num_prgs, b->num_prgs);
+  EQ(a->prg_size, b->prg_size);
+  EQ(a->dig_bf_interface, b->dig_bf_interface);
+  for (int prg = 0; prg < a->num_prgs; ++prg) {
+    for (int dbf_if = 0; dbf_if < a->dig_bf_interface; ++dbf_if) {
+      EQ(a->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx, b->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx);
+    }
+  }
+
+  return true;
+}
+
+static bool eq_ul_tti_request_prach_pdu(const nfapi_nr_prach_pdu_t *a, const nfapi_nr_prach_pdu_t *b)
+{
+  EQ(a->phys_cell_id, b->phys_cell_id);
+  EQ(a->num_prach_ocas, b->num_prach_ocas);
+  EQ(a->prach_format, b->prach_format);
+  EQ(a->num_ra, b->num_ra);
+  EQ(a->prach_start_symbol, b->prach_start_symbol);
+  EQ(a->num_cs, b->num_cs);
+  EQ(eq_ul_tti_beamforming(&a->beamforming, &b->beamforming), true);
+  return true;
+}
+
+static bool eq_ul_tti_request_pusch_pdu(const nfapi_nr_pusch_pdu_t *a, const nfapi_nr_pusch_pdu_t *b)
+{
+  EQ(a->pdu_bit_map, b->pdu_bit_map);
+  EQ(a->rnti, b->rnti);
+  EQ(a->handle, b->handle);
+  EQ(a->bwp_size, b->bwp_size);
+  EQ(a->bwp_start, b->bwp_start);
+  EQ(a->subcarrier_spacing, b->subcarrier_spacing);
+  EQ(a->cyclic_prefix, b->cyclic_prefix);
+  EQ(a->target_code_rate, b->target_code_rate);
+  EQ(a->qam_mod_order, b->qam_mod_order);
+  EQ(a->mcs_index, b->mcs_index);
+  EQ(a->mcs_table, b->mcs_table);
+  EQ(a->transform_precoding, b->transform_precoding);
+  EQ(a->data_scrambling_id, b->data_scrambling_id);
+  EQ(a->nrOfLayers, b->nrOfLayers);
+  EQ(a->ul_dmrs_symb_pos, b->ul_dmrs_symb_pos);
+  EQ(a->dmrs_config_type, b->dmrs_config_type);
+  EQ(a->ul_dmrs_scrambling_id, b->ul_dmrs_scrambling_id);
+  EQ(a->pusch_identity, b->pusch_identity);
+  EQ(a->scid, b->scid);
+  EQ(a->num_dmrs_cdm_grps_no_data, b->num_dmrs_cdm_grps_no_data);
+  EQ(a->dmrs_ports, b->dmrs_ports);
+  EQ(a->resource_alloc, b->resource_alloc);
+  for (int i = 0; i < 36; ++i) {
+    EQ(a->rb_bitmap[i], b->rb_bitmap[i]);
+  }
+  EQ(a->rb_start, b->rb_start);
+  EQ(a->rb_size, b->rb_size);
+  EQ(a->vrb_to_prb_mapping, b->vrb_to_prb_mapping);
+  EQ(a->frequency_hopping, b->frequency_hopping);
+  EQ(a->tx_direct_current_location, b->tx_direct_current_location);
+  EQ(a->uplink_frequency_shift_7p5khz, b->uplink_frequency_shift_7p5khz);
+  EQ(a->start_symbol_index, b->start_symbol_index);
+  EQ(a->nr_of_symbols, b->nr_of_symbols);
+
+  if (a->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
+    const nfapi_nr_pusch_data_t *a_pusch_data = &a->pusch_data;
+    const nfapi_nr_pusch_data_t *b_pusch_data = &b->pusch_data;
+    EQ(a_pusch_data->rv_index, b_pusch_data->rv_index);
+    EQ(a_pusch_data->harq_process_id, b_pusch_data->harq_process_id);
+    EQ(a_pusch_data->new_data_indicator, b_pusch_data->new_data_indicator);
+    EQ(a_pusch_data->tb_size, b_pusch_data->tb_size);
+    EQ(a_pusch_data->num_cb, b_pusch_data->num_cb);
+    for (int i = 0; i < (a_pusch_data->num_cb + 7) / 8; ++i) {
+      EQ(a_pusch_data->cb_present_and_position[i], b_pusch_data->cb_present_and_position[i]);
+    }
+  }
+  if (a->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
+    const nfapi_nr_pusch_uci_t *a_pusch_uci = &a->pusch_uci;
+    const nfapi_nr_pusch_uci_t *b_pusch_uci = &b->pusch_uci;
+    EQ(a_pusch_uci->harq_ack_bit_length, b_pusch_uci->harq_ack_bit_length);
+    EQ(a_pusch_uci->csi_part1_bit_length, b_pusch_uci->csi_part1_bit_length);
+    EQ(a_pusch_uci->csi_part2_bit_length, b_pusch_uci->csi_part2_bit_length);
+    EQ(a_pusch_uci->alpha_scaling, b_pusch_uci->alpha_scaling);
+    EQ(a_pusch_uci->beta_offset_harq_ack, b_pusch_uci->beta_offset_harq_ack);
+    EQ(a_pusch_uci->beta_offset_csi1, b_pusch_uci->beta_offset_csi1);
+    EQ(a_pusch_uci->beta_offset_csi2, b_pusch_uci->beta_offset_csi2);
+  }
+  if (a->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+    const nfapi_nr_pusch_ptrs_t *a_pusch_ptrs = &a->pusch_ptrs;
+    const nfapi_nr_pusch_ptrs_t *b_pusch_ptrs = &b->pusch_ptrs;
+
+    EQ(a_pusch_ptrs->num_ptrs_ports, b_pusch_ptrs->num_ptrs_ports);
+    for (int i = 0; i < a_pusch_ptrs->num_ptrs_ports; ++i) {
+      const nfapi_nr_ptrs_ports_t *a_ptrs_port = &a_pusch_ptrs->ptrs_ports_list[i];
+      const nfapi_nr_ptrs_ports_t *b_ptrs_port = &b_pusch_ptrs->ptrs_ports_list[i];
+
+      EQ(a_ptrs_port->ptrs_port_index, b_ptrs_port->ptrs_port_index);
+      EQ(a_ptrs_port->ptrs_dmrs_port, b_ptrs_port->ptrs_dmrs_port);
+      EQ(a_ptrs_port->ptrs_re_offset, b_ptrs_port->ptrs_re_offset);
+    }
+
+    EQ(a_pusch_ptrs->ptrs_time_density, b_pusch_ptrs->ptrs_time_density);
+    EQ(a_pusch_ptrs->ptrs_freq_density, b_pusch_ptrs->ptrs_freq_density);
+    EQ(a_pusch_ptrs->ul_ptrs_power, b_pusch_ptrs->ul_ptrs_power);
+  }
+  if (a->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
+    const nfapi_nr_dfts_ofdm_t *a_dfts_ofdm = &a->dfts_ofdm;
+    const nfapi_nr_dfts_ofdm_t *b_dfts_ofdm = &b->dfts_ofdm;
+
+    EQ(a_dfts_ofdm->low_papr_group_number, b_dfts_ofdm->low_papr_group_number);
+    EQ(a_dfts_ofdm->low_papr_sequence_number, b_dfts_ofdm->low_papr_sequence_number);
+    EQ(a_dfts_ofdm->ul_ptrs_sample_density, b_dfts_ofdm->ul_ptrs_sample_density);
+    EQ(a_dfts_ofdm->ul_ptrs_time_density_transform_precoding, b_dfts_ofdm->ul_ptrs_time_density_transform_precoding);
+  }
+  EQ(eq_ul_tti_beamforming(&a->beamforming, &b->beamforming), true);
+  EQ(a->maintenance_parms_v3.ldpcBaseGraph, b->maintenance_parms_v3.ldpcBaseGraph);
+  EQ(a->maintenance_parms_v3.tbSizeLbrmBytes, b->maintenance_parms_v3.tbSizeLbrmBytes);
+  return true;
+}
+
+static bool eq_ul_tti_request_pucch_pdu(const nfapi_nr_pucch_pdu_t *a, const nfapi_nr_pucch_pdu_t *b)
+{
+  EQ(a->rnti, b->rnti);
+  EQ(a->handle, b->handle);
+  EQ(a->bwp_size, b->bwp_size);
+  EQ(a->bwp_start, b->bwp_start);
+  EQ(a->subcarrier_spacing, b->subcarrier_spacing);
+  EQ(a->cyclic_prefix, b->cyclic_prefix);
+  EQ(a->format_type, b->format_type);
+  EQ(a->multi_slot_tx_indicator, b->multi_slot_tx_indicator);
+  EQ(a->pi_2bpsk, b->pi_2bpsk);
+  EQ(a->prb_start, b->prb_start);
+  EQ(a->prb_size, b->prb_size);
+  EQ(a->start_symbol_index, b->start_symbol_index);
+  EQ(a->nr_of_symbols, b->nr_of_symbols);
+  EQ(a->freq_hop_flag, b->freq_hop_flag);
+  EQ(a->second_hop_prb, b->second_hop_prb);
+  EQ(a->group_hop_flag, b->group_hop_flag);
+  EQ(a->sequence_hop_flag, b->sequence_hop_flag);
+  EQ(a->hopping_id, b->hopping_id);
+  EQ(a->initial_cyclic_shift, b->initial_cyclic_shift);
+  EQ(a->data_scrambling_id, b->data_scrambling_id);
+  EQ(a->time_domain_occ_idx, b->time_domain_occ_idx);
+  EQ(a->pre_dft_occ_idx, b->pre_dft_occ_idx);
+  EQ(a->pre_dft_occ_len, b->pre_dft_occ_len);
+  EQ(a->add_dmrs_flag, b->add_dmrs_flag);
+  EQ(a->dmrs_scrambling_id, b->dmrs_scrambling_id);
+  EQ(a->dmrs_cyclic_shift, b->dmrs_cyclic_shift);
+  EQ(a->sr_flag, b->sr_flag);
+  EQ(a->bit_len_harq, b->bit_len_harq);
+  EQ(a->bit_len_csi_part1, b->bit_len_csi_part1);
+  EQ(a->bit_len_csi_part2, b->bit_len_csi_part2);
+  EQ(eq_ul_tti_beamforming(&a->beamforming, &b->beamforming), true);
+  return true;
+}
+
+static bool eq_ul_tti_request_srs_parameters(const nfapi_v4_srs_parameters_t *a,
+                                             const uint8_t num_symbols,
+                                             const nfapi_v4_srs_parameters_t *b)
+{
+  EQ(a->srs_bandwidth_size, b->srs_bandwidth_size);
+  for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
+    const nfapi_v4_srs_parameters_symbols_t *a_symbol = &a->symbol_list[symbol_idx];
+    const nfapi_v4_srs_parameters_symbols_t *b_symbol = &b->symbol_list[symbol_idx];
+    EQ(a_symbol->srs_bandwidth_start, b_symbol->srs_bandwidth_start);
+    EQ(a_symbol->sequence_group, b_symbol->sequence_group);
+    EQ(a_symbol->sequence_number, b_symbol->sequence_number);
+  }
+
+#ifdef ENABLE_AERIAL
+  // For Aerial, we always process the 4 reported symbols, not only the ones indicated by num_symbols
+  for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
+    const nfapi_v4_srs_parameters_symbols_t *a_symbol = &a->symbol_list[symbol_idx];
+    const nfapi_v4_srs_parameters_symbols_t *b_symbol = &b->symbol_list[symbol_idx];
+    EQ(a_symbol->srs_bandwidth_start, b_symbol->srs_bandwidth_start);
+    EQ(a_symbol->sequence_group, b_symbol->sequence_group);
+    EQ(a_symbol->sequence_number, b_symbol->sequence_number);
+  }
+#endif // ENABLE_AERIAL
+
+  EQ(a->usage, b->usage);
+  const uint8_t nUsage = __builtin_popcount(a->usage);
+  for (int idx = 0; idx < nUsage; ++idx) {
+    EQ(a->report_type[idx], b->report_type[idx]);
+  }
+  EQ(a->singular_Value_representation, b->singular_Value_representation);
+  EQ(a->iq_representation, b->iq_representation);
+  EQ(a->prg_size, b->prg_size);
+  EQ(a->num_total_ue_antennas, b->num_total_ue_antennas);
+  EQ(a->ue_antennas_in_this_srs_resource_set, b->ue_antennas_in_this_srs_resource_set);
+  EQ(a->sampled_ue_antennas, b->sampled_ue_antennas);
+  EQ(a->report_scope, b->report_scope);
+  EQ(a->num_ul_spatial_streams_ports, b->num_ul_spatial_streams_ports);
+  for (int idx = 0; idx < a->num_ul_spatial_streams_ports; ++idx) {
+    EQ(a->Ul_spatial_stream_ports[idx], b->Ul_spatial_stream_ports[idx]);
+  }
+  return true;
+}
+
+static bool eq_ul_tti_request_srs_pdu(const nfapi_nr_srs_pdu_t *a, const nfapi_nr_srs_pdu_t *b)
+{
+  EQ(a->rnti, b->rnti);
+  EQ(a->handle, b->handle);
+  EQ(a->bwp_size, b->bwp_size);
+  EQ(a->bwp_start, b->bwp_start);
+  EQ(a->subcarrier_spacing, b->subcarrier_spacing);
+  EQ(a->cyclic_prefix, b->cyclic_prefix);
+  EQ(a->num_ant_ports, b->num_ant_ports);
+  EQ(a->num_symbols, b->num_symbols);
+  EQ(a->num_repetitions, b->num_repetitions);
+  EQ(a->time_start_position, b->time_start_position);
+  EQ(a->config_index, b->config_index);
+  EQ(a->sequence_id, b->sequence_id);
+  EQ(a->bandwidth_index, b->bandwidth_index);
+  EQ(a->comb_size, b->comb_size);
+  EQ(a->comb_offset, b->comb_offset);
+  EQ(a->cyclic_shift, b->cyclic_shift);
+  EQ(a->frequency_position, b->frequency_position);
+  EQ(a->frequency_shift, b->frequency_shift);
+  EQ(a->frequency_hopping, b->frequency_hopping);
+  EQ(a->group_or_sequence_hopping, b->group_or_sequence_hopping);
+  EQ(a->resource_type, b->resource_type);
+  EQ(a->t_srs, b->t_srs);
+  EQ(a->t_offset, b->t_offset);
+  EQ(eq_ul_tti_beamforming(&a->beamforming, &b->beamforming), true);
+  EQ(eq_ul_tti_request_srs_parameters(&a->srs_parameters_v4, 1 << a->num_symbols, &b->srs_parameters_v4), true);
+  return true;
+}
+
+bool eq_ul_tti_request(const nfapi_nr_ul_tti_request_t *a, const nfapi_nr_ul_tti_request_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+
+  EQ(a->SFN, b->SFN);
+  EQ(a->Slot, b->Slot);
+  EQ(a->n_pdus, b->n_pdus);
+  EQ(a->rach_present, b->rach_present);
+  EQ(a->n_ulsch, b->n_ulsch);
+  EQ(a->n_ulcch, b->n_ulcch);
+  EQ(a->n_group, b->n_group);
+
+  for (int PDU = 0; PDU < a->n_pdus; ++PDU) {
+    // take the PDU at the start of loops
+    const nfapi_nr_ul_tti_request_number_of_pdus_t *a_pdu = &a->pdus_list[PDU];
+    const nfapi_nr_ul_tti_request_number_of_pdus_t *b_pdu = &b->pdus_list[PDU];
+
+    EQ(a_pdu->pdu_type, b_pdu->pdu_type);
+    EQ(a_pdu->pdu_size, b_pdu->pdu_size);
+
+    switch (a_pdu->pdu_type) {
+      case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+        EQ(eq_ul_tti_request_prach_pdu(&a_pdu->prach_pdu, &b_pdu->prach_pdu), true);
+        break;
+      case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+        EQ(eq_ul_tti_request_pusch_pdu(&a_pdu->pusch_pdu, &b_pdu->pusch_pdu), true);
+        break;
+      case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+        EQ(eq_ul_tti_request_pucch_pdu(&a_pdu->pucch_pdu, &b_pdu->pucch_pdu), true);
+        break;
+      case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
+        EQ(eq_ul_tti_request_srs_pdu(&a_pdu->srs_pdu, &b_pdu->srs_pdu), true);
+        break;
+      default:
+        // PDU Type is not any known value
+        return false;
+    }
+  }
+
+  for (int nGroup = 0; nGroup < a->n_group; ++nGroup) {
+    EQ(a->groups_list[nGroup].n_ue, b->groups_list[nGroup].n_ue);
+    for (int UE = 0; UE < a->groups_list[nGroup].n_ue; ++UE) {
+      EQ(a->groups_list[nGroup].ue_list[UE].pdu_idx, b->groups_list[nGroup].ue_list[UE].pdu_idx);
+    }
+  }
+  return true;
+}
+
+bool eq_slot_indication(const nfapi_nr_slot_indication_scf_t *a, const nfapi_nr_slot_indication_scf_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+
+  EQ(a->sfn, b->sfn);
+  EQ(a->slot, b->slot);
+  return true;
+}
+
+bool eq_ul_dci_request_PDU(const nfapi_nr_ul_dci_request_pdus_t *a, const nfapi_nr_ul_dci_request_pdus_t *b)
+{
+  EQ(a->PDUType, b->PDUType);
+  EQ(a->PDUSize, b->PDUSize);
+  // Is the same PDU as the DL_TTI.request PDCCH PDU, reuse comparison function
+  EQ(eq_dl_tti_request_pdcch_pdu(&a->pdcch_pdu.pdcch_pdu_rel15, &b->pdcch_pdu.pdcch_pdu_rel15), true);
+  return true;
+}
+
+bool eq_ul_dci_request(const nfapi_nr_ul_dci_request_t *a, const nfapi_nr_ul_dci_request_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+
+  EQ(a->SFN, b->SFN);
+  EQ(a->Slot, b->Slot);
+  EQ(a->numPdus, b->numPdus);
+  for (int pdu_idx = 0; pdu_idx < a->numPdus; ++pdu_idx) {
+    EQ(eq_ul_dci_request_PDU(&a->ul_dci_pdu_list[pdu_idx], &b->ul_dci_pdu_list[pdu_idx]), true);
+  }
+  return true;
+}
+
+bool eq_tx_data_request_PDU(const nfapi_nr_pdu_t *a, const nfapi_nr_pdu_t *b)
+{
+  EQ(a->PDU_length, b->PDU_length);
+  EQ(a->PDU_index, b->PDU_index);
+  EQ(a->num_TLV, b->num_TLV);
+  for (int tlv_idx = 0; tlv_idx < a->num_TLV; ++tlv_idx) {
+    const nfapi_nr_tx_data_request_tlv_t *a_tlv = &a->TLVs[tlv_idx];
+    const nfapi_nr_tx_data_request_tlv_t *b_tlv = &b->TLVs[tlv_idx];
+    EQ(a_tlv->tag, b_tlv->tag);
+    EQ(a_tlv->length, b_tlv->length);
+    switch (a_tlv->tag) {
+      case 0:
+        for (int payload_idx = 0; payload_idx < (a_tlv->length + 3) / 4; ++payload_idx) {
+          // value.direct
+          EQ(a_tlv->value.direct[payload_idx], b_tlv->value.direct[payload_idx]);
+        }
+        break;
+      case 1:
+        for (int payload_idx = 0; payload_idx < (a_tlv->length + 3) / 4; ++payload_idx) {
+          // value.ptr
+          EQ(a_tlv->value.ptr[payload_idx], b_tlv->value.ptr[payload_idx]);
+        }
+        break;
+      default:
+        break;
+    }
+  }
+  return true;
+}
+
+bool eq_tx_data_request(const nfapi_nr_tx_data_request_t *a, const nfapi_nr_tx_data_request_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+
+  EQ(a->SFN, b->SFN);
+  EQ(a->Slot, b->Slot);
+  EQ(a->Number_of_PDUs, b->Number_of_PDUs);
+  for (int pdu_idx = 0; pdu_idx < a->Number_of_PDUs; ++pdu_idx) {
+    EQ(eq_tx_data_request_PDU(&a->pdu_list[pdu_idx], &b->pdu_list[pdu_idx]), true);
+  }
+  return true;
+}
+
+bool eq_rx_data_indication_PDU(const nfapi_nr_rx_data_pdu_t *a, const nfapi_nr_rx_data_pdu_t *b)
+{
+  EQ(a->handle, b->handle);
+  EQ(a->rnti, b->rnti);
+  EQ(a->harq_id, b->harq_id);
+  EQ(a->pdu_length, b->pdu_length);
+  EQ(a->ul_cqi, b->ul_cqi);
+  EQ(a->timing_advance, b->timing_advance);
+  EQ(a->rssi, b->rssi);
+  for (int i = 0; i < a->pdu_length; ++i) {
+    EQ(a->pdu[i], b->pdu[i]);
+  }
+  return true;
+}
+
+bool eq_rx_data_indication(const nfapi_nr_rx_data_indication_t *a, const nfapi_nr_rx_data_indication_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+  EQ(a->sfn, b->sfn);
+  EQ(a->slot, b->slot);
+  EQ(a->number_of_pdus, b->number_of_pdus);
+  for (int pdu_idx = 0; pdu_idx < a->number_of_pdus; ++pdu_idx) {
+    EQ(eq_rx_data_indication_PDU(&a->pdu_list[pdu_idx], &b->pdu_list[pdu_idx]), true);
+  }
+  return true;
+}
+
+bool eq_crc_indication_CRC(const nfapi_nr_crc_t *a, const nfapi_nr_crc_t *b)
+{
+  EQ(a->handle, b->handle);
+  EQ(a->rnti, b->rnti);
+  EQ(a->harq_id, b->harq_id);
+  EQ(a->tb_crc_status, b->tb_crc_status);
+  EQ(a->num_cb, b->num_cb);
+  if (a->num_cb > 0) {
+    for (int cb = 0; cb < (a->num_cb / 8) + 1; ++cb) {
+      EQ(a->cb_crc_status[cb], b->cb_crc_status[cb]);
+    }
+  }
+  EQ(a->ul_cqi, b->ul_cqi);
+  EQ(a->timing_advance, b->timing_advance);
+  EQ(a->rssi, b->rssi);
+  return true;
+}
+
+bool eq_crc_indication(const nfapi_nr_crc_indication_t *a, const nfapi_nr_crc_indication_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+  EQ(a->sfn, b->sfn);
+  EQ(a->slot, b->slot);
+  EQ(a->number_crcs, b->number_crcs);
+  for (int crc_idx = 0; crc_idx < a->number_crcs; ++crc_idx) {
+    EQ(eq_crc_indication_CRC(&a->crc_list[crc_idx], &b->crc_list[crc_idx]), true);
+  }
+  return true;
+}
+
+bool eq_uci_indication_sr_pdu_0_1(const nfapi_nr_sr_pdu_0_1_t *a, const nfapi_nr_sr_pdu_0_1_t *b)
+{
+  EQ(a->sr_indication, b->sr_indication);
+  EQ(a->sr_confidence_level, b->sr_confidence_level);
+  return true;
+}
+
+bool eq_uci_indication_sr_pdu_2_3_4(const nfapi_nr_sr_pdu_2_3_4_t *a, const nfapi_nr_sr_pdu_2_3_4_t *b)
+{
+  EQ(a->sr_bit_len, b->sr_bit_len);
+  for (int i = 0; i < (a->sr_bit_len / 8) + 1; ++i) {
+    EQ(a->sr_payload[i], b->sr_payload[i]);
+  }
+  return true;
+}
+
+bool eq_uci_indication_harq_pdu_0_1(const nfapi_nr_harq_pdu_0_1_t *a, const nfapi_nr_harq_pdu_0_1_t *b)
+{
+  EQ(a->num_harq, b->num_harq);
+  EQ(a->harq_confidence_level, b->harq_confidence_level);
+  for (int i = 0; i < a->num_harq; ++i) {
+    EQ(a->harq_list[i].harq_value, b->harq_list[i].harq_value);
+  }
+  return true;
+}
+
+bool eq_uci_indication_harq_pdu_2_3_4(const nfapi_nr_harq_pdu_2_3_4_t *a, const nfapi_nr_harq_pdu_2_3_4_t *b)
+{
+  EQ(a->harq_crc, b->harq_crc);
+  EQ(a->harq_bit_len, b->harq_bit_len);
+  for (int i = 0; i < (a->harq_bit_len / 8) + 1; ++i) {
+    EQ(a->harq_payload[i], b->harq_payload[i]);
+  }
+  return true;
+}
+
+bool eq_uci_indication_csi_part1(const nfapi_nr_csi_part1_pdu_t *a, const nfapi_nr_csi_part1_pdu_t *b)
+{
+  EQ(a->csi_part1_crc, b->csi_part1_crc);
+  EQ(a->csi_part1_bit_len, b->csi_part1_bit_len);
+  for (int i = 0; i < (a->csi_part1_bit_len / 8) + 1; ++i) {
+    EQ(a->csi_part1_payload[i], b->csi_part1_payload[i]);
+  }
+  return true;
+}
+
+bool eq_uci_indication_csi_part2(const nfapi_nr_csi_part2_pdu_t *a, const nfapi_nr_csi_part2_pdu_t *b)
+{
+  EQ(a->csi_part2_crc, b->csi_part2_crc);
+  EQ(a->csi_part2_bit_len, b->csi_part2_bit_len);
+  for (int i = 0; i < (a->csi_part2_bit_len / 8) + 1; ++i) {
+    EQ(a->csi_part2_payload[i], b->csi_part2_payload[i]);
+  }
+  return true;
+}
+
+bool eq_uci_indication_PUSCH(const nfapi_nr_uci_pusch_pdu_t *a, const nfapi_nr_uci_pusch_pdu_t *b)
+{
+  EQ(a->pduBitmap, b->pduBitmap);
+  EQ(a->handle, b->handle);
+  EQ(a->rnti, b->rnti);
+  EQ(a->ul_cqi, b->ul_cqi);
+  EQ(a->timing_advance, b->timing_advance);
+  EQ(a->rssi, b->rssi);
+
+  // Bit 0 not used in PUSCH PDU
+  // HARQ
+  if ((a->pduBitmap >> 1) & 0x01) {
+    EQ(eq_uci_indication_harq_pdu_2_3_4(&a->harq, &b->harq), true);
+  }
+  // CSI Part 1
+  if ((a->pduBitmap >> 2) & 0x01) {
+    EQ(eq_uci_indication_csi_part1(&a->csi_part1, &b->csi_part1), true);
+  }
+  // CSI Part 2
+  if ((a->pduBitmap >> 3) & 0x01) {
+    EQ(eq_uci_indication_csi_part2(&a->csi_part2, &b->csi_part2), true);
+  }
+  return true;
+}
+
+bool eq_uci_indication_PUCCH_0_1(const nfapi_nr_uci_pucch_pdu_format_0_1_t *a, const nfapi_nr_uci_pucch_pdu_format_0_1_t *b)
+{
+  EQ(a->pduBitmap, b->pduBitmap);
+  EQ(a->handle, b->handle);
+  EQ(a->rnti, b->rnti);
+  EQ(a->pucch_format, b->pucch_format);
+  EQ(a->ul_cqi, b->ul_cqi);
+  EQ(a->timing_advance, b->timing_advance);
+  EQ(a->rssi, b->rssi);
+
+  // SR
+  if (a->pduBitmap & 0x01) {
+    EQ(eq_uci_indication_sr_pdu_0_1(&a->sr, &b->sr), true);
+  }
+  // HARQ
+  if ((a->pduBitmap >> 1) & 0x01) {
+    EQ(eq_uci_indication_harq_pdu_0_1(&a->harq, &b->harq), true);
+  }
+  return true;
+}
+
+bool eq_uci_indication_PUCCH_2_3_4(const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *a, const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *b)
+{
+  EQ(a->pduBitmap, b->pduBitmap);
+  EQ(a->handle, b->handle);
+  EQ(a->rnti, b->rnti);
+  EQ(a->pucch_format, b->pucch_format);
+  EQ(a->ul_cqi, b->ul_cqi);
+  EQ(a->timing_advance, b->timing_advance);
+  EQ(a->rssi, b->rssi);
+  // SR
+  if (a->pduBitmap & 0x01) {
+    EQ(eq_uci_indication_sr_pdu_2_3_4(&a->sr, &b->sr), true);
+  }
+  // HARQ
+  if ((a->pduBitmap >> 1) & 0x01) {
+    EQ(eq_uci_indication_harq_pdu_2_3_4(&a->harq, &b->harq), true);
+  }
+  // CSI Part 1
+  if ((a->pduBitmap >> 2) & 0x01) {
+    EQ(eq_uci_indication_csi_part1(&a->csi_part1, &b->csi_part1), true);
+  }
+  // CSI Part 2
+  if ((a->pduBitmap >> 3) & 0x01) {
+    EQ(eq_uci_indication_csi_part2(&a->csi_part2, &b->csi_part2), true);
+  }
+  return true;
+}
+
+bool eq_uci_indication_UCI(const nfapi_nr_uci_t *a, const nfapi_nr_uci_t *b)
+{
+  EQ(a->pdu_type, b->pdu_type);
+  EQ(a->pdu_size, b->pdu_size);
+  switch (a->pdu_type) {
+    case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
+      EQ(eq_uci_indication_PUSCH(&a->pusch_pdu, &b->pusch_pdu), true);
+      break;
+    case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
+      EQ(eq_uci_indication_PUCCH_0_1(&a->pucch_pdu_format_0_1, &b->pucch_pdu_format_0_1), true);
+      break;
+    case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
+      EQ(eq_uci_indication_PUCCH_2_3_4(&a->pucch_pdu_format_2_3_4, &b->pucch_pdu_format_2_3_4), true);
+      break;
+    default:
+      AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", a->pdu_type);
+      break;
+  }
+  return true;
+}
+
+bool eq_uci_indication(const nfapi_nr_uci_indication_t *a, const nfapi_nr_uci_indication_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+  EQ(a->sfn, b->sfn);
+  EQ(a->slot, b->slot);
+  EQ(a->num_ucis, b->num_ucis);
+  for (int crc_idx = 0; crc_idx < a->num_ucis; ++crc_idx) {
+    EQ(eq_uci_indication_UCI(&a->uci_list[crc_idx], &b->uci_list[crc_idx]), true);
+  }
+  return true;
+}
+
+static bool eq_srs_indication_report_tlv(const nfapi_srs_report_tlv_t *a, const nfapi_srs_report_tlv_t *b)
+{
+  EQ(a->tag, b->tag);
+  EQ(a->length, b->length);
+  for (int i = 0; i < (a->length + 3) / 4; ++i) {
+    EQ(a->value[i], b->value[i]);
+  }
+  return true;
+}
+
+static bool eq_srs_indication_PDU(const nfapi_nr_srs_indication_pdu_t *a, const nfapi_nr_srs_indication_pdu_t *b)
+{
+  EQ(a->handle, b->handle);
+  EQ(a->rnti, b->rnti);
+  EQ(a->timing_advance_offset, b->timing_advance_offset);
+  EQ(a->timing_advance_offset_nsec, b->timing_advance_offset_nsec);
+  EQ(a->srs_usage, b->srs_usage);
+  EQ(a->report_type, b->report_type);
+  EQ(eq_srs_indication_report_tlv(&a->report_tlv, &b->report_tlv), true);
+  return true;
+}
+
+bool eq_srs_indication(const nfapi_nr_srs_indication_t *a, const nfapi_nr_srs_indication_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+  EQ(a->sfn, b->sfn);
+  EQ(a->slot, b->slot);
+  EQ(a->control_length, b->control_length);
+  EQ(a->number_of_pdus, b->number_of_pdus);
+  for (int pdu_idx = 0; pdu_idx < a->number_of_pdus; ++pdu_idx) {
+    EQ(eq_srs_indication_PDU(&a->pdu_list[pdu_idx], &b->pdu_list[pdu_idx]), true);
+  }
+  return true;
+}
+
+static bool eq_rach_indication_PDU(const nfapi_nr_prach_indication_pdu_t *a, const nfapi_nr_prach_indication_pdu_t *b)
+{
+  EQ(a->phy_cell_id, b->phy_cell_id);
+  EQ(a->symbol_index, b->symbol_index);
+  EQ(a->slot_index, b->slot_index);
+  EQ(a->freq_index, b->freq_index);
+  EQ(a->avg_rssi, b->avg_rssi);
+  EQ(a->avg_snr, b->avg_snr);
+  EQ(a->num_preamble, b->num_preamble);
+  for (int preamble_idx = 0; preamble_idx < a->num_preamble; ++preamble_idx) {
+    const nfapi_nr_prach_indication_preamble_t *a_pr = &a->preamble_list[preamble_idx];
+    const nfapi_nr_prach_indication_preamble_t *b_pr = &b->preamble_list[preamble_idx];
+    EQ(a_pr->preamble_index, b_pr->preamble_index);
+    EQ(a_pr->timing_advance, b_pr->timing_advance);
+    EQ(a_pr->preamble_pwr, b_pr->preamble_pwr);
+  }
+  return true;
+}
+
+bool eq_rach_indication(const nfapi_nr_rach_indication_t *a, const nfapi_nr_rach_indication_t *b)
+{
+  EQ(a->header.message_id, b->header.message_id);
+  EQ(a->header.message_length, b->header.message_length);
+  EQ(a->sfn, b->sfn);
+  EQ(a->slot, b->slot);
+  EQ(a->number_of_pdus, b->number_of_pdus);
+  for (int pdu_idx = 0; pdu_idx < a->number_of_pdus; ++pdu_idx) {
+    EQ(eq_rach_indication_PDU(&a->pdu_list[pdu_idx], &b->pdu_list[pdu_idx]), true);
+  }
+  return true;
+}
+
+void free_dl_tti_request(nfapi_nr_dl_tti_request_t *msg)
+{
+  if (msg->vendor_extension) {
+    free(msg->vendor_extension);
+  }
+}
+
+void free_ul_tti_request(nfapi_nr_ul_tti_request_t *msg)
+{
+  for (int idx_pdu = 0; idx_pdu < msg->n_pdus; ++idx_pdu) {
+    nfapi_nr_ul_tti_request_number_of_pdus_t *pdu = &msg->pdus_list[idx_pdu];
+    switch (pdu->pdu_type) {
+      case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+        free(pdu->pusch_pdu.pusch_ptrs.ptrs_ports_list);
+        break;
+      default:
+        break;
+    }
+  }
+}
+
+void free_slot_indication(nfapi_nr_slot_indication_scf_t *msg)
+{
+  // Nothing to free
+}
+
+void free_ul_dci_request(nfapi_nr_ul_dci_request_t *msg)
+{
+  // Nothing to free
+}
+
+void free_tx_data_request(nfapi_nr_tx_data_request_t *msg)
+{
+  for (int pdu_idx = 0; pdu_idx < msg->Number_of_PDUs; ++pdu_idx) {
+    nfapi_nr_pdu_t *pdu = &msg->pdu_list[pdu_idx];
+    for (int tlv_idx = 0; tlv_idx < pdu->num_TLV; ++tlv_idx) {
+      nfapi_nr_tx_data_request_tlv_t *tlv = &pdu->TLVs[tlv_idx];
+      if (tlv->tag == 1) {
+        // value.ptr
+        free(tlv->value.ptr);
+      }
+    }
+  }
+}
+
+void free_rx_data_indication(nfapi_nr_rx_data_indication_t *msg)
+{
+  if (msg->number_of_pdus > 0) {
+    for (int pdu_idx = 0; pdu_idx < msg->number_of_pdus; ++pdu_idx) {
+      nfapi_nr_rx_data_pdu_t *rx_pdu = &msg->pdu_list[pdu_idx];
+      if (rx_pdu->pdu) {
+        free(rx_pdu->pdu);
+      }
+    }
+    free(msg->pdu_list);
+  }
+}
+
+void free_crc_indication(nfapi_nr_crc_indication_t *msg)
+{
+  if (msg->crc_list) {
+    for (int crc_idx = 0; crc_idx < msg->number_crcs; ++crc_idx) {
+      nfapi_nr_crc_t *crc = &msg->crc_list[crc_idx];
+      if (crc->cb_crc_status) {
+        free(crc->cb_crc_status);
+      }
+    }
+    free(msg->crc_list);
+  }
+}
+
+void free_uci_indication(nfapi_nr_uci_indication_t *msg)
+{
+  if (msg->uci_list) {
+    for (int pdu_idx = 0; pdu_idx < msg->num_ucis; ++pdu_idx) {
+      nfapi_nr_uci_t *uci_pdu = &msg->uci_list[pdu_idx];
+      switch (uci_pdu->pdu_type) {
+        case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
+          nfapi_nr_uci_pusch_pdu_t *pdu = &uci_pdu->pusch_pdu;
+          // Bit 0 not used in PUSCH PDU
+          // HARQ
+          if ((pdu->pduBitmap >> 1) & 0x01) {
+            if (pdu->harq.harq_payload) {
+              free(pdu->harq.harq_payload);
+            }
+          }
+          // CSI Part 1
+          if ((pdu->pduBitmap >> 2) & 0x01) {
+            if (pdu->csi_part1.csi_part1_payload) {
+              free(pdu->csi_part1.csi_part1_payload);
+            }
+          }
+          // CSI Part 2
+          if ((pdu->pduBitmap >> 3) & 0x01) {
+            if (pdu->csi_part2.csi_part2_payload) {
+              free(pdu->csi_part2.csi_part2_payload);
+            }
+          }
+          break;
+        }
+        case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
+          // Nothing to free
+          break;
+        }
+        case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
+          nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu = &uci_pdu->pucch_pdu_format_2_3_4;
+          // SR
+          if (pdu->pduBitmap & 0x01) {
+            if (pdu->sr.sr_payload) {
+              free(pdu->sr.sr_payload);
+            }
+          }
+          // HARQ
+          if ((pdu->pduBitmap >> 1) & 0x01) {
+            if (pdu->harq.harq_payload) {
+              free(pdu->harq.harq_payload);
+            }
+          }
+          // CSI Part 1
+          if ((pdu->pduBitmap >> 2) & 0x01) {
+            if (pdu->csi_part1.csi_part1_payload) {
+              free(pdu->csi_part1.csi_part1_payload);
+            }
+          }
+          // CSI Part 2
+          if ((pdu->pduBitmap >> 3) & 0x01) {
+            if (pdu->csi_part2.csi_part2_payload) {
+              free(pdu->csi_part2.csi_part2_payload);
+            }
+          }
+          break;
+        }
+        default:
+          AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", uci_pdu->pdu_type);
+          break;
+      }
+    }
+    free(msg->uci_list);
+  }
+}
+
+void free_srs_indication(nfapi_nr_srs_indication_t *msg)
+{
+  if (msg->pdu_list) {
+    free(msg->pdu_list);
+  }
+}
+
+void free_rach_indication(nfapi_nr_rach_indication_t *msg)
+{
+  if (msg->pdu_list) {
+    free(msg->pdu_list);
+  }
+}
+
+static void copy_dl_tti_beamforming(const nfapi_nr_tx_precoding_and_beamforming_t *src,
+                                    nfapi_nr_tx_precoding_and_beamforming_t *dst)
+{
+  dst->num_prgs = src->num_prgs;
+  dst->prg_size = src->prg_size;
+  dst->dig_bf_interfaces = src->dig_bf_interfaces;
+  for (int prg = 0; prg < dst->num_prgs; ++prg) {
+    dst->prgs_list[prg].pm_idx = src->prgs_list[prg].pm_idx;
+    for (int dbf_if = 0; dbf_if < dst->dig_bf_interfaces; ++dbf_if) {
+      dst->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx = src->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx;
+    }
+  }
+}
+
+static void copy_dl_tti_request_pdcch_pdu(const nfapi_nr_dl_tti_pdcch_pdu_rel15_t *src, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *dst)
+{
+  dst->BWPSize = src->BWPSize;
+  dst->BWPStart = src->BWPStart;
+  dst->SubcarrierSpacing = src->SubcarrierSpacing;
+  dst->CyclicPrefix = src->CyclicPrefix;
+  dst->StartSymbolIndex = src->StartSymbolIndex;
+  dst->DurationSymbols = src->DurationSymbols;
+  for (int fdr_idx = 0; fdr_idx < 6; ++fdr_idx) {
+    dst->FreqDomainResource[fdr_idx] = src->FreqDomainResource[fdr_idx];
+  }
+  dst->CceRegMappingType = src->CceRegMappingType;
+  dst->RegBundleSize = src->RegBundleSize;
+  dst->InterleaverSize = src->InterleaverSize;
+  dst->CoreSetType = src->CoreSetType;
+  dst->ShiftIndex = src->ShiftIndex;
+  dst->precoderGranularity = src->precoderGranularity;
+  dst->numDlDci = src->numDlDci;
+  for (int dl_dci = 0; dl_dci < dst->numDlDci; ++dl_dci) {
+    nfapi_nr_dl_dci_pdu_t *dst_dci_pdu = &dst->dci_pdu[dl_dci];
+    const nfapi_nr_dl_dci_pdu_t *src_dci_pdu = &src->dci_pdu[dl_dci];
+    dst_dci_pdu->RNTI = src_dci_pdu->RNTI;
+    dst_dci_pdu->ScramblingId = src_dci_pdu->ScramblingId;
+    dst_dci_pdu->ScramblingRNTI = src_dci_pdu->ScramblingRNTI;
+    dst_dci_pdu->CceIndex = src_dci_pdu->CceIndex;
+    dst_dci_pdu->AggregationLevel = src_dci_pdu->AggregationLevel;
+    copy_dl_tti_beamforming(&src_dci_pdu->precodingAndBeamforming, &dst_dci_pdu->precodingAndBeamforming);
+    dst_dci_pdu->beta_PDCCH_1_0 = src_dci_pdu->beta_PDCCH_1_0;
+    dst_dci_pdu->powerControlOffsetSS = src_dci_pdu->powerControlOffsetSS;
+    dst_dci_pdu->PayloadSizeBits = src_dci_pdu->PayloadSizeBits;
+    for (int i = 0; i < 8; ++i) {
+      dst_dci_pdu->Payload[i] = src_dci_pdu->Payload[i];
+    }
+  }
+}
+
+static void copy_dl_tti_request_pdsch_pdu(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t *src, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dst)
+{
+  dst->pduBitmap = src->pduBitmap;
+  dst->rnti = src->rnti;
+  dst->pduIndex = src->pduIndex;
+  dst->BWPSize = src->BWPSize;
+  dst->BWPStart = src->BWPStart;
+  dst->SubcarrierSpacing = src->SubcarrierSpacing;
+  dst->CyclicPrefix = src->CyclicPrefix;
+  dst->NrOfCodewords = src->NrOfCodewords;
+  for (int cw = 0; cw < dst->NrOfCodewords; ++cw) {
+    dst->targetCodeRate[cw] = src->targetCodeRate[cw];
+    dst->qamModOrder[cw] = src->qamModOrder[cw];
+    dst->mcsIndex[cw] = src->mcsIndex[cw];
+    dst->mcsTable[cw] = src->mcsTable[cw];
+    dst->rvIndex[cw] = src->rvIndex[cw];
+    dst->TBSize[cw] = src->TBSize[cw];
+  }
+  dst->dataScramblingId = src->dataScramblingId;
+  dst->nrOfLayers = src->nrOfLayers;
+  dst->transmissionScheme = src->transmissionScheme;
+  dst->refPoint = src->refPoint;
+  dst->dlDmrsSymbPos = src->dlDmrsSymbPos;
+  dst->dmrsConfigType = src->dmrsConfigType;
+  dst->dlDmrsScramblingId = src->dlDmrsScramblingId;
+  dst->SCID = src->SCID;
+  dst->numDmrsCdmGrpsNoData = src->numDmrsCdmGrpsNoData;
+  dst->dmrsPorts = src->dmrsPorts;
+  dst->resourceAlloc = src->resourceAlloc;
+  for (int i = 0; i < 36; ++i) {
+    dst->rbBitmap[i] = src->rbBitmap[i];
+  }
+  dst->rbStart = src->rbStart;
+  dst->rbSize = src->rbSize;
+  dst->VRBtoPRBMapping = src->VRBtoPRBMapping;
+  dst->StartSymbolIndex = src->StartSymbolIndex;
+  dst->NrOfSymbols = src->NrOfSymbols;
+  dst->PTRSPortIndex = src->PTRSPortIndex;
+  dst->PTRSTimeDensity = src->PTRSTimeDensity;
+  dst->PTRSFreqDensity = src->PTRSFreqDensity;
+  dst->PTRSReOffset = src->PTRSReOffset;
+  dst->nEpreRatioOfPDSCHToPTRS = src->nEpreRatioOfPDSCHToPTRS;
+  copy_dl_tti_beamforming(&src->precodingAndBeamforming, &dst->precodingAndBeamforming);
+  dst->powerControlOffset = src->powerControlOffset;
+  dst->powerControlOffsetSS = src->powerControlOffsetSS;
+  dst->isLastCbPresent = src->isLastCbPresent;
+  dst->isInlineTbCrc = src->isInlineTbCrc;
+  dst->dlTbCrc = src->dlTbCrc;
+  dst->maintenance_parms_v3.ldpcBaseGraph = src->maintenance_parms_v3.ldpcBaseGraph;
+  dst->maintenance_parms_v3.tbSizeLbrmBytes = src->maintenance_parms_v3.tbSizeLbrmBytes;
+}
+
+static void copy_dl_tti_request_csi_rs_pdu(const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *src, nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *dst)
+{
+  dst->bwp_size = src->bwp_size;
+  dst->bwp_start = src->bwp_start;
+  dst->subcarrier_spacing = src->subcarrier_spacing;
+  dst->cyclic_prefix = src->cyclic_prefix;
+  dst->start_rb = src->start_rb;
+  dst->nr_of_rbs = src->nr_of_rbs;
+  dst->csi_type = src->csi_type;
+  dst->row = src->row;
+  dst->freq_domain = src->freq_domain;
+  dst->symb_l0 = src->symb_l0;
+  dst->symb_l1 = src->symb_l1;
+  dst->cdm_type = src->cdm_type;
+  dst->freq_density = src->freq_density;
+  dst->scramb_id = src->scramb_id;
+  dst->power_control_offset = src->power_control_offset;
+  dst->power_control_offset_ss = src->power_control_offset_ss;
+  copy_dl_tti_beamforming(&src->precodingAndBeamforming, &dst->precodingAndBeamforming);
+}
+
+static void copy_dl_tti_request_ssb_pdu(const nfapi_nr_dl_tti_ssb_pdu_rel15_t *src, nfapi_nr_dl_tti_ssb_pdu_rel15_t *dst)
+{
+  dst->PhysCellId = src->PhysCellId;
+  dst->BetaPss = src->BetaPss;
+  dst->SsbBlockIndex = src->SsbBlockIndex;
+  dst->SsbSubcarrierOffset = src->SsbSubcarrierOffset;
+  dst->ssbOffsetPointA = src->ssbOffsetPointA;
+  dst->bchPayloadFlag = src->bchPayloadFlag;
+  dst->bchPayload = src->bchPayload;
+  dst->ssbRsrp = src->ssbRsrp;
+  copy_dl_tti_beamforming(&src->precoding_and_beamforming, &dst->precoding_and_beamforming);
+}
+
+static void copy_dl_tti_request_pdu(const nfapi_nr_dl_tti_request_pdu_t *src, nfapi_nr_dl_tti_request_pdu_t *dst)
+{
+  dst->PDUType = src->PDUType;
+  dst->PDUSize = src->PDUSize;
+
+  switch (dst->PDUType) {
+    case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE:
+      copy_dl_tti_request_pdcch_pdu(&src->pdcch_pdu.pdcch_pdu_rel15, &dst->pdcch_pdu.pdcch_pdu_rel15);
+      break;
+    case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE:
+      copy_dl_tti_request_pdsch_pdu(&src->pdsch_pdu.pdsch_pdu_rel15, &dst->pdsch_pdu.pdsch_pdu_rel15);
+      break;
+    case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE:
+      copy_dl_tti_request_csi_rs_pdu(&src->csi_rs_pdu.csi_rs_pdu_rel15, &dst->csi_rs_pdu.csi_rs_pdu_rel15);
+      break;
+    case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
+      copy_dl_tti_request_ssb_pdu(&src->ssb_pdu.ssb_pdu_rel15, &dst->ssb_pdu.ssb_pdu_rel15);
+      break;
+    default:
+      // PDU Type is not any known value
+      AssertFatal(1 == 0, "PDU Type value unknown, allowed values range from 0 to 3\n");
+  }
+}
+
+void copy_dl_tti_request(const nfapi_nr_dl_tti_request_t *src, nfapi_nr_dl_tti_request_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->SFN = src->SFN;
+  dst->Slot = src->Slot;
+  dst->dl_tti_request_body.nPDUs = src->dl_tti_request_body.nPDUs;
+  dst->dl_tti_request_body.nGroup = src->dl_tti_request_body.nGroup;
+  for (int pdu = 0; pdu < dst->dl_tti_request_body.nPDUs; ++pdu) {
+    copy_dl_tti_request_pdu(&src->dl_tti_request_body.dl_tti_pdu_list[pdu], &dst->dl_tti_request_body.dl_tti_pdu_list[pdu]);
+  }
+  if (dst->dl_tti_request_body.nGroup > 0) {
+    for (int nGroup = 0; nGroup < dst->dl_tti_request_body.nGroup; ++nGroup) {
+      dst->dl_tti_request_body.nUe[nGroup] = src->dl_tti_request_body.nUe[nGroup];
+      for (int UE = 0; UE < dst->dl_tti_request_body.nUe[nGroup]; ++UE) {
+        dst->dl_tti_request_body.PduIdx[nGroup][UE] = src->dl_tti_request_body.PduIdx[nGroup][UE];
+      }
+    }
+  }
+}
+
+static void copy_ul_tti_beamforming(const nfapi_nr_ul_beamforming_t *src, nfapi_nr_ul_beamforming_t *dst)
+{
+  dst->trp_scheme = src->trp_scheme;
+  dst->num_prgs = src->num_prgs;
+  dst->prg_size = src->prg_size;
+  dst->dig_bf_interface = src->dig_bf_interface;
+
+  for (int prg = 0; prg < dst->num_prgs; ++prg) {
+    if (dst->dig_bf_interface > 0) {
+      for (int dbf_if = 0; dbf_if < dst->dig_bf_interface; ++dbf_if) {
+        dst->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx = src->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx;
+      }
+    }
+  }
+}
+
+static void copy_ul_tti_request_prach_pdu(const nfapi_nr_prach_pdu_t *src, nfapi_nr_prach_pdu_t *dst)
+{
+  dst->phys_cell_id = src->phys_cell_id;
+  dst->num_prach_ocas = src->num_prach_ocas;
+  dst->prach_format = src->prach_format;
+  dst->num_ra = src->num_ra;
+  dst->prach_start_symbol = src->prach_start_symbol;
+  dst->num_cs = src->num_cs;
+  copy_ul_tti_beamforming(&src->beamforming, &dst->beamforming);
+}
+
+static void copy_ul_tti_request_pusch_pdu(const nfapi_nr_pusch_pdu_t *src, nfapi_nr_pusch_pdu_t *dst)
+{
+  dst->pdu_bit_map = src->pdu_bit_map;
+  dst->rnti = src->rnti;
+  dst->handle = src->handle;
+  dst->bwp_size = src->bwp_size;
+  dst->bwp_start = src->bwp_start;
+  dst->subcarrier_spacing = src->subcarrier_spacing;
+  dst->cyclic_prefix = src->cyclic_prefix;
+  dst->target_code_rate = src->target_code_rate;
+  dst->qam_mod_order = src->qam_mod_order;
+  dst->mcs_index = src->mcs_index;
+  dst->mcs_table = src->mcs_table;
+  dst->transform_precoding = src->transform_precoding;
+  dst->data_scrambling_id = src->data_scrambling_id;
+  dst->nrOfLayers = src->nrOfLayers;
+  dst->ul_dmrs_symb_pos = src->ul_dmrs_symb_pos;
+  dst->dmrs_config_type = src->dmrs_config_type;
+  dst->ul_dmrs_scrambling_id = src->ul_dmrs_scrambling_id;
+  dst->pusch_identity = src->pusch_identity;
+  dst->scid = src->scid;
+  dst->num_dmrs_cdm_grps_no_data = src->num_dmrs_cdm_grps_no_data;
+  dst->dmrs_ports = src->dmrs_ports;
+  dst->resource_alloc = src->resource_alloc;
+  for (int i = 0; i < 36; ++i) {
+    dst->rb_bitmap[i] = src->rb_bitmap[i];
+  }
+  dst->rb_start = src->rb_start;
+  dst->rb_size = src->rb_size;
+  dst->vrb_to_prb_mapping = src->vrb_to_prb_mapping;
+  dst->frequency_hopping = src->frequency_hopping;
+  dst->tx_direct_current_location = src->tx_direct_current_location;
+  dst->uplink_frequency_shift_7p5khz = src->uplink_frequency_shift_7p5khz;
+  dst->start_symbol_index = src->start_symbol_index;
+  dst->nr_of_symbols = src->nr_of_symbols;
+
+  if (dst->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
+    const nfapi_nr_pusch_data_t *src_pusch_data = &src->pusch_data;
+    nfapi_nr_pusch_data_t *dst_pusch_data = &dst->pusch_data;
+    dst_pusch_data->rv_index = src_pusch_data->rv_index;
+    dst_pusch_data->harq_process_id = src_pusch_data->harq_process_id;
+    dst_pusch_data->new_data_indicator = src_pusch_data->new_data_indicator;
+    dst_pusch_data->tb_size = src_pusch_data->tb_size;
+    dst_pusch_data->num_cb = src_pusch_data->num_cb;
+    for (int i = 0; i < (src_pusch_data->num_cb + 7) / 8; ++i) {
+      dst_pusch_data->cb_present_and_position[i] = src_pusch_data->cb_present_and_position[i];
+    }
+  }
+  if (src->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
+    const nfapi_nr_pusch_uci_t *src_pusch_uci = &src->pusch_uci;
+    nfapi_nr_pusch_uci_t *dst_pusch_uci = &dst->pusch_uci;
+    dst_pusch_uci->harq_ack_bit_length = src_pusch_uci->harq_ack_bit_length;
+    dst_pusch_uci->csi_part1_bit_length = src_pusch_uci->csi_part1_bit_length;
+    dst_pusch_uci->csi_part2_bit_length = src_pusch_uci->csi_part2_bit_length;
+    dst_pusch_uci->alpha_scaling = src_pusch_uci->alpha_scaling;
+    dst_pusch_uci->beta_offset_harq_ack = src_pusch_uci->beta_offset_harq_ack;
+    dst_pusch_uci->beta_offset_csi1 = src_pusch_uci->beta_offset_csi1;
+    dst_pusch_uci->beta_offset_csi2 = src_pusch_uci->beta_offset_csi2;
+  }
+  if (src->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+    const nfapi_nr_pusch_ptrs_t *src_pusch_ptrs = &src->pusch_ptrs;
+    nfapi_nr_pusch_ptrs_t *dst_pusch_ptrs = &dst->pusch_ptrs;
+
+    dst_pusch_ptrs->num_ptrs_ports = src_pusch_ptrs->num_ptrs_ports;
+    dst_pusch_ptrs->ptrs_ports_list = calloc(dst_pusch_ptrs->num_ptrs_ports, sizeof(nfapi_nr_ptrs_ports_t));
+    for (int i = 0; i < src_pusch_ptrs->num_ptrs_ports; ++i) {
+      const nfapi_nr_ptrs_ports_t *src_ptrs_port = &src_pusch_ptrs->ptrs_ports_list[i];
+      nfapi_nr_ptrs_ports_t *dst_ptrs_port = &dst_pusch_ptrs->ptrs_ports_list[i];
+
+      dst_ptrs_port->ptrs_port_index = src_ptrs_port->ptrs_port_index;
+      dst_ptrs_port->ptrs_dmrs_port = src_ptrs_port->ptrs_dmrs_port;
+      dst_ptrs_port->ptrs_re_offset = src_ptrs_port->ptrs_re_offset;
+    }
+
+    dst_pusch_ptrs->ptrs_time_density = src_pusch_ptrs->ptrs_time_density;
+    dst_pusch_ptrs->ptrs_freq_density = src_pusch_ptrs->ptrs_freq_density;
+    dst_pusch_ptrs->ul_ptrs_power = src_pusch_ptrs->ul_ptrs_power;
+  }
+  if (src->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
+    const nfapi_nr_dfts_ofdm_t *src_dfts_ofdm = &src->dfts_ofdm;
+    nfapi_nr_dfts_ofdm_t *dst_dfts_ofdm = &dst->dfts_ofdm;
+
+    dst_dfts_ofdm->low_papr_group_number = src_dfts_ofdm->low_papr_group_number;
+    dst_dfts_ofdm->low_papr_sequence_number = src_dfts_ofdm->low_papr_sequence_number;
+    dst_dfts_ofdm->ul_ptrs_sample_density = src_dfts_ofdm->ul_ptrs_sample_density;
+    dst_dfts_ofdm->ul_ptrs_time_density_transform_precoding = src_dfts_ofdm->ul_ptrs_time_density_transform_precoding;
+  }
+  copy_ul_tti_beamforming(&src->beamforming, &dst->beamforming);
+  dst->maintenance_parms_v3.ldpcBaseGraph = src->maintenance_parms_v3.ldpcBaseGraph;
+  dst->maintenance_parms_v3.tbSizeLbrmBytes = src->maintenance_parms_v3.tbSizeLbrmBytes;
+}
+
+static void copy_ul_tti_request_pucch_pdu(const nfapi_nr_pucch_pdu_t *src, nfapi_nr_pucch_pdu_t *dst)
+{
+  dst->rnti = src->rnti;
+  dst->handle = src->handle;
+  dst->bwp_size = src->bwp_size;
+  dst->bwp_start = src->bwp_start;
+  dst->subcarrier_spacing = src->subcarrier_spacing;
+  dst->cyclic_prefix = src->cyclic_prefix;
+  dst->format_type = src->format_type;
+  dst->multi_slot_tx_indicator = src->multi_slot_tx_indicator;
+  dst->pi_2bpsk = src->pi_2bpsk;
+  dst->prb_start = src->prb_start;
+  dst->prb_size = src->prb_size;
+  dst->start_symbol_index = src->start_symbol_index;
+  dst->nr_of_symbols = src->nr_of_symbols;
+  dst->freq_hop_flag = src->freq_hop_flag;
+  dst->second_hop_prb = src->second_hop_prb;
+  dst->group_hop_flag = src->group_hop_flag;
+  dst->sequence_hop_flag = src->sequence_hop_flag;
+  dst->hopping_id = src->hopping_id;
+  dst->initial_cyclic_shift = src->initial_cyclic_shift;
+  dst->data_scrambling_id = src->data_scrambling_id;
+  dst->time_domain_occ_idx = src->time_domain_occ_idx;
+  dst->pre_dft_occ_idx = src->pre_dft_occ_idx;
+  dst->pre_dft_occ_len = src->pre_dft_occ_len;
+  dst->add_dmrs_flag = src->add_dmrs_flag;
+  dst->dmrs_scrambling_id = src->dmrs_scrambling_id;
+  dst->dmrs_cyclic_shift = src->dmrs_cyclic_shift;
+  dst->sr_flag = src->sr_flag;
+  dst->bit_len_harq = src->bit_len_harq;
+  dst->bit_len_csi_part1 = src->bit_len_csi_part1;
+  dst->bit_len_csi_part2 = src->bit_len_csi_part2;
+  copy_ul_tti_beamforming(&src->beamforming, &dst->beamforming);
+}
+
+static void copy_ul_tti_request_srs_parameters(const nfapi_v4_srs_parameters_t *src,
+                                               const uint8_t num_symbols,
+                                               nfapi_v4_srs_parameters_t *dst)
+{
+  dst->srs_bandwidth_size = src->srs_bandwidth_size;
+  for (int symbol_idx = 0; symbol_idx < num_symbols; ++symbol_idx) {
+    nfapi_v4_srs_parameters_symbols_t *dst_symbol = &dst->symbol_list[symbol_idx];
+    const nfapi_v4_srs_parameters_symbols_t *src_symbol = &src->symbol_list[symbol_idx];
+    dst_symbol->srs_bandwidth_start = src_symbol->srs_bandwidth_start;
+    dst_symbol->sequence_group = src_symbol->sequence_group;
+    dst_symbol->sequence_number = src_symbol->sequence_number;
+  }
+
+#ifdef ENABLE_AERIAL
+  // For Aerial, we always process the 4 reported symbols, not only the ones indicated by num_symbols
+  for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
+    nfapi_v4_srs_parameters_symbols_t *dst_symbol = &dst->symbol_list[symbol_idx];
+    const nfapi_v4_srs_parameters_symbols_t *src_symbol = &src->symbol_list[symbol_idx];
+    dst_symbol->srs_bandwidth_start = src_symbol->srs_bandwidth_start;
+    dst_symbol->sequence_group = src_symbol->sequence_group;
+    dst_symbol->sequence_number = src_symbol->sequence_number;
+  }
+#endif // ENABLE_AERIAL
+  dst->usage = src->usage;
+  const uint8_t nUsage = __builtin_popcount(dst->usage);
+  for (int idx = 0; idx < nUsage; ++idx) {
+    dst->report_type[idx] = src->report_type[idx];
+  }
+  dst->singular_Value_representation = src->singular_Value_representation;
+  dst->iq_representation = src->iq_representation;
+  dst->prg_size = src->prg_size;
+  dst->num_total_ue_antennas = src->num_total_ue_antennas;
+  dst->ue_antennas_in_this_srs_resource_set = src->ue_antennas_in_this_srs_resource_set;
+  dst->sampled_ue_antennas = src->sampled_ue_antennas;
+  dst->report_scope = src->report_scope;
+  dst->num_ul_spatial_streams_ports = src->num_ul_spatial_streams_ports;
+  for (int idx = 0; idx < dst->num_ul_spatial_streams_ports; ++idx) {
+    dst->Ul_spatial_stream_ports[idx] = src->Ul_spatial_stream_ports[idx];
+  }
+}
+
+static void copy_ul_tti_request_srs_pdu(const nfapi_nr_srs_pdu_t *src, nfapi_nr_srs_pdu_t *dst)
+{
+  dst->rnti = src->rnti;
+  dst->handle = src->handle;
+  dst->bwp_size = src->bwp_size;
+  dst->bwp_start = src->bwp_start;
+  dst->subcarrier_spacing = src->subcarrier_spacing;
+  dst->cyclic_prefix = src->cyclic_prefix;
+  dst->num_ant_ports = src->num_ant_ports;
+  dst->num_symbols = src->num_symbols;
+  dst->num_repetitions = src->num_repetitions;
+  dst->time_start_position = src->time_start_position;
+  dst->config_index = src->config_index;
+  dst->sequence_id = src->sequence_id;
+  dst->bandwidth_index = src->bandwidth_index;
+  dst->comb_size = src->comb_size;
+  dst->comb_offset = src->comb_offset;
+  dst->cyclic_shift = src->cyclic_shift;
+  dst->frequency_position = src->frequency_position;
+  dst->frequency_shift = src->frequency_shift;
+  dst->frequency_hopping = src->frequency_hopping;
+  dst->group_or_sequence_hopping = src->group_or_sequence_hopping;
+  dst->resource_type = src->resource_type;
+  dst->t_srs = src->t_srs;
+  dst->t_offset = src->t_offset;
+  copy_ul_tti_beamforming(&src->beamforming, &dst->beamforming);
+  copy_ul_tti_request_srs_parameters(&src->srs_parameters_v4, 1 << src->num_symbols, &dst->srs_parameters_v4);
+}
+
+void copy_ul_tti_request(const nfapi_nr_ul_tti_request_t *src, nfapi_nr_ul_tti_request_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+
+  dst->SFN = src->SFN;
+  dst->Slot = src->Slot;
+  dst->n_pdus = src->n_pdus;
+  dst->rach_present = src->rach_present;
+  dst->n_ulsch = src->n_ulsch;
+  dst->n_ulcch = src->n_ulcch;
+  dst->n_group = src->n_group;
+
+  for (int PDU = 0; PDU < src->n_pdus; ++PDU) {
+    // take the PDU at the start of loops
+    const nfapi_nr_ul_tti_request_number_of_pdus_t *src_pdu = &src->pdus_list[PDU];
+    nfapi_nr_ul_tti_request_number_of_pdus_t *dst_pdu = &dst->pdus_list[PDU];
+
+    dst_pdu->pdu_type = src_pdu->pdu_type;
+    dst_pdu->pdu_size = src_pdu->pdu_size;
+
+    switch (src_pdu->pdu_type) {
+      case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE:
+        copy_ul_tti_request_prach_pdu(&src_pdu->prach_pdu, &dst_pdu->prach_pdu);
+        break;
+      case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE:
+        copy_ul_tti_request_pusch_pdu(&src_pdu->pusch_pdu, &dst_pdu->pusch_pdu);
+        break;
+      case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE:
+        copy_ul_tti_request_pucch_pdu(&src_pdu->pucch_pdu, &dst_pdu->pucch_pdu);
+        break;
+      case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE:
+        copy_ul_tti_request_srs_pdu(&src_pdu->srs_pdu, &dst_pdu->srs_pdu);
+        break;
+      default:
+        // PDU Type is not any known value
+        AssertFatal(1 == 0, "PDU Type value unknown, allowed values range from 0 to 3\n");
+    }
+  }
+
+  for (int nGroup = 0; nGroup < src->n_group; ++nGroup) {
+    dst->groups_list[nGroup].n_ue = src->groups_list[nGroup].n_ue;
+    for (int UE = 0; UE < src->groups_list[nGroup].n_ue; ++UE) {
+      dst->groups_list[nGroup].ue_list[UE].pdu_idx = src->groups_list[nGroup].ue_list[UE].pdu_idx;
+    }
+  }
+}
+
+void copy_slot_indication(const nfapi_nr_slot_indication_scf_t *src, nfapi_nr_slot_indication_scf_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+
+  dst->sfn = src->sfn;
+  dst->slot = src->slot;
+}
+
+void copy_ul_dci_request_pdu(const nfapi_nr_ul_dci_request_pdus_t *src, nfapi_nr_ul_dci_request_pdus_t *dst)
+{
+  dst->PDUType = src->PDUType;
+  dst->PDUSize = src->PDUSize;
+
+  // Is the same PDU as the DL_TTI.request PDCCH PDU, reuse copy function
+  copy_dl_tti_request_pdcch_pdu(&src->pdcch_pdu.pdcch_pdu_rel15, &dst->pdcch_pdu.pdcch_pdu_rel15);
+}
+
+void copy_ul_dci_request(const nfapi_nr_ul_dci_request_t *src, nfapi_nr_ul_dci_request_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+
+  dst->SFN = src->SFN;
+  dst->Slot = src->Slot;
+  dst->numPdus = src->numPdus;
+
+  for (int pdu_idx = 0; pdu_idx < src->numPdus; ++pdu_idx) {
+    copy_ul_dci_request_pdu(&src->ul_dci_pdu_list[pdu_idx], &dst->ul_dci_pdu_list[pdu_idx]);
+  }
+}
+
+void copy_tx_data_request_PDU(const nfapi_nr_pdu_t *src, nfapi_nr_pdu_t *dst)
+{
+  dst->PDU_length = src->PDU_length;
+  dst->PDU_index = src->PDU_index;
+  dst->num_TLV = src->num_TLV;
+  for (int tlv_idx = 0; tlv_idx < src->num_TLV; ++tlv_idx) {
+    const nfapi_nr_tx_data_request_tlv_t *src_tlv = &src->TLVs[tlv_idx];
+    nfapi_nr_tx_data_request_tlv_t *dst_tlv = &dst->TLVs[tlv_idx];
+    dst_tlv->tag = src_tlv->tag;
+    dst_tlv->length = src_tlv->length;
+    switch (src_tlv->tag) {
+      case 0:
+        // value.direct
+        memcpy(dst_tlv->value.direct, src_tlv->value.direct, sizeof(src_tlv->value.direct));
+        break;
+      case 1:
+        // value.ptr
+        dst_tlv->value.ptr = calloc((src_tlv->length + 3) / 4, sizeof(uint32_t));
+        memcpy(dst_tlv->value.ptr, src_tlv->value.ptr, src_tlv->length);
+        break;
+      default:
+        AssertFatal(1 == 0, "TX_DATA request TLV tag value unsupported");
+        break;
+    }
+  }
+}
+
+void copy_tx_data_request(const nfapi_nr_tx_data_request_t *src, nfapi_nr_tx_data_request_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+
+  dst->SFN = src->SFN;
+  dst->Slot = src->Slot;
+  dst->Number_of_PDUs = src->Number_of_PDUs;
+  for (int pdu_idx = 0; pdu_idx < src->Number_of_PDUs; ++pdu_idx) {
+    copy_tx_data_request_PDU(&src->pdu_list[pdu_idx], &dst->pdu_list[pdu_idx]);
+  }
+}
+
+size_t get_tx_data_request_size(const nfapi_nr_tx_data_request_t *msg)
+{
+  // Get size of the whole message ( allocated pointer included )
+  size_t total_size = sizeof(msg->header);
+  total_size += sizeof(msg->SFN);
+  total_size += sizeof(msg->Slot);
+  total_size += sizeof(msg->Number_of_PDUs);
+  for (int pdu_idx = 0; pdu_idx < msg->Number_of_PDUs; ++pdu_idx) {
+    const nfapi_nr_pdu_t *pdu = &msg->pdu_list[pdu_idx];
+    total_size += sizeof(pdu->PDU_length);
+    total_size += sizeof(pdu->PDU_index);
+    total_size += sizeof(pdu->num_TLV);
+    for (int tlv_idx = 0; tlv_idx < pdu->num_TLV; ++tlv_idx) {
+      const nfapi_nr_tx_data_request_tlv_t *tlv = &pdu->TLVs[tlv_idx];
+      total_size += sizeof(tlv->tag);
+      total_size += sizeof(tlv->length);
+      if (tlv->tag == 0) {
+        total_size += sizeof(tlv->value.direct);
+      } else {
+        total_size += (tlv->length + 3) / 4 * sizeof(uint32_t);
+      }
+    }
+  }
+  return total_size;
+}
+
+void copy_rx_data_indication_PDU(const nfapi_nr_rx_data_pdu_t *src, nfapi_nr_rx_data_pdu_t *dst)
+{
+  dst->handle = src->handle;
+  dst->rnti = src->rnti;
+  dst->harq_id = src->harq_id;
+  dst->pdu_length = src->pdu_length;
+  dst->ul_cqi = src->ul_cqi;
+  dst->timing_advance = src->timing_advance;
+  dst->rssi = src->rssi;
+  dst->pdu = calloc(dst->pdu_length, sizeof(uint8_t));
+  memcpy(dst->pdu, src->pdu, src->pdu_length);
+}
+
+void copy_rx_data_indication(const nfapi_nr_rx_data_indication_t *src, nfapi_nr_rx_data_indication_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+
+  dst->sfn = src->sfn;
+  dst->slot = src->slot;
+  dst->number_of_pdus = src->number_of_pdus;
+  dst->pdu_list = calloc(dst->number_of_pdus, sizeof(*dst->pdu_list));
+  for (int pdu_idx = 0; pdu_idx < src->number_of_pdus; ++pdu_idx) {
+    copy_rx_data_indication_PDU(&src->pdu_list[pdu_idx], &dst->pdu_list[pdu_idx]);
+  }
+}
+
+size_t get_rx_data_indication_size(const nfapi_nr_rx_data_indication_t *msg)
+{
+  // Get size of the whole message ( allocated pointer included )
+  size_t total_size = sizeof(msg->header);
+  total_size += sizeof(msg->sfn);
+  total_size += sizeof(msg->slot);
+  total_size += sizeof(msg->number_of_pdus);
+  for (int pdu_idx = 0; pdu_idx < msg->number_of_pdus; ++pdu_idx) {
+    const nfapi_nr_rx_data_pdu_t *pdu = &msg->pdu_list[pdu_idx];
+    total_size += sizeof(pdu->handle);
+    total_size += sizeof(pdu->rnti);
+    total_size += sizeof(pdu->harq_id);
+    total_size += sizeof(pdu->pdu_length);
+    total_size += sizeof(pdu->ul_cqi);
+    total_size += sizeof(pdu->timing_advance);
+    total_size += sizeof(pdu->rssi);
+    total_size += pdu->pdu_length;
+  }
+  return total_size;
+}
+
+void copy_crc_indication_CRC(const nfapi_nr_crc_t *src, nfapi_nr_crc_t *dst)
+{
+  dst->handle = src->handle;
+  dst->rnti = src->rnti;
+  dst->harq_id = src->harq_id;
+  dst->tb_crc_status = src->tb_crc_status;
+  dst->num_cb = src->num_cb;
+  if (dst->num_cb > 0) {
+    const uint16_t cb_len = (dst->num_cb / 8) + 1;
+    dst->cb_crc_status = calloc(cb_len, sizeof(uint8_t));
+    for (int cb = 0; cb < cb_len; ++cb) {
+      dst->cb_crc_status[cb] = src->cb_crc_status[cb];
+    }
+  }
+  dst->ul_cqi = src->ul_cqi;
+  dst->timing_advance = src->timing_advance;
+  dst->rssi = src->rssi;
+}
+
+void copy_crc_indication(const nfapi_nr_crc_indication_t *src, nfapi_nr_crc_indication_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+
+  dst->sfn = src->sfn;
+  dst->slot = src->slot;
+  dst->number_crcs = src->number_crcs;
+  dst->crc_list = calloc(dst->number_crcs, sizeof(*dst->crc_list));
+  for (int crc_idx = 0; crc_idx < src->number_crcs; ++crc_idx) {
+    copy_crc_indication_CRC(&src->crc_list[crc_idx], &dst->crc_list[crc_idx]);
+  }
+}
+
+size_t get_crc_indication_size(const nfapi_nr_crc_indication_t *msg)
+{
+  // Get size of the whole message ( allocated pointer included )
+  size_t total_size = sizeof(msg->header);
+  total_size += sizeof(msg->sfn);
+  total_size += sizeof(msg->slot);
+  total_size += sizeof(msg->number_crcs);
+  for (int crc_idx = 0; crc_idx < msg->number_crcs; ++crc_idx) {
+    const nfapi_nr_crc_t *crc = &msg->crc_list[crc_idx];
+    total_size += sizeof(crc->handle);
+    total_size += sizeof(crc->rnti);
+    total_size += sizeof(crc->harq_id);
+    total_size += sizeof(crc->tb_crc_status);
+    total_size += sizeof(crc->num_cb);
+    if (crc->num_cb > 0) {
+      total_size += crc->num_cb / 8 + 1;
+    }
+    total_size += sizeof(crc->ul_cqi);
+    total_size += sizeof(crc->timing_advance);
+    total_size += sizeof(crc->rssi);
+  }
+  return total_size;
+}
+
+void copy_uci_indication_sr_pdu_0_1(const nfapi_nr_sr_pdu_0_1_t *src, nfapi_nr_sr_pdu_0_1_t *dst)
+{
+  dst->sr_indication = src->sr_indication;
+  dst->sr_confidence_level = src->sr_confidence_level;
+}
+
+void copy_uci_indication_sr_pdu_2_3_4(const nfapi_nr_sr_pdu_2_3_4_t *src, nfapi_nr_sr_pdu_2_3_4_t *dst)
+{
+  dst->sr_bit_len = src->sr_bit_len;
+  const uint16_t sr_len = (dst->sr_bit_len / 8) + 1;
+  dst->sr_payload = calloc(sr_len, sizeof(*dst->sr_payload));
+  for (int i = 0; i < sr_len; ++i) {
+    dst->sr_payload[i] = src->sr_payload[i];
+  }
+}
+
+void copy_uci_indication_harq_pdu_0_1(const nfapi_nr_harq_pdu_0_1_t *src, nfapi_nr_harq_pdu_0_1_t *dst)
+{
+  dst->num_harq = src->num_harq;
+  dst->harq_confidence_level = src->harq_confidence_level;
+  for (int i = 0; i < dst->num_harq; ++i) {
+    dst->harq_list[i].harq_value = src->harq_list[i].harq_value;
+  }
+}
+
+void copy_uci_indication_harq_pdu_2_3_4(const nfapi_nr_harq_pdu_2_3_4_t *src, nfapi_nr_harq_pdu_2_3_4_t *dst)
+{
+  dst->harq_crc = src->harq_crc;
+  dst->harq_bit_len = src->harq_bit_len;
+  const uint16_t harq_length = (dst->harq_bit_len / 8) + 1;
+  dst->harq_payload = calloc(harq_length, sizeof(*dst->harq_payload));
+  for (int i = 0; i < harq_length; ++i) {
+    dst->harq_payload[i] = src->harq_payload[i];
+  }
+}
+
+void copy_uci_indication_csi_part1(const nfapi_nr_csi_part1_pdu_t *src, nfapi_nr_csi_part1_pdu_t *dst)
+{
+  dst->csi_part1_crc = src->csi_part1_crc;
+  dst->csi_part1_bit_len = src->csi_part1_bit_len;
+  const uint16_t payload_length = (dst->csi_part1_bit_len / 8) + 1;
+  dst->csi_part1_payload = calloc(payload_length, sizeof(*dst->csi_part1_payload));
+  for (int i = 0; i < payload_length; ++i) {
+    dst->csi_part1_payload[i] = src->csi_part1_payload[i];
+  }
+}
+
+void copy_uci_indication_csi_part2(const nfapi_nr_csi_part2_pdu_t *src, nfapi_nr_csi_part2_pdu_t *dst)
+{
+  dst->csi_part2_crc = src->csi_part2_crc;
+  dst->csi_part2_bit_len = src->csi_part2_bit_len;
+  const uint16_t payload_length = (dst->csi_part2_bit_len / 8) + 1;
+  dst->csi_part2_payload = calloc(payload_length, sizeof(*dst->csi_part2_payload));
+  for (int i = 0; i < payload_length; ++i) {
+    dst->csi_part2_payload[i] = src->csi_part2_payload[i];
+  }
+}
+
+void copy_uci_indication_PUSCH(const nfapi_nr_uci_pusch_pdu_t *src, nfapi_nr_uci_pusch_pdu_t *dst)
+{
+  dst->pduBitmap = src->pduBitmap;
+  dst->handle = src->handle;
+  dst->rnti = src->rnti;
+  dst->ul_cqi = src->ul_cqi;
+  dst->timing_advance = src->timing_advance;
+  dst->rssi = src->rssi;
+
+  // Bit 0 not used in PUSCH PDU
+  // HARQ
+  if ((dst->pduBitmap >> 1) & 0x01) {
+    copy_uci_indication_harq_pdu_2_3_4(&src->harq, &dst->harq);
+  }
+  // CSI Part 1
+  if ((dst->pduBitmap >> 2) & 0x01) {
+    copy_uci_indication_csi_part1(&src->csi_part1, &dst->csi_part1);
+  }
+  // CSI Part 2
+  if ((dst->pduBitmap >> 3) & 0x01) {
+    copy_uci_indication_csi_part2(&src->csi_part2, &dst->csi_part2);
+  }
+}
+
+void copy_uci_indication_PUCCH_0_1(const nfapi_nr_uci_pucch_pdu_format_0_1_t *src, nfapi_nr_uci_pucch_pdu_format_0_1_t *dst)
+{
+  dst->pduBitmap = src->pduBitmap;
+  dst->handle = src->handle;
+  dst->rnti = src->rnti;
+  dst->pucch_format = src->pucch_format;
+  dst->ul_cqi = src->ul_cqi;
+  dst->timing_advance = src->timing_advance;
+  dst->rssi = src->rssi;
+
+  // SR
+  if (dst->pduBitmap & 0x01) {
+    copy_uci_indication_sr_pdu_0_1(&src->sr, &dst->sr);
+  }
+  // HARQ
+  if ((dst->pduBitmap >> 1) & 0x01) {
+    copy_uci_indication_harq_pdu_0_1(&src->harq, &dst->harq);
+  }
+}
+
+void copy_uci_indication_PUCCH_2_3_4(const nfapi_nr_uci_pucch_pdu_format_2_3_4_t *src, nfapi_nr_uci_pucch_pdu_format_2_3_4_t *dst)
+{
+  dst->pduBitmap = src->pduBitmap;
+  dst->handle = src->handle;
+  dst->rnti = src->rnti;
+  dst->pucch_format = src->pucch_format;
+  dst->ul_cqi = src->ul_cqi;
+  dst->timing_advance = src->timing_advance;
+  dst->rssi = src->rssi;
+  // SR
+  if (dst->pduBitmap & 0x01) {
+    copy_uci_indication_sr_pdu_2_3_4(&src->sr, &dst->sr);
+  }
+  // HARQ
+  if ((dst->pduBitmap >> 1) & 0x01) {
+    copy_uci_indication_harq_pdu_2_3_4(&src->harq, &dst->harq);
+  }
+  // CSI Part 1
+  if ((dst->pduBitmap >> 2) & 0x01) {
+    copy_uci_indication_csi_part1(&src->csi_part1, &dst->csi_part1);
+  }
+  // CSI Part 2
+  if ((dst->pduBitmap >> 3) & 0x01) {
+    copy_uci_indication_csi_part2(&src->csi_part2, &dst->csi_part2);
+  }
+}
+
+void copy_uci_indication_UCI(const nfapi_nr_uci_t *src, nfapi_nr_uci_t *dst)
+{
+  dst->pdu_type = src->pdu_type;
+  dst->pdu_size = src->pdu_size;
+  switch (dst->pdu_type) {
+    case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
+      copy_uci_indication_PUSCH(&src->pusch_pdu, &dst->pusch_pdu);
+      break;
+    case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
+      copy_uci_indication_PUCCH_0_1(&src->pucch_pdu_format_0_1, &dst->pucch_pdu_format_0_1);
+      break;
+    case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
+      copy_uci_indication_PUCCH_2_3_4(&src->pucch_pdu_format_2_3_4, &dst->pucch_pdu_format_2_3_4);
+      break;
+    default:
+      AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", src->pdu_type);
+      break;
+  }
+}
+
+void copy_uci_indication(const nfapi_nr_uci_indication_t *src, nfapi_nr_uci_indication_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+  dst->sfn = src->sfn;
+  dst->slot = src->slot;
+  dst->num_ucis = src->num_ucis;
+  dst->uci_list = calloc(dst->num_ucis, sizeof(*dst->uci_list));
+  for (int crc_idx = 0; crc_idx < src->num_ucis; ++crc_idx) {
+    copy_uci_indication_UCI(&src->uci_list[crc_idx], &dst->uci_list[crc_idx]);
+  }
+}
+
+size_t get_uci_indication_size(const nfapi_nr_uci_indication_t *msg)
+{
+  // Get size of the message (allocated pointer included)
+  size_t total_size = 0;
+
+  // Header and fixed-size fields
+  total_size += sizeof(msg->header);
+  total_size += sizeof(msg->sfn);
+  total_size += sizeof(msg->slot);
+  total_size += sizeof(msg->num_ucis);
+
+  // Loop through each UCI in the uci_list
+  for (int uci_idx = 0; uci_idx < msg->num_ucis; ++uci_idx) {
+    const nfapi_nr_uci_t *uci_pdu = &msg->uci_list[uci_idx];
+
+    total_size += sizeof(uci_pdu->pdu_type);
+    total_size += sizeof(uci_pdu->pdu_size);
+
+    switch (uci_pdu->pdu_type) {
+      case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
+        total_size += sizeof(uci_pdu->pusch_pdu);
+
+        // HARQ payload, CSI Part 1 and 2 are conditionally allocated
+        if ((uci_pdu->pusch_pdu.pduBitmap >> 1) & 0x01) {
+          total_size += uci_pdu->pusch_pdu.harq.harq_bit_len / 8 + 1;
+        }
+        if ((uci_pdu->pusch_pdu.pduBitmap >> 2) & 0x01) {
+          total_size += uci_pdu->pusch_pdu.csi_part1.csi_part1_bit_len / 8 + 1;
+        }
+        if ((uci_pdu->pusch_pdu.pduBitmap >> 3) & 0x01) {
+          total_size += uci_pdu->pusch_pdu.csi_part2.csi_part2_bit_len / 8 + 1;
+        }
+        break;
+
+      case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
+        total_size += sizeof(uci_pdu->pucch_pdu_format_0_1);
+        // SR and HARQ are conditionally filled, but neither require calloc inside
+        break;
+
+      case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
+        total_size += sizeof(uci_pdu->pucch_pdu_format_2_3_4);
+
+        // SR, HARQ, CSI Part 1, and CSI Part 2 are conditionally allocated
+        if (uci_pdu->pucch_pdu_format_2_3_4.pduBitmap & 0x01) {
+          total_size += uci_pdu->pucch_pdu_format_2_3_4.sr.sr_bit_len / 8 + 1;
+        }
+        if ((uci_pdu->pucch_pdu_format_2_3_4.pduBitmap >> 1) & 0x01) {
+          total_size += uci_pdu->pucch_pdu_format_2_3_4.harq.harq_bit_len / 8 + 1;
+        }
+        if ((uci_pdu->pucch_pdu_format_2_3_4.pduBitmap >> 2) & 0x01) {
+          total_size += uci_pdu->pucch_pdu_format_2_3_4.csi_part1.csi_part1_bit_len / 8 + 1;
+        }
+        if ((uci_pdu->pucch_pdu_format_2_3_4.pduBitmap >> 3) & 0x01) {
+          total_size += uci_pdu->pucch_pdu_format_2_3_4.csi_part2.csi_part2_bit_len / 8 + 1;
+        }
+        break;
+
+      default:
+        AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", uci_pdu->pdu_type);
+        break;
+    }
+  }
+
+  // Finally, add the size of the uci_list pointer itself
+  total_size += msg->num_ucis * sizeof(*msg->uci_list);
+
+  return total_size;
+}
+
+void copy_srs_indication_report_tlv(const nfapi_srs_report_tlv_t *src, nfapi_srs_report_tlv_t *dst)
+{
+  dst->tag = src->tag;
+  dst->length = src->length;
+  for (int i = 0; i < (dst->length + 3) / 4; ++i) {
+    dst->value[i] = src->value[i];
+  }
+}
+
+void copy_srs_indication_PDU(const nfapi_nr_srs_indication_pdu_t *src, nfapi_nr_srs_indication_pdu_t *dst)
+{
+  dst->handle = src->handle;
+  dst->rnti = src->rnti;
+  dst->timing_advance_offset = src->timing_advance_offset;
+  dst->timing_advance_offset_nsec = src->timing_advance_offset_nsec;
+  dst->srs_usage = src->srs_usage;
+  dst->report_type = src->report_type;
+  copy_srs_indication_report_tlv(&src->report_tlv, &dst->report_tlv);
+}
+
+void copy_srs_indication(const nfapi_nr_srs_indication_t *src, nfapi_nr_srs_indication_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+  dst->sfn = src->sfn;
+  dst->slot = src->slot;
+  dst->control_length = src->control_length;
+  dst->number_of_pdus = src->number_of_pdus;
+  dst->pdu_list = calloc(dst->number_of_pdus, sizeof(*dst->pdu_list));
+  for (int pdu_idx = 0; pdu_idx < src->number_of_pdus; ++pdu_idx) {
+    copy_srs_indication_PDU(&src->pdu_list[pdu_idx], &dst->pdu_list[pdu_idx]);
+  }
+}
+
+size_t get_srs_indication_size(const nfapi_nr_srs_indication_t *msg)
+{
+  // Get size of the message (allocated pointer included)
+  size_t total_size = 0;
+
+  // Header and fixed-size fields
+  total_size += sizeof(msg->header);
+  total_size += sizeof(msg->sfn);
+  total_size += sizeof(msg->slot);
+  total_size += sizeof(msg->control_length);
+  total_size += sizeof(msg->number_of_pdus);
+  total_size += msg->number_of_pdus * sizeof(*msg->pdu_list);
+
+  return total_size;
+}
+
+static void copy_rach_indication_PDU(const nfapi_nr_prach_indication_pdu_t *src, nfapi_nr_prach_indication_pdu_t *dst)
+{
+  dst->phy_cell_id = src->phy_cell_id;
+  dst->symbol_index = src->symbol_index;
+  dst->slot_index = src->slot_index;
+  dst->freq_index = src->freq_index;
+  dst->avg_rssi = src->avg_rssi;
+  dst->avg_snr = src->avg_snr;
+  dst->num_preamble = src->num_preamble;
+  for (int preamble_idx = 0; preamble_idx < dst->num_preamble; ++preamble_idx) {
+    nfapi_nr_prach_indication_preamble_t *dst_pr = &dst->preamble_list[preamble_idx];
+    const nfapi_nr_prach_indication_preamble_t *src_pr = &src->preamble_list[preamble_idx];
+    dst_pr->preamble_index = src_pr->preamble_index;
+    dst_pr->timing_advance = src_pr->timing_advance;
+    dst_pr->preamble_pwr = src_pr->preamble_pwr;
+  }
+}
+
+void copy_rach_indication(const nfapi_nr_rach_indication_t *src, nfapi_nr_rach_indication_t *dst)
+{
+  dst->header.message_id = src->header.message_id;
+  dst->header.message_length = src->header.message_length;
+  dst->sfn = src->sfn;
+  dst->slot = src->slot;
+  dst->number_of_pdus = src->number_of_pdus;
+  dst->pdu_list = calloc(dst->number_of_pdus, sizeof(*dst->pdu_list));
+  for (int pdu_idx = 0; pdu_idx < dst->number_of_pdus; ++pdu_idx) {
+    copy_rach_indication_PDU(&src->pdu_list[pdu_idx], &dst->pdu_list[pdu_idx]);
+  }
+}
+
+size_t get_rach_indication_size(nfapi_nr_rach_indication_t *msg)
+{
+  // Get size of the message (allocated pointer included)
+  size_t total_size = 0;
+
+  // Header and fixed-size fields
+  total_size += sizeof(msg->header);
+  total_size += sizeof(msg->sfn);
+  total_size += sizeof(msg->slot);
+  total_size += sizeof(msg->number_of_pdus);
+  total_size += msg->number_of_pdus * sizeof(*msg->pdu_list);
+
+  return total_size;
+}
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_common_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_common_interface.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa3b9316a62dafb1a82bb1e2847793665a56e2eb
--- /dev/null
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_common_interface.h
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef NFAPI_COMMON_INTERFACE_H
+#define NFAPI_COMMON_INTERFACE_H
+
+typedef struct {
+  uint16_t tag;
+  uint16_t length;
+} nfapi_tl_t;
+
+/*! Configuration options for the p7 pack unpack functions
+ *
+ */
+
+typedef struct nfapi_p7_codec_config {
+  /*! Optional call back to allow the user to define the memory allocator.
+   *  \param size The size of the memory to allocate
+   *  \return a pointer to a valid memory block or 0 if it has failed.
+   *
+   * If not set the nfapi unpack functions will use malloc
+   */
+  void* (*allocate)(size_t size);
+
+  /*! Optional call back to allow the user to define the memory deallocator.
+   *  \param ptr A poiner to a memory block allocated by the allocate callback
+   *
+   *	If not set the client should use free
+   */
+  void (*deallocate)(void* ptr);
+
+  /*! Optional call back function to handle unpacking vendor extension tlv.
+   *  \param tl A pointer to a decoded tag length structure
+   *  \param ppReadPackedMsg A handle to the read buffer.
+   *  \param end The end of the read buffer
+   *  \param ve A handle to a vendor extention structure that the call back should allocate if the structure can be decoded
+   *  \param config A pointer to the p7 codec configuration
+   *  \return return 0 if packed successfully, -1 if failed.
+   *
+   *  If not set the tlv will be skipped
+   *
+   *  Client should use the help methods in nfapi.h to decode the vendor extention.
+   *
+   *  \todo Add code example
+   */
+  int (*unpack_vendor_extension_tlv)(nfapi_tl_t* tl,
+                                     uint8_t** ppReadPackedMsg,
+                                     uint8_t* end,
+                                     void** ve,
+                                     struct nfapi_p7_codec_config* config);
+
+  /*! Optional call back function to handle packing vendor extension tlv.
+   *  \param ve A pointer to a vendor extention structure.
+   *  \param ppWritePackedMsg A handle to the write buffer
+   *  \param end The end of the write buffer. The callee should make sure not to write beyond the end
+   *  \param config A pointer to the p7 codec configuration
+   *  \return return 0 if packed successfully, -1 if failed.
+   *
+   *  If not set the the tlv will be skipped
+   *
+   *  Client should use the help methods in nfapi.h to encode the vendor extention
+   *
+   *  \todo Add code example
+   */
+  int (*pack_vendor_extension_tlv)(void* ve, uint8_t** ppWritePackedMsg, uint8_t* end, struct nfapi_p7_codec_config* config);
+
+  /*! Optional call back function to handle unpacking vendor extension messages.
+   *  \param header A pointer to a decode P7 message header for the vendor extention message
+   *  \param ppReadPackedMsg A handle to the encoded data buffer
+   *  \param end A pointer to the end of the encoded data buffer
+   *  \param config  A pointer to the p7 codec configuration
+   *  \return 0 if unpacked successfully, -1 if failed
+   *
+   *  If not set the message will be ignored
+   *
+   *  If the message if is unknown the function should return -1
+   */
+  int (*unpack_p7_vendor_extension)(void* header, uint8_t** ppReadPackedMsg, uint8_t* end, struct nfapi_p7_codec_config* config);
+
+  /*! Optional call back function to handle packing vendor extension messages.
+   *  \param header A poiner to a P7 message structure for the venfor extention message
+   *  \param ppWritePackedmsg A handle to the buffer to write the encoded message into
+   *  \param end A pointer to the end of the buffer
+   *  \param cofig A pointer to the p7 codec configuration
+   *  \return 0 if packed successfully, -1 if failed
+   *
+   * If not set the the message will be ingored
+   *
+   *  If the message if is unknown the function should return -1
+   */
+  int (*pack_p7_vendor_extension)(void* header, uint8_t** ppWritePackedmsg, uint8_t* end, struct nfapi_p7_codec_config* config);
+
+  /*! Optional user data that will be passed back with callbacks
+   */
+  void* user_data;
+
+} nfapi_p7_codec_config_t;
+
+/*! Configuration options for the p4 & p5 pack unpack functions
+ *
+ */
+typedef struct nfapi_p4_p5_codec_config {
+  /*! Optional call back to allow the user to define the memory allocator.
+   *  \param size The size of the memory to allocate
+   *  \return a pointer to a valid memory block or 0 if it has failed.
+   *
+   *  If not set the nfapi unpack functions will use malloc
+   */
+  void* (*allocate)(size_t size);
+
+  /*! Optional call back to allow the user to define the memory deallocator.
+   *  \param ptr A poiner to a memory block allocated by the allocate callback
+   *
+   *  If not set free will be used
+   */
+  void (*deallocate)(void* ptr);
+
+  /*! Optional call back function to handle unpacking vendor extension tlv.
+   *  \param tl A pointer to a decoded tag length structure
+   *  \param ppReadPackedMsg A handle to the data buffer to decode
+   *  \param end A pointer to the end of the buffer
+   *  \param ve A handle to a vendor extention structure that will be allocated by this callback
+   *  \param config A pointer to the P4/P5 codec configuration
+   *  \return 0 if unpacked successfully, -1 if failed
+   *
+   *  If not set the tlv will be skipped
+   */
+  int (*unpack_vendor_extension_tlv)(nfapi_tl_t* tl,
+                                     uint8_t** ppReadPackedMsg,
+                                     uint8_t* end,
+                                     void** ve,
+                                     struct nfapi_p4_p5_codec_config* config);
+
+  /*! Optional call back function to handle packing vendor extension tlv.
+   *  \param ve
+   *  \param ppWritePackedMsg A handle to the data buffer pack the tlv into
+   *  \param end A pointer to the end of the buffer
+   *  \param config A pointer to the P4/P5 codec configuration
+   *  \return 0 if packed successfully, -1 if failed
+   *
+   *  If not set the the tlv will be skipped
+   */
+  int (*pack_vendor_extension_tlv)(void* ve, uint8_t** ppWritePackedMsg, uint8_t* end, struct nfapi_p4_p5_codec_config* config);
+
+  /*! Optional call back function to handle unpacking vendor extension messages.
+   *  \param header A pointer to a decode P4/P5 message header
+   *  \param ppReadPackgedMsg A handle to the data buffer to decode
+   *  \param end A pointer to the end of the buffer
+   *  \param config A pointer to the P4/P5 codec configuration
+   *  \return 0 if packed successfully, -1 if failed
+   *
+   * If not set the message will be ignored
+   */
+  int (*unpack_p4_p5_vendor_extension)(void* header,
+                                       uint8_t** ppReadPackedMsg,
+                                       uint8_t* end,
+                                       struct nfapi_p4_p5_codec_config* config);
+
+  /*! Optional call back function to handle packing vendor extension messages.
+   *  \param header A pointer to the P4/P5 message header to be encoded
+   *  \param ppWritePackedMsg A handle to the data buffer pack the message into
+   *  \param end A pointer to the end of the buffer
+   *  \param config A pointer to the P4/P5 codec configuration
+   *  \return 0 if packed successfully, -1 if failed
+   *
+   *  If not set the the message will be ingored
+   */
+  int (*pack_p4_p5_vendor_extension)(void* header,
+                                     uint8_t** ppwritepackedmsg,
+                                     uint8_t* end,
+                                     struct nfapi_p4_p5_codec_config* config);
+
+  /*! Optional user data that will be passed back with callbacks
+   */
+  void* user_data;
+
+} nfapi_p4_p5_codec_config_t;
+
+#endif // NFAPI_COMMON_INTERFACE_H
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
index 3312fa832eb3d4b56a132b0d14c7f1f28f479920..2d761bab8865827a196c3736df8ed8c337f52f53 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 "nfapi_common_interface.h"
 
 // Constants - update based on implementation
 #define NFAPI_MAX_PHY_RF_INSTANCES 2
@@ -27,7 +28,7 @@
 #define NFAPI_PNF_PARAM_GENERAL_OUI_LENGTH 3
 #define NFAPI_MAX_NUM_RF_BANDS 16
 
-#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
+#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
 
 // The following definition control the size of arrays used in the interface.
 // These may be changed if desired. They are used in the encoder to make sure 
@@ -92,19 +93,19 @@ typedef signed short	int16_t;
 typedef signed char		int8_t;
 
 typedef struct {
-	uint16_t phy_id;
-	uint16_t message_id;
-	uint16_t message_length;
-	uint16_t spare;
+  uint16_t phy_id;
+  uint16_t message_id;
+  uint16_t message_length;
+  uint16_t spare;
 } nfapi_p4_p5_message_header_t;
 
 typedef struct {
-	uint16_t phy_id;
-	uint16_t message_id;
-	uint16_t message_length;
-	uint16_t m_segment_sequence; /* This consists of 3 fields - namely, M, Segement & Sequence number*/
-	uint32_t checksum;
-	uint32_t transmit_timestamp;
+  uint16_t phy_id;
+  uint16_t message_id;
+  uint16_t message_length;
+  uint16_t m_segment_sequence; /* This consists of 3 fields - namely, M, Segement & Sequence number*/
+  uint32_t checksum;
+  uint32_t transmit_timestamp;
 } nfapi_p7_message_header_t;
 
 #define NFAPI_PHY_ID_NA 0
@@ -116,10 +117,6 @@ typedef struct {
 #define NFAPI_P7_GET_SEQUENCE(_mss) ( (_mss) & 0x00FF )
 #define NFAPI_P7_SET_MSS(_more, _segm, _sequ) ( (((_more) & 0x1) << 7) | (((_segm) & 0x7) << 4) | ((_sequ) & 0xF) )
 
-typedef struct {
-	uint16_t tag;
-	uint16_t length;
-} nfapi_tl_t;
 #define NFAPI_TAG_LENGTH_PACKED_LEN 4
 
 // Convenience methods to convert between SFN/SLOT formats
@@ -2537,29 +2534,6 @@ typedef struct {
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_timing_info_t;
 
-typedef struct {
-	nfapi_p7_message_header_t header;
-	
-	uint32_t last_sfn;
-	uint32_t last_slot;
-	uint32_t time_since_last_timing_info;
-	
-	uint32_t dl_tti_jitter;
-	uint32_t tx_data_request_jitter;
-	uint32_t ul_tti_jitter;
-	uint32_t ul_dci_jitter;
-
-	int32_t dl_tti_latest_delay;
-	int32_t tx_data_request_latest_delay;
-	int32_t ul_tti_latest_delay;
-	int32_t ul_dci_latest_delay;
-	
-	int32_t dl_tti_earliest_arrival;
-	int32_t tx_data_request_earliest_arrival;
-	int32_t ul_tti_earliest_arrival;
-	int32_t ul_dci_earliest_arrival;
-	nfapi_vendor_extension_tlv_t vendor_extension;
-} nfapi_nr_timing_info_t;
 
 typedef struct {
 	nfapi_tl_t tl;
@@ -3772,160 +3746,6 @@ typedef struct
 // Configuration options for the encode decode functions
 //
 
-/*! Configuration options for the p7 pack unpack functions
- *
- */
-typedef struct nfapi_p7_codec_config {
-
-	/*! Optional call back to allow the user to define the memory allocator. 
-	 *  \param size The size of the memory to allocate
-	 *  \return a pointer to a valid memory block or 0 if it has failed.
-	 *
-	 * If not set the nfapi unpack functions will use malloc
-	 */
-	void* (*allocate)(size_t size);
-
-	/*! Optional call back to allow the user to define the memory deallocator. 
-	 *  \param ptr A poiner to a memory block allocated by the allocate callback
-	 * 
-	 *	If not set the client should use free
-	 */
-	void (*deallocate)(void* ptr);
-
-	/*! Optional call back function to handle unpacking vendor extension tlv.
-	 *  \param tl A pointer to a decoded tag length structure
-	 *  \param ppReadPackedMsg A handle to the read buffer. 
-	 *  \param end The end of the read buffer
-	 *  \param ve A handle to a vendor extention structure that the call back should allocate if the structure can be decoded
-	 *  \param config A pointer to the p7 codec configuration
-	 *  \return return 0 if packed successfully, -1 if failed.
-	 *
-	 *  If not set the tlv will be skipped
-	 *
-	 *  Client should use the help methods in nfapi.h to decode the vendor extention.
-	 * 
-	 *  \todo Add code example
-	 */
-	int (*unpack_vendor_extension_tlv)(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, void** ve, struct nfapi_p7_codec_config* config);
-
-	/*! Optional call back function to handle packing vendor extension tlv. 
-	 *  \param ve A pointer to a vendor extention structure.
-	 *  \param ppWritePackedMsg A handle to the write buffer
-	 *  \param end The end of the write buffer. The callee should make sure not to write beyond the end
-	 *  \param config A pointer to the p7 codec configuration
-	 *  \return return 0 if packed successfully, -1 if failed.
-	 * 
-	 *  If not set the the tlv will be skipped
-	 * 
-	 *  Client should use the help methods in nfapi.h to encode the vendor extention
-	 * 
-	 *  \todo Add code example
-	 */
-	int (*pack_vendor_extension_tlv)(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, struct nfapi_p7_codec_config* config);
-
-	/*! Optional call back function to handle unpacking vendor extension messages. 
-	 *  \param header A pointer to a decode P7 message header for the vendor extention message
-	 *  \param ppReadPackedMsg A handle to the encoded data buffer
-	 *  \param end A pointer to the end of the encoded data buffer
-	 *  \param config  A pointer to the p7 codec configuration
-	 *  \return 0 if unpacked successfully, -1 if failed
-	 *
-	 *  If not set the message will be ignored
-	 *
-	 *  If the message if is unknown the function should return -1
-	 */
-	int (*unpack_p7_vendor_extension)(nfapi_p7_message_header_t* header, uint8_t **ppReadPackedMsg, uint8_t *end, struct nfapi_p7_codec_config* config);
-
-	/*! Optional call back function to handle packing vendor extension messages. 
-	 *  \param header A poiner to a P7 message structure for the venfor extention message
-	 *  \param ppWritePackedmsg A handle to the buffer to write the encoded message into
-	 *  \param end A pointer to the end of the buffer
-	 *  \param cofig A pointer to the p7 codec configuration
-	 *  \return 0 if packed successfully, -1 if failed
-	 * 
-	 * If not set the the message will be ingored
-	 *	 
-	 *  If the message if is unknown the function should return -1
-	 */
-	int (*pack_p7_vendor_extension)(nfapi_p7_message_header_t* header, uint8_t **ppWritePackedmsg, uint8_t *end, struct nfapi_p7_codec_config* config);
-
-	/*! Optional user data that will be passed back with callbacks
-	 */
-	void* user_data;
-
-} nfapi_p7_codec_config_t;
-
-/*! Configuration options for the p4 & p5 pack unpack functions
- *
- */
-typedef struct nfapi_p4_p5_codec_config {
-
-	/*! Optional call back to allow the user to define the memory allocator.
-     *  \param size The size of the memory to allocate
-	 *  \return a pointer to a valid memory block or 0 if it has failed.
-	 *
-	 *  If not set the nfapi unpack functions will use malloc
-	 */
-	void* (*allocate)(size_t size);
-
-	/*! Optional call back to allow the user to define the memory deallocator. 
-	 *  \param ptr A poiner to a memory block allocated by the allocate callback
-	 *
-	 *  If not set free will be used
-	 */
-	void (*deallocate)(void* ptr);
-
-	/*! Optional call back function to handle unpacking vendor extension tlv.
-	 *  \param tl A pointer to a decoded tag length structure
-	 *  \param ppReadPackedMsg A handle to the data buffer to decode
-	 *  \param end A pointer to the end of the buffer
-	 *  \param ve A handle to a vendor extention structure that will be allocated by this callback
-	 *  \param config A pointer to the P4/P5 codec configuration
-	 *  \return 0 if unpacked successfully, -1 if failed
-	 *  
-	 *  If not set the tlv will be skipped
-	 */
-	int (*unpack_vendor_extension_tlv)(nfapi_tl_t* tl, uint8_t **ppReadPackedMsg, uint8_t *end, void** ve, struct nfapi_p4_p5_codec_config* config);
-
-	/*! Optional call back function to handle packing vendor extension tlv. 
-	 *  \param ve
-	 *  \param ppWritePackedMsg A handle to the data buffer pack the tlv into
-	 *  \param end A pointer to the end of the buffer
-	 *  \param config A pointer to the P4/P5 codec configuration
-	 *  \return 0 if packed successfully, -1 if failed
-	 *
-	 *  If not set the the tlv will be skipped
-	 */
-	int (*pack_vendor_extension_tlv)(void* ve, uint8_t **ppWritePackedMsg, uint8_t *end, struct nfapi_p4_p5_codec_config* config);
-
-	/*! Optional call back function to handle unpacking vendor extension messages. 
-	 *  \param header A pointer to a decode P4/P5 message header
-	 *  \param ppReadPackgedMsg A handle to the data buffer to decode
-	 *  \param end A pointer to the end of the buffer
-	 *  \param config A pointer to the P4/P5 codec configuration
-	 *  \return 0 if packed successfully, -1 if failed
-	 *
-	 * If not set the message will be ignored
-	 */
-	int (*unpack_p4_p5_vendor_extension)(nfapi_p4_p5_message_header_t* header, uint8_t **ppReadPackedMsg, uint8_t *end, struct nfapi_p4_p5_codec_config* config);
-
-	/*! Optional call back function to handle packing vendor extension messages.
-	 *  \param header A pointer to the P4/P5 message header to be encoded
-	 *  \param ppWritePackedMsg A handle to the data buffer pack the message into
-	 *  \param end A pointer to the end of the buffer
-	 *  \param config A pointer to the P4/P5 codec configuration
-	 *  \return 0 if packed successfully, -1 if failed
-	 *  
-	 *  If not set the the message will be ingored
-	 */
-	int (*pack_p4_p5_vendor_extension)(nfapi_p4_p5_message_header_t* header, uint8_t **ppwritepackedmsg, uint8_t *end, struct nfapi_p4_p5_codec_config* config);
-
-	/*! Optional user data that will be passed back with callbacks
-	 */
-	void* user_data;
-
-} nfapi_p4_p5_codec_config_t;
-
 //
 // Functions
 // 
@@ -3979,21 +3799,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
  * 
  */
 int nfapi_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
-int nfapi_nr_p5_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPackedBuf, uint32_t packedBufLen, nfapi_p4_p5_codec_config_t* config);
 
-/*! \brief Packs a NFAPI P5 message body
- *  \param header A pointer to the header of the P5 message
- *  \param ppWritePackedMsg A pointer to the buffer where to pack the P5 message
- *  \param end Pointer to the end of the packing buffer
- *  \param config A pointer to the nfapi configuration structure
- *  \return 0 means success, -1 means failure.
- *
- * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
- */
-uint8_t pack_nr_p5_message_body(nfapi_p4_p5_message_header_t* header,
-                                uint8_t** ppWritePackedMsg,
-                                uint8_t* end,
-                                nfapi_p4_p5_codec_config_t* config);
 
 /*! \brief Decodes an NFAPI P5 message header
  *  \param pMessageBuf A pointer to an encoded P5 message header
@@ -4017,7 +3823,6 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
  *
  * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf 
  */
-int nfapi_nr_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
 int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t* config);
 
 /*! \brief Encodes an NFAPI P7 message to a buffer
@@ -4031,7 +3836,6 @@ int nfapi_p5_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
  * 
  */
 int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
-int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t* config);
 
 /*! \brief Decodes an NFAPI P7 message header
  *  \param pMessageBuf A pointer to an encoded P7 message header
@@ -4057,7 +3861,6 @@ int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
  * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf 
  */
 int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
-int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config);
 
 /*! \brief Calculates the checksum of a  message
  *
@@ -4083,42 +3886,4 @@ int nfapi_p7_update_checksum(uint8_t* buffer, uint32_t len);
  */
 int nfapi_p7_update_transmit_timestamp(uint8_t* buffer, uint32_t timestamp);
 
-/*! \brief Encodes a nfapi_nr_srs_normalized_channel_iq_matrix_t to a buffer
- *
- *  \param pMessageBuf A pointer to a nfapi_nr_srs_normalized_channel_iq_matrix_t structure
- *  \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_normalized_channel_iq_matrix_t will be packed into
- *  \param packedBufLen The size of the buffer
- *  \return number of bytes written to the buffer
- */
-int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen);
-
-/*! \brief Decodes a nfapi_nr_srs_normalized_channel_iq_matrix_t from a buffer
- *
- *  \param pMessageBuf A pointer to an encoded nfapi_nr_srs_normalized_channel_iq_matrix_t
- *  \param messageBufLen The size of the encoded nfapi_nr_srs_normalized_channel_iq_matrix_t
- *  \param pUnpackedBuf A pointer to the nfapi_nr_srs_normalized_channel_iq_matrix_t
- *  \param unpackedBufLen The size of nfapi_nr_srs_normalized_channel_iq_matrix_t structure.
- *  \return 0 means success, -1 means failure.
- */
-int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen);
-
-/*! \brief Encodes a nfapi_nr_srs_beamforming_report_t to a buffer
- *
- *  \param pMessageBuf A pointer to a nfapi_nr_srs_beamforming_report_t structure
- *  \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_beamforming_report_t will be packed into
- *  \param packedBufLen The size of the buffer
- *  \return number of bytes written to the buffer
- */
-int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen);
-
-/*! \brief Decodes a nfapi_nr_srs_beamforming_report_t from a buffer
- *
- *  \param pMessageBuf A pointer to an encoded nfapi_nr_srs_beamforming_report_t
- *  \param messageBufLen The size of the encoded nfapi_nr_srs_beamforming_report_t
- *  \param pUnpackedBuf A pointer to the nfapi_nr_srs_beamforming_report_t
- *  \param unpackedBufLen The size of nfapi_nr_srs_beamforming_report_t structure.
- *  \return 0 means success, -1 means failure.
- */
-int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen);
-
 #endif /* _NFAPI_INTERFACE_H_ */
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
index 4e9987b0cb6fc5b521ab4836d85fd4885e09fd2f..c68566634dcf1bd550e53df80bb743c9df98f81c 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
@@ -8,6 +8,10 @@
 
 #ifndef _NFAPI_NR_INTERFACE_H_
 #define _NFAPI_NR_INTERFACE_H_
+#include "nfapi_common_interface.h"
+
+#define NFAPI_NR_P5_HEADER_LENGTH 10
+#define NFAPI_NR_P7_HEADER_LENGTH 18
 
 //These TLVs are used exclusively by nFAPI
 #define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100
@@ -26,6 +30,22 @@
 #define NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG 0xA000
 #define NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG 0xA001
 
+typedef struct {
+  uint16_t phy_id;
+  uint16_t message_id;
+  uint32_t message_length;
+  uint16_t spare;
+} nfapi_nr_p4_p5_message_header_t;
+
+typedef struct {
+  uint16_t phy_id;
+  uint16_t message_id;
+  uint32_t message_length;
+  uint16_t m_segment_sequence; /* This consists of 3 fields - namely, M, Segement & Sequence number*/
+  uint32_t checksum;
+  uint32_t transmit_timestamp;
+} nfapi_nr_p7_message_header_t;
+
 typedef enum {
   NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=1,
   NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=0
@@ -48,4 +68,178 @@ typedef enum {
   NFAPI_NR_SRS_ANTENNASWITCH = 3
 } nfapi_nr_srs_usage_e;
 
+/*! \brief Encodes an NFAPI P5 message to a buffer
+ *  \param pMessageBuf A pointer to a nfapi p5 message structure
+ *  \param messageBufLen The size of the p5 message structure
+ *  \param pPackedBuf A pointer to the buffer that the p5 message will be packed into
+ *  \param packedBufLen The size of the buffer
+ *  \param config A pointer to the nfapi configuration structure
+ *  \return != 0 means success, -1 means failure.
+ *
+ * The function will encode a nFAPI P5 message structure pointed to be pMessageBuf into a byte stream pointed to by pPackedBuf.
+ * The function returns the message length that was packed
+ */
+int nfapi_nr_p5_message_pack(void *pMessageBuf,
+                             uint32_t messageBufLen,
+                             void *pPackedBuf,
+                             uint32_t packedBufLen,
+                             nfapi_p4_p5_codec_config_t *config);
+
+/*! \brief Packs a NFAPI P5 message body
+ *  \param header A pointer to the header of the P5 message
+ *  \param ppWritePackedMsg A pointer to the buffer where to pack the P5 message
+ *  \param end Pointer to the end of the packing buffer
+ *  \param config A pointer to the nfapi configuration structure
+ *  \return 1 means success, 0 means failure.
+ *
+ * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
+ */
+uint8_t pack_nr_p5_message_body(nfapi_nr_p4_p5_message_header_t *header,
+                                uint8_t **ppWritePackedMsg,
+                                uint8_t *end,
+                                nfapi_p4_p5_codec_config_t *config);
+
+/*! \brief Decodes an NFAPI P5 message header
+ *  \param pMessageBuf A pointer to an encoded P5 message header
+ *  \param messageBufLen The size of the encoded P5 message header
+ *  \param pUnpackedBuf A pointer to the nfapi_message_header
+ *  \param unpackedBufLen The size of nfapi_message_header structure.
+ *  \param config A pointer to the nfapi configuration structure
+ *  \return 10 ( size of the unpacked header ) on success, -1 on failure.
+ *
+ * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 header structure pointed to by pUnpackedBuf
+ */
+int nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
+                                      uint32_t messageBufLen,
+                                      void *pUnpackedBuf,
+                                      uint32_t unpackedBufLen,
+                                      nfapi_p4_p5_codec_config_t *config);
+
+/*! \brief Decodes a NFAPI P5 message
+ *  \param pMessageBuf A pointer to an encoded P5 message
+ *  \param messageBufLen The size of the encoded P5 message
+ *  \param pUnpackedBuf A pointer to the nfapi_message_header
+ *  \param unpackedBufLen The size of nfapi_message_header structure.
+ *  \param config A pointer to the nfapi configuration structure
+ *  \return != -1 means success, -1 means failure.
+ *
+ * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
+ */
+int nfapi_nr_p5_message_unpack(void *pMessageBuf,
+                               uint32_t messageBufLen,
+                               void *pUnpackedBuf,
+                               uint32_t unpackedBufLen,
+                               nfapi_p4_p5_codec_config_t *config);
+
+/*! \brief Encodes an NFAPI P7 message to a buffer
+ *  \param pMessageBuf A pointer to a nfapi p7 message structure
+ *  \param pPackedBuf A pointer to the buffer that the p7 message will be packed into
+ *  \param packedBufLen The size of the buffer
+ *  \param config A pointer to the nfapi configuration structure
+ *  \return != -1 means success, -1 means failure.
+ *
+ * The function will encode a nFAPI P7 message structure pointed to be pMessageBuf into a byte stream pointed to by pPackedBuf.
+ * The function returns the message length packed
+ */
+int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config);
+
+/*! \brief Decodes an NFAPI P7 message header
+ *  \param pMessageBuf A pointer to an encoded P7 message header
+ *  \param messageBufLen The size of the encoded P7 message header
+ *  \param pUnpackedBuf A pointer to the nfapi_message_header
+ *  \param unpackedBufLen The size of nfapi_message_header structure.
+ *  \param config A pointer to the nfapi configuration structure
+ *  \return 0 means success, -1 means failure.
+ *
+ * The function will decode a byte stream pointed to by pMessageBuf into a nfapi_p7_message_header structure pointer to by
+ pUnpackedBuf
+
+ */
+int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
+                                      uint32_t messageBufLen,
+                                      void *pUnpackedBuf,
+                                      uint32_t unpackedBufLen,
+                                      nfapi_p7_codec_config_t *config);
+
+/*! \brief Decodes a NFAPI P7 message
+ *  \param pMessageBuf A pointer to an encoded P7 message
+ *  \param messageBufLen The size of the encoded P7 message
+ *  \param pUnpackedBuf A pointer to the nfapi_message_header
+ *  \param unpackedBufLen The size of nfapi_message_header structure.
+ *  \param config A pointer to the nfapi configuration structure
+ *  \return 0 means success, -1 means failure.
+ *
+ * The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf
+ */
+int nfapi_nr_p7_message_unpack(void *pMessageBuf,
+                               uint32_t messageBufLen,
+                               void *pUnpackedBuf,
+                               uint32_t unpackedBufLen,
+                               nfapi_p7_codec_config_t *config);
+
+/*! \brief Calculates the checksum of a  message
+ *
+ *  \param buffer Pointer to the packed message
+ *  \param len The length of the message
+ *  \return The checksum. If there is an error the function with return -1
+ */
+uint32_t nfapi_nr_p7_calculate_checksum(uint8_t *buffer, uint32_t len);
+
+/*! \brief Calculates & updates the checksum in the message
+ *
+ *  \param buffer Pointer to the packed message
+ *  \param len The length of the message
+ *  \return 0 means success, -1 means failure.
+ */
+int nfapi_nr_p7_update_checksum(uint8_t *buffer, uint32_t len);
+
+/*! \brief Updates the transmition time stamp in the p7 message header
+ *
+ *  \param buffer Pointer to the packed message
+ *  \param timestamp The time stamp value
+ *  \return 0 means success, -1 means failure.
+ */
+int nfapi_nr_p7_update_transmit_timestamp(uint8_t *buffer, uint32_t timestamp);
+
+/*! \brief Encodes a nfapi_nr_srs_normalized_channel_iq_matrix_t to a buffer
+ *
+ *  \param pMessageBuf A pointer to a nfapi_nr_srs_normalized_channel_iq_matrix_t structure
+ *  \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_normalized_channel_iq_matrix_t will be packed into
+ *  \param packedBufLen The size of the buffer
+ *  \return number of bytes written to the buffer
+ */
+int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen);
+
+/*! \brief Decodes a nfapi_nr_srs_normalized_channel_iq_matrix_t from a buffer
+ *
+ *  \param pMessageBuf A pointer to an encoded nfapi_nr_srs_normalized_channel_iq_matrix_t
+ *  \param messageBufLen The size of the encoded nfapi_nr_srs_normalized_channel_iq_matrix_t
+ *  \param pUnpackedBuf A pointer to the nfapi_nr_srs_normalized_channel_iq_matrix_t
+ *  \param unpackedBufLen The size of nfapi_nr_srs_normalized_channel_iq_matrix_t structure.
+ *  \return 0 means success, -1 means failure.
+ */
+int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf,
+                                               uint32_t messageBufLen,
+                                               void *pUnpackedBuf,
+                                               uint32_t unpackedBufLen);
+
+/*! \brief Encodes a nfapi_nr_srs_beamforming_report_t to a buffer
+ *
+ *  \param pMessageBuf A pointer to a nfapi_nr_srs_beamforming_report_t structure
+ *  \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_beamforming_report_t will be packed into
+ *  \param packedBufLen The size of the buffer
+ *  \return number of bytes written to the buffer
+ */
+int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen);
+
+/*! \brief Decodes a nfapi_nr_srs_beamforming_report_t from a buffer
+ *
+ *  \param pMessageBuf A pointer to an encoded nfapi_nr_srs_beamforming_report_t
+ *  \param messageBufLen The size of the encoded nfapi_nr_srs_beamforming_report_t
+ *  \param pUnpackedBuf A pointer to the nfapi_nr_srs_beamforming_report_t
+ *  \param unpackedBufLen The size of nfapi_nr_srs_beamforming_report_t structure.
+ *  \return 0 means success, -1 means failure.
+ */
+int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen);
+
 #endif
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index 2476833d7c815cb1c26eb8431bb0579f51143a8e..f82c6c414a587b5fe47b19cf60cf4174989431b7 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -11,6 +11,7 @@
 
 #include "stddef.h"
 #include "nfapi_interface.h"
+#include "nfapi_nr_interface.h"
 
 #define NFAPI_NR_MAX_NB_CCE_AGGREGATION_LEVELS 5
 #define NFAPI_NR_MAX_NB_TCI_STATES_PDCCH 64
@@ -68,6 +69,8 @@ typedef enum {
   NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION = 0X88,
   NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION = 0X89,
   // RESERVED 0X8a ~ 0xff
+  NFAPI_NR_PHY_MSG_TYPE_VENDOR_EXT_SLOT_RESPONSE = 0x8F, // Aerial-specfiic
+
   NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST = 0x0100,
   NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_RESPONSE = 0x0101,
   NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST = 0x0102,
@@ -510,12 +513,12 @@ typedef enum {    // Table 2-27
 
 //PNF P5 NR 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_pnf_param_request_t;
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	uint8_t error_code;
   uint8_t num_tlvs;
 	nfapi_pnf_param_general_t pnf_param_general;
@@ -524,36 +527,36 @@ typedef struct {
 } nfapi_nr_pnf_param_response_t;
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	uint8_t num_tlvs;
 	nfapi_pnf_phy_rf_config_t pnf_phy_rf_config;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_pnf_config_request_t;
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	uint8_t error_code;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_pnf_config_response_t;
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_pnf_start_request_t;
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	uint32_t error_code;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_pnf_start_response_t;
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_pnf_stop_request_t;
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	uint32_t error_code;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_pnf_stop_response_t;
@@ -561,13 +564,13 @@ typedef struct {
 
 /* PARAM.REQUEST */
 typedef struct {
-  nfapi_p4_p5_message_header_t  header;
+  nfapi_nr_p4_p5_message_header_t  header;
 	nfapi_vendor_extension_tlv_t  vendor_extension;
 } nfapi_nr_param_request_scf_t;
 
 /* PARAM.RESPONSE */
 typedef struct {
-  nfapi_p4_p5_message_header_t  header;
+  nfapi_nr_p4_p5_message_header_t  header;
   uint8_t       error_code;
   
   uint8_t                       num_tlv;
@@ -589,7 +592,7 @@ typedef struct {
 
 /* CONFIG.REQUEST */
 typedef struct {
-  nfapi_p4_p5_message_header_t  header;
+  nfapi_nr_p4_p5_message_header_t  header;
 
   uint8_t                       num_tlv;
   nfapi_vendor_extension_tlv_t  vendor_extension;
@@ -627,7 +630,7 @@ typedef struct {
 
 /* CONFIG.RESPONSE */
 typedef struct {
-  nfapi_p4_p5_message_header_t  header;
+  nfapi_nr_p4_p5_message_header_t  header;
   uint8_t error_code;
   uint8_t num_invalid_tlvs;
   uint8_t num_invalid_tlvs_configured_in_idle;
@@ -644,12 +647,12 @@ typedef struct {
 //3.3.3 START
 
 typedef struct {
-	nfapi_p4_p5_message_header_t header;
+	nfapi_nr_p4_p5_message_header_t header;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_start_request_scf_t;
 
 typedef struct {
-  nfapi_p4_p5_message_header_t header;
+  nfapi_nr_p4_p5_message_header_t header;
   nfapi_nr_start_errors_e error_code;
   nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_start_response_scf_t;
@@ -657,17 +660,17 @@ typedef struct {
 //3.3.4 STOP
 
 typedef struct {
-  nfapi_p4_p5_message_header_t header;
+  nfapi_nr_p4_p5_message_header_t header;
   nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_stop_request_scf_t;
 
 typedef struct {
-  nfapi_p4_p5_message_header_t header;
+  nfapi_nr_p4_p5_message_header_t header;
   nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_stop_indication_scf_t;
 
 typedef struct {
-  nfapi_p4_p5_message_header_t header;
+  nfapi_nr_p4_p5_message_header_t header;
   uint16_t sfn;
   uint16_t slot;
   uint8_t message_id; // Which message received on the PNF has an error
@@ -708,7 +711,7 @@ typedef struct {
 #define NFAPI_NR_SLOT_INDICATION_PERIOD_NUMEROLOGY_3 125 //us
 
 typedef struct {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t sfn; //0->1023
   uint16_t slot;//0->319
   
@@ -894,6 +897,19 @@ typedef struct {
   uint8_t nEpreRatioOfPDSCHToPTRS;
   // Beamforming
   nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming;
+  // TX Power info
+  /// Ratio of PDSCH EPRE to NZP CSI-RSEPRE [TS38.214,sec 5.2.2.3.1]
+  uint8_t powerControlOffset;
+  /// Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES [TS38.214, sec 5.2.2.3.1]
+  uint8_t powerControlOffsetSS;
+  // CBG fields
+  /// Indicates whether last CB is present in the CBG retransmission ( 0 -> not included; 1 -> included )
+  uint8_t isLastCbPresent;
+  /// Indicates whether TB CRC is part of data payload or control message ( 0 -> payload; 1 -> control message )
+  uint8_t isInlineTbCrc;
+  /// TB CRC: to be used in the last CB, applicable only if last CB is present
+  uint32_t dlTbCrc;
+
   nfapi_v3_pdsch_maintenance_parameters_t maintenance_parms_v3;
 }nfapi_nr_dl_tti_pdsch_pdu_rel15_t;
 
@@ -1070,23 +1086,46 @@ typedef struct {
 
 
 typedef struct {
-	nfapi_p7_message_header_t header;
+	nfapi_nr_p7_message_header_t header;
 	uint32_t t1;
 	int32_t delta_sfn_slot;
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_dl_node_sync_t;
 
 typedef struct {
-	nfapi_p7_message_header_t header;
+	nfapi_nr_p7_message_header_t header;
 	uint32_t t1;
 	uint32_t t2;
 	uint32_t t3;	
 	nfapi_vendor_extension_tlv_t vendor_extension;
 } nfapi_nr_ul_node_sync_t;
 
+typedef struct {
+  nfapi_nr_p7_message_header_t header;
+
+  uint32_t last_sfn;
+  uint32_t last_slot;
+  uint32_t time_since_last_timing_info;
+
+  uint32_t dl_tti_jitter;
+  uint32_t tx_data_request_jitter;
+  uint32_t ul_tti_jitter;
+  uint32_t ul_dci_jitter;
+
+  int32_t dl_tti_latest_delay;
+  int32_t tx_data_request_latest_delay;
+  int32_t ul_tti_latest_delay;
+  int32_t ul_dci_latest_delay;
+
+  int32_t dl_tti_earliest_arrival;
+  int32_t tx_data_request_earliest_arrival;
+  int32_t ul_tti_earliest_arrival;
+  int32_t ul_dci_earliest_arrival;
+  nfapi_vendor_extension_tlv_t vendor_extension;
+} nfapi_nr_timing_info_t;
 
 typedef struct {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   /// System Frame Number (0-1023)
   uint16_t SFN;
   /// Slot number (0-19)
@@ -1320,7 +1359,7 @@ typedef struct
   uint8_t  dmrs_cyclic_shift;
 
   uint8_t  sr_flag;
-  uint8_t  bit_len_harq;
+  uint16_t bit_len_harq;
   uint16_t bit_len_csi_part1;
   uint16_t bit_len_csi_part2;
 
@@ -1336,7 +1375,7 @@ typedef struct {
 
 typedef struct {
   uint16_t srs_bandwidth_size;                    // mSRS,b: Number of PRB’s that are sounded for each SRS symbol, per 3GPP TS 38.211, section 6.4.1.4.3. Value: 4->272
-  nfapi_v4_srs_parameters_symbols_t *symbol_list;
+  nfapi_v4_srs_parameters_symbols_t symbol_list[4];
   uint32_t usage;                                 // Bitmap indicating the type of report(s) expected at L2 from the SRS signaled by this PDU. Bit positions: 0 – beamManagement; 1 – codebook; 2 – nonCodebook; 3 – antennaSwitching; 4 – 255: reserved. For each of this bit positions: 1 = requested; 0 = not requested. nUsage = sum(all bits in usage)
   uint8_t report_type[4];                         // Interpretation of each Report Type depends on usage: beamManagement (1 = PRG SNR, 2-255 reserved); codebook (1 = PRG I and Q channel estimate, per srs Tx port and gNB antenna element, 2-255 reserved); nonCodebook (1 = PRG I and Q channel estimate, per SRI and gNB antenna element, 2-255 reserved); antennaSwitching (1 = SVD representation UE Rx and gNB sets of antenna element, 2-255 reserved); all (0 – no report required).
   uint8_t singular_Value_representation;          // 0 – 8-bit dB; 1 – 16-bit linear; 255 – not applicable
@@ -1420,7 +1459,7 @@ typedef struct
 } nfapi_nr_ul_tti_request_number_of_groups_t;
 
 typedef struct {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t SFN; //0->1023   
   uint16_t Slot;//0->319
   uint8_t n_pdus;//Number of PDUs that are included in this message. All PDUs in the message are numbered in order. Value 0 -> 255
@@ -1464,7 +1503,7 @@ typedef struct {
 } nfapi_nr_ul_dci_request_pdus_t;
 
 typedef struct {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t SFN;
   uint16_t Slot;
   uint8_t  numPdus;
@@ -1510,7 +1549,7 @@ typedef struct
 #define NFAPI_NR_MAX_TX_REQUEST_PDUS 16
 typedef struct
 {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t SFN;
   uint16_t Slot;
   uint16_t Number_of_PDUs;
@@ -1545,7 +1584,7 @@ typedef struct
 
 typedef struct
 {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t sfn;
   uint16_t slot;
   uint16_t number_of_pdus;
@@ -1573,7 +1612,7 @@ typedef struct
 
 typedef struct
 {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t sfn;
   uint16_t slot;
   uint16_t number_crcs;
@@ -1710,7 +1749,7 @@ typedef struct
 
 typedef struct
 {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t sfn;
   uint16_t slot;
   uint16_t num_ucis;
@@ -1721,6 +1760,44 @@ typedef struct
 
 /// 5G PHY FAPI Specification: SRS indication - Section 3.4.10
 
+// Table 3–133 Channel SVD Representation
+
+typedef struct {
+  // Array of (Nu*Nu) entries of the type denoted by ‘iq Representation’
+  // U[ueAntenna uI, left eigenvector leI] = array[uI*Nu + leI]
+  uint8_t* left_eigenvectors_matrix_u;
+
+  // Array of (Nu) entries of the type denoted by ‘singular
+  // Values Representation’
+  // Σ[left eigenvector leI, right eigenvector reI] =
+  // • 0 if leI ≠ reI
+  // • 0 if min(leI, reI) ≥ Nu
+  // • array[leI] if leI = reI
+  uint8_t* diagonal_entries_of_singular_matrix_sum_f;
+
+  // Array of (Nu*Ng) entries of the type denoted by ‘iq
+  // Representation’
+  //  H
+  // VF[right eigenvector reI, gNB antenna gI] =
+  // array[reI*Ng + gI],
+  //- reI: 0…Nu-1
+  //- gI: 0…Ng-1
+  uint8_t* complex_conjugate_of_matrix_of_right_eigenvectors_v_hf;
+} nfapi_nr_srs_channel_svd_representation_prg_t;
+
+typedef struct {
+  uint8_t normalized_iq_representation; // 0: 16-bit normalized complex number (iqSize = 2); 1: 32-bit normalized complex number
+                                        // (iqSize = 4)
+  uint8_t normalized_singular_value_representation; // 0: 8-bit linear representation (sSize = 1); 1:16-bit linear representation
+                                                    // (sSize = 2)
+  int8_t singular_value_scaling; // dB-domain representation of singular value scaling
+  uint16_t num_gnb_antenna_elements; // Ng: Number of gNB antenna elements
+  uint8_t num_ue_srs_ports; // Nu: Number of sampled UE SRS ports
+  uint16_t prg_size; // Size in RBs of a precoding resource block group (PRG)
+  uint16_t num_prgs; // Number of PRGs to be reported for this SRS PDU
+  nfapi_nr_srs_channel_svd_representation_prg_t* prg_list;
+} nfapi_nr_srs_channel_svd_representation_t;
+
 // Normalized channel I/Q matrix
 
 typedef struct {
@@ -1748,11 +1825,11 @@ typedef struct {
   uint8_t num_symbols;                  // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1.
   uint8_t wide_band_snr;                // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid.
   uint8_t num_reported_symbols;         // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4.
-  nfapi_nr_srs_reported_symbol_t prgs;
+  nfapi_nr_srs_reported_symbol_t* reported_symbol_list;
 } nfapi_nr_srs_beamforming_report_t;
 
 // SRS indication
-
+#define NFAPI_NR_SRS_IND_MAX_PDU 100
 typedef struct {
   uint16_t tag;                         // 0: Report is carried directly in the value field; 3: The offset from the end of the control portion of the message to the beginning of the report. Other values are reserved.
   uint32_t length;                      // Length of the actual report in bytes, without the padding bytes.
@@ -1770,7 +1847,7 @@ typedef struct {
 } nfapi_nr_srs_indication_pdu_t;
 
 typedef struct {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t sfn;                         // SFN. Value: 0 -> 1023
   uint16_t slot;                        // Slot. Value: 0 -> 159
   uint16_t control_length;              // Size of control portion of SRS indication. 0 if reports are included inline; >0 if reports are concatenated to the end of the message.
@@ -1780,6 +1857,7 @@ typedef struct {
 
 
 //3.4.11 rach_indication
+#define NFAPI_NR_RACH_IND_MAX_PDU 100
 //table 3-74
 typedef struct
 {
@@ -1803,7 +1881,7 @@ typedef struct{
 
 typedef struct
 {
-  nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
   uint16_t sfn;
   uint16_t slot;
   uint8_t number_of_pdus;
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h b/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h
index 5a6fe08701a539890ed9c885e8eab83c77bf1825..4116422268b7ae93cda4d342fba357c655f5b24d 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h
@@ -34,56 +34,16 @@
 #include "nfapi_interface.h"
 #include "nfapi_nr_interface_scf.h"
 
-uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
-                                  uint8_t *end,
-                                  nfapi_nr_slot_indication_scf_t *msg,
-                                  nfapi_p7_codec_config_t *config);
-
 void *nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t *config);
 
-uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg,
-                                 uint8_t *end,
-                                 nfapi_nr_srs_indication_t *pNfapiMsg,
-                                 nfapi_p7_codec_config_t *config);
-
-uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
-uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
-uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
 uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
 
 uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
 
-uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
-uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
-uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
-uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
-uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
-uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
-
 uint8_t pack_nr_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
 
 uint8_t pack_nr_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
 
 uint8_t pack_nr_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
 
-uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg,
-                                 uint8_t *end,
-                                 nfapi_nr_crc_indication_t *msg,
-                                 nfapi_p7_codec_config_t *config);
-
-uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
-
-uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
-                                  uint8_t *end,
-                                  nfapi_nr_rach_indication_t *msg,
-                                  nfapi_p7_codec_config_t *config);
-
 #endif // OPENAIRINTERFACE_NR_NFAPI_P7_H
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c
index 9615d3b934dfa891bb11cef94893a421f7a6b84e..64ec807d51b62025881edfdacad2aa26c33b6638 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p4.c
@@ -1616,7 +1616,12 @@ int nfapi_p4_message_pack(void *pMessageBuf, uint32_t messageBufLen, void *pPack
 
 // Main unpack functions - public
 
-int nfapi_p4_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+int nfapi_p4_message_header_unpack(void *pMessageBuf,
+                                   uint32_t messageBufLen,
+                                   void *pUnpackedBuf,
+                                   uint32_t unpackedBufLen,
+                                   nfapi_p4_p5_codec_config_t *config)
+{
   nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
   uint8_t *pReadPackedMessage = pMessageBuf;
 
@@ -1632,17 +1637,21 @@ int nfapi_p4_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
     return -1;
   }
 
-  // process the headei
-  if (pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-      pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-      pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-      pull16(&pReadPackedMessage, &pMessageHeader->spare, end))
+  // process the header
+  if (pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+      && pull16(&pReadPackedMessage, &pMessageHeader->message_length, end)
+      && pull16(&pReadPackedMessage, &pMessageHeader->spare, end))
     return -1;
 
   return 0;
 }
 
-int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+int nfapi_p4_message_unpack(void *pMessageBuf,
+                            uint32_t messageBufLen,
+                            void *pUnpackedBuf,
+                            uint32_t unpackedBufLen,
+                            nfapi_p4_p5_codec_config_t *config)
+{
   int result = 0;
   nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
   uint8_t *pReadPackedMessage = pMessageBuf;
@@ -1661,12 +1670,10 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
   // clean the supplied buffer for - tag value blanking
   (void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
   // process the header
-  if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->spare, end)))
+  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->message_length, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->spare, end)))
     return -1;
 
   // look for the specific message
@@ -1779,7 +1786,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
       if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_RESPONSE, unpackedBufLen))
         result = unpack_system_information_response(&pReadPackedMessage, end, pMessageHeader, config);
       else
-        result =  -1;
+        result = -1;
 
       break;
 
@@ -1787,7 +1794,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
       if (check_unpack_length(NFAPI_SYSTEM_INFORMATION_INDICATION, unpackedBufLen))
         result = unpack_system_information_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
-        result =  -1;
+        result = -1;
 
       break;
 
@@ -1808,12 +1815,14 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
       break;
 
     default:
-      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
-        if(config && config->unpack_p4_p5_vendor_extension) {
+      if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if (config && config->unpack_p4_p5_vendor_extension) {
           result = (config->unpack_p4_p5_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
         } else {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+          NFAPI_TRACE(NFAPI_TRACE_ERROR,
+                      "%s VE NFAPI message ID %d. No ve decoder provided\n",
+                      __FUNCTION__,
+                      pMessageHeader->message_id);
         }
       } else {
         NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown P4 message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
@@ -1822,7 +1831,7 @@ int nfapi_p4_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
       break;
   }
 
-  if(result == 0)
+  if (result == 0)
     return -1;
 
   return result;
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
index a5a7810f405421d140c435cf3198ea171c31b69a..1aeef4b766ac12248da73d856dc2cdb180d87dfc 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p5.c
@@ -1185,7 +1185,7 @@ static uint8_t pack_measurement_response(void *msg, uint8_t **ppWritePackedMsg,
           pack_vendor_extension_tlv(pNfapiMsg->vendor_extension, ppWritePackedMsg, end, config));
 }
 
-uint8_t pack_nr_p5_message_body(nfapi_p4_p5_message_header_t *header,
+uint8_t pack_nr_p5_message_body(nfapi_nr_p4_p5_message_header_t *header,
                                 uint8_t **ppWritePackedMsg,
                                 uint8_t *end,
                                 nfapi_p4_p5_codec_config_t *config)
@@ -1377,11 +1377,8 @@ int nfapi_nr_p5_message_pack(void *pMessageBuf,
                              uint32_t packedBufLen,
                              nfapi_p4_p5_codec_config_t *config)
 {
-  nfapi_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
+  nfapi_nr_p4_p5_message_header_t *pMessageHeader = pMessageBuf;
   uint8_t *pWritePackedMessage = pPackedBuf;
-  uint32_t packedMsgLen;
-  uint32_t packedBodyLen;
-  uint16_t packedMsgLen16;
 
   if (pMessageBuf == NULL || pPackedBuf == NULL) {
     NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 Pack supplied pointers are null\n");
@@ -1390,28 +1387,26 @@ int nfapi_nr_p5_message_pack(void *pMessageBuf,
 
   uint8_t *pPackMessageEnd = pPackedBuf + packedBufLen;
   uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-  uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[8];
-  uint8_t *pPacketBodyField = &pWritePackedMessage[8];
+  uint8_t *pPacketBodyFieldStart = &pWritePackedMessage[10];
+  uint8_t *pPacketBodyField = &pWritePackedMessage[10];
 
   // pack the message
   if (push16(pMessageHeader->phy_id, &pWritePackedMessage, pPackMessageEnd)
       && push16(pMessageHeader->message_id, &pWritePackedMessage, pPackMessageEnd)
-      && push16(0, &pWritePackedMessage, pPackMessageEnd) && push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd)
+      && push32(0, &pWritePackedMessage, pPackMessageEnd) && push16(pMessageHeader->spare, &pWritePackedMessage, pPackMessageEnd)
       && pack_nr_p5_message_body(pMessageHeader, &pPacketBodyField, pPackMessageEnd, config)) {
     // to check if whole message is bigger than the buffer provided
-    packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pPacketBodyField);
+    uint32_t packedMsgLen = get_packed_msg_len((uintptr_t)pPackedBuf, (uintptr_t)pPacketBodyField);
     // obtain the length of the message body to pack
-    packedBodyLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
+    uint32_t packedBodyLen = get_packed_msg_len((uintptr_t)pPacketBodyFieldStart, (uintptr_t)pPacketBodyField);
 
-    if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
+    if (packedMsgLen > packedBufLen) {
       NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
       return -1;
-    } else {
-      packedMsgLen16 = (uint16_t)packedBodyLen;
     }
 
     // Update the message length in the header
-    if (!push16(packedMsgLen16, &pPackedLengthField, pPackMessageEnd))
+    if (!push32(packedBodyLen, &pPackedLengthField, pPackMessageEnd))
       return -1;
 
     // return the packed length
@@ -2299,7 +2294,12 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen
 
 // Main unpack functions - public
 
-int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p4_p5_codec_config_t *config) {
+int nfapi_p5_message_header_unpack(void *pMessageBuf,
+                                   uint32_t messageBufLen,
+                                   void *pUnpackedBuf,
+                                   uint32_t unpackedBufLen,
+                                   nfapi_p4_p5_codec_config_t *config)
+{
   nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
   uint8_t *pReadPackedMessage = pMessageBuf;
 
@@ -2316,10 +2316,42 @@ int nfapi_p5_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
   }
 
   // process the header
-  return ( pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-           pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-           pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-           pull16(&pReadPackedMessage, &pMessageHeader->spare, end) );
+  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->message_length, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) {
+    return -1;
+  }
+
+  return 8;
+}
+
+int nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
+                                      uint32_t messageBufLen,
+                                      void *pUnpackedBuf,
+                                      uint32_t unpackedBufLen,
+                                      nfapi_p4_p5_codec_config_t *config)
+{
+  nfapi_nr_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied pointers are null\n");
+    return -1;
+  }
+
+  uint8_t *end = pMessageBuf + messageBufLen;
+
+  if (messageBufLen < NFAPI_NR_P5_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p4_p5_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+  // process the header
+  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->message_length, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) {
+    return -1;
+  }
+  return NFAPI_NR_P5_HEADER_LENGTH;
 }
 
 int nfapi_nr_p5_message_unpack(void *pMessageBuf,
@@ -2328,41 +2360,24 @@ int nfapi_nr_p5_message_unpack(void *pMessageBuf,
                                uint32_t unpackedBufLen,
                                nfapi_p4_p5_codec_config_t *config)
 {
-  nfapi_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
-  uint8_t *pReadPackedMessage = pMessageBuf;
-
   if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
     NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied pointers are null\n");
     return -1;
   }
-
-  uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
-
-  if (messageBufLen < NFAPI_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p4_p5_message_header_t)) {
+  if (messageBufLen < NFAPI_NR_P5_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p4_p5_message_header_t)) {
     NFAPI_TRACE(NFAPI_TRACE_ERROR, "P5 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
     return -1;
   }
 
-  uint8_t *ptr = pReadPackedMessage;
-  printf("\n Read NR message unpack: ");
-
-  while (ptr < end) {
-    printf(" %02x ", *ptr);
-    ptr++;
-  }
-
-  printf("\n");
+  nfapi_nr_p4_p5_message_header_t *pMessageHeader = pUnpackedBuf;
   // clean the supplied buffer for - tag value blanking
   (void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
   // process the header
-  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
-        && pull16(&pReadPackedMessage, &pMessageHeader->message_length, end)
-        && pull16(&pReadPackedMessage, &pMessageHeader->spare, end))) {
-    // failed to read the header
+  if (!nfapi_nr_p5_message_header_unpack(pMessageBuf, messageBufLen, pMessageHeader, unpackedBufLen, config)) {
     return -1;
   }
-
+  uint8_t *pReadPackedMessage = pMessageBuf + NFAPI_NR_P5_HEADER_LENGTH;
+  uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
   int result = -1;
 
   if (check_nr_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0) {
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index bcaf7a524ddff848dfbb89829802d31ddec3f4b6..df554ab599834c74d0e9e708c36e3eb7ad30ecfc 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -39,6 +39,8 @@
 #include <debug.h>
 #include "nfapi_nr_interface_scf.h"
 #include "nr_nfapi_p7.h"
+#include "nr_fapi.h"
+#include "nr_fapi_p7.h"
 
 extern int nfapi_unpack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppReadPackedMsg, void *user_data);
 extern int nfapi_pack_p7_vendor_extension(nfapi_p7_message_header_t *header, uint8_t **ppWritePackedMsg, void *user_data);
@@ -62,15 +64,50 @@ int nfapi_p7_update_checksum(uint8_t *buffer, uint32_t len) {
   return (push32(checksum, &p_write, buffer + len) > 0 ? 0 : -1);
 }
 
-int nfapi_p7_update_transmit_timestamp(uint8_t *buffer, uint32_t timestamp) {
+int nfapi_p7_update_transmit_timestamp(uint8_t *buffer, uint32_t timestamp)
+{
   uint8_t *p_write = &buffer[12];
-  return (push32(timestamp, &p_write, buffer + 16) > 0 ? 0 : -1);
+  return (push32(timestamp, &p_write, buffer + NFAPI_P7_HEADER_LENGTH) > 0 ? 0 : -1);
 }
 
 uint32_t nfapi_p7_calculate_checksum(uint8_t *buffer, uint32_t len) {
   return nfapi_calculate_checksum(buffer, len);
 }
 
+uint32_t nfapi_nr_calculate_checksum(uint8_t *buffer, uint16_t len)
+{
+  uint32_t chksum = 0;
+  // calcaulte upto the checksum
+  chksum = crc32(chksum, buffer, 10);
+  // skip the checksum
+  uint8_t zeros[4] = {0, 0, 0, 0};
+  chksum = crc32(chksum, zeros, 4);
+  // continu with the rest of the mesage
+  chksum = crc32(chksum, &buffer[NFAPI_NR_P7_HEADER_LENGTH], len - NFAPI_NR_P7_HEADER_LENGTH);
+  // return the inverse
+  return ~(chksum);
+}
+
+int nfapi_nr_p7_update_checksum(uint8_t *buffer, uint32_t len)
+{
+  uint32_t checksum = nfapi_nr_calculate_checksum(buffer, len);
+  // 10 is the beginning position of checksum
+  uint8_t *p_write = &buffer[10];
+  return (push32(checksum, &p_write, buffer + len) > 0 ? 0 : -1);
+}
+
+int nfapi_nr_p7_update_transmit_timestamp(uint8_t *buffer, uint32_t timestamp)
+{
+  // 14 is the beginning position of transmit_timestamp
+  uint8_t *p_write = &buffer[14];
+  return (push32(timestamp, &p_write, buffer + NFAPI_NR_P7_HEADER_LENGTH) > 0 ? 0 : -1);
+}
+
+uint32_t nfapi_nr_p7_calculate_checksum(uint8_t *buffer, uint32_t len)
+{
+  return nfapi_nr_calculate_checksum(buffer, len);
+}
+
 void *nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t *config) {
   if(size == 0)
     return 0;
@@ -198,174 +235,6 @@ static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t *value, uint8_t **ppW
   return 1;
 }
 
-static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
-  return (push16(value->bwp_size, ppWritePackedMsg, end) && push16(value->bwp_start, ppWritePackedMsg, end)
-          && push8(value->subcarrier_spacing, ppWritePackedMsg, end) && push8(value->cyclic_prefix, ppWritePackedMsg, end)
-          && push16(value->start_rb, ppWritePackedMsg, end) && push16(value->nr_of_rbs, ppWritePackedMsg, end)
-          && push8(value->csi_type, ppWritePackedMsg, end) && push8(value->row, ppWritePackedMsg, end)
-          && push16(value->freq_domain, ppWritePackedMsg, end) && push8(value->symb_l0, ppWritePackedMsg, end)
-          && push8(value->symb_l1, ppWritePackedMsg, end) && push8(value->cdm_type, ppWritePackedMsg, end)
-          && push8(value->freq_density, ppWritePackedMsg, end) && push16(value->scramb_id, ppWritePackedMsg, end)
-          && push8(value->power_control_offset, ppWritePackedMsg, end)
-          && push8(value->power_control_offset_ss, ppWritePackedMsg, end) &&
-          // TODO Add Precoding and Beamforming, hardcoded for now
-          push16(0, ppWritePackedMsg, end) && push16(0, ppWritePackedMsg, end) && push8(0, ppWritePackedMsg, end));
-}
-
-static uint8_t pack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
-
-  if (!(push16(value->BWPSize, ppWritePackedMsg, end) && push16(value->BWPStart, ppWritePackedMsg, end)
-        && push8(value->SubcarrierSpacing, ppWritePackedMsg, end) && push8(value->CyclicPrefix, ppWritePackedMsg, end)
-        && push8(value->StartSymbolIndex, ppWritePackedMsg, end) && push8(value->DurationSymbols, ppWritePackedMsg, end)
-        && pusharray8(value->FreqDomainResource, 6, 6, ppWritePackedMsg, end)
-        && push8(value->CceRegMappingType, ppWritePackedMsg, end) && push8(value->RegBundleSize, ppWritePackedMsg, end)
-        && push8(value->InterleaverSize, ppWritePackedMsg, end) && push8(value->CoreSetType, ppWritePackedMsg, end)
-        && push16(value->ShiftIndex, ppWritePackedMsg, end) && push8(value->precoderGranularity, ppWritePackedMsg, end)
-        && push16(value->numDlDci, ppWritePackedMsg, end))) {
-    return 0;
-  }
-
-  for (uint16_t i = 0; i < value->numDlDci; ++i) {
-    if (!(push16(value->dci_pdu[i].RNTI, ppWritePackedMsg, end) && push16(value->dci_pdu[i].ScramblingId, ppWritePackedMsg, end)
-          && push16(value->dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end)
-          && push8(value->dci_pdu[i].CceIndex, ppWritePackedMsg, end)
-          && push8(value->dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) {
-      return 0;
-    }
-    // Precoding and beamforming
-    // TODO get these values from elsewhere and delete the hardcoded ones
-    value->dci_pdu[i].precodingAndBeamforming.num_prgs = 0;
-    value->dci_pdu[i].precodingAndBeamforming.prg_size = 0; // 1 PRG of max size for analogue beamforming
-    value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces = 0;
-    value->dci_pdu[i].precodingAndBeamforming.prgs_list[0].pm_idx = 0;
-    value->dci_pdu[i].precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
-    if (!(push16(value->dci_pdu[i].precodingAndBeamforming.num_prgs, ppWritePackedMsg, end)
-          && push16(value->dci_pdu[i].precodingAndBeamforming.prg_size, ppWritePackedMsg, end)
-          && push8(value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
-      return 0;
-    }
-    for (int prg = 0; prg < value->dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
-      if (!push16(value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx, ppWritePackedMsg, end)) {
-        return 0;
-      }
-      for (int digInt = 0; digInt < value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces; digInt++) {
-        if (!push16(value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].dig_bf_interface_list[digInt].beam_idx,
-                    ppWritePackedMsg,
-                    end)) {
-          return 0;
-        }
-      }
-    }
-    // TX Power info
-    if (!(push8(value->dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end)
-          && push8(value->dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
-          // DCI Payload fields
-          push16(value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
-          // Pack DCI Payload
-          pack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end))) {
-      return 0;
-    }
-  }
-  return 1;
-}
-
-static uint8_t pack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
-
-  if (!(push16(value->pduBitmap, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
-        && push16(value->pduIndex, ppWritePackedMsg, end) && push16(value->BWPSize, ppWritePackedMsg, end)
-        && push16(value->BWPStart, ppWritePackedMsg, end) && push8(value->SubcarrierSpacing, ppWritePackedMsg, end)
-        && push8(value->CyclicPrefix, ppWritePackedMsg, end) && push8(value->NrOfCodewords, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  for (int i = 0; i < value->NrOfCodewords; ++i) {
-    if (!(push16(value->targetCodeRate[i], ppWritePackedMsg, end) && push8(value->qamModOrder[i], ppWritePackedMsg, end)
-          && push8(value->mcsIndex[i], ppWritePackedMsg, end) && push8(value->mcsTable[i], ppWritePackedMsg, end)
-          && push8(value->rvIndex[i], ppWritePackedMsg, end) && push32(value->TBSize[i], ppWritePackedMsg, end))) {
-      return 0;
-    }
-  }
-
-  if (!(push16(value->dataScramblingId, ppWritePackedMsg, end) && push8(value->nrOfLayers, ppWritePackedMsg, end)
-        && push8(value->transmissionScheme, ppWritePackedMsg, end) && push8(value->refPoint, ppWritePackedMsg, end)
-        && push16(value->dlDmrsSymbPos, ppWritePackedMsg, end) && push8(value->dmrsConfigType, ppWritePackedMsg, end)
-        && push16(value->dlDmrsScramblingId, ppWritePackedMsg, end) && push8(value->SCID, ppWritePackedMsg, end)
-        && push8(value->numDmrsCdmGrpsNoData, ppWritePackedMsg, end) && push16(value->dmrsPorts, ppWritePackedMsg, end)
-        && push8(value->resourceAlloc, ppWritePackedMsg, end) && (int)pusharray8(value->rbBitmap, 36, 36, ppWritePackedMsg, end)
-        && push16(value->rbStart, ppWritePackedMsg, end) && push16(value->rbSize, ppWritePackedMsg, end)
-        && push8(value->VRBtoPRBMapping, ppWritePackedMsg, end) && push8(value->StartSymbolIndex, ppWritePackedMsg, end)
-        && push8(value->NrOfSymbols, ppWritePackedMsg, end))) {
-    return 0;
-  }
-
-  // Check pduBitMap bit 1 to add or not PTRS parameters
-  if (value->pduBitmap & 0b1) {
-    if (!(push8(value->PTRSPortIndex, ppWritePackedMsg, end) && push8(value->PTRSTimeDensity, ppWritePackedMsg, end)
-          && push8(value->PTRSFreqDensity, ppWritePackedMsg, end) && push8(value->PTRSReOffset, ppWritePackedMsg, end)
-          && push8(value->nEpreRatioOfPDSCHToPTRS, ppWritePackedMsg, end))) {
-      return 0;
-    }
-  }
-
-  if (!(push16(value->precodingAndBeamforming.num_prgs, ppWritePackedMsg, end)
-        && push16(value->precodingAndBeamforming.prg_size, ppWritePackedMsg, end)
-        && push8(value->precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  for (int i = 0; i < value->precodingAndBeamforming.num_prgs; ++i) {
-    if (!push16(value->precodingAndBeamforming.prgs_list[i].pm_idx, ppWritePackedMsg, end)) {
-      return 0;
-    }
-    for (int k = 0; k < value->precodingAndBeamforming.dig_bf_interfaces; ++k) {
-      if (!push16(value->precodingAndBeamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, ppWritePackedMsg, end)) {
-        return 0;
-      }
-    }
-  }
-  // TODO Add TX power info
-  // Hardcoded values that represent 0db
-  if (!(push8(0, ppWritePackedMsg, end) && // powerControlOffset
-        push8(0, ppWritePackedMsg, end))) { // powerControlOffsetSS
-    return 0;
-  }
-  // TODO Add CBG Fields
-  return 1;
-}
-
-static uint8_t pack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Packing ssb. \n");
-  nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
-
-  if (!(push16(value->PhysCellId, ppWritePackedMsg, end) && push8(value->BetaPss, ppWritePackedMsg, end)
-        && push8(value->SsbBlockIndex, ppWritePackedMsg, end) && push8(value->SsbSubcarrierOffset, ppWritePackedMsg, end)
-        && push16(value->ssbOffsetPointA, ppWritePackedMsg, end) && push8(value->bchPayloadFlag, ppWritePackedMsg, end)
-        && push8((value->bchPayload >> 16) & 0xff, ppWritePackedMsg, end)
-        && push8((value->bchPayload >> 8) & 0xff, ppWritePackedMsg, end) && push8(value->bchPayload & 0xff, ppWritePackedMsg, end)
-        && push8(0, ppWritePackedMsg, end)
-        // TODO add Tx Power Info
-        && push16(value->precoding_and_beamforming.num_prgs, ppWritePackedMsg, end)
-        && push16(value->precoding_and_beamforming.prg_size, ppWritePackedMsg, end)
-        && push8(value->precoding_and_beamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  for (int i = 0; i < value->precoding_and_beamforming.num_prgs; ++i) {
-    if (!push16(value->precoding_and_beamforming.prgs_list[i].pm_idx, ppWritePackedMsg, end)) {
-      return 0;
-    }
-    for (int k = 0; k < value->precoding_and_beamforming.dig_bf_interfaces; ++k) {
-      if (!push16(value->precoding_and_beamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, ppWritePackedMsg, end)) {
-        return 0;
-      }
-    }
-  }
-  return 1;
-}
 
 static uint8_t pack_dl_config_dci_dl_pdu_rel13_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
   nfapi_dl_config_dci_dl_pdu_rel13_t *value = (nfapi_dl_config_dci_dl_pdu_rel13_t *)tlv;
@@ -647,49 +516,6 @@ static uint8_t pack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppWrit
           push8(value->nrs_antenna_ports_assumed_by_the_ue, ppWritePackedMsg, end));
 }
 
-static uint8_t pack_dl_tti_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)tlv;
-  uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
-  if (!push16(value->PDUType, ppWritePackedMsg, end))
-    return 0;
-  uint8_t *pPackedLengthField = *ppWritePackedMsg;
-  if (!push16(value->PDUSize, ppWritePackedMsg, end))
-    return 0;
-
-  // first match the pdu type, then call the respective function
-  switch (value->PDUType) {
-    case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
-      if (!(pack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15, ppWritePackedMsg, end)))
-        return 0;
-    } break;
-
-    case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
-      if (!(pack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15, ppWritePackedMsg, end)))
-        return 0;
-    } break;
-
-    case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
-      if (!(pack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15, ppWritePackedMsg, end)))
-        return 0;
-    } break;
-
-    case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
-      if (!(pack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15, ppWritePackedMsg, end)))
-        return 0;
-    } break;
-
-    default: {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType);
-    } break;
-  }
-  // pack proper size
-  uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
-  uint16_t packedMsgLen = msgEnd - msgHead;
-  value->PDUSize = packedMsgLen;
-  return push16(value->PDUSize, &pPackedLengthField, end);
-}
-
 static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
   nfapi_dl_config_request_body_t *value = (nfapi_dl_config_request_body_t *)tlv;
 
@@ -830,34 +656,6 @@ static uint8_t pack_dl_config_request_body_value(void *tlv, uint8_t **ppWritePac
   return 1;
 }
 
-uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
-
-  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
-        && push8(pNfapiMsg->dl_tti_request_body.nPDUs, ppWritePackedMsg, end)
-        && push8(pNfapiMsg->dl_tti_request_body.nGroup, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
-    if (!pack_dl_tti_request_body_value(&pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i], ppWritePackedMsg, end))
-      return 0;
-  }
-
-  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
-    if (!push8(pNfapiMsg->dl_tti_request_body.nUe[i], ppWritePackedMsg, end))
-      return 0;
-    for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
-      if (!(push32(pNfapiMsg->dl_tti_request_body.PduIdx[i][j], ppWritePackedMsg, end))) {
-        return 0;
-      }
-    }
-    return 0;
-  }
-
-  return 1;
-}
-
 static uint8_t pack_dl_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
   nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg;
   //return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
@@ -925,213 +723,6 @@ static uint8_t pack_ul_config_request_ulsch_rel13_value(void *tlv, uint8_t **ppW
           push8(ulsch_pdu_rel13->empty_symbols_due_to_re_tunning, ppWritePackedMsg, end));
 }
 
-//Pack fns for ul_tti PDUS
-
-static uint8_t pack_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *prach_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  if (!(push16(prach_pdu->phys_cell_id, ppWritePackedMsg, end) && push8(prach_pdu->num_prach_ocas, ppWritePackedMsg, end)
-        && push8(prach_pdu->prach_format, ppWritePackedMsg, end) && push8(prach_pdu->num_ra, ppWritePackedMsg, end)
-        && push8(prach_pdu->prach_start_symbol, ppWritePackedMsg, end) && push16(prach_pdu->num_cs, ppWritePackedMsg, end))) {
-    return 0;
-  }
-
-  // Pack RX Beamforming PDU
-  if (!(push16(prach_pdu->beamforming.num_prgs, ppWritePackedMsg, end)
-        && push16(prach_pdu->beamforming.prg_size, ppWritePackedMsg, end)
-        && push8(prach_pdu->beamforming.dig_bf_interface, ppWritePackedMsg, end)))
-    return 0;
-
-  for (int prg = 0; prg < prach_pdu->beamforming.num_prgs; prg++) {
-    for (int digBFInterface = 0; digBFInterface < prach_pdu->beamforming.dig_bf_interface; digBFInterface++) {
-      if (!push16(prach_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end))
-        return 0;
-    }
-  }
-  return 1;
-}
-
-static uint8_t pack_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pucch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  if (!(push16(pucch_pdu->rnti, ppWritePackedMsg, end) && push32(pucch_pdu->handle, ppWritePackedMsg, end)
-        && push16(pucch_pdu->bwp_size, ppWritePackedMsg, end) && push16(pucch_pdu->bwp_start, ppWritePackedMsg, end)
-        && push8(pucch_pdu->subcarrier_spacing, ppWritePackedMsg, end) && push8(pucch_pdu->cyclic_prefix, ppWritePackedMsg, end)
-        && push8(pucch_pdu->format_type, ppWritePackedMsg, end) && push8(pucch_pdu->multi_slot_tx_indicator, ppWritePackedMsg, end)
-        && push8(pucch_pdu->pi_2bpsk, ppWritePackedMsg, end) && push16(pucch_pdu->prb_start, ppWritePackedMsg, end)
-        && push16(pucch_pdu->prb_size, ppWritePackedMsg, end) && push8(pucch_pdu->start_symbol_index, ppWritePackedMsg, end)
-        && push8(pucch_pdu->nr_of_symbols, ppWritePackedMsg, end) && push8(pucch_pdu->freq_hop_flag, ppWritePackedMsg, end)
-        && push16(pucch_pdu->second_hop_prb, ppWritePackedMsg, end) && push8(pucch_pdu->group_hop_flag, ppWritePackedMsg, end)
-        && push8(pucch_pdu->sequence_hop_flag, ppWritePackedMsg, end) && push16(pucch_pdu->hopping_id, ppWritePackedMsg, end)
-        && push16(pucch_pdu->initial_cyclic_shift, ppWritePackedMsg, end)
-        && push16(pucch_pdu->data_scrambling_id, ppWritePackedMsg, end)
-        && push8(pucch_pdu->time_domain_occ_idx, ppWritePackedMsg, end) && push8(pucch_pdu->pre_dft_occ_idx, ppWritePackedMsg, end)
-        && push8(pucch_pdu->pre_dft_occ_len, ppWritePackedMsg, end) && push8(pucch_pdu->add_dmrs_flag, ppWritePackedMsg, end)
-        && push16(pucch_pdu->dmrs_scrambling_id, ppWritePackedMsg, end)
-        && push8(pucch_pdu->dmrs_cyclic_shift, ppWritePackedMsg, end) && push8(pucch_pdu->sr_flag, ppWritePackedMsg, end)
-        && push16(pucch_pdu->bit_len_harq, ppWritePackedMsg, end) && push16(pucch_pdu->bit_len_csi_part1, ppWritePackedMsg, end)
-        && push16(pucch_pdu->bit_len_csi_part2, ppWritePackedMsg, end)
-        // Pack RX Beamforming PDU
-        && push16(pucch_pdu->beamforming.num_prgs, ppWritePackedMsg, end)
-        && push16(pucch_pdu->beamforming.prg_size, ppWritePackedMsg, end)
-        && push8(pucch_pdu->beamforming.dig_bf_interface, ppWritePackedMsg, end))) {
-    return 0;
-  }
-
-  for (int prg = 0; prg < pucch_pdu->beamforming.num_prgs; prg++) {
-    for (int digBFInterface = 0; digBFInterface < pucch_pdu->beamforming.dig_bf_interface; digBFInterface++) {
-      if (!push16(pucch_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end))
-        return 0;
-    }
-  }
-  return 1;
-}
-
-static uint8_t pack_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  if (!(push16(pusch_pdu->pdu_bit_map, ppWritePackedMsg, end) && push16(pusch_pdu->rnti, ppWritePackedMsg, end)
-        && push32(pusch_pdu->handle, ppWritePackedMsg, end) && push16(pusch_pdu->bwp_size, ppWritePackedMsg, end)
-        && push16(pusch_pdu->bwp_start, ppWritePackedMsg, end) && push8(pusch_pdu->subcarrier_spacing, ppWritePackedMsg, end)
-        && push8(pusch_pdu->cyclic_prefix, ppWritePackedMsg, end) && push16(pusch_pdu->target_code_rate, ppWritePackedMsg, end)
-        && push8(pusch_pdu->qam_mod_order, ppWritePackedMsg, end) && push8(pusch_pdu->mcs_index, ppWritePackedMsg, end)
-        && push8(pusch_pdu->mcs_table, ppWritePackedMsg, end) && push8(pusch_pdu->transform_precoding, ppWritePackedMsg, end)
-        && push16(pusch_pdu->data_scrambling_id, ppWritePackedMsg, end) && push8(pusch_pdu->nrOfLayers, ppWritePackedMsg, end)
-        && push16(pusch_pdu->ul_dmrs_symb_pos, ppWritePackedMsg, end) && push8(pusch_pdu->dmrs_config_type, ppWritePackedMsg, end)
-        && push16(pusch_pdu->ul_dmrs_scrambling_id, ppWritePackedMsg, end)
-        && push16(pusch_pdu->pusch_identity, ppWritePackedMsg, end) && push8(pusch_pdu->scid, ppWritePackedMsg, end)
-        && push8(pusch_pdu->num_dmrs_cdm_grps_no_data, ppWritePackedMsg, end)
-        && push16(pusch_pdu->dmrs_ports, ppWritePackedMsg, end) && push8(pusch_pdu->resource_alloc, ppWritePackedMsg, end)
-        && pusharray8(pusch_pdu->rb_bitmap, 36, 36, ppWritePackedMsg, end) && push16(pusch_pdu->rb_start, ppWritePackedMsg, end)
-        && push16(pusch_pdu->rb_size, ppWritePackedMsg, end) && push8(pusch_pdu->vrb_to_prb_mapping, ppWritePackedMsg, end)
-        && push8(pusch_pdu->frequency_hopping, ppWritePackedMsg, end)
-        && push16(pusch_pdu->tx_direct_current_location, ppWritePackedMsg, end)
-        && push8(pusch_pdu->uplink_frequency_shift_7p5khz, ppWritePackedMsg, end)
-        && push8(pusch_pdu->start_symbol_index, ppWritePackedMsg, end) && push8(pusch_pdu->nr_of_symbols, ppWritePackedMsg, end)
-        // TODO: ignoring beamforming tlv for now
-        )) {
-    return 0;
-  }
-  // Pack Optional Data only included if indicated in pduBitmap
-  switch (pusch_pdu->pdu_bit_map) {
-    case PUSCH_PDU_BITMAP_PUSCH_DATA: {
-      // pack optional TLVs
-      if (!(push8(pusch_pdu->pusch_data.rv_index, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_data.harq_process_id, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_data.new_data_indicator, ppWritePackedMsg, end)
-            && push32(pusch_pdu->pusch_data.tb_size, ppWritePackedMsg, end)
-            && push16(pusch_pdu->pusch_data.num_cb, ppWritePackedMsg, end)
-            && pusharray8(pusch_pdu->pusch_data.cb_present_and_position,
-                          (pusch_pdu->pusch_data.num_cb + 7) / 8,
-                          (pusch_pdu->pusch_data.num_cb + 7) / 8,
-                          ppWritePackedMsg,
-                          end))) {
-        return 0;
-      }
-    } break;
-
-    case PUSCH_PDU_BITMAP_PUSCH_UCI: {
-      if (!(push16(pusch_pdu->pusch_uci.harq_ack_bit_length, ppWritePackedMsg, end)
-            && push16(pusch_pdu->pusch_uci.csi_part1_bit_length, ppWritePackedMsg, end)
-            && push16(pusch_pdu->pusch_uci.csi_part2_bit_length, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_uci.alpha_scaling, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_uci.beta_offset_harq_ack, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_uci.beta_offset_csi1, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_uci.beta_offset_csi2, ppWritePackedMsg, end))) {
-        return 0;
-      }
-    } break;
-
-    case PUSCH_PDU_BITMAP_PUSCH_PTRS: {
-      if (!push8(pusch_pdu->pusch_ptrs.num_ptrs_ports, ppWritePackedMsg, end)) {
-        return 0;
-      }
-      for (int i = 0; i < pusch_pdu->pusch_ptrs.num_ptrs_ports; ++i) {
-        if (!(push16(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_port_index, ppWritePackedMsg, end)
-              && push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_dmrs_port, ppWritePackedMsg, end)
-              && push8(pusch_pdu->pusch_ptrs.ptrs_ports_list[i].ptrs_re_offset, ppWritePackedMsg, end))) {
-          return 0;
-        }
-      }
-
-      if (!(push8(pusch_pdu->pusch_ptrs.ptrs_time_density, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_ptrs.ptrs_freq_density, ppWritePackedMsg, end)
-            && push8(pusch_pdu->pusch_ptrs.ul_ptrs_power, ppWritePackedMsg, end))) {
-        return 0;
-      }
-    } break;
-
-    case PUSCH_PDU_BITMAP_DFTS_OFDM: {
-      if (!(push8(pusch_pdu->dfts_ofdm.low_papr_group_number, ppWritePackedMsg, end)
-            && push16(pusch_pdu->dfts_ofdm.low_papr_sequence_number, ppWritePackedMsg, end)
-            && push8(pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, ppWritePackedMsg, end)
-            && push8(pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, ppWritePackedMsg, end))) {
-        return 0;
-      }
-    } break;
-
-    default: {
-      NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map);
-    }
-  }
-  // Pack RX Beamforming PDU
-  if (!(push16(pusch_pdu->beamforming.num_prgs, ppWritePackedMsg, end)
-        && push16(pusch_pdu->beamforming.prg_size, ppWritePackedMsg, end)
-        && push8(pusch_pdu->beamforming.dig_bf_interface, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  for (int prg = 0; prg < pusch_pdu->beamforming.num_prgs; prg++) {
-    for (int digBFInterface = 0; digBFInterface < pusch_pdu->beamforming.dig_bf_interface; digBFInterface++) {
-      if (!push16(pusch_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, ppWritePackedMsg, end)) {
-        return 0;
-      }
-    }
-  }
-  return 1;
-}
-
-static uint8_t pack_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *srs_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
-  if(!(
-          push16(srs_pdu->rnti, ppWritePackedMsg, end) &&
-          push32(srs_pdu->handle, ppWritePackedMsg, end) &&
-          push16(srs_pdu->bwp_size, ppWritePackedMsg, end) &&
-          push16(srs_pdu->bwp_start, ppWritePackedMsg, end) &&
-          push8(srs_pdu->subcarrier_spacing, ppWritePackedMsg, end) &&
-          push8(srs_pdu->cyclic_prefix, ppWritePackedMsg, end) &&
-          push8(srs_pdu->num_ant_ports, ppWritePackedMsg, end) &&
-          push8(srs_pdu->num_symbols, ppWritePackedMsg, end) &&
-          push8(srs_pdu->num_repetitions, ppWritePackedMsg, end) &&
-          push8(srs_pdu->time_start_position, ppWritePackedMsg, end) &&
-          push8(srs_pdu->config_index, ppWritePackedMsg, end) &&
-          push16(srs_pdu->sequence_id, ppWritePackedMsg, end) &&
-          push8(srs_pdu->bandwidth_index, ppWritePackedMsg, end) &&
-          push8(srs_pdu->comb_size, ppWritePackedMsg, end) &&
-          push8(srs_pdu->comb_offset, ppWritePackedMsg, end) &&
-          push8(srs_pdu->cyclic_shift, ppWritePackedMsg, end) &&
-          push8(srs_pdu->frequency_position, ppWritePackedMsg, end) &&
-          push16(srs_pdu->frequency_shift, ppWritePackedMsg, end) &&
-          push8(srs_pdu->frequency_hopping, ppWritePackedMsg, end) &&
-          push8(srs_pdu->group_or_sequence_hopping, ppWritePackedMsg, end) &&
-          push8(srs_pdu->resource_type, ppWritePackedMsg, end) &&
-          push16(srs_pdu->t_srs, ppWritePackedMsg, end) &&
-          push16(srs_pdu->t_offset, ppWritePackedMsg, end)
-          // TODO: ignoring beamforming tlv for now
-        )){
-    return 0;
-  }
-  // Rx Beamforming PDU
-  if(!(push16(srs_pdu->beamforming.num_prgs,ppWritePackedMsg,end) &&
-    push16(srs_pdu->beamforming.prg_size,ppWritePackedMsg,end) &&
-    push8(srs_pdu->beamforming.dig_bf_interface,ppWritePackedMsg,end))){
-      return 0;
-  }
-  for(int prg = 0; prg < srs_pdu->beamforming.num_prgs; prg ++){
-    for(int digInt = 0; digInt < srs_pdu->beamforming.dig_bf_interface; digInt++){
-      if(!push16(srs_pdu->beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx,ppWritePackedMsg,end)){
-        return 0;
-      }
-    }
-  }
-  return 1;
-}
-
 static uint8_t pack_ul_config_request_ulsch_pdu(nfapi_ul_config_ulsch_pdu *ulsch_pdu, uint8_t **ppWritePackedMsg, uint8_t *end) {
   return ( pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG, &ulsch_pdu->ulsch_pdu_rel8, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel8_value) &&
            pack_tlv(NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL10_TAG, &ulsch_pdu->ulsch_pdu_rel10, ppWritePackedMsg, end, &pack_ul_config_request_ulsch_rel10_value) &&
@@ -1422,66 +1013,6 @@ static uint8_t pack_ul_config_request_nrach_pdu_rel13_value(void *tlv, uint8_t *
            push8(nrach_pdu_rel13->nprach_config_2, ppWritePackedMsg, end));
 }
 
-static uint8_t pack_ul_tti_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_ul_tti_request_number_of_pdus_t *value = (nfapi_nr_ul_tti_request_number_of_pdus_t *)tlv;
-  uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
-  if (!push16(value->pdu_type, ppWritePackedMsg, end)) {
-    return 0;
-  }
-  uint8_t *pPackedLengthField = *ppWritePackedMsg;
-
-  if (!push16(value->pdu_size, ppWritePackedMsg, end))
-    return 0;
-  // pack PDUs
-  //  first match the pdu type, then call the respective function
-  switch (value->pdu_type) {
-    case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
-      if (!pack_ul_tti_request_prach_pdu(&value->prach_pdu, ppWritePackedMsg, end))
-        return 0;
-    } break;
-
-    case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
-      if (!pack_ul_tti_request_pucch_pdu(&value->pucch_pdu, ppWritePackedMsg, end))
-        return 0;
-    } break;
-
-    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
-      if (!pack_ul_tti_request_pusch_pdu(&value->pusch_pdu, ppWritePackedMsg, end))
-        return 0;
-    } break;
-
-    case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
-      if (!pack_ul_tti_request_srs_pdu(&value->srs_pdu, ppWritePackedMsg, end))
-        return 0;
-    } break;
-
-    default: {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", value->pdu_type);
-    } break;
-  }
-
-  // pack proper size
-  uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
-  uint16_t packedMsgLen = msgEnd - msgHead;
-  value->pdu_size = packedMsgLen;
-  return push16(value->pdu_size, &pPackedLengthField, end);
-}
-
-static uint8_t pack_ul_tti_groups_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
-  nfapi_nr_ul_tti_request_number_of_groups_t *value = (nfapi_nr_ul_tti_request_number_of_groups_t *)tlv;
-
-  if(!push8(value->n_ue, ppWritePackedMsg, end))
-    return 0;
-
-  for(int i=0; i<value->n_ue; i++) {
-    if(!push8(value->ue_list[i].pdu_idx, ppWritePackedMsg, end))
-      return 0;
-  }
-
-  return 1;
-}
-
 static uint8_t pack_ul_config_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
   nfapi_ul_config_request_body_t *value = (nfapi_ul_config_request_body_t *)tlv;
 
@@ -1655,52 +1186,6 @@ static uint8_t pack_ul_config_request_body_value(void *tlv, uint8_t **ppWritePac
   return 1;
 }
 
-uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
-  pNfapiMsg->n_ulcch = 0;
-  pNfapiMsg->n_ulsch = 0;
-  for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
-    switch ((&pNfapiMsg->pdus_list[i])->pdu_type) {
-      case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
-        pNfapiMsg->n_ulcch++;
-      } break;
-      case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
-        pNfapiMsg->n_ulsch++;
-      } break;
-      default:
-        break;
-    }
-  }
-
-  if (!push16(pNfapiMsg->SFN, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(pNfapiMsg->Slot, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(pNfapiMsg->n_pdus, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(pNfapiMsg->rach_present, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(pNfapiMsg->n_ulsch, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(pNfapiMsg->n_ulcch, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(pNfapiMsg->n_group, ppWritePackedMsg, end))
-    return 0;
-
-  for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
-    if (!pack_ul_tti_pdu_list_value(&pNfapiMsg->pdus_list[i], ppWritePackedMsg, end))
-      return 0;
-  }
-
-  for (int i = 0; i < pNfapiMsg->n_group; i++) {
-    if (!pack_ul_tti_groups_list_value(&pNfapiMsg->groups_list[i], ppWritePackedMsg, end))
-      return 0;
-  }
-
-  return 1;
-}
-
 static uint8_t pack_ul_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
   nfapi_ul_config_request_t *pNfapiMsg = (nfapi_ul_config_request_t *)msg;
   return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
@@ -1901,105 +1386,6 @@ static uint8_t pack_hi_dci0_request_body_value(void *tlv, uint8_t **ppWritePacke
   return 1;
 }
 
-static uint8_t pack_ul_dci_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)tlv;
-  uintptr_t msgHead = (uintptr_t)*ppWritePackedMsg;
-  if (!push16(value->PDUType, ppWritePackedMsg, end)) {
-    return 0;
-  }
-  uint8_t *pPackedLengthField = *ppWritePackedMsg;
-  if (!(push16(value->PDUSize, ppWritePackedMsg, end) && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, ppWritePackedMsg, end)
-        && push16(value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, ppWritePackedMsg, end)
-        && pusharray8(value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, ppWritePackedMsg, end)
-        && push16(value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, ppWritePackedMsg, end)
-        && push8(value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, ppWritePackedMsg, end)
-        && push16(value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  for (int i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
-    if (!(push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, ppWritePackedMsg, end)
-          && push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, ppWritePackedMsg, end)
-          && push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, ppWritePackedMsg, end)
-          && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, ppWritePackedMsg, end)
-          && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, ppWritePackedMsg, end))) {
-      return 0;
-    }
-    // Precoding and Beamforming
-    // TODO get these values from elsewhere and delete the hardcoded ones
-    value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs = 0;
-    value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prg_size = 0;
-    value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces = 0;
-    value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[0].pm_idx = 0;
-    value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = 0;
-
-    if (!(push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs, ppWritePackedMsg, end)
-          && push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prg_size, ppWritePackedMsg, end)
-          && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, ppWritePackedMsg, end))) {
-      return 0;
-    }
-    for (int prg = 0; prg < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
-      if (!push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx,
-                  ppWritePackedMsg,
-                  end)) {
-        return 0;
-      }
-      for (int digInt = 0; digInt < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces;
-           digInt++) {
-        if (!push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i]
-                        .precodingAndBeamforming.prgs_list[prg]
-                        .dig_bf_interface_list[digInt]
-                        .beam_idx,
-                    ppWritePackedMsg,
-                    end)) {
-          return 0;
-        }
-      }
-    }
-    if (!(push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, ppWritePackedMsg, end)
-          && push8(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, ppWritePackedMsg, end) &&
-          // DCI Payload fields
-          push16(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, ppWritePackedMsg, end) &&
-          // Pack DCI Payload
-          pack_dci_payload(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload,
-                           value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits,
-                           ppWritePackedMsg,
-                           end))) {
-      return 0;
-    }
-  }
-
-  // pack proper size
-  uintptr_t msgEnd = (uintptr_t)*ppWritePackedMsg;
-  uint16_t packedMsgLen = msgEnd - msgHead;
-  value->PDUSize = packedMsgLen;
-  return push16(value->PDUSize, &pPackedLengthField, end);
-}
-
-uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
-
-  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
-        && push8(pNfapiMsg->numPdus, ppWritePackedMsg, end)))
-    return 0;
-
-  for (int i = 0; i < pNfapiMsg->numPdus; i++) {
-    if (!pack_ul_dci_pdu_list_value(&pNfapiMsg->ul_dci_pdu_list[i], ppWritePackedMsg, end))
-      return 0;
-  }
-
-  return 1;
-}
-
 static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
   nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t *)msg;
   return ( push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end) &&
@@ -2008,55 +1394,6 @@ static uint8_t pack_hi_dci0_request(void *msg, uint8_t **ppWritePackedMsg, uint8
 }
 
 //pack_tx_data_pdu_list_value
-static uint8_t pack_tx_data_pdu_list_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_pdu_t *value = (nfapi_nr_pdu_t *)tlv;
-  if (!(push32(value->PDU_length, ppWritePackedMsg, end) && push16(value->PDU_index, ppWritePackedMsg, end)
-        && push32(value->num_TLV, ppWritePackedMsg, end)))
-    return 0;
-
-  uint16_t i = 0;
-  uint16_t total_number_of_tlvs = value->num_TLV;
-
-  for (; i < total_number_of_tlvs; ++i) {
-    if (!(push16(value->TLVs[i].tag, ppWritePackedMsg, end) && push32(value->TLVs[i].length, ppWritePackedMsg, end)))
-      return 0;
-
-    switch (value->TLVs[i].tag) {
-      case 0: {
-        if (!pusharray32(value->TLVs[i].value.direct,
-                         (value->TLVs[i].length + 3) / 4,
-                         (value->TLVs[i].length + 3) / 4,
-                         ppWritePackedMsg,
-                         end)) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
-          return 0;
-        }
-        break;
-      }
-
-      case 1: {
-        if (!pusharray32(value->TLVs[i].value.ptr,
-                         (value->TLVs[i].length + 3) / 4,
-                         (value->TLVs[i].length + 3) / 4,
-                         ppWritePackedMsg,
-                         end)) {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s():%d. value->TLVs[i].length %d \n", __FUNCTION__, __LINE__, value->TLVs[i].length);
-          return 0;
-        }
-
-        break;
-      }
-
-      default: {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", value->TLVs[i].tag);
-        break;
-      }
-    }
-  }
-
-  return 1;
-}
 
 static uint8_t pack_tx_request_body_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
   nfapi_tx_request_body_t *value = (nfapi_tx_request_body_t *)tlv;
@@ -2101,30 +1438,6 @@ static uint8_t pack_tx_request_body_value(void *tlv, uint8_t **ppWritePackedMsg,
   return 1;
 }
 
-static uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
-
-  if (!(push16(pNfapiMsg->SFN, ppWritePackedMsg, end) && push16(pNfapiMsg->Slot, ppWritePackedMsg, end)
-        && push16(pNfapiMsg->Number_of_PDUs, ppWritePackedMsg, end)))
-    return 0;
-
-  for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
-    if (!pack_tx_data_pdu_list_value(&pNfapiMsg->pdu_list[i], ppWritePackedMsg, end)) {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR,
-                  "%s():%d. Error packing TX_DATA.request PDU #%d, PDU length = %d PDU IDX = %d\n",
-                  __FUNCTION__,
-                  __LINE__,
-                  i,
-                  pNfapiMsg->pdu_list[i].PDU_length,
-                  pNfapiMsg->pdu_list[i].PDU_index);
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
 static uint8_t pack_tx_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
   nfapi_tx_request_t *pNfapiMsg = (nfapi_tx_request_t *)msg;
   int x = push16(pNfapiMsg->sfn_sf, ppWritePackedMsg, end);
@@ -3157,119 +2470,79 @@ uint8_t pack_nr_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end,
 
 //NR UPLINK indication function packing
 
-//SLOT INDICATION
-
-uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
-
-  if (!(push16((uint16_t)pNfapiMsg->sfn, ppWritePackedMsg, end) && push16((uint16_t)pNfapiMsg->slot, ppWritePackedMsg, end)))
-    return 0;
-
-  return 1;
-}
-
-//RX DATA INDICATION
+//SRS INDICATION
 
-static uint8_t pack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
+int pack_nr_srs_channel_svd_representation(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen)
 {
-  if (!(push32(value->handle, ppWritePackedMsg, end)
-        && push16(value->rnti, ppWritePackedMsg, end)
-        && push8(value->harq_id, ppWritePackedMsg, end)
-        && push32(value->pdu_length, ppWritePackedMsg, end)
-        && push8(value->ul_cqi, ppWritePackedMsg, end)
-        && push16(value->timing_advance, ppWritePackedMsg, end)
-        && push16(value->rssi, ppWritePackedMsg, end)))
-    return 0;
-
-  if (pusharray8(value->pdu, value->pdu_length, value->pdu_length, ppWritePackedMsg, end) == 0)
-    return 0;
+  nfapi_nr_srs_channel_svd_representation_t *value = (nfapi_nr_srs_channel_svd_representation_t *)pMessageBuf;
 
-  return 1;
-}
+  const uint16_t iq_size = value->normalized_iq_representation == 0 ? 2 : 4;
+  const uint16_t ng = value->num_gnb_antenna_elements;
+  const uint8_t nu = value->num_ue_srs_ports;
 
-uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t *)msg;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *end = pPackedBuf + packedBufLen;
 
-  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
-        && push16(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
+  if (!(push8(value->normalized_iq_representation, &pWritePackedMessage, end)
+        && push8(value->normalized_singular_value_representation, &pWritePackedMessage, end)
+        && pushs8(value->singular_value_scaling, &pWritePackedMessage, end)
+        && push16(value->num_gnb_antenna_elements, &pWritePackedMessage, end)
+        && push8(value->num_ue_srs_ports, &pWritePackedMessage, end) && push16(value->prg_size, &pWritePackedMessage, end)
+        && push16(value->num_prgs, &pWritePackedMessage, end))) {
     return 0;
-
-  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
-    if (!pack_nr_rx_data_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
-      return 0;
   }
 
-  return 1;
-}
-
-//NR CRC INDICATION
-
-static uint8_t pack_nr_crc_indication_body(nfapi_nr_crc_t *value, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  if (!(push32(value->handle, ppWritePackedMsg, end) && push16(value->rnti, ppWritePackedMsg, end)
-        && push8(value->harq_id, ppWritePackedMsg, end) && push8(value->tb_crc_status, ppWritePackedMsg, end)
-        && push16(value->num_cb, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  if (value->num_cb != 0) {
-    if (!pusharray8(value->cb_crc_status,
-                    (int)(value->num_cb / 8) + 1,
-                    (int)(value->num_cb / 8) + 1,
-                    ppWritePackedMsg,
-                    end)) { // length is ceil(NumCb/8)
+  for (int prg_idx = 0; prg_idx < value->num_prgs; ++prg_idx) {
+    const nfapi_nr_srs_channel_svd_representation_prg_t *prg = &value->prg_list[prg_idx];
+    if (!(pusharray8(prg->left_eigenvectors_matrix_u, nu * nu * iq_size, nu * nu * iq_size, &pWritePackedMessage, end))) {
       return 0;
     }
-  }
-  if (!(push8(value->ul_cqi, ppWritePackedMsg, end) && push16(value->timing_advance, ppWritePackedMsg, end)
-        && push16(value->rssi, ppWritePackedMsg, end))) {
-    return 0;
-  }
-  return 1;
-}
-
-uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
-
-  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
-        && push16(pNfapiMsg->number_crcs, ppWritePackedMsg, end)))
-    return 0;
-
-  for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
-    if (!pack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppWritePackedMsg, end))
+    if (!(pusharray8(prg->diagonal_entries_of_singular_matrix_sum_f, nu * iq_size, nu * iq_size, &pWritePackedMessage, end))) {
+      return 0;
+    }
+    if (!(pusharray8(prg->complex_conjugate_of_matrix_of_right_eigenvectors_v_hf,
+                     nu * ng * iq_size,
+                     nu * ng * iq_size,
+                     &pWritePackedMessage,
+                     end))) {
       return 0;
+    }
   }
 
-  return 1;
+  // Message length
+  uintptr_t msgHead = (uintptr_t)pPackedBuf;
+  uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
+  return (msgEnd - msgHead);
 }
 
-//SRS INDICATION
-
-int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) {
-
-  nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix = (nfapi_nr_srs_normalized_channel_iq_matrix_t*)pMessageBuf;
+int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen)
+{
+  nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix =
+      (nfapi_nr_srs_normalized_channel_iq_matrix_t *)pMessageBuf;
 
   uint8_t *pWritePackedMessage = pPackedBuf;
   uint8_t *end = pPackedBuf + packedBufLen;
 
-  if(!(push8(nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, &pWritePackedMessage, end) &&
-       push16(nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, &pWritePackedMessage, end) &&
-       push16(nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, &pWritePackedMessage, end) &&
-       push16(nr_srs_normalized_channel_iq_matrix->prg_size, &pWritePackedMessage, end) &&
-       push16(nr_srs_normalized_channel_iq_matrix->num_prgs, &pWritePackedMessage, end))) {
+  if (!(push8(nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, &pWritePackedMessage, end)
+        && push16(nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, &pWritePackedMessage, end)
+        && push16(nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, &pWritePackedMessage, end)
+        && push16(nr_srs_normalized_channel_iq_matrix->prg_size, &pWritePackedMessage, end)
+        && push16(nr_srs_normalized_channel_iq_matrix->num_prgs, &pWritePackedMessage, end))) {
     return 0;
   }
 
-  uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs*nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports*nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
+  uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs
+                                 * nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports
+                                 * nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
   if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) {
+    // 0: 16-bit normalized complex number (iqSize = 2)
     channel_matrix_size <<= 1;
   } else {
+    // 1: 32-bit normalized complex number (iqSize = 4)
     channel_matrix_size <<= 2;
   }
 
-  for(int i = 0; i < channel_matrix_size; i++) {
+  for (int i = 0; i < channel_matrix_size; i++) {
     if (!push8(nr_srs_normalized_channel_iq_matrix->channel_matrix[i], &pWritePackedMessage, end)) {
       return 0;
     }
@@ -3278,7 +2551,7 @@ int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf
   // Message length
   uintptr_t msgHead = (uintptr_t)pPackedBuf;
   uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
-  return (msgEnd-msgHead);
+  return (msgEnd - msgHead);
 }
 
 static uint8_t pack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, uint8_t **ppWritePackedMsg, uint8_t *end) {
@@ -3296,476 +2569,159 @@ static uint8_t pack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs,
   return 1;
 }
 
-int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen) {
-
-  nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*)pMessageBuf;
+int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen)
+{
+  nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t *)pMessageBuf;
 
   uint8_t *pWritePackedMessage = pPackedBuf;
   uint8_t *end = pPackedBuf + packedBufLen;
 
-  if(!(push16(nr_srs_beamforming_report->prg_size, &pWritePackedMessage, end) &&
-       push8(nr_srs_beamforming_report->num_symbols, &pWritePackedMessage, end) &&
-       push8(nr_srs_beamforming_report->wide_band_snr, &pWritePackedMessage, end) &&
-       push8(nr_srs_beamforming_report->num_reported_symbols, &pWritePackedMessage, end))) {
+  if (!(push16(nr_srs_beamforming_report->prg_size, &pWritePackedMessage, end)
+        && push8(nr_srs_beamforming_report->num_symbols, &pWritePackedMessage, end)
+        && push8(nr_srs_beamforming_report->wide_band_snr, &pWritePackedMessage, end)
+        && push8(nr_srs_beamforming_report->num_reported_symbols, &pWritePackedMessage, end))) {
     return 0;
   }
 
-  if (!pack_nr_srs_reported_symbol(&nr_srs_beamforming_report->prgs, &pWritePackedMessage, end)) {
-    return 0;
+  for (int reported_symbol = 0; reported_symbol < nr_srs_beamforming_report->num_reported_symbols; ++reported_symbol) {
+    if (!pack_nr_srs_reported_symbol(&nr_srs_beamforming_report->reported_symbol_list[reported_symbol],
+                                     &pWritePackedMessage,
+                                     end)) {
+      return 0;
+    }
   }
 
   // Message length
   uintptr_t msgHead = (uintptr_t)pPackedBuf;
   uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
-  return (msgEnd-msgHead);
+  return (msgEnd - msgHead);
 }
 
-static uint8_t pack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
+// Main pack function - public
 
-  if(!(push16(report_tlv->tag, ppWritePackedMsg, end) &&
-       push32(report_tlv->length, ppWritePackedMsg, end))) {
-    return 0;
-  }
+int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_p7_message_header_t *pMessageHeader = pMessageBuf;
+  uint8_t *pWritePackedMessage = pPackedBuf;
+  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
 
-  for(int i = 0; i < report_tlv->length; i++) {
-    if (!push32(report_tlv->value[i], ppWritePackedMsg, end)) {
-      return 0;
-    }
+  if (pMessageBuf == NULL || pPackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
+    return -1;
   }
 
-  return 1;
-}
-
-static uint8_t pack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppWritePackedMsg, uint8_t *end) {
+  uint8_t *end = (uint8_t *)pPackedBuf + packedBufLen;
 
-  if(!(push32(value->handle, ppWritePackedMsg, end) &&
-       push16(value->rnti, ppWritePackedMsg, end) &&
-       push16(value->timing_advance_offset, ppWritePackedMsg, end) &&
-       pushs16(value->timing_advance_offset_nsec, ppWritePackedMsg, end) &&
-       push8(value->srs_usage, ppWritePackedMsg, end) &&
-       push8(value->report_type, ppWritePackedMsg, end))) {
-    return 0;
+  // process the header
+  if (!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && push16(pMessageHeader->message_id, &pWritePackedMessage, end)
+        && push32(0 /*pMessageHeader->message_length*/, &pWritePackedMessage, end)
+        && push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end)
+        && push32(0 /*pMessageHeader->checksum*/, &pWritePackedMessage, end)
+        && push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
+    return -1;
   }
 
-  if (!pack_nr_srs_report_tlv(&value->report_tlv, ppWritePackedMsg, end)) {
-    return 0;
+  if (pMessageHeader->message_id != NFAPI_TIMING_INFO) {
+    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__,
+    // pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
   }
+  // look for the specific message
+  uint8_t result = 0;
+  switch (pMessageHeader->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-  return 1;
-}
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_srs_indication_t *pNfapiMsg = (nfapi_nr_srs_indication_t *)msg;
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
-        && push16(pNfapiMsg->control_length, ppWritePackedMsg, end) && push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end))) {
-    return 0;
-  }
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
+    case NFAPI_UE_RELEASE_REQUEST:
+      result = pack_nr_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
-    if (!pack_nr_srs_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end)) {
-      return 0;
-    }
-  }
+    case NFAPI_UE_RELEASE_RESPONSE:
+      result = pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-  return 1;
-}
+    case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
+      result = pack_nr_slot_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-//RACH INDICATION
+    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
+      result = pack_nr_rx_data_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-static uint8_t pack_nr_rach_indication_body(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-	nfapi_nr_prach_indication_pdu_t* value = (nfapi_nr_prach_indication_pdu_t*)tlv;
-
-	if(!(push16(value->phy_cell_id, ppWritePackedMsg, end) &&
-	 	 push8(value->symbol_index, ppWritePackedMsg, end) &&
-		 push8(value->slot_index, ppWritePackedMsg, end) &&
-		 push8(value->freq_index, ppWritePackedMsg, end) &&
-		 push8(value->avg_rssi, ppWritePackedMsg, end) &&
-		 push8(value->avg_snr, ppWritePackedMsg, end) &&
-		 push8(value->num_preamble, ppWritePackedMsg, end)
-		 ))
-		  return 0;
-	for(int i = 0; i < value->num_preamble; i++)
-	{
-		if(!(push8(value->preamble_list[i].preamble_index, ppWritePackedMsg, end) &&
-			push16(value->preamble_list[i].timing_advance, ppWritePackedMsg, end) &&
-			push32(value->preamble_list[i].preamble_pwr, ppWritePackedMsg, end)
-			))
-			return 0;
-	}
-	return 1;
-}
+    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
+      result = pack_nr_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
+    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
+      result = pack_nr_uci_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-  if (!(push16(pNfapiMsg->sfn, ppWritePackedMsg, end) && push16(pNfapiMsg->slot, ppWritePackedMsg, end)
-        && push8(pNfapiMsg->number_of_pdus, ppWritePackedMsg, end)))
-    return 0;
+    case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
+      result = pack_nr_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
-    if (!pack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppWritePackedMsg, end))
-      return 0;
-  }
+    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
+      result = pack_nr_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-  return 1;
-}
+    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+      result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-//UCI INDICATION
+    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+      result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-static uint8_t pack_nr_uci_pucch_0_1(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
-  nfapi_nr_uci_pucch_pdu_format_0_1_t* value = (nfapi_nr_uci_pucch_pdu_format_0_1_t*)tlv;
+    case NFAPI_TIMING_INFO:
+      result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
+      break;
 
-	if (!push8(value->pduBitmap, ppWritePackedMsg, end))
-		return 0;
-	if (!push32(value->handle, ppWritePackedMsg, end))
-		return 0;
-	if (!push16(value->rnti, ppWritePackedMsg, end))
-		return 0;
-	if (!push8(value->pucch_format, ppWritePackedMsg, end))
-		return 0;
-	if (!push8(value->ul_cqi, ppWritePackedMsg, end))
-		return 0;
-	if (!push16(value->timing_advance, ppWritePackedMsg, end))
-		return 0;
-	if (!push16(value->rssi, ppWritePackedMsg, end))
-		return 0;
-	if (value->pduBitmap & 0x01) { //SR
-		if (!push8(value->sr.sr_indication, ppWritePackedMsg, end))
-			return 0;
-		if (!push8(value->sr.sr_confidence_level, ppWritePackedMsg, end))
-			return 0;
-	}
+    default: {
+      if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if (config && config->pack_p7_vendor_extension) {
+          result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR,
+                      "%s VE NFAPI message ID %d. No ve ecoder provided\n",
+                      __FUNCTION__,
+                      pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+    } break;
+  }
 
-	if (((value->pduBitmap >> 1) & 0x01)) { //HARQ
-		if (!push8(value->harq.num_harq, ppWritePackedMsg, end))
-			return 0;
-		if (!push8(value->harq.harq_confidence_level, ppWritePackedMsg, end))
-			return 0;
-		for (int i = 0; i < value->harq.num_harq; i++)
-		{
-			if (!push8(value->harq.harq_list[i].harq_value, ppWritePackedMsg, end))
-				return 0;
-		}
-	}
+  if (result == 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
+    return -1;
+  }
 
-  return 1;
-}
+  // check for a valid message length
+  uintptr_t msgHead = (uintptr_t)pPackedBuf;
+  uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
+  uint32_t packedMsgLen = msgEnd - msgHead;
+  if (packedMsgLen > packedBufLen) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
+    return -1;
+  }
 
-static uint8_t pack_nr_uci_pucch_2_3_4(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
-  nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value = (nfapi_nr_uci_pucch_pdu_format_2_3_4_t*) tlv;
+  // Update the message length in the header
+  pMessageHeader->message_length = packedMsgLen;
 
-  if (!push8(value->pduBitmap, ppWritePackedMsg, end))
-    return 0;
-  if (!push32(value->handle, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(value->rnti, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(value->pucch_format-2, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(value->ul_cqi, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(value->timing_advance, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(value->rssi, ppWritePackedMsg, end))
-    return 0;
-
-  if (value->pduBitmap & 0x01) { //SR
-    if (!push16(value->sr.sr_bit_len, ppWritePackedMsg, end))
-      return 0;
-    if (!pusharray8(value->sr.sr_payload,
-                    (int)((value->sr.sr_bit_len / 8) + 1),
-                    (int)((value->sr.sr_bit_len / 8) + 1),
-                    ppWritePackedMsg,
-                    end))
-      return 0;
-  }
-
-  if ((value->pduBitmap >> 1) & 0x01) { //HARQ
-    if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
-      return 0;
-    if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
-      return 0;
-    if (!pusharray8(value->harq.harq_payload,
-                    (int)((value->harq.harq_bit_len / 8) + 1),
-                    (int)((value->harq.harq_bit_len / 8) + 1),
-                    ppWritePackedMsg,
-                    end))
-      return 0;
-  }
-
-  if ((value->pduBitmap >> 2) & 0x01) { //CSI-1
-    if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
-      return 0;
-    if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
-      return 0;
-    if (!pusharray8(value->csi_part1.csi_part1_payload,
-                    (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                    (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                    ppWritePackedMsg,
-                    end))
-      return 0;
-  }
-
-  if ((value->pduBitmap >> 3) & 0x01) { //CSI-2
-    if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
-      return 0;
-    if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
-      return 0;
-    if (!pusharray8(value->csi_part2.csi_part2_payload,
-                    (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                    (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                    ppWritePackedMsg,
-                    end))
-      return 0;
-  }
-
-  return 1;
-}
-
-static uint8_t pack_nr_uci_pusch(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  nfapi_nr_uci_pusch_pdu_t *value = (nfapi_nr_uci_pusch_pdu_t *)tlv;
-
-  if (!push8(value->pduBitmap, ppWritePackedMsg, end))
-    return 0;
-  if (!push32(value->handle, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(value->rnti, ppWritePackedMsg, end))
-    return 0;
-  if (!push8(value->ul_cqi, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(value->timing_advance, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(value->rssi, ppWritePackedMsg, end))
-    return 0;
-
-  // Bit 0 not used in PUSCH PDU
-  if ((value->pduBitmap >> 1) & 0x01) { // HARQ
-    if (!push8(value->harq.harq_crc, ppWritePackedMsg, end))
-      return 0;
-    if (!push16(value->harq.harq_bit_len, ppWritePackedMsg, end))
-      return 0;
-
-    if (!pusharray8(value->harq.harq_payload,
-                    (int)((value->harq.harq_bit_len / 8) + 1),
-                    (int)((value->harq.harq_bit_len / 8) + 1),
-                    ppWritePackedMsg,
-                    end))
-      return 0;
-  }
-
-  if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
-    if (!push8(value->csi_part1.csi_part1_crc, ppWritePackedMsg, end))
-      return 0;
-    if (!push16(value->csi_part1.csi_part1_bit_len, ppWritePackedMsg, end))
-      return 0;
-
-    if (!pusharray8(value->csi_part1.csi_part1_payload,
-                    (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                    (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                    ppWritePackedMsg,
-                    end))
-      return 0;
-  }
-
-  if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
-    if (!push8(value->csi_part2.csi_part2_crc, ppWritePackedMsg, end))
-      return 0;
-    if (!push16(value->csi_part2.csi_part2_bit_len, ppWritePackedMsg, end))
-      return 0;
-
-    if (!pusharray8(value->csi_part2.csi_part2_payload,
-                    (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                    (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                    ppWritePackedMsg,
-                    end))
-      return 0;
-  }
-
-  return 1;
-}
-
-static uint8_t pack_nr_uci_indication_body(nfapi_nr_uci_t* value, uint8_t **ppWritePackedMsg, uint8_t *end)
-{
-  if (!push16(value->pdu_type, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(value->pdu_size, ppWritePackedMsg, end))
-    return 0;
-
-  switch (value->pdu_type) {
-    case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
-      if(!pack_nr_uci_pusch(&value->pusch_pdu, ppWritePackedMsg, end)){
-        return 0;
-      }
-      break;
-
-    case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
-      if(!pack_nr_uci_pucch_0_1(&value->pucch_pdu_format_0_1, ppWritePackedMsg, end)){
-        return 0;
-      }
-      break;
-
-    case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
-      if(!pack_nr_uci_pucch_2_3_4(&value->pucch_pdu_format_2_3_4, ppWritePackedMsg, end)){
-        return 0;
-      }
-      break;
-  }
-
-  return 1;
-}
-
-uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
-
-  if (!push16(pNfapiMsg->sfn, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(pNfapiMsg->slot, ppWritePackedMsg, end))
-    return 0;
-  if (!push16(pNfapiMsg->num_ucis, ppWritePackedMsg, end))
-    return 0;
-
-  for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
-    if (!pack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppWritePackedMsg, end))
-      return 0;
-  }
-
-  return 1;
-}
-
-// Main pack function - public
-
-int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config)
-{
-  nfapi_p7_message_header_t *pMessageHeader = pMessageBuf;
-  uint8_t *pWritePackedMessage = pPackedBuf;
-  uint8_t *pPackedLengthField = &pWritePackedMessage[4];
-
-  if (pMessageBuf == NULL || pPackedBuf == NULL) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack supplied pointers are null\n");
-    return -1;
-  }
-
-  uint8_t *end = (uint8_t *)pPackedBuf + packedBufLen;
-
-  // process the header
-  if (!(push16(pMessageHeader->phy_id, &pWritePackedMessage, end) && push16(pMessageHeader->message_id, &pWritePackedMessage, end)
-        && push16(0 /*pMessageHeader->message_length*/, &pWritePackedMessage, end)
-        && push16(pMessageHeader->m_segment_sequence, &pWritePackedMessage, end)
-        && push32(0 /*pMessageHeader->checksum*/, &pWritePackedMessage, end)
-        && push32(pMessageHeader->transmit_timestamp, &pWritePackedMessage, end))) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack header failed\n");
-    return -1;
-  }
-
-  if (pMessageHeader->message_id != NFAPI_TIMING_INFO) {
-    // NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() message_id:0x%04x phy_id:%u m_segment_sequence:%u timestamp:%u\n", __FUNCTION__,
-    // pMessageHeader->message_id, pMessageHeader->phy_id, pMessageHeader->m_segment_sequence, pMessageHeader->transmit_timestamp);
-  }
-  // look for the specific message
-  uint8_t result = 0;
-  switch (pMessageHeader->message_id) {
-    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-      result = pack_dl_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-      result = pack_ul_tti_request(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-      result = pack_tx_data_request(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-      result = pack_ul_dci_request(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-    case NFAPI_UE_RELEASE_REQUEST:
-      result = pack_nr_ue_release_request(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_UE_RELEASE_RESPONSE:
-      result = pack_ue_release_response(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
-      result = pack_nr_slot_indication(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
-      result = pack_nr_rx_data_indication(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
-      result = pack_nr_crc_indication(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
-      result = pack_nr_uci_indication(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
-      result = pack_nr_srs_indication(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
-      result = pack_nr_rach_indication(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-      result = pack_nr_dl_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
-      result = pack_nr_ul_node_sync(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    case NFAPI_TIMING_INFO:
-      result = pack_nr_timing_info(pMessageHeader, &pWritePackedMessage, end, config);
-      break;
-
-    default: {
-      if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
-        if (config && config->pack_p7_vendor_extension) {
-          result = (config->pack_p7_vendor_extension)(pMessageHeader, &pWritePackedMessage, end, config);
-        } else {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR,
-                      "%s VE NFAPI message ID %d. No ve ecoder provided\n",
-                      __FUNCTION__,
-                      pMessageHeader->message_id);
-        }
-      } else {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-      }
-    } break;
-  }
-
-  if (result == 0) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
-    return -1;
-  }
-
-  // check for a valid message length
-  uintptr_t msgHead = (uintptr_t)pPackedBuf;
-  uintptr_t msgEnd = (uintptr_t)pWritePackedMessage;
-  uint32_t packedMsgLen = msgEnd - msgHead;
-  uint16_t packedMsgLen16;
-  if (packedMsgLen > 0xFFFF || packedMsgLen > packedBufLen) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Packed message length error %d, buffer supplied %d\n", packedMsgLen, packedBufLen);
-    return -1;
-  } else {
-    packedMsgLen16 = (uint16_t)packedMsgLen;
-  }
-
-  // Update the message length in the header
-  pMessageHeader->message_length = packedMsgLen16;
-
-  if (!push16(packedMsgLen16, &pPackedLengthField, end))
+  if (!push32(pMessageHeader->message_length, &pPackedLengthField, end))
     return -1;
 
   if (1) {
@@ -3947,179 +2903,6 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
 
 // Unpack routines
 // NR:
-static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
-  uint16_t num_prgs = 0, prg_size = 0;
-  uint8_t dig_bf_interfaces = 0;
-  return (pull16(ppReadPackedMsg, &value->bwp_size, end) && pull16(ppReadPackedMsg, &value->bwp_start, end)
-          && pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &value->cyclic_prefix, end)
-          && pull16(ppReadPackedMsg, &value->start_rb, end) && pull16(ppReadPackedMsg, &value->nr_of_rbs, end)
-          && pull8(ppReadPackedMsg, &value->csi_type, end) && pull8(ppReadPackedMsg, &value->row, end)
-          && pull16(ppReadPackedMsg, &value->freq_domain, end) && pull8(ppReadPackedMsg, &value->symb_l0, end)
-          && pull8(ppReadPackedMsg, &value->symb_l1, end) && pull8(ppReadPackedMsg, &value->cdm_type, end)
-          && pull8(ppReadPackedMsg, &value->freq_density, end) && pull16(ppReadPackedMsg, &value->scramb_id, end)
-          && pull8(ppReadPackedMsg, &value->power_control_offset, end)
-          && pull8(ppReadPackedMsg, &value->power_control_offset_ss, end) &&
-          // Precoding and Beamforming hardcoded to 0
-          pull16(ppReadPackedMsg, &num_prgs, end) && pull16(ppReadPackedMsg, &prg_size, end)
-          && pull8(ppReadPackedMsg, &dig_bf_interfaces, end));
-}
-
-static uint8_t unpack_dl_tti_pdcch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  nfapi_nr_dl_tti_pdcch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t *)tlv;
-
-  if (!(pull16(ppReadPackedMsg, &value->BWPSize, end) && pull16(ppReadPackedMsg, &value->BWPStart, end)
-        && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end) && pull8(ppReadPackedMsg, &value->CyclicPrefix, end)
-        && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end) && pull8(ppReadPackedMsg, &value->DurationSymbols, end)
-        && pullarray8(ppReadPackedMsg, value->FreqDomainResource, 6, 6, end)
-        && pull8(ppReadPackedMsg, &value->CceRegMappingType, end) && pull8(ppReadPackedMsg, &value->RegBundleSize, end)
-        && pull8(ppReadPackedMsg, &value->InterleaverSize, end) && pull8(ppReadPackedMsg, &value->CoreSetType, end)
-        && pull16(ppReadPackedMsg, &value->ShiftIndex, end) && pull8(ppReadPackedMsg, &value->precoderGranularity, end)
-        && pull16(ppReadPackedMsg, &value->numDlDci, end))) {
-    return 0;
-  }
-
-  for (uint16_t i = 0; i < value->numDlDci; ++i) {
-    if (!(pull16(ppReadPackedMsg, &value->dci_pdu[i].RNTI, end) && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingId, end)
-          && pull16(ppReadPackedMsg, &value->dci_pdu[i].ScramblingRNTI, end)
-          && pull8(ppReadPackedMsg, &value->dci_pdu[i].CceIndex, end)
-          && pull8(ppReadPackedMsg, &value->dci_pdu[i].AggregationLevel, end)
-          && pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.num_prgs, end)
-          && pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.prg_size, end)
-          && pull8(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, end))) {
-      return 0;
-    }
-    for (int prg = 0; prg < value->dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
-      if (!pull16(ppReadPackedMsg, &value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx, end)) {
-        return 0;
-      }
-      for (int digInt = 0; digInt < value->dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces; digInt++) {
-        if (!pull16(ppReadPackedMsg,
-                    &value->dci_pdu[i].precodingAndBeamforming.prgs_list[prg].dig_bf_interface_list[digInt].beam_idx,
-                    end)) {
-          return 0;
-        }
-      }
-    }
-    if (!(pull8(ppReadPackedMsg, &value->dci_pdu[i].beta_PDCCH_1_0, end)
-          && pull8(ppReadPackedMsg, &value->dci_pdu[i].powerControlOffsetSS, end)
-          && pull16(ppReadPackedMsg, &value->dci_pdu[i].PayloadSizeBits, end)
-          && unpack_dci_payload(value->dci_pdu[i].Payload, value->dci_pdu[i].PayloadSizeBits, ppReadPackedMsg, end))) {
-      return 0;
-    }
-  }
-  // TODO: resolve the packaging of array (currently sending a single element)
-  return 1;
-}
-
-static uint8_t unpack_dl_tti_pdsch_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  nfapi_nr_dl_tti_pdsch_pdu_rel15_t *value = (nfapi_nr_dl_tti_pdsch_pdu_rel15_t *)tlv;
-  // TODO: resolve the packaging of array (currently sending a single element)
-  uint8_t powerControlOffset = 0, powerControlOffsetSS = 0;
-
-  if (!(pull16(ppReadPackedMsg, &value->pduBitmap, end) && pull16(ppReadPackedMsg, &value->rnti, end)
-        && pull16(ppReadPackedMsg, &value->pduIndex, end) && pull16(ppReadPackedMsg, &value->BWPSize, end)
-        && pull16(ppReadPackedMsg, &value->BWPStart, end) && pull8(ppReadPackedMsg, &value->SubcarrierSpacing, end)
-        && pull8(ppReadPackedMsg, &value->CyclicPrefix, end) && pull8(ppReadPackedMsg, &value->NrOfCodewords, end))) {
-    return 0;
-  }
-  for (int i = 0; i < value->NrOfCodewords; ++i) {
-    if (!(pull16(ppReadPackedMsg, &value->targetCodeRate[i], end) && pull8(ppReadPackedMsg, &value->qamModOrder[i], end)
-          && pull8(ppReadPackedMsg, &value->mcsIndex[i], end) && pull8(ppReadPackedMsg, &value->mcsTable[i], end)
-          && pull8(ppReadPackedMsg, &value->rvIndex[i], end) && pull32(ppReadPackedMsg, &value->TBSize[i], end))) {
-      return 0;
-    }
-  }
-
-  if (!(pull16(ppReadPackedMsg, &value->dataScramblingId, end) && pull8(ppReadPackedMsg, &value->nrOfLayers, end)
-        && pull8(ppReadPackedMsg, &value->transmissionScheme, end) && pull8(ppReadPackedMsg, &value->refPoint, end)
-        && pull16(ppReadPackedMsg, &value->dlDmrsSymbPos, end) && pull8(ppReadPackedMsg, &value->dmrsConfigType, end)
-        && pull16(ppReadPackedMsg, &value->dlDmrsScramblingId, end) && pull8(ppReadPackedMsg, &value->SCID, end)
-        && pull8(ppReadPackedMsg, &value->numDmrsCdmGrpsNoData, end) && pull16(ppReadPackedMsg, &value->dmrsPorts, end)
-        && pull8(ppReadPackedMsg, &value->resourceAlloc, end) && pullarray8(ppReadPackedMsg, &value->rbBitmap[0], 36, 36, end)
-        && pull16(ppReadPackedMsg, &value->rbStart, end) && pull16(ppReadPackedMsg, &value->rbSize, end)
-        && pull8(ppReadPackedMsg, &value->VRBtoPRBMapping, end) && pull8(ppReadPackedMsg, &value->StartSymbolIndex, end)
-        && pull8(ppReadPackedMsg, &value->NrOfSymbols, end))) {
-    return 0;
-  }
-  // Check pduBitMap bit 1 to pull PTRS parameters or not
-  if (value->pduBitmap & 0b1) {
-    if (!(pull8(ppReadPackedMsg, &value->PTRSPortIndex, end) && pull8(ppReadPackedMsg, &value->PTRSTimeDensity, end)
-          && pull8(ppReadPackedMsg, &value->PTRSFreqDensity, end) && pull8(ppReadPackedMsg, &value->PTRSReOffset, end)
-          && pull8(ppReadPackedMsg, &value->nEpreRatioOfPDSCHToPTRS, end))) {
-      return 0;
-    }
-  }
-
-  if (!(pull16(ppReadPackedMsg, &value->precodingAndBeamforming.num_prgs, end)
-        && pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prg_size, end)
-        && pull8(ppReadPackedMsg, &value->precodingAndBeamforming.dig_bf_interfaces, end))) {
-    return 0;
-  }
-
-  for (int i = 0; i < value->precodingAndBeamforming.num_prgs; ++i) {
-    if (!pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prgs_list[i].pm_idx, end)) {
-      return 0;
-    }
-    for (int k = 0; k < value->precodingAndBeamforming.dig_bf_interfaces; ++k) {
-      if (!pull16(ppReadPackedMsg, &value->precodingAndBeamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, end)) {
-        return 0;
-      }
-    }
-  }
-  // TODO Add TX power info
-  // Hardcoded values that represent 0db
-
-  if (!(pull8(ppReadPackedMsg, &powerControlOffset, end) && // powerControlOffset
-        pull8(ppReadPackedMsg, &powerControlOffsetSS, end))) { // powerControlOffsetSS
-    return 0;
-  }
-  // TODO Add CBG Fields
-  return 1;
-}
-
-static uint8_t unpack_dl_tti_ssb_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  NFAPI_TRACE(NFAPI_TRACE_DEBUG, "Unpacking ssb. \n");
-  uint8_t byte3, byte2, byte1, byte0;
-  nfapi_nr_dl_tti_ssb_pdu_rel15_t *value = (nfapi_nr_dl_tti_ssb_pdu_rel15_t *)tlv;
-
-  if (!(pull16(ppReadPackedMsg, &value->PhysCellId, end) && pull8(ppReadPackedMsg, &value->BetaPss, end)
-        && pull8(ppReadPackedMsg, &value->SsbBlockIndex, end) && pull8(ppReadPackedMsg, &value->SsbSubcarrierOffset, end)
-        && pull16(ppReadPackedMsg, &value->ssbOffsetPointA, end) && pull8(ppReadPackedMsg, &value->bchPayloadFlag, end)
-        && pull8(ppReadPackedMsg, &byte3, end) && pull8(ppReadPackedMsg, &byte2, end) && pull8(ppReadPackedMsg, &byte1, end)
-        && pull8(ppReadPackedMsg, &byte0, end))) { // this should be always 0, bchpayload is 24 bits
-    return 0;
-  }
-  // rebuild the bchpayload
-  value->bchPayload = byte3;
-  value->bchPayload = value->bchPayload << 8;
-  value->bchPayload |= byte2;
-  value->bchPayload = value->bchPayload << 8;
-  value->bchPayload |= byte1;
-  // TODO add Tx Power Info
-  if (!(pull8(ppReadPackedMsg, &byte1, end) && pull8(ppReadPackedMsg, &byte0, end)
-        && pull16(ppReadPackedMsg, &value->precoding_and_beamforming.num_prgs, end)
-        && pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prg_size, end)
-        && pull8(ppReadPackedMsg, &value->precoding_and_beamforming.dig_bf_interfaces, end))) {
-    return 0;
-  }
-
-  for (int i = 0; i < value->precoding_and_beamforming.num_prgs; ++i) {
-    if (!pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prgs_list[i].pm_idx, end)) {
-      return 0;
-    }
-    for (int k = 0; k < value->precoding_and_beamforming.dig_bf_interfaces; ++k) {
-      if (!pull16(ppReadPackedMsg, &value->precoding_and_beamforming.prgs_list[i].dig_bf_interface_list[k].beam_idx, end)) {
-        return 0;
-      }
-    }
-  }
-  return 1;
-}
 
 // LTE:
 static uint8_t unpack_dl_config_dci_dl_pdu_rel8_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
@@ -4510,51 +3293,6 @@ static uint8_t unpack_dl_config_ndlsch_pdu_rel13_value(void *tlv, uint8_t **ppRe
 }
 
 
-static uint8_t unpack_dl_tti_request_body_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
-  nfapi_nr_dl_tti_request_pdu_t *value = (nfapi_nr_dl_tti_request_pdu_t *)msg;
-
-  if(!(pull16(ppReadPackedMsg, &value->PDUType, end) &&
-       pull16(ppReadPackedMsg, (uint16_t *) &value->PDUSize, end)))
-    return 0;
-
-  // first match the pdu type, then call the respective function
-  switch(value->PDUType) {
-    case NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE: {
-      if(!(unpack_dl_tti_csi_rs_pdu_rel15_value(&value->csi_rs_pdu.csi_rs_pdu_rel15,ppReadPackedMsg,end)))
-        return 0;
-    }
-    break;
-
-    case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: {
-      if(!(unpack_dl_tti_pdcch_pdu_rel15_value(&value->pdcch_pdu.pdcch_pdu_rel15,ppReadPackedMsg,end)))
-        return 0;
-    }
-    break;
-
-    case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: {
-      if(!(unpack_dl_tti_pdsch_pdu_rel15_value(&value->pdsch_pdu.pdsch_pdu_rel15,ppReadPackedMsg,end)))
-        return 0;
-    }
-    break;
-
-    case NFAPI_NR_DL_TTI_SSB_PDU_TYPE: {
-      if(!(unpack_dl_tti_ssb_pdu_rel15_value(&value->ssb_pdu.ssb_pdu_rel15,ppReadPackedMsg,end)))
-        return 0;
-    }
-    break;
-
-    default: {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid DL_TTI pdu type %d \n", value->PDUType );
-    }
-    break;
-  }
-
-  return 1;
-}
-
-
-
-
 static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config) {
   nfapi_dl_config_request_body_t *value = (nfapi_dl_config_request_body_t *)tlv;
 
@@ -4723,291 +3461,6 @@ static uint8_t unpack_dl_config_request_body_value(void *tlv, uint8_t **ppReadPa
   return 1;
 }
 
-static uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_dl_tti_request_t *pNfapiMsg = (nfapi_nr_dl_tti_request_t *)msg;
-
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
-        && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nPDUs, end)
-        && pull8(ppReadPackedMsg, &pNfapiMsg->dl_tti_request_body.nGroup, end))) {
-    return 0;
-  }
-  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nPDUs; i++) {
-    if (!unpack_dl_tti_request_body_value(ppReadPackedMsg, end, &pNfapiMsg->dl_tti_request_body.dl_tti_pdu_list[i]))
-      return 0;
-  }
-
-  int arr[12];
-  if (!pullarray8(ppReadPackedMsg, pNfapiMsg->dl_tti_request_body.nUe, 256, pNfapiMsg->dl_tti_request_body.nGroup, end)) {
-    return 0;
-  }
-  for (int i = 0; i < pNfapiMsg->dl_tti_request_body.nGroup; i++) {
-    for (int j = 0; j < pNfapiMsg->dl_tti_request_body.nUe[i]; j++) {
-      arr[j] = pNfapiMsg->dl_tti_request_body.PduIdx[i][j];
-    }
-
-    if (!(pullarrays32(ppReadPackedMsg, arr, 12, pNfapiMsg->dl_tti_request_body.nUe[i], end)))
-      return 0;
-  }
-
-  return 1;
-}
-
-static uint8_t unpack_ul_tti_request_prach_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  nfapi_nr_prach_pdu_t *prach_pdu = (nfapi_nr_prach_pdu_t *)tlv;
-
-  if (!(pull16(ppReadPackedMsg, &prach_pdu->phys_cell_id, end) && pull8(ppReadPackedMsg, &prach_pdu->num_prach_ocas, end)
-        && pull8(ppReadPackedMsg, &prach_pdu->prach_format, end) && pull8(ppReadPackedMsg, &prach_pdu->num_ra, end)
-        && pull8(ppReadPackedMsg, &prach_pdu->prach_start_symbol, end) && pull16(ppReadPackedMsg, &prach_pdu->num_cs, end))) {
-    return 0;
-  }
-  // Unpack RX Beamforming PDU
-  if (!(pull16(ppReadPackedMsg, &prach_pdu->beamforming.num_prgs, end)
-        && pull16(ppReadPackedMsg, &prach_pdu->beamforming.prg_size, end)
-        && pull8(ppReadPackedMsg, &prach_pdu->beamforming.dig_bf_interface, end))) {
-    return 0;
-  }
-  for (int prg = 0; prg < prach_pdu->beamforming.num_prgs; prg++) {
-    for (int digBFInterface = 0; digBFInterface < prach_pdu->beamforming.dig_bf_interface; digBFInterface++) {
-      if (!pull16(ppReadPackedMsg, &prach_pdu->beamforming.prgs_list[prg].dig_bf_interface_list[digBFInterface].beam_idx, end)) {
-        return 0;
-      }
-    }
-  }
-
-  return 1;
-}
-
-static uint8_t unpack_ul_tti_request_pucch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  nfapi_nr_pucch_pdu_t *pucch_pdu = (nfapi_nr_pucch_pdu_t *)tlv;
-  uint16_t dummy16 = 0;
-  uint8_t dummy8 = 0;
-  return (pull16(ppReadPackedMsg, &pucch_pdu->rnti, end) && pull32(ppReadPackedMsg, &pucch_pdu->handle, end)
-          && pull16(ppReadPackedMsg, &pucch_pdu->bwp_size, end) && pull16(ppReadPackedMsg, &pucch_pdu->bwp_start, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->subcarrier_spacing, end) && pull8(ppReadPackedMsg, &pucch_pdu->cyclic_prefix, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->format_type, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->multi_slot_tx_indicator, end) && pull8(ppReadPackedMsg, &pucch_pdu->pi_2bpsk, end)
-          && pull16(ppReadPackedMsg, &pucch_pdu->prb_start, end) && pull16(ppReadPackedMsg, &pucch_pdu->prb_size, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->start_symbol_index, end) && pull8(ppReadPackedMsg, &pucch_pdu->nr_of_symbols, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->freq_hop_flag, end) && pull16(ppReadPackedMsg, &pucch_pdu->second_hop_prb, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->group_hop_flag, end) && pull8(ppReadPackedMsg, &pucch_pdu->sequence_hop_flag, end)
-          && pull16(ppReadPackedMsg, &pucch_pdu->hopping_id, end) && pull16(ppReadPackedMsg, &pucch_pdu->initial_cyclic_shift, end)
-          && pull16(ppReadPackedMsg, &pucch_pdu->data_scrambling_id, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->time_domain_occ_idx, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_idx, end) && pull8(ppReadPackedMsg, &pucch_pdu->pre_dft_occ_len, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->add_dmrs_flag, end) && pull16(ppReadPackedMsg, &pucch_pdu->dmrs_scrambling_id, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->dmrs_cyclic_shift, end) && pull8(ppReadPackedMsg, &pucch_pdu->sr_flag, end)
-          && pull8(ppReadPackedMsg, &pucch_pdu->bit_len_harq, end) && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part1, end)
-          && pull16(ppReadPackedMsg, &pucch_pdu->bit_len_csi_part2, end) &&
-          // TODO: ignoring beamforming tlv for now
-          pull16(ppReadPackedMsg, &dummy16, end) && pull16(ppReadPackedMsg, &dummy16, end) && pull8(ppReadPackedMsg, &dummy8, end));
-}
-
-static uint8_t unpack_ul_tti_request_pusch_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  nfapi_nr_pusch_pdu_t *pusch_pdu = (nfapi_nr_pusch_pdu_t *)tlv;
-
-  if (!(pull16(ppReadPackedMsg, &pusch_pdu->pdu_bit_map, end) && pull16(ppReadPackedMsg, &pusch_pdu->rnti, end)
-        && pull32(ppReadPackedMsg, &pusch_pdu->handle, end) && pull16(ppReadPackedMsg, &pusch_pdu->bwp_size, end)
-        && pull16(ppReadPackedMsg, &pusch_pdu->bwp_start, end) && pull8(ppReadPackedMsg, &pusch_pdu->subcarrier_spacing, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->cyclic_prefix, end) && pull16(ppReadPackedMsg, &pusch_pdu->target_code_rate, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->qam_mod_order, end) && pull8(ppReadPackedMsg, &pusch_pdu->mcs_index, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->mcs_table, end) && pull8(ppReadPackedMsg, &pusch_pdu->transform_precoding, end)
-        && pull16(ppReadPackedMsg, &pusch_pdu->data_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->nrOfLayers, end)
-        && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_symb_pos, end) && pull8(ppReadPackedMsg, &pusch_pdu->dmrs_config_type, end)
-        && pull16(ppReadPackedMsg, &pusch_pdu->ul_dmrs_scrambling_id, end) && pull8(ppReadPackedMsg, &pusch_pdu->scid, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->num_dmrs_cdm_grps_no_data, end)
-        && pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end) && pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->resource_alloc, end) && pull16(ppReadPackedMsg, &pusch_pdu->dmrs_ports, end)
-        && pull16(ppReadPackedMsg, &pusch_pdu->rb_start, end) && pull16(ppReadPackedMsg, &pusch_pdu->rb_size, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->vrb_to_prb_mapping, end) && pull8(ppReadPackedMsg, &pusch_pdu->frequency_hopping, end)
-        && pull16(ppReadPackedMsg, &pusch_pdu->tx_direct_current_location, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->uplink_frequency_shift_7p5khz, end)
-        && pull8(ppReadPackedMsg, &pusch_pdu->start_symbol_index, end) && pull8(ppReadPackedMsg, &pusch_pdu->nr_of_symbols, end)
-        // TODO: ignoring beamforming tlv for now
-        ))
-    return 0;
-
-  // Pack Optional Data only included if indicated in pduBitmap
-  switch (pusch_pdu->pdu_bit_map) {
-    case PUSCH_PDU_BITMAP_PUSCH_DATA: {
-      // pack optional TLVs
-      if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.rv_index, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_data.harq_process_id, end)
-            && pull32(ppReadPackedMsg, &pusch_pdu->pusch_data.tb_size, end)
-            && pull16(ppReadPackedMsg, &pusch_pdu->pusch_data.num_cb, end)
-            && pullarray8(ppReadPackedMsg, pusch_pdu->pusch_data.cb_present_and_position, 1, 1, end))) {
-        return 0;
-      }
-    } break;
-
-    case PUSCH_PDU_BITMAP_PUSCH_UCI: {
-      if (!(pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.harq_ack_bit_length, end)
-            && pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part1_bit_length, end)
-            && pull16(ppReadPackedMsg, &pusch_pdu->pusch_uci.csi_part2_bit_length, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.alpha_scaling, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_harq_ack, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi1, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_uci.beta_offset_csi2, end))) {
-        return 0;
-      }
-    } break;
-
-    case PUSCH_PDU_BITMAP_PUSCH_PTRS: {
-      if (!(pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.num_ptrs_ports, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_dmrs_port, end)
-            && pull16(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_port_index, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_ports_list->ptrs_re_offset, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_time_density, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ptrs_freq_density, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->pusch_ptrs.ul_ptrs_power, end))) {
-        return 0;
-      }
-    } break;
-
-    case PUSCH_PDU_BITMAP_DFTS_OFDM: {
-      if (!(pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_group_number, end)
-            && pull16(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.low_papr_sequence_number, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_sample_density, end)
-            && pull8(ppReadPackedMsg, &pusch_pdu->dfts_ofdm.ul_ptrs_time_density_transform_precoding, end))) {
-        return 0;
-      }
-    } break;
-
-    default: {
-      NFAPI_TRACE(NFAPI_TRACE_INFO, "Invalid pdu bitmap %d \n", pusch_pdu->pdu_bit_map);
-    }
-  }
-  uint16_t dummy16 = 0;
-  uint8_t dummy8 = 0;
-  if (!(pull16(ppReadPackedMsg, &dummy16, end) && pull16(ppReadPackedMsg, &dummy16, end) && pull8(ppReadPackedMsg, &dummy8, end))) {
-    return 0;
-  }
-
-  return 1;
-}
-
-static uint8_t unpack_ul_tti_request_srs_pdu(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
-  nfapi_nr_srs_pdu_t *srs_pdu = (nfapi_nr_srs_pdu_t *)tlv;
-  return(
-          pull16(ppReadPackedMsg, &srs_pdu->rnti, end) &&
-          pull32(ppReadPackedMsg, &srs_pdu->handle, end) &&
-          pull16(ppReadPackedMsg, &srs_pdu->bwp_size, end) &&
-          pull16(ppReadPackedMsg, &srs_pdu->bwp_start, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->subcarrier_spacing, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->cyclic_prefix, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->num_ant_ports, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->num_symbols,  end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->num_repetitions, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->time_start_position, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->config_index, end) &&
-          pull16(ppReadPackedMsg, &srs_pdu->sequence_id, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->bandwidth_index, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->comb_size, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->comb_offset, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->cyclic_shift, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->frequency_position, end) &&
-          pull16(ppReadPackedMsg, &srs_pdu->frequency_shift, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->frequency_hopping, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->group_or_sequence_hopping, end) &&
-          pull8(ppReadPackedMsg, &srs_pdu->resource_type, end) &&
-          pull16(ppReadPackedMsg, &srs_pdu->t_srs, end) &&
-          pull16(ppReadPackedMsg, &srs_pdu->t_offset, end)
-          // TODO: ignoring beamforming tlv for now
-        );
-}
-
-
-static uint8_t unpack_ul_tti_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
-  nfapi_nr_ul_tti_request_number_of_pdus_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_pdus_t *)msg;
-
-  if(!(pull16(ppReadPackedMsg, &pNfapiMsg->pdu_type, end) &&
-       pull16(ppReadPackedMsg, &pNfapiMsg->pdu_size, end) ))
-    return 0;
-
-  // first natch the pdu type, then call the respective function
-  switch(pNfapiMsg->pdu_type) {
-    case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: {
-      if(!unpack_ul_tti_request_prach_pdu(&pNfapiMsg->prach_pdu, ppReadPackedMsg, end))
-        return 0;
-    }
-    break;
-
-    case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: {
-      if(!unpack_ul_tti_request_pucch_pdu(&pNfapiMsg->pucch_pdu, ppReadPackedMsg, end))
-        return 0;
-    }
-    break;
-
-    case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: {
-      if(!unpack_ul_tti_request_pusch_pdu(&pNfapiMsg->pusch_pdu, ppReadPackedMsg, end))
-        return 0;
-    }
-    break;
-
-    case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: {
-      if(!unpack_ul_tti_request_srs_pdu(&pNfapiMsg->srs_pdu, ppReadPackedMsg, end))
-        return 0;
-    }
-    break;
-
-    default: {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid UL_TTI pdu type %d \n", pNfapiMsg->pdu_type );
-    }
-    break;
-  }
-
-  return 1;
-}
-
-
-static uint8_t unpack_ul_tti_groups_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
-  nfapi_nr_ul_tti_request_number_of_groups_t *pNfapiMsg = (nfapi_nr_ul_tti_request_number_of_groups_t *)msg;
-
-  if(!pull8(ppReadPackedMsg, &pNfapiMsg->n_ue, end))
-    return 0;
-
-  for (int i = 0; i < pNfapiMsg->n_ue; i++) {
-    if(!pull8(ppReadPackedMsg, &pNfapiMsg->ue_list[i].pdu_idx,end) )
-      return 0;
-  }
-
-  return 1;
-}
-
-static uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_ul_tti_request_t *pNfapiMsg = (nfapi_nr_ul_tti_request_t *)msg;
-
-  if (!pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end))
-    return 0;
-  if (!pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end))
-    return 0;
-  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_pdus, end))
-    return 0;
-  if (!pull8(ppReadPackedMsg, &pNfapiMsg->rach_present, end))
-    return 0;
-  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulcch, end))
-    return 0;
-  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_ulsch, end))
-    return 0;
-  if (!pull8(ppReadPackedMsg, &pNfapiMsg->n_group, end))
-    return 0;
-  for (int i = 0; i < pNfapiMsg->n_pdus; i++) {
-    if (!unpack_ul_tti_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdus_list[i]))
-      return 0;
-  }
-
-  for (int i = 0; i < pNfapiMsg->n_group; i++) {
-    if (!unpack_ul_tti_groups_list_value(ppReadPackedMsg, end, &pNfapiMsg->groups_list[i]))
-      return 0;
-  }
-
-  return 1;
-}
-
 static uint8_t unpack_dl_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
   nfapi_dl_config_request_t *pNfapiMsg = (nfapi_dl_config_request_t *)msg;
   unpack_p7_tlv_t unpack_fns[] = {
@@ -5786,88 +4239,6 @@ static uint8_t unpack_hi_dci0_request_body_value(void *tlv, uint8_t **ppReadPack
 
   return 1;
 }
-//unpack_ul_dci_pdu_list_value
-
-static uint8_t unpack_ul_dci_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg)
-{
-  nfapi_nr_ul_dci_request_pdus_t *value = (nfapi_nr_ul_dci_request_pdus_t *)msg;
-
-  if (!(pull16(ppReadPackedMsg, &value->PDUType, end) && pull16(ppReadPackedMsg, &value->PDUSize, end)
-        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPSize, end)
-        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.BWPStart, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.SubcarrierSpacing, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CyclicPrefix, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.StartSymbolIndex, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.DurationSymbols, end)
-        && pullarray8(ppReadPackedMsg, value->pdcch_pdu.pdcch_pdu_rel15.FreqDomainResource, 6, 6, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CceRegMappingType, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.RegBundleSize, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.InterleaverSize, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.CoreSetType, end)
-        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.ShiftIndex, end)
-        && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.precoderGranularity, end)
-        && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.numDlDci, end))) {
-    return 0;
-  }
-
-  for (uint16_t i = 0; i < value->pdcch_pdu.pdcch_pdu_rel15.numDlDci; ++i) {
-    if (!(pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].RNTI, end)
-          && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingId, end)
-          && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].ScramblingRNTI, end)
-          && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].CceIndex, end)
-          && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].AggregationLevel, end)
-          && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs, end)
-          && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prg_size, end)
-          && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces, end))) {
-      return 0;
-    }
-    for (int prg = 0; prg < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.num_prgs; prg++) {
-      if (!pull16(ppReadPackedMsg,
-                  &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.prgs_list[prg].pm_idx,
-                  end)) {
-        return 0;
-      }
-      for (int digInt = 0; digInt < value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].precodingAndBeamforming.dig_bf_interfaces;
-           digInt++) {
-        if (!pull16(ppReadPackedMsg,
-                    &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i]
-                         .precodingAndBeamforming.prgs_list[prg]
-                         .dig_bf_interface_list[digInt]
-                         .beam_idx,
-                    end)) {
-          return 0;
-        }
-      }
-    }
-    if (!(pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].beta_PDCCH_1_0, end)
-          && pull8(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].powerControlOffsetSS, end)
-          && pull16(ppReadPackedMsg, &value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits, end)
-          && unpack_dci_payload(value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].Payload,
-                                value->pdcch_pdu.pdcch_pdu_rel15.dci_pdu[i].PayloadSizeBits,
-                                ppReadPackedMsg,
-                                end))) {
-      return 0;
-    }
-  }
-  return 1;
-}
-
-static uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
-  nfapi_nr_ul_dci_request_t *pNfapiMsg = (nfapi_nr_ul_dci_request_t *)msg;
-
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) &&
-        pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end) &&
-        pull8(ppReadPackedMsg, &pNfapiMsg->numPdus, end)
-       ))
-    return 0;
-
-  for(int i=0; i< pNfapiMsg->numPdus; i++) {
-    if (!unpack_ul_dci_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->ul_dci_pdu_list[i]))
-      return 0;
-  }
-
-  return 1;
-}
 
 static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
   nfapi_hi_dci0_request_t *pNfapiMsg = (nfapi_hi_dci0_request_t *)msg;
@@ -5877,67 +4248,6 @@ static uint8_t unpack_hi_dci0_request(uint8_t **ppReadPackedMsg, uint8_t *end, v
   return (pull16(ppReadPackedMsg, &pNfapiMsg->sfn_sf, end) &&
           unpack_p7_tlv_list(unpack_fns, sizeof(unpack_fns)/sizeof(unpack_tlv_t), ppReadPackedMsg, end, config, &pNfapiMsg->vendor_extension));
 }
-static uint8_t unpack_tx_data_pdu_list_value(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg) {
-  nfapi_nr_pdu_t *pNfapiMsg = (nfapi_nr_pdu_t *)msg;
-
-  if (!(pull32(ppReadPackedMsg, &pNfapiMsg->PDU_length, end) && pull16(ppReadPackedMsg, &pNfapiMsg->PDU_index, end)
-        && pull32(ppReadPackedMsg, &pNfapiMsg->num_TLV, end)))
-    return 0;
-
-  uint16_t i = 0;
-  uint16_t total_number_of_tlvs = pNfapiMsg->num_TLV;
-
-  for(; i < total_number_of_tlvs; ++i) {
-    if (!(pull16(ppReadPackedMsg, &pNfapiMsg->TLVs[i].tag, end) && pull32(ppReadPackedMsg, &pNfapiMsg->TLVs[i].length, end)))
-      return 0;
-
-    switch(pNfapiMsg->TLVs[i].tag) {
-      case 0: {
-        if (!pullarray32(ppReadPackedMsg, pNfapiMsg->TLVs[i].value.direct,
-                         sizeof(pNfapiMsg->TLVs[i].value.direct) / sizeof(uint32_t),
-                         (pNfapiMsg->TLVs[i].length+3)/4, end))
-          return 0;
-
-        break;
-      }
-
-      case 1: {
-        if (!pullarray32(ppReadPackedMsg,
-                         pNfapiMsg->TLVs[i].value.ptr,
-                         (pNfapiMsg->TLVs[i].length + 3) / 4,
-                         (pNfapiMsg->TLVs[i].length + 3) / 4,
-                         end))
-          return 0;
-
-        break;
-      }
-
-      default: {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "FIXME : Invalid tag value %d \n", pNfapiMsg->TLVs[i].tag );
-        break;
-      }
-    }
-  }
-
-  return 1;
-}
-
-static uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_tx_data_request_t *pNfapiMsg = (nfapi_nr_tx_data_request_t *)msg;
-
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->SFN, end) && pull16(ppReadPackedMsg, &pNfapiMsg->Slot, end)
-        && pull16(ppReadPackedMsg, &pNfapiMsg->Number_of_PDUs, end)))
-    return 0;
-
-  for (int i = 0; i < pNfapiMsg->Number_of_PDUs; i++) {
-    if (!unpack_tx_data_pdu_list_value(ppReadPackedMsg, end, &pNfapiMsg->pdu_list[i])) {
-      return 0;
-    }
-  }
-
-  return 1;
-}
 
 static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
   uint8_t proceed = 1;
@@ -6014,589 +4324,148 @@ static uint8_t unpack_tx_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
             NFAPI_TRACE(NFAPI_TRACE_ERROR, "NULL pdu\n");
           }
         }
-      }
-      break;
-
-      default: {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request FIXME : Invalid pdu type %d \n", generic_tl.tag );
-      }
-      break;
-    };
-  }
-
-  return 1;
-}
-
-//UNPACK NR UPLINK INDICATION FUNCTIONS
-
-//SLOT INDICATION
-
-uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
-                                  uint8_t *end,
-                                  nfapi_nr_slot_indication_scf_t *msg,
-                                  nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_slot_indication_scf_t *pNfapiMsg = (nfapi_nr_slot_indication_scf_t *)msg;
-
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)))
-    return 0;
-
-  return 1;
-}
-
-//RX DATA INDICATION
-
-static uint8_t unpack_nr_rx_data_indication_body(nfapi_nr_rx_data_pdu_t *value,
-                                                 uint8_t **ppReadPackedMsg,
-                                                 uint8_t *end,
-                                                 nfapi_p7_codec_config_t *config)
-{
-  if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
-        && pull8(ppReadPackedMsg, &value->harq_id, end) && pull32(ppReadPackedMsg, &value->pdu_length, end)
-        && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
-        && pull16(ppReadPackedMsg, &value->rssi, end)))
-    return 0;
-
-  value->pdu = nfapi_p7_allocate(sizeof(*value->pdu) * value->pdu_length, config);
-  if (pullarray8(ppReadPackedMsg, value->pdu, value->pdu_length, value->pdu_length, end) == 0) {
-    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s pullarray8 failure\n", __FUNCTION__);
-    return 0;
-  }
-  return 1;
-}
-
-static uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, nfapi_nr_rx_data_indication_t *msg, nfapi_p7_codec_config_t* config)
-{
-  nfapi_nr_rx_data_indication_t *pNfapiMsg = (nfapi_nr_rx_data_indication_t*)msg;
-
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn , end) &&
-        pull16(ppReadPackedMsg, &pNfapiMsg->slot , end) &&
-        pull16(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end)
-  ))
-    return 0;
-
-  if (pNfapiMsg->number_of_pdus > 0)
-  {
-    pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config);
-  }
-
-  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++)
-  {
-    if(!unpack_nr_rx_data_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end, config))
-      return 0;
-  }
-
-  return 1;
-}
-
-//NR CRC INDICATION
-
-uint8_t unpack_nr_crc_indication_body(nfapi_nr_crc_t *value, uint8_t **ppReadPackedMsg, uint8_t *end)
-{
-  if (!(pull32(ppReadPackedMsg, &value->handle, end) && pull16(ppReadPackedMsg, &value->rnti, end)
-        && pull8(ppReadPackedMsg, &value->harq_id, end) && pull8(ppReadPackedMsg, &value->tb_crc_status, end)
-        && pull16(ppReadPackedMsg, &value->num_cb, end))) {
-    return 0;
-  }
-  if (value->num_cb != 0) {
-    if (!pullarray8(ppReadPackedMsg,
-                    value->cb_crc_status,
-                    (int)(value->num_cb / 8) + 1,
-                    (int)(value->num_cb / 8) + 1,
-                    end)) { // length is ceil(NumCb/8)
-      return 0;
-    }
-  }
-  if (!(pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
-        && pull16(ppReadPackedMsg, &value->rssi, end))) {
-    return 0;
-  }
-
-  // memcpy((nfapi_nr_crc_t *)tlv,value,sizeof(nfapi_nr_crc_t));
-
-  return 1;
-}
-
-uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg,
-                                 uint8_t *end,
-                                 nfapi_nr_crc_indication_t *msg,
-                                 nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_crc_indication_t *pNfapiMsg = (nfapi_nr_crc_indication_t *)msg;
-
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
-        && pull16(ppReadPackedMsg, &pNfapiMsg->number_crcs, end)))
-    return 0;
-
-  if (pNfapiMsg->number_crcs > 0) {
-    pNfapiMsg->crc_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->crc_list) * pNfapiMsg->number_crcs, config);
-  }
-
-  for (int i = 0; i < pNfapiMsg->number_crcs; i++) {
-    if (!unpack_nr_crc_indication_body(&pNfapiMsg->crc_list[i], ppReadPackedMsg, end))
-      return 0;
-  }
-
-  return 1;
-}
-
-//SRS INDICATION
-
-int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen) {
-
-  nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix = (nfapi_nr_srs_normalized_channel_iq_matrix_t*)pUnpackedBuf;
-  uint8_t *pReadPackedMessage = pMessageBuf;
-  uint8_t *end = pMessageBuf + messageBufLen;
-
-  memset(pUnpackedBuf, 0, unpackedBufLen);
-
-  if(!(pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, end) &&
-       pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, end) &&
-       pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, end) &&
-       pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->prg_size, end) &&
-       pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_prgs, end))) {
-    return -1;
-  }
-
-  uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs*nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports*nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
-  if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) {
-    channel_matrix_size <<= 1;
-  } else {
-    channel_matrix_size <<= 2;
-  }
-
-  for(int i = 0; i < channel_matrix_size; i++) {
-    if (!pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->channel_matrix[i], end)) {
-      return 0;
-    }
-  }
-
-  return 0;
-}
-
-static uint8_t unpack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, uint8_t **ppReadPackedMsg, uint8_t *end) {
-
-  if(!pull16(ppReadPackedMsg, &prgs->num_prgs, end)) {
-    return 0;
-  }
-
-  for(int i = 0; i < prgs->num_prgs; i++) {
-    if (!pull8(ppReadPackedMsg, &prgs->prg_list[i].rb_snr, end)) {
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen) {
-
-  nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t*)pUnpackedBuf;
-  uint8_t *pReadPackedMessage = pMessageBuf;
-  uint8_t *end = pMessageBuf + messageBufLen;
-
-  memset(pUnpackedBuf, 0, unpackedBufLen);
-
-  if(!(pull16(&pReadPackedMessage, &nr_srs_beamforming_report->prg_size, end) &&
-       pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_symbols, end) &&
-       pull8(&pReadPackedMessage, &nr_srs_beamforming_report->wide_band_snr, end) &&
-       pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_reported_symbols, end))) {
-    return -1;
-  }
-
-  if (!unpack_nr_srs_reported_symbol(&nr_srs_beamforming_report->prgs, &pReadPackedMessage, end)) {
-    return -1;
-  }
-
-  return 0;
-}
-
-static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
-
-  if(!(pull16(ppReadPackedMsg, &report_tlv->tag, end) &&
-       pull32(ppReadPackedMsg, &report_tlv->length, end))) {
-    return 0;
-  }
-
-  for(int i = 0; i < report_tlv->length; i++) {
-    if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) {
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-static uint8_t unpack_nr_srs_indication_body(nfapi_nr_srs_indication_pdu_t *value, uint8_t **ppReadPackedMsg, uint8_t *end) {
-
-  if(!(pull32(ppReadPackedMsg, &value->handle, end) &&
-       pull16(ppReadPackedMsg, &value->rnti, end) &&
-       pull16(ppReadPackedMsg, &value->timing_advance_offset, end) &&
-       pulls16(ppReadPackedMsg, &value->timing_advance_offset_nsec, end) &&
-       pull8(ppReadPackedMsg, &value->srs_usage, end) &&
-       pull8(ppReadPackedMsg, &value->report_type, end))) {
-    return 0;
-  }
-
-  if (!unpack_nr_srs_report_tlv(&value->report_tlv, ppReadPackedMsg, end)) {
-    return 0;
-  }
-
-  return 1;
-}
-
-uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg,
-                                 uint8_t *end,
-                                 nfapi_nr_srs_indication_t *pNfapiMsg,
-                                 nfapi_p7_codec_config_t *config)
-{
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
-        && pull16(ppReadPackedMsg, &pNfapiMsg->control_length, end) && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
-    return 0;
-  }
-
-  for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
-    if (!unpack_nr_srs_indication_body(&pNfapiMsg->pdu_list[i], ppReadPackedMsg, end)) {
-      return 0;
-    }
-  }
-
-  return 1;
-}
-
-//NR RACH
-
-static uint8_t unpack_nr_rach_indication_body(nfapi_nr_prach_indication_pdu_t *value,
-                                              uint8_t **ppReadPackedMsg,
-                                              uint8_t *end,
-                                              nfapi_p7_codec_config_t *config)
-{
-  if (!(pull16(ppReadPackedMsg, &value->phy_cell_id, end) && pull8(ppReadPackedMsg, &value->symbol_index, end)
-        && pull8(ppReadPackedMsg, &value->slot_index, end) && pull8(ppReadPackedMsg, &value->freq_index, end)
-        && pull8(ppReadPackedMsg, &value->avg_rssi, end) && pull8(ppReadPackedMsg, &value->avg_snr, end)
-        && pull8(ppReadPackedMsg, &value->num_preamble, end))) {
-    return 0;
-  }
-
-  for (int i = 0; i < value->num_preamble; i++) {
-    nfapi_nr_prach_indication_preamble_t *preamble = &(value->preamble_list[i]);
-    if (!(pull8(ppReadPackedMsg, &preamble->preamble_index, end) && pull16(ppReadPackedMsg, &preamble->timing_advance, end)
-          && pull32(ppReadPackedMsg, &preamble->preamble_pwr, end))) {
-      return 0;
-    }
-  }
-  return 1;
-}
-
-uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg,
-                                  uint8_t *end,
-                                  nfapi_nr_rach_indication_t *msg,
-                                  nfapi_p7_codec_config_t *config)
-{
-  nfapi_nr_rach_indication_t *pNfapiMsg = (nfapi_nr_rach_indication_t *)msg;
-
-  if (!(pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end) && pull16(ppReadPackedMsg, &pNfapiMsg->slot, end)
-        && pull8(ppReadPackedMsg, &pNfapiMsg->number_of_pdus, end))) {
-    return 0;
-  }
-
-  if (pNfapiMsg->number_of_pdus > 0) {
-    pNfapiMsg->pdu_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->pdu_list) * pNfapiMsg->number_of_pdus, config);
-    for (int i = 0; i < pNfapiMsg->number_of_pdus; i++) {
-      if (!unpack_nr_rach_indication_body(&(pNfapiMsg->pdu_list[i]), ppReadPackedMsg, end, config))
-        return 0;
-    }
-  }
-  return 1;
-}
-
-//NR UCI
-
-static uint8_t unpack_nr_uci_pucch_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *value,
-                                       uint8_t **ppReadPackedMsg,
-                                       uint8_t *end,
-                                       nfapi_p7_codec_config_t *config)
-{
-  if (!(pull8(ppReadPackedMsg, &value->pduBitmap, end) && pull32(ppReadPackedMsg, &value->handle, end)
-        && pull16(ppReadPackedMsg, &value->rnti, end) && pull8(ppReadPackedMsg, &value->pucch_format, end)
-        && pull8(ppReadPackedMsg, &value->ul_cqi, end) && pull16(ppReadPackedMsg, &value->timing_advance, end)
-        && pull16(ppReadPackedMsg, &value->rssi, end)))
-    return 0;
-  if (value->pduBitmap & 0x01) { // SR
-    if (!(pull8(ppReadPackedMsg, &value->sr.sr_indication, end) && pull8(ppReadPackedMsg, &value->sr.sr_confidence_level, end)))
-      return 0;
-  }
-
-  if (((value->pduBitmap >> 1) & 0x01)) { // HARQ
-
-    if (!(pull8(ppReadPackedMsg, &value->harq.num_harq, end) && pull8(ppReadPackedMsg, &value->harq.harq_confidence_level, end)))
-      return 0;
-    if (value->harq.num_harq > 0) {
-      for (int i = 0; i < value->harq.num_harq; i++) {
-        if (!pull8(ppReadPackedMsg, &value->harq.harq_list[i].harq_value, end)) {
-          return 0;
-        }
-      }
-    }
-  }
-
-  return 1;
-}
-
-static uint8_t unpack_nr_uci_pucch_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t* value,
-                                         uint8_t **ppReadPackedMsg,
-                                         uint8_t *end,
-                                         nfapi_p7_codec_config_t *config) {
-
-	if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
-		return 0;
-	if (!pull32(ppReadPackedMsg, &value->handle, end))
-                return 0;
-	if (!pull16(ppReadPackedMsg, &value->rnti, end))
-                return 0;
-	if (!pull8(ppReadPackedMsg, &value->pucch_format, end))
-                return 0;
-	if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
-                return 0;
-	if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
-                return 0;
-	if (!pull16(ppReadPackedMsg, &value->rssi, end))
-                return 0;
-
-  value->pucch_format += 2;
-	if (value->pduBitmap & 0x01) { //SR
-		if (!pull16(ppReadPackedMsg, &value->sr.sr_bit_len, end))
-			return 0;
-
-		value->sr.sr_payload = nfapi_p7_allocate(sizeof(*value->sr.sr_payload) *
-                                                         (int)((value->sr.sr_bit_len / 8) + 1),
-                                                         config);
-		if (value->sr.sr_payload == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->sr.sr_payload\n", __FUNCTION__);
-			return 0;
-		}
-
-		if (!pullarray8(ppReadPackedMsg, value->sr.sr_payload,
-				(int)((value->sr.sr_bit_len / 8) + 1),
-				(int)((value->sr.sr_bit_len / 8) + 1),
-                                end))
-			return 0;
-	}
-
-	if ((value->pduBitmap >> 1) & 0x01) { //HARQ
-		if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
-			return 0;
-		if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
-			return 0;
-
-		value->harq.harq_payload = nfapi_p7_allocate(sizeof(*value->harq.harq_payload) *
-                                                             (int)((value->harq.harq_bit_len / 8) + 1),
-                                                             config);
-		if (value->harq.harq_payload == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
-			return 0;
-		}
-
-		if (!pullarray8(ppReadPackedMsg, value->harq.harq_payload,
-				(int)((value->harq.harq_bit_len / 8) + 1),
-				(int)((value->harq.harq_bit_len / 8) + 1),
-                                end))
-			return 0;
-	}
+      }
+      break;
 
-	if ((value->pduBitmap >> 2) & 0x01) { //CSI-1
-		if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
-			return 0;
-		if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
-			return 0;
+      default: {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "unpack_tx_request FIXME : Invalid pdu type %d \n", generic_tl.tag );
+      }
+      break;
+    };
+  }
 
-		value->csi_part1.csi_part1_payload = nfapi_p7_allocate(sizeof(*value->csi_part1.csi_part1_payload) *
-                                                                       (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                                                                       config);
-		if (value->csi_part1.csi_part1_payload == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n",
-				    __FUNCTION__);
-			return 0;
-		}
+  return 1;
+}
 
-		if (!pullarray8(ppReadPackedMsg, value->csi_part1.csi_part1_payload,
-                                (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                                (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                                end))
-			return 0;
-	}
+//UNPACK NR UPLINK INDICATION FUNCTIONS
 
-	if ((value->pduBitmap >> 3) & 0x01) { //CSI-2
-		if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
-			return 0;
-		if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
-			return 0;
 
-		value->csi_part2.csi_part2_payload = nfapi_p7_allocate(sizeof(*value->csi_part2.csi_part2_payload) *
-                                                                       (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                                                                       config);
-		if (value->csi_part2.csi_part2_payload == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n",
-			            __FUNCTION__);
-			return 0;
-		}
+//SRS INDICATION
 
-		if (!pullarray8(ppReadPackedMsg, value->csi_part2.csi_part2_payload,
-                                (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                                (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                                end))
-			return 0;
-	}
+int unpack_nr_srs_channel_svd_representation(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen)
+{
+  nfapi_nr_srs_channel_svd_representation_t *value = (nfapi_nr_srs_channel_svd_representation_t *)pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
 
-	return 1;
-}
+  memset(pUnpackedBuf, 0, unpackedBufLen);
+  if (!(pull8(&pReadPackedMessage, &value->normalized_iq_representation, end)
+        && pull8(&pReadPackedMessage, &value->normalized_singular_value_representation, end)
+        && pulls8(&pReadPackedMessage, &value->singular_value_scaling, end)
+        && pull16(&pReadPackedMessage, &value->num_gnb_antenna_elements, end)
+        && pull8(&pReadPackedMessage, &value->num_ue_srs_ports, end) && pull16(&pReadPackedMessage, &value->prg_size, end)
+        && pull16(&pReadPackedMessage, &value->num_prgs, end))) {
+    return -1;
+  }
+  const uint16_t iq_size = value->normalized_iq_representation == 0 ? 2 : 4;
+  const uint16_t ng = value->num_gnb_antenna_elements;
+  const uint8_t nu = value->num_ue_srs_ports;
 
-static uint8_t unpack_nr_uci_pusch(nfapi_nr_uci_pusch_pdu_t *value,
-                                   uint8_t **ppReadPackedMsg,
-                                   uint8_t *end,
-                                   nfapi_p7_codec_config_t *config)
-{
-  if (!pull8(ppReadPackedMsg, &value->pduBitmap, end))
-    return 0;
-  if (!pull32(ppReadPackedMsg, &value->handle, end))
-    return 0;
-  if (!pull16(ppReadPackedMsg, &value->rnti, end))
-    return 0;
-  if (!pull8(ppReadPackedMsg, &value->ul_cqi, end))
-    return 0;
-  if (!pull16(ppReadPackedMsg, &value->timing_advance, end))
-    return 0;
-  if (!pull16(ppReadPackedMsg, &value->rssi, end))
-    return 0;
+  value->prg_list = calloc(value->num_prgs, sizeof(*value->prg_list));
 
-  // Bit 0 not used in PUSCH PDU
-  if ((value->pduBitmap >> 1) & 0x01) { // HARQ
-    if (!pull8(ppReadPackedMsg, &value->harq.harq_crc, end))
+  for (int prg_idx = 0; prg_idx < value->num_prgs; ++prg_idx) {
+    nfapi_nr_srs_channel_svd_representation_prg_t *prg = &value->prg_list[prg_idx];
+    prg->left_eigenvectors_matrix_u = calloc(nu * nu * iq_size, sizeof(*prg->left_eigenvectors_matrix_u));
+    if (!(pullarray8(&pReadPackedMessage, prg->left_eigenvectors_matrix_u, nu * nu * iq_size, nu * nu * iq_size, end))) {
       return 0;
-    if (!pull16(ppReadPackedMsg, &value->harq.harq_bit_len, end))
-      return 0;
-
-    value->harq.harq_payload =
-        nfapi_p7_allocate(sizeof(*value->harq.harq_payload) * (int)((value->harq.harq_bit_len / 8) + 1), config);
-    if (value->harq.harq_payload == NULL) {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->harq.harq_payload\n", __FUNCTION__);
+    }
+    prg->diagonal_entries_of_singular_matrix_sum_f = calloc(nu * iq_size, sizeof(*prg->diagonal_entries_of_singular_matrix_sum_f));
+    if (!(pullarray8(&pReadPackedMessage, prg->diagonal_entries_of_singular_matrix_sum_f, nu * iq_size, nu * iq_size, end))) {
       return 0;
     }
-
-    if (!pullarray8(ppReadPackedMsg,
-                    value->harq.harq_payload,
-                    (int)((value->harq.harq_bit_len / 8) + 1),
-                    (int)((value->harq.harq_bit_len / 8) + 1),
-                    end))
+    prg->complex_conjugate_of_matrix_of_right_eigenvectors_v_hf =
+        calloc(nu * ng * iq_size, sizeof(*prg->complex_conjugate_of_matrix_of_right_eigenvectors_v_hf));
+    if (!(pullarray8(&pReadPackedMessage,
+                     prg->complex_conjugate_of_matrix_of_right_eigenvectors_v_hf,
+                     nu * ng * iq_size,
+                     nu * ng * iq_size,
+                     end))) {
       return 0;
+    }
   }
+  return 1;
+}
 
-  if ((value->pduBitmap >> 2) & 0x01) { // CSI-1
-    if (!pull8(ppReadPackedMsg, &value->csi_part1.csi_part1_crc, end))
-      return 0;
-    if (!pull16(ppReadPackedMsg, &value->csi_part1.csi_part1_bit_len, end))
-      return 0;
+int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf,
+                                               uint32_t messageBufLen,
+                                               void *pUnpackedBuf,
+                                               uint32_t unpackedBufLen)
+{
+  nfapi_nr_srs_normalized_channel_iq_matrix_t *nr_srs_normalized_channel_iq_matrix =
+      (nfapi_nr_srs_normalized_channel_iq_matrix_t *)pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
 
-    value->csi_part1.csi_part1_payload =
-        nfapi_p7_allocate(sizeof(*value->csi_part1.csi_part1_payload) * (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                          config);
-    if (value->csi_part1.csi_part1_payload == NULL) {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part1.csi_part1_payload\n", __FUNCTION__);
-      return 0;
-    }
+  memset(pUnpackedBuf, 0, unpackedBufLen);
 
-    if (!pullarray8(ppReadPackedMsg,
-                    value->csi_part1.csi_part1_payload,
-                    (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                    (int)((value->csi_part1.csi_part1_bit_len / 8) + 1),
-                    end))
-      return 0;
+  if (!(pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->normalized_iq_representation, end)
+        && pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements, end)
+        && pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports, end)
+        && pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->prg_size, end)
+        && pull16(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->num_prgs, end))) {
+    return -1;
   }
 
-  if ((value->pduBitmap >> 3) & 0x01) { // CSI-2
-    if (!pull8(ppReadPackedMsg, &value->csi_part2.csi_part2_crc, end))
-      return 0;
-    if (!pull16(ppReadPackedMsg, &value->csi_part2.csi_part2_bit_len, end))
-      return 0;
+  uint16_t channel_matrix_size = nr_srs_normalized_channel_iq_matrix->num_prgs
+                                 * nr_srs_normalized_channel_iq_matrix->num_ue_srs_ports
+                                 * nr_srs_normalized_channel_iq_matrix->num_gnb_antenna_elements;
+  if (nr_srs_normalized_channel_iq_matrix->normalized_iq_representation == 0) {
+    // 0: 16-bit normalized complex number (iqSize = 2)
+    channel_matrix_size <<= 1;
+  } else {
+    // 1: 32-bit normalized complex number (iqSize = 4)
+    channel_matrix_size <<= 2;
+  }
 
-    value->csi_part2.csi_part2_payload =
-        nfapi_p7_allocate(sizeof(*value->csi_part2.csi_part2_payload) * (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                          config);
-    if (value->csi_part2.csi_part2_payload == NULL) {
-      NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s failed to allocate value->csi_part2.csi_part2_payload\n", __FUNCTION__);
+  for (int i = 0; i < channel_matrix_size; i++) {
+    if (!pull8(&pReadPackedMessage, &nr_srs_normalized_channel_iq_matrix->channel_matrix[i], end)) {
       return 0;
     }
-
-    if (!pullarray8(ppReadPackedMsg,
-                    value->csi_part2.csi_part2_payload,
-                    (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                    (int)((value->csi_part2.csi_part2_bit_len / 8) + 1),
-                    end))
-      return 0;
   }
 
   return 1;
 }
 
-static uint8_t unpack_nr_uci_indication_body(nfapi_nr_uci_t *value,
-                                             uint8_t **ppReadPackedMsg,
-                                             uint8_t *end,
-                                             nfapi_p7_codec_config_t *config)
-{
-  if (!pull16(ppReadPackedMsg, &value->pdu_type, end))
-    return 0;
-  if (!pull16(ppReadPackedMsg, &value->pdu_size, end))
+static uint8_t unpack_nr_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *prgs, uint8_t **ppReadPackedMsg, uint8_t *end) {
+
+  if(!pull16(ppReadPackedMsg, &prgs->num_prgs, end)) {
     return 0;
+  }
 
-  switch (value->pdu_type) {
-    case NFAPI_NR_UCI_PUSCH_PDU_TYPE: {
-      nfapi_nr_uci_pusch_pdu_t *uci_pdu = &value->pusch_pdu;
-      if (!unpack_nr_uci_pusch(uci_pdu, ppReadPackedMsg, end, config))
-        return 0;
-      break;
-    }
-    case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE: {
-      nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu = &value->pucch_pdu_format_0_1;
-      if (!unpack_nr_uci_pucch_0_1(uci_pdu, ppReadPackedMsg, end, config))
-        return 0;
-      break;
-    }
-    case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE: {
-      nfapi_nr_uci_pucch_pdu_format_2_3_4_t *uci_pdu = &value->pucch_pdu_format_2_3_4;
-      if (!unpack_nr_uci_pucch_2_3_4(uci_pdu, ppReadPackedMsg, end, config))
-        return 0;
-      break;
+  for(int i = 0; i < prgs->num_prgs; i++) {
+    if (!pull8(ppReadPackedMsg, &prgs->prg_list[i].rb_snr, end)) {
+      return 0;
     }
-    default:
-      NFAPI_TRACE(NFAPI_TRACE_WARN, "Unexpected pdu type %d\n", value->pdu_type);
-      break;
   }
 
   return 1;
 }
 
-uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config)
+int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen)
 {
-  nfapi_nr_uci_indication_t *pNfapiMsg = (nfapi_nr_uci_indication_t *)msg;
+  nfapi_nr_srs_beamforming_report_t *nr_srs_beamforming_report = (nfapi_nr_srs_beamforming_report_t *)pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
+  uint8_t *end = pMessageBuf + messageBufLen;
 
-  if (!pull16(ppReadPackedMsg, &pNfapiMsg->sfn, end))
-    return 0;
-  if (!pull16(ppReadPackedMsg, &pNfapiMsg->slot, end))
-    return 0;
-  if (!pull16(ppReadPackedMsg, &pNfapiMsg->num_ucis, end))
-    return 0;
+  memset(pUnpackedBuf, 0, unpackedBufLen);
 
-  pNfapiMsg->uci_list = nfapi_p7_allocate(sizeof(*pNfapiMsg->uci_list) * pNfapiMsg->num_ucis, config);
-  for (int i = 0; i < pNfapiMsg->num_ucis; i++) {
-    if (!unpack_nr_uci_indication_body(&pNfapiMsg->uci_list[i], ppReadPackedMsg, end, config))
-      return 0;
+  if (!(pull16(&pReadPackedMessage, &nr_srs_beamforming_report->prg_size, end)
+        && pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_symbols, end)
+        && pull8(&pReadPackedMessage, &nr_srs_beamforming_report->wide_band_snr, end)
+        && pull8(&pReadPackedMessage, &nr_srs_beamforming_report->num_reported_symbols, end))) {
+    return -1;
+  }
+  nr_srs_beamforming_report->reported_symbol_list =
+      calloc(nr_srs_beamforming_report->num_reported_symbols, sizeof(*nr_srs_beamforming_report->reported_symbol_list));
+  for (int reported_symbol = 0; reported_symbol < nr_srs_beamforming_report->num_reported_symbols; ++reported_symbol) {
+    if (!unpack_nr_srs_reported_symbol(&nr_srs_beamforming_report->reported_symbol_list[reported_symbol],
+                                       &pReadPackedMessage,
+                                       end)) {
+      return -1;
+    }
   }
 
-  return 1;
+  return 0;
 }
 
 static uint8_t unpack_ue_release_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config) {
@@ -8030,81 +5899,45 @@ static int check_unpack_length(nfapi_message_id_e msgId, uint32_t unpackedBufLen
   return retLen;
 }
 
-static int check_nr_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen)
-{
-	int retLen = 0;
-
-	switch (msgId)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_dl_tti_request_t))
-				retLen = sizeof(nfapi_nr_dl_tti_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_ul_tti_request_t))
-				retLen = sizeof(nfapi_nr_ul_tti_request_t);
-			break;
-
-		case NFAPI_SUBFRAME_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_subframe_indication_t))
-				retLen = sizeof(nfapi_subframe_indication_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_ul_dci_request_t))
-				retLen = sizeof(nfapi_nr_ul_dci_request_t);
-			break;
-
-		case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-			if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t))
-				retLen = sizeof(nfapi_nr_tx_data_request_t);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nr_rx_data_indication_t))
-				retLen = sizeof(nfapi_nr_rx_data_indication_t);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nr_crc_indication_t))
-				retLen = sizeof(nfapi_nr_crc_indication_t);
-			break;
+// Main unpack functions - public
 
-		case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nr_rach_indication_t))
-				retLen = sizeof(nfapi_nr_rach_indication_t);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nr_uci_indication_t))
-				retLen = sizeof(nfapi_nr_uci_indication_t);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
-			if (unpackedBufLen >= sizeof(nfapi_nr_srs_indication_t))
-				retLen = sizeof(nfapi_nr_srs_indication_t);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-			if (unpackedBufLen >= sizeof(nfapi_nr_dl_node_sync_t))
-				retLen = sizeof(nfapi_nr_dl_node_sync_t);
-			break;
+int nfapi_p7_message_header_unpack(void *pMessageBuf,
+                                   uint32_t messageBufLen,
+                                   void *pUnpackedBuf,
+                                   uint32_t unpackedBufLen,
+                                   nfapi_p7_codec_config_t *config)
+{
+  nfapi_p7_message_header_t *pMessageHeader = pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
 
-		case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
-			if (unpackedBufLen >= sizeof(nfapi_nr_ul_node_sync_t))
-				retLen = sizeof(nfapi_nr_ul_node_sync_t);
-			break;
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied pointers are null\n");
+    return -1;
+  }
 
-		default:
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown message ID %d\n", msgId);
-			break;
-	}
+  uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
 
-	return retLen;
+  if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
+  // process the header
+  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->message_length, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->checksum, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
+    return -1;
+  return 0;
 }
 
-
-
-// Main unpack functions - public
-
-int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t *config) {
-  nfapi_p7_message_header_t *pMessageHeader = pUnpackedBuf;
+int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
+                                      uint32_t messageBufLen,
+                                      void *pUnpackedBuf,
+                                      uint32_t unpackedBufLen,
+                                      nfapi_p7_codec_config_t *config)
+{
+  nfapi_nr_p7_message_header_t *pMessageHeader = pUnpackedBuf;
   uint8_t *pReadPackedMessage = pMessageBuf;
 
   if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
@@ -8114,24 +5947,27 @@ int nfapi_p7_message_header_unpack(void *pMessageBuf, uint32_t messageBufLen, vo
 
   uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
 
-  if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t)) {
+  if (messageBufLen < NFAPI_NR_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p7_message_header_t)) {
     NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 header unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
     return -1;
   }
-
   // process the header
-  if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
-       pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
-       pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
+  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->message_length, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->checksum, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
     return -1;
 
   return 0;
 }
 
-int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t *config) {
+int nfapi_p7_message_unpack(void *pMessageBuf,
+                            uint32_t messageBufLen,
+                            void *pUnpackedBuf,
+                            uint32_t unpackedBufLen,
+                            nfapi_p7_codec_config_t *config)
+{
   int result = 0;
   nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t *)pUnpackedBuf;
   uint8_t *pReadPackedMessage = pMessageBuf;
@@ -8159,19 +5995,16 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
   */
   // clean the supplied buffer for - tag value blanking
   (void)memset(pUnpackedBuf, 0, unpackedBufLen);
-
   // process the header
-  if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-       pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
-       pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
-       pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) {
+  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->message_length, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->checksum, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) {
     NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
     return -1;
   }
-
-  if((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
+  if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
     NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
     return -1;
   }
@@ -8188,7 +6021,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
   switch (pMessageHeader->message_id) {
     case NFAPI_DL_CONFIG_REQUEST:
       if (check_unpack_length(NFAPI_DL_CONFIG_REQUEST, unpackedBufLen))
-        result = unpack_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8204,7 +6037,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_TX_REQUEST:
       if (check_unpack_length(NFAPI_TX_REQUEST, unpackedBufLen))
-        result = unpack_tx_request(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_tx_request(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8212,7 +6045,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_HI_DCI0_REQUEST:
       if (check_unpack_length(NFAPI_HI_DCI0_REQUEST, unpackedBufLen))
-        result = unpack_hi_dci0_request(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_hi_dci0_request(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8220,7 +6053,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_UE_RELEASE_REQUEST:
       if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
-        result = unpack_ue_release_request(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8228,7 +6061,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_HARQ_INDICATION:
       if (check_unpack_length(NFAPI_HARQ_INDICATION, unpackedBufLen))
-        result = unpack_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_harq_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8236,7 +6069,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_CRC_INDICATION:
       if (check_unpack_length(NFAPI_CRC_INDICATION, unpackedBufLen))
-        result = unpack_crc_indication(&pReadPackedMessage,end, pMessageHeader, config);
+        result = unpack_crc_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8244,7 +6077,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_RX_ULSCH_INDICATION:
       if (check_unpack_length(NFAPI_RX_ULSCH_INDICATION, unpackedBufLen))
-        result = unpack_rx_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_rx_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8252,7 +6085,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_RACH_INDICATION:
       if (check_unpack_length(NFAPI_RACH_INDICATION, unpackedBufLen))
-        result = unpack_rach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_rach_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8260,7 +6093,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_SRS_INDICATION:
       if (check_unpack_length(NFAPI_SRS_INDICATION, unpackedBufLen))
-        result = unpack_srs_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_srs_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8268,7 +6101,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_RX_SR_INDICATION:
       if (check_unpack_length(NFAPI_RX_SR_INDICATION, unpackedBufLen))
-        result = unpack_sr_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_sr_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8276,7 +6109,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_RX_CQI_INDICATION:
       if (check_unpack_length(NFAPI_RX_CQI_INDICATION, unpackedBufLen))
-        result = unpack_cqi_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_cqi_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8284,7 +6117,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_LBT_DL_CONFIG_REQUEST:
       if (check_unpack_length(NFAPI_LBT_DL_CONFIG_REQUEST, unpackedBufLen))
-        result = unpack_lbt_dl_config_request(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_lbt_dl_config_request(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8292,7 +6125,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_LBT_DL_INDICATION:
       if (check_unpack_length(NFAPI_LBT_DL_INDICATION, unpackedBufLen))
-        result = unpack_lbt_dl_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_lbt_dl_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8300,7 +6133,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_NB_HARQ_INDICATION:
       if (check_unpack_length(NFAPI_NB_HARQ_INDICATION, unpackedBufLen))
-        result = unpack_nb_harq_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_nb_harq_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8308,7 +6141,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_NRACH_INDICATION:
       if (check_unpack_length(NFAPI_NRACH_INDICATION, unpackedBufLen))
-        result = unpack_nrach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_nrach_indication(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8316,7 +6149,7 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_DL_NODE_SYNC:
       if (check_unpack_length(NFAPI_DL_NODE_SYNC, unpackedBufLen))
-        result = unpack_dl_node_sync(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
@@ -8340,19 +6173,21 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
 
     case NFAPI_UE_RELEASE_RESPONSE:
       if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
-        result = unpack_ue_release_resp(&pReadPackedMessage,  end, pMessageHeader, config);
+        result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config);
       else
         return -1;
 
       break;
 
     default:
-      if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-          pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
-        if(config && config->unpack_p7_vendor_extension) {
+      if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if (config && config->unpack_p7_vendor_extension) {
           result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
         } else {
-          NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
+          NFAPI_TRACE(NFAPI_TRACE_ERROR,
+                      "%s VE NFAPI message ID %d. No ve decoder provided\n",
+                      __FUNCTION__,
+                      pMessageHeader->message_id);
         }
       } else {
         NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
@@ -8361,173 +6196,152 @@ int nfapi_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUn
       break;
   }
 
-  if(result == 0)
+  if (result == 0)
     return -1;
   else
     return 0;
 }
 
-int nfapi_nr_p7_message_unpack(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen, nfapi_p7_codec_config_t* config)
+int nfapi_nr_p7_message_unpack(void *pMessageBuf,
+                               uint32_t messageBufLen,
+                               void *pUnpackedBuf,
+                               uint32_t unpackedBufLen,
+                               nfapi_p7_codec_config_t *config)
 {
-	int result = 0;
-	nfapi_p7_message_header_t *pMessageHeader = (nfapi_p7_message_header_t*)pUnpackedBuf;
-	uint8_t *pReadPackedMessage = pMessageBuf;
-
-	if (pMessageBuf == NULL || pUnpackedBuf == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
-		return -1;
-	}
-
-        uint8_t *end = (uint8_t*)pMessageBuf + messageBufLen;
+  int result = 0;
+  nfapi_nr_p7_message_header_t *pMessageHeader = (nfapi_nr_p7_message_header_t *)pUnpackedBuf;
+  uint8_t *pReadPackedMessage = pMessageBuf;
 
-	if (messageBufLen < NFAPI_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_p7_message_header_t))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
-		return -1;
-	}
+  if (pMessageBuf == NULL || pUnpackedBuf == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied pointers are null\n");
+    return -1;
+  }
 
-	// clean the supplied buffer for - tag value blanking
-	(void)memset(pUnpackedBuf, 0, unpackedBufLen);
+  uint8_t *end = (uint8_t *)pMessageBuf + messageBufLen;
 
-	// process the header
-	if(!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_id, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->message_length, end) &&
-		 pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->checksum, end) &&
-		 pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end)))
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
-		return -1;
-	}
+  if (messageBufLen < NFAPI_NR_P7_HEADER_LENGTH || unpackedBufLen < sizeof(nfapi_nr_p7_message_header_t)) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack supplied message buffer is too small %d, %d\n", messageBufLen, unpackedBufLen);
+    return -1;
+  }
 
-	if((uint8_t*)(pMessageBuf + pMessageHeader->message_length) > end)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
-		return -1;
-	}
+  // process the header
+  if (!(pull16(&pReadPackedMessage, &pMessageHeader->phy_id, end) && pull16(&pReadPackedMessage, &pMessageHeader->message_id, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->message_length, end)
+        && pull16(&pReadPackedMessage, &pMessageHeader->m_segment_sequence, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->checksum, end)
+        && pull32(&pReadPackedMessage, &pMessageHeader->transmit_timestamp, end))) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack header failed\n");
+    return -1;
+  }
+  if ((uint8_t *)(pMessageBuf + pMessageHeader->message_length) > end) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack message length is greater than the message buffer \n");
+    return -1;
+  }
 
-	/*
-	if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n");
-		return -1;
-	}
-	*/
+  /*
+  if(check_unpack_length(pMessageHeader->message_id, unpackedBufLen) == 0)
+  {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 unpack unpack buffer is not large enough \n");
+    return -1;
+  }
+  */
 
-	// look for the specific message
-	switch (pMessageHeader->message_id)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
-				result = unpack_dl_tti_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			break;
+  // look for the specific message
+  switch (pMessageHeader->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST, unpackedBufLen))
+        result = unpack_dl_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
-				result = unpack_ul_tti_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
-				result = unpack_tx_data_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
-				result = unpack_ul_dci_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			break;
-		case NFAPI_UE_RELEASE_REQUEST:
-			if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
-				result = unpack_ue_release_request(&pReadPackedMessage,  end, pMessageHeader, config);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION, unpackedBufLen)){
-				nfapi_nr_slot_indication_scf_t* msg = (nfapi_nr_slot_indication_scf_t*) pMessageHeader;
-				result = unpack_nr_slot_indication(&pReadPackedMessage,  end, msg, config);
-			}
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST, unpackedBufLen))
+        result = unpack_ul_tti_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST, unpackedBufLen))
+        result = unpack_tx_data_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST, unpackedBufLen))
+        result = unpack_ul_dci_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+    case NFAPI_UE_RELEASE_REQUEST:
+      if (check_unpack_length(NFAPI_UE_RELEASE_REQUEST, unpackedBufLen))
+        result = unpack_ue_release_request(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION, unpackedBufLen)) {
+        nfapi_nr_slot_indication_scf_t *msg = (nfapi_nr_slot_indication_scf_t *)pMessageHeader;
+        result = unpack_nr_slot_indication(&pReadPackedMessage, end, msg, config);
+      }
+      break;
 
-		case  NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION, unpackedBufLen)){
-				nfapi_nr_rx_data_indication_t* msg = (nfapi_nr_rx_data_indication_t*) pMessageHeader;
-				msg->pdu_list = (nfapi_nr_rx_data_pdu_t*) malloc(sizeof(nfapi_nr_rx_data_pdu_t));
-				msg->pdu_list->pdu = (uint8_t *) malloc(sizeof(uint8_t));
-				result = unpack_nr_rx_data_indication(&pReadPackedMessage,  end, msg, config);
-			}
+    case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_rx_data_indication(&pReadPackedMessage, end, pMessageHeader, config);
+      }
 			break;
 
-		case  NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION, unpackedBufLen)){
-
-				nfapi_nr_crc_indication_t* msg = (nfapi_nr_crc_indication_t*) pMessageHeader;
-				msg->crc_list = (nfapi_nr_crc_t*) malloc(sizeof(nfapi_nr_crc_t));
-				result = unpack_nr_crc_indication(&pReadPackedMessage,end , msg, config);
+    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_crc_indication(&pReadPackedMessage, end, pMessageHeader, config);
 			}
 			break;
 
-		case  NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION, unpackedBufLen)){
-				nfapi_nr_uci_indication_t* msg = (nfapi_nr_uci_indication_t*) pMessageHeader;
-				msg->uci_list = (nfapi_nr_uci_t*) malloc(sizeof(nfapi_nr_uci_t));
-				result = unpack_nr_uci_indication(&pReadPackedMessage,  end, msg, config);
+    case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_uci_indication(&pReadPackedMessage, end, pMessageHeader, config);
 			}
 			break;
 
-		case  NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION, unpackedBufLen)){
-				nfapi_nr_srs_indication_t* msg = (nfapi_nr_srs_indication_t*) pMessageHeader;
-				msg->pdu_list = (nfapi_nr_srs_indication_pdu_t*) malloc(sizeof(nfapi_nr_srs_indication_pdu_t));
-				result = unpack_nr_srs_indication(&pReadPackedMessage,  end, msg, config);
+    case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_srs_indication(&pReadPackedMessage,  end, pMessageHeader, config);
 			}
 			break;
 
-		case  NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION, unpackedBufLen)){
-				nfapi_nr_rach_indication_t* msg = (nfapi_nr_rach_indication_t*) pMessageHeader;
-				result = unpack_nr_rach_indication(&pReadPackedMessage,  end, msg, config);
+    case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION, unpackedBufLen)) {
+        result = unpack_nr_rach_indication(&pReadPackedMessage,  end, pMessageHeader, config);
 			}
 			break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, unpackedBufLen))
-				result = unpack_nr_dl_node_sync(&pReadPackedMessage,  end, pMessageHeader, config);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC, unpackedBufLen))
+        result = unpack_nr_dl_node_sync(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
-			if (check_nr_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC, unpackedBufLen))
-				result = unpack_nr_ul_node_sync(&pReadPackedMessage, end , pMessageHeader, config);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
+      if (check_nr_fapi_unpack_length(NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC, unpackedBufLen))
+        result = unpack_nr_ul_node_sync(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
 
-		case NFAPI_TIMING_INFO:
-			if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
-				result = unpack_nr_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
-			break;
+    case NFAPI_TIMING_INFO:
+      if (check_unpack_length(NFAPI_TIMING_INFO, unpackedBufLen))
+        result = unpack_nr_timing_info(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
 
-		case NFAPI_UE_RELEASE_RESPONSE:
-			if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
-				result = unpack_ue_release_resp(&pReadPackedMessage,  end, pMessageHeader, config);
-			break;
+    case NFAPI_UE_RELEASE_RESPONSE:
+      if (check_unpack_length(NFAPI_UE_RELEASE_RESPONSE, unpackedBufLen))
+        result = unpack_ue_release_resp(&pReadPackedMessage, end, pMessageHeader, config);
+      break;
 
-		default:
+    default:
 
-			if(pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-			   pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-			{
-				if(config && config->unpack_p7_vendor_extension)
-				{
-					result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s VE NFAPI message ID %d. No ve decoder provided\n", __FUNCTION__, pMessageHeader->message_id);
-				}
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
-			}
-			break;
-	}
+      if (pMessageHeader->message_id >= NFAPI_VENDOR_EXT_MSG_MIN && pMessageHeader->message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        if (config && config->unpack_p7_vendor_extension) {
+          result = (config->unpack_p7_vendor_extension)(pMessageHeader, &pReadPackedMessage, end, config);
+        } else {
+          NFAPI_TRACE(NFAPI_TRACE_ERROR,
+                      "%s VE NFAPI message ID %d. No ve decoder provided\n",
+                      __FUNCTION__,
+                      pMessageHeader->message_id);
+        }
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s NFAPI Unknown message ID %d\n", __FUNCTION__, pMessageHeader->message_id);
+      }
+      break;
+  }
 
   if (result == 0) {
     NFAPI_TRACE(NFAPI_TRACE_ERROR, "P7 Pack failed to pack message\n");
diff --git a/nfapi/open-nFAPI/pnf/inc/pnf.h b/nfapi/open-nFAPI/pnf/inc/pnf.h
index 8c4e5cf9ab083c03c034f7dad57d8703328bd6d1..7275db76e172fd0f3bd0700a1cb8c6934ebc4f94 100644
--- a/nfapi/open-nFAPI/pnf/inc/pnf.h
+++ b/nfapi/open-nFAPI/pnf/inc/pnf.h
@@ -20,7 +20,7 @@
 
 #include "nfapi_pnf_interface.h"
 
-#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
+#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
 
 typedef struct {
 
@@ -40,7 +40,7 @@ int pnf_connect(pnf_t *pnf);
 int pnf_message_pump(pnf_t *pnf);
 int pnf_nr_message_pump(pnf_t *pnf);
 
-int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
+int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len);
 int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
 int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
 int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id);
diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h
index cab245569165bd51a93c40ae6ca53b96ae4ba760..737e76e04fc863b1f340d31a26fee586e97ed038 100644
--- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h
+++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h
@@ -25,7 +25,7 @@
 
 #include "nfapi_pnf_interface.h"
 
-#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
+#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
 
 typedef struct {
 	uint16_t dl_conf_ontime;
@@ -148,7 +148,7 @@ typedef struct {
 int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
 int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7);
 int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
-int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len);
+int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len);
 int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
 
 
@@ -164,7 +164,7 @@ pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pn
 void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
 void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
 
-int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len);
+int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len);
 
 #endif /* _PNF_P7_H_ */
 
diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
index 14782bdcf4ae856abf49ad1b0fa335f00c0fe71a..cb8dd6f6d71694b9d0885a3970d5ad2664f2620a 100644
--- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
+++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
@@ -305,19 +305,19 @@ typedef struct nfapi_pnf_config
 	 *  \param msg A pointer to the decode P4/P5 message
 	 *  \return not current used
 	 */
-	int (*vendor_ext)(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg);
+	int (*vendor_ext)(nfapi_pnf_config_t* config, void* msg);
 	
 	/*! A callback to allocate vendor extension message
 	 * \param message_id The message id from the decode P4/P5 message header
 	 * \param msg_size A pointer a the size of the allocated message structure. The callee should set this
 	 * \return A pointer to a allocated P4/P5 message structure
 	 */
-	nfapi_p4_p5_message_header_t* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
+	void* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
 	
 	/*! A callback to deallocate vendor extension message 
 	 * \param header A pointer to an P4/P5 message structure
 	 */
-	void (*deallocate_p4_p5_vendor_ext)(nfapi_p4_p5_message_header_t* header);
+	void (*deallocate_p4_p5_vendor_ext)(void* header);
 
 
 
@@ -571,8 +571,8 @@ typedef struct
 typedef struct 
 {
 	//uint16_t sfn_slot
-	int16_t sfn;
-	int16_t slot;
+	uint16_t sfn;
+	uint16_t slot;
 	//TODO: Change P7 structs to NR
 	nfapi_nr_dl_tti_request_t* dl_tti_req;//nfapi_dl_config_request_t* dl_config_req; 
 	nfapi_nr_ul_tti_request_t* ul_tti_req;//nfapi_ul_config_request_t* ul_config_req;
@@ -711,7 +711,7 @@ typedef struct nfapi_pnf_p7_config
 	 * \param msg A pointer to a decode vendor extention message
 	 * \return not currently used
 	 */
-	int (*vendor_ext)(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
+	int (*vendor_ext)(nfapi_pnf_p7_config_t* config, void* msg);
 
 	/*! A callback to allocate vendor extension message
 	 * \param message_id The vendor extention message id from the decode message header
@@ -720,12 +720,12 @@ typedef struct nfapi_pnf_p7_config
 	 * 
 	 * 
 	 */
-	nfapi_p7_message_header_t* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
+	void* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
 	
 	/*! A callback to deallocate vendor extension message
 	 * \param header A pointer to a p7 vendor extention message
 	 */
-	void (*deallocate_p7_vendor_ext)(nfapi_p7_message_header_t* header);
+	void (*deallocate_p7_vendor_ext)(void* header);
 
 
 
diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c
index 9ee06b1ca8190717be596a9817ec33eece93635a..f3e44663f89a5a13847bd9eb99a939a2d3a21cca 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf.c
@@ -1519,100 +1519,96 @@ void pnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, pnf_t* pnf, uin
 	}
 }
 
-void pnf_nr_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
+void pnf_nr_handle_p5_message(pnf_t* pnf, void* pRecvMsg, int recvMsgLen)
 {
-	nfapi_p4_p5_message_header_t messageHeader;
+  nfapi_nr_p4_p5_message_header_t messageHeader;
 
-	// validate the input params
-	if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
-		return;
-	}
+  // validate the input params
+  if (pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
+    return;
+  }
 
-	// unpack the message header
-	if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &pnf->_public.codec_config) < 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
-		return;
-	}
+  // unpack the message header
+  if (nfapi_nr_p5_message_header_unpack(pRecvMsg,
+                                        recvMsgLen,
+                                        &messageHeader,
+                                        sizeof(nfapi_nr_p4_p5_message_header_t),
+                                        &pnf->_public.codec_config)
+      < 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+    return;
+  }
 
-	switch (messageHeader.message_id)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
-			pnf_nr_handle_pnf_param_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+  switch (messageHeader.message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_PARAM_REQUEST:
+      pnf_nr_handle_pnf_param_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
-			pnf_nr_handle_pnf_config_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_CONFIG_REQUEST:
+      pnf_nr_handle_pnf_config_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
-			pnf_nr_handle_pnf_start_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_PNF_START_REQUEST:
+      pnf_nr_handle_pnf_start_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_PNF_STOP_REQUEST:
-			pnf_handle_pnf_stop_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_PNF_STOP_REQUEST:
+      pnf_handle_pnf_stop_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
-			pnf_nr_handle_param_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
+      pnf_nr_handle_param_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
-			pnf_nr_handle_config_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
+      pnf_nr_handle_config_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
-			pnf_nr_handle_start_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
+      pnf_nr_handle_start_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
-			pnf_nr_handle_stop_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
+      pnf_nr_handle_stop_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_MEASUREMENT_REQUEST:
-			pnf_handle_measurement_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_MEASUREMENT_REQUEST:
+      pnf_handle_measurement_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_RSSI_REQUEST:
-			pnf_handle_rssi_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_RSSI_REQUEST:
+      pnf_handle_rssi_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_CELL_SEARCH_REQUEST:
-			pnf_handle_cell_search_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_CELL_SEARCH_REQUEST:
+      pnf_handle_cell_search_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_BROADCAST_DETECT_REQUEST:
-			pnf_handle_broadcast_detect_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_BROADCAST_DETECT_REQUEST:
+      pnf_handle_broadcast_detect_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
-			pnf_handle_system_information_schedule_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_SYSTEM_INFORMATION_SCHEDULE_REQUEST:
+      pnf_handle_system_information_schedule_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_SYSTEM_INFORMATION_REQUEST:
-			pnf_handle_system_information_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_SYSTEM_INFORMATION_REQUEST:
+      pnf_handle_system_information_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		case NFAPI_NMM_STOP_REQUEST:
-			pnf_handle_nmm_stop_request(pnf, pRecvMsg, recvMsgLen);
-			break;
+    case NFAPI_NMM_STOP_REQUEST:
+      pnf_handle_nmm_stop_request(pnf, pRecvMsg, recvMsgLen);
+      break;
 
-		default:
-			{
-				if(messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-				   messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-				{
-					pnf_handle_vendor_extension(pRecvMsg, recvMsgLen, pnf, messageHeader.message_id);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
-				}
-			}
-			break;
-	}
+    default: {
+      if (messageHeader.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && messageHeader.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        pnf_handle_vendor_extension(pRecvMsg, recvMsgLen, pnf, messageHeader.message_id);
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P5 Unknown message ID %d\n", __FUNCTION__, messageHeader.message_id);
+      }
+    } break;
+  }
 }
 
 void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
@@ -1711,21 +1707,17 @@ void pnf_handle_p5_message(pnf_t* pnf, void *pRecvMsg, int recvMsgLen)
 	}
 }
 
-
-int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
+int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len)
 {
-	int packed_len = nfapi_nr_p5_message_pack(msg, msg_len,
-										   pnf->tx_message_buffer,
-										   sizeof(pnf->tx_message_buffer),
-										   &pnf->_public.codec_config);
+  int packed_len =
+      nfapi_nr_p5_message_pack(msg, msg_len, pnf->tx_message_buffer, sizeof(pnf->tx_message_buffer), &pnf->_public.codec_config);
 
-	if (packed_len < 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed (%d)\n", packed_len);
-		return -1;
-	}
+  if (packed_len < 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_nr_p5_message_pack failed (%d)\n", packed_len);
+    return -1;
+  }
 
-	return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0/*msg->stream_id*/);
+  return pnf_send_message(pnf, pnf->tx_message_buffer, packed_len, 0 /*msg->stream_id*/);
 }
 
 
@@ -2123,7 +2115,7 @@ int pnf_nr_read_dispatch_message(pnf_t* pnf)
   // 3. Read the buffer
   // 4. Handle the p5 message
 
-  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint32_t header_buffer_size = NFAPI_NR_P5_HEADER_LENGTH;
   uint8_t header_buffer[header_buffer_size];
 
   uint32_t stack_buffer_size = 32; // should it be the size of then sctp_notificatoin structure
@@ -2155,8 +2147,8 @@ int pnf_nr_read_dispatch_message(pnf_t* pnf)
       return 0;
     }
 
-    nfapi_p4_p5_message_header_t header;
-    int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
+    nfapi_nr_p4_p5_message_header_t header;
+    int unpack_result = nfapi_nr_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
     if (unpack_result < 0) {
       NFAPI_TRACE(NFAPI_TRACE_INFO, "PNF Failed to unpack p5 message header\n");
       return 0;
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
index a7e7e0cb6e3dc78d98cabb5177a1cdf84a9fd593..a7f0385d9e82990d54474d6b2031b16e6635646b 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
@@ -666,95 +666,83 @@ int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t*
 	return 0;
 }
 
-
-int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* header, uint32_t msg_len)
+int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len)
 {
-	header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, pnf_p7->sequence_number);
+  header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, pnf_p7->sequence_number);
 
-	// Need to guard against different threads calling the encode function at the same time
-	if(pthread_mutex_lock(&(pnf_p7->pack_mutex)) != 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
-		return -1;
-	}
+  // Need to guard against different threads calling the encode function at the same time
+  if (pthread_mutex_lock(&(pnf_p7->pack_mutex)) != 0) {
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to lock mutex\n");
+    return -1;
+  }
 
-	int len = nfapi_nr_p7_message_pack(header, pnf_p7->tx_message_buffer, sizeof(pnf_p7->tx_message_buffer), &pnf_p7->_public.codec_config);
+  int len =
+      nfapi_nr_p7_message_pack(header, pnf_p7->tx_message_buffer, sizeof(pnf_p7->tx_message_buffer), &pnf_p7->_public.codec_config);
 
-	if (len < 0)
-	{
-		if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
-			return -1;
-		}
-		
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p7_message_pack failed with return %d\n", len );
-		return -1;
-	}
+  if (len < 0) {
+    if (pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) {
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+      return -1;
+    }
 
-	if(len > pnf_p7->_public.segment_size)
-	{
-		int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ; 
-		int seg_body_len = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ; 
-		int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); 
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p7_message_pack failed with return %d\n", len);
+    return -1;
+  }
 
-		int segment = 0;
-		int offset = NFAPI_P7_HEADER_LENGTH;
-		uint8_t buffer[pnf_p7->_public.segment_size];
-		for(segment = 0; segment < segment_count; ++segment)
-		{
-			uint8_t last = 0;
-			uint16_t size = pnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH;
-			if(segment + 1 == segment_count)
-			{
-				last = 1;
-				size = (msg_body_len) - (seg_body_len * segment);
-			}
+  if (len > pnf_p7->_public.segment_size) {
+    int msg_body_len = len - NFAPI_NR_P7_HEADER_LENGTH;
+    int seg_body_len = pnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH;
+    int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0);
 
-			uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH;
+    int segment = 0;
+    int offset = NFAPI_NR_P7_HEADER_LENGTH;
+    uint8_t buffer[pnf_p7->_public.segment_size];
+    for (segment = 0; segment < segment_count; ++segment) {
+      uint8_t last = 0;
+      uint16_t size = pnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH;
+      if (segment + 1 == segment_count) {
+        last = 1;
+        size = (msg_body_len) - (seg_body_len * segment);
+      }
 
-			// Update the header with the m and segement 
-			memcpy(&buffer[0], pnf_p7->tx_message_buffer, NFAPI_P7_HEADER_LENGTH);
+      uint16_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH;
 
-			// set the segment length
-			buffer[4] = (segment_size & 0xFF00) >> 8;
-			buffer[5] = (segment_size & 0xFF);
+      // Update the header with the m and segement
+      memcpy(&buffer[0], pnf_p7->tx_message_buffer, NFAPI_NR_P7_HEADER_LENGTH);
 
-			// set the m & segment number
-			buffer[6] = ((!last) << 7) + segment;
+      // set the segment length
+      buffer[6] = (segment_size & 0xFF00) >> 8;
+      buffer[7] = (segment_size & 0xFF);
 
-			memcpy(&buffer[NFAPI_P7_HEADER_LENGTH], pnf_p7->tx_message_buffer + offset, size);
-			offset += size;
+      // set the m & segment number
+      buffer[8] = ((!last) << 7) + segment;
 
-			if(pnf_p7->_public.checksum_enabled)
-			{
-				nfapi_p7_update_checksum(buffer, segment_size);
-			}
+      memcpy(&buffer[NFAPI_NR_P7_HEADER_LENGTH], pnf_p7->tx_message_buffer + offset, size);
+      offset += size;
 
+      if (pnf_p7->_public.checksum_enabled) {
+        nfapi_nr_p7_update_checksum(buffer, segment_size);
+      }
 
-			pnf_p7_send_message(pnf_p7, &buffer[0], segment_size);
-		}
-	}
-	else
-	{
-		if(pnf_p7->_public.checksum_enabled)
-		{
-			nfapi_p7_update_checksum(pnf_p7->tx_message_buffer, len);
-		}
+      pnf_p7_send_message(pnf_p7, &buffer[0], segment_size);
+    }
+  } else {
+    if (pnf_p7->_public.checksum_enabled) {
+      nfapi_nr_p7_update_checksum(pnf_p7->tx_message_buffer, len);
+    }
 
-		// simple case that the message fits in a single segment
-		pnf_p7_send_message(pnf_p7, pnf_p7->tx_message_buffer, len);
-	}
+    // simple case that the message fits in a single segment
+    pnf_p7_send_message(pnf_p7, pnf_p7->tx_message_buffer, len);
+  }
 
-	pnf_p7->sequence_number++;
-	
-	if(pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
-		return -1;
-	}
+  pnf_p7->sequence_number++;
 
-	return 0;
+  if (pthread_mutex_unlock(&(pnf_p7->pack_mutex)) != 0) {
+    NFAPI_TRACE(NFAPI_TRACE_INFO, "failed to unlock mutex\n");
+    return -1;
+  }
+
+  return 0;
 }
 
 void pnf_pack_and_send_timing_info(pnf_p7_t* pnf_p7)
@@ -2607,62 +2595,52 @@ void pnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,
 	}
 }
 
-void pnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,  uint32_t rx_hr_time)
+void pnf_nr_dispatch_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
 {
-	nfapi_p7_message_header_t header;
+  nfapi_nr_p7_message_header_t header;
 
-	// validate the input params
-	if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
-		return;
-	}
+  // validate the input params
+  if (pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
+    return;
+  }
 
-	// unpack the message header
-	if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &pnf_p7->_public.codec_config) < 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
-		return;
-	}
+  // unpack the message header
+  if (nfapi_nr_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &pnf_p7->_public.codec_config) < 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+    return;
+  }
 
-	// ensure the message is sensible
-	if (recvMsgLen < 8 || pRecvMsg == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
-		return;
-	}
+  // ensure the message is sensible
+  if (recvMsgLen < 8 || pRecvMsg == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
+    return;
+  }
 
-	switch (header.message_id)
-	{
-		case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
-			pnf_nr_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
-			pnf_handle_dl_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
-			pnf_handle_ul_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
-			pnf_handle_ul_dci_request(pRecvMsg, recvMsgLen, pnf_p7);
-			break;
-		case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
-			pnf_handle_tx_data_request(pRecvMsg, recvMsgLen, pnf_p7);
-			break;
-		default:
-			{
-				if(header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN &&
-				   header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX)
-				{
-					pnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, pnf_p7, header.message_id);
-				}
-				else
-				{
-					NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P7 Unknown message ID %d\n", __FUNCTION__, header.message_id);
-				}
-			}
-			break;
-	}
+  switch (header.message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
+      pnf_nr_handle_dl_node_sync(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
+      pnf_handle_dl_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
+      pnf_handle_ul_tti_request(pRecvMsg, recvMsgLen, pnf_p7);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
+      pnf_handle_ul_dci_request(pRecvMsg, recvMsgLen, pnf_p7);
+      break;
+    case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
+      pnf_handle_tx_data_request(pRecvMsg, recvMsgLen, pnf_p7);
+      break;
+    default: {
+      if (header.message_id >= NFAPI_VENDOR_EXT_MSG_MIN && header.message_id <= NFAPI_VENDOR_EXT_MSG_MAX) {
+        pnf_handle_p7_vendor_extension(pRecvMsg, recvMsgLen, pnf_p7, header.message_id);
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s P7 Unknown message ID %d\n", __FUNCTION__, header.message_id);
+      }
+    } break;
+  }
 }
 
 void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,  uint32_t rx_hr_time)
@@ -2771,110 +2749,104 @@ void pnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,  ui
 	
 }
 
-void pnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7,  uint32_t rx_hr_time)
+void pnf_nr_handle_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, uint32_t rx_hr_time)
 {
-	nfapi_p7_message_header_t messageHeader;
-
-	// validate the input params
-	if(pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, pnf_p7);
-		return;
-	}
-
-	// unpack the message header
-	if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &pnf_p7->_public.codec_config) < 0)
-	{
-		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
-		return;
-	}
-
-	uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence);
-	uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence);
-	uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence);
+  nfapi_nr_p7_message_header_t messageHeader;
 
-	if(pnf_p7->_public.checksum_enabled)
-	{
-		uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen);
-		if(checksum != messageHeader.checksum)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d\n", checksum, messageHeader.checksum);
-			return;
-		}
-	}
+  // validate the input params
+  if (pRecvMsg == NULL || recvMsgLen < 4 || pnf_p7 == NULL) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "pnf_handle_p7_message: invalid input params (%p %d %p)\n", pRecvMsg, recvMsgLen, pnf_p7);
+    return;
+  }
 
-	if(m == 0 && segment_num == 0)
-	{
-		// we have a complete message
-		// ensure the message is sensible
-		if (recvMsgLen < 8 || pRecvMsg == NULL)
-		{
-			NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
-			return;
-		}
+  // unpack the message header
+  if (nfapi_nr_p7_message_header_unpack(pRecvMsg,
+                                        recvMsgLen,
+                                        &messageHeader,
+                                        sizeof(nfapi_nr_p7_message_header_t),
+                                        &pnf_p7->_public.codec_config)
+      < 0) {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
+    return;
+  }
 
-		pnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
-	}
-	else
-	{
-		pnf_p7_rx_message_t* rx_msg = pnf_p7_rx_reassembly_queue_add_segment(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, sequence_num, segment_num, m, pRecvMsg, recvMsgLen);
+  uint8_t m = NFAPI_P7_GET_MORE(messageHeader.m_segment_sequence);
+  uint8_t sequence_num = NFAPI_P7_GET_SEQUENCE(messageHeader.m_segment_sequence);
+  uint8_t segment_num = NFAPI_P7_GET_SEGMENT(messageHeader.m_segment_sequence);
 
-		if(rx_msg->num_segments_received == rx_msg->num_segments_expected)
-		{
-			// send the buffer on
-			uint16_t i = 0;
-			uint16_t length = 0;
-			for(i = 0; i < rx_msg->num_segments_expected; ++i)
-			{
-				length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0);
-			}
-			
-			if(pnf_p7->reassemby_buffer_size < length)
-			{
-				pnf_p7_free(pnf_p7, pnf_p7->reassemby_buffer);
-				pnf_p7->reassemby_buffer = 0;
-			}
-
-			if(pnf_p7->reassemby_buffer == 0)
-			{
-				NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing PNF_P7 Reassembly buffer %d->%d\n", pnf_p7->reassemby_buffer_size, length);
-				pnf_p7->reassemby_buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, length);
+  if (pnf_p7->_public.checksum_enabled) {
+    uint32_t checksum = nfapi_nr_p7_calculate_checksum(pRecvMsg, recvMsgLen);
+    if (checksum != messageHeader.checksum) {
+      NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d\n", checksum, messageHeader.checksum);
+      return;
+    }
+  }
 
-				if(pnf_p7->reassemby_buffer == 0)
-				{
-					NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length);
-					return;
-				}
-                                memset(pnf_p7->reassemby_buffer, 0, length);
-				pnf_p7->reassemby_buffer_size = length;
-			}
-			
-			uint16_t offset = 0;
-			for(i = 0; i < rx_msg->num_segments_expected; ++i)
-			{
-				if(i == 0)
-				{
-					memcpy(pnf_p7->reassemby_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length);
-					offset += rx_msg->segments[i].length;
-				}
-				else
-				{
-					memcpy(pnf_p7->reassemby_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH);
-					offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH;
-				}
-			}
+  if (m == 0 && segment_num == 0) {
+    // we have a complete message
+    // ensure the message is sensible
+    if (recvMsgLen < 8 || pRecvMsg == NULL) {
+      NFAPI_TRACE(NFAPI_TRACE_WARN, "Invalid message size: %d, ignoring\n", recvMsgLen);
+      return;
+    }
 
-			
-			pnf_nr_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time);
+    pnf_nr_dispatch_p7_message(pRecvMsg, recvMsgLen, pnf_p7, rx_hr_time);
+  } else {
+    pnf_p7_rx_message_t* rx_msg = pnf_p7_rx_reassembly_queue_add_segment(pnf_p7,
+                                                                         &(pnf_p7->reassembly_queue),
+                                                                         rx_hr_time,
+                                                                         sequence_num,
+                                                                         segment_num,
+                                                                         m,
+                                                                         pRecvMsg,
+                                                                         recvMsgLen);
+
+    if (rx_msg->num_segments_received == rx_msg->num_segments_expected) {
+      // send the buffer on
+      uint16_t i = 0;
+      uint16_t length = 0;
+      for (i = 0; i < rx_msg->num_segments_expected; ++i) {
+        length += rx_msg->segments[i].length - (i > 0 ? NFAPI_NR_P7_HEADER_LENGTH : 0);
+      }
+
+      if (pnf_p7->reassemby_buffer_size < length) {
+        pnf_p7_free(pnf_p7, pnf_p7->reassemby_buffer);
+        pnf_p7->reassemby_buffer = 0;
+      }
+
+      if (pnf_p7->reassemby_buffer == 0) {
+        NFAPI_TRACE(NFAPI_TRACE_NOTE, "Resizing PNF_P7 Reassembly buffer %d->%d\n", pnf_p7->reassemby_buffer_size, length);
+        pnf_p7->reassemby_buffer = (uint8_t*)pnf_p7_malloc(pnf_p7, length);
+
+        if (pnf_p7->reassemby_buffer == 0) {
+          NFAPI_TRACE(NFAPI_TRACE_NOTE, "Failed to allocate PNF_P7 reassemby buffer len:%d\n", length);
+          return;
+        }
+        memset(pnf_p7->reassemby_buffer, 0, length);
+        pnf_p7->reassemby_buffer_size = length;
+      }
+
+      uint16_t offset = 0;
+      for (i = 0; i < rx_msg->num_segments_expected; ++i) {
+        if (i == 0) {
+          memcpy(pnf_p7->reassemby_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length);
+          offset += rx_msg->segments[i].length;
+        } else {
+          memcpy(pnf_p7->reassemby_buffer + offset,
+                 rx_msg->segments[i].buffer + NFAPI_NR_P7_HEADER_LENGTH,
+                 rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH);
+          offset += rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH;
+        }
+      }
 
+      pnf_nr_dispatch_p7_message(pnf_p7->reassemby_buffer, length, pnf_p7, rx_msg->rx_hr_time);
 
-			// delete the structure
-			pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7, &(pnf_p7->reassembly_queue), rx_msg);
-		}
-	}
+      // delete the structure
+      pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7, &(pnf_p7->reassembly_queue), rx_msg);
+    }
+  }
 
-	pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 1000);
-	
+  pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7, &(pnf_p7->reassembly_queue), rx_hr_time, 1000);
 }
 
 
@@ -2949,63 +2921,63 @@ void pnf_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
 
 void pnf_nr_nfapi_p7_read_dispatch_message(pnf_p7_t* pnf_p7, uint32_t now_hr_time)
 {
-	int recvfrom_result = 0;
-	struct sockaddr_in remote_addr;
-	socklen_t remote_addr_size = sizeof(remote_addr);
-	remote_addr.sin_family = 2; //hardcoded
-	do
-	{
-		// peek the header
-		uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH];
-		recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
-		if(recvfrom_result > 0)
-		{
-			// get the segment size
-			nfapi_p7_message_header_t header;
-			nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, 34, 0);
-
-			// resize the buffer if we have a large segment
-			if(header.message_length > pnf_p7->rx_message_buffer_size)
-			{
-				NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length); 
-				pnf_p7->rx_message_buffer = realloc(pnf_p7->rx_message_buffer, header.message_length);
-				pnf_p7->rx_message_buffer_size = header.message_length;
-			}
-
-			// read the segment
-			recvfrom_result = recvfrom(pnf_p7->p7_sock, pnf_p7->rx_message_buffer, header.message_length, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size);
-
-		now_hr_time = pnf_get_current_time_hr(); //moved to here - get closer timestamp???
-
-			if(recvfrom_result > 0)
-			{
-				pnf_nr_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time);
-				//printf("\npnf_handle_p7_message sfn=%d,slot=%d\n",pnf_p7->sfn,pnf_p7->slot);
-			}
-		}
-		else if(recvfrom_result == 0)
-		{
-			// recv zero length message
-			recvfrom_result = recvfrom(pnf_p7->p7_sock, header_buffer, 0, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size);
-		}
+  int recvfrom_result = 0;
+  struct sockaddr_in remote_addr;
+  socklen_t remote_addr_size = sizeof(remote_addr);
+  remote_addr.sin_family = 2; // hardcoded
+  do {
+    // peek the header
+    uint8_t header_buffer[NFAPI_NR_P7_HEADER_LENGTH];
+    recvfrom_result = recvfrom(pnf_p7->p7_sock,
+                               header_buffer,
+                               NFAPI_NR_P7_HEADER_LENGTH,
+                               MSG_DONTWAIT | MSG_PEEK,
+                               (struct sockaddr*)&remote_addr,
+                               &remote_addr_size);
+    if (recvfrom_result > 0) {
+      // get the segment size
+      nfapi_nr_p7_message_header_t header;
+      nfapi_nr_p7_message_header_unpack(header_buffer, NFAPI_NR_P7_HEADER_LENGTH, &header, 34, 0);
+
+      // resize the buffer if we have a large segment
+      if (header.message_length > pnf_p7->rx_message_buffer_size) {
+        NFAPI_TRACE(NFAPI_TRACE_NOTE, "reallocing rx buffer %d\n", header.message_length);
+        pnf_p7->rx_message_buffer = realloc(pnf_p7->rx_message_buffer, header.message_length);
+        pnf_p7->rx_message_buffer_size = header.message_length;
+      }
+
+      // read the segment
+      recvfrom_result = recvfrom(pnf_p7->p7_sock,
+                                 pnf_p7->rx_message_buffer,
+                                 header.message_length,
+                                 MSG_DONTWAIT,
+                                 (struct sockaddr*)&remote_addr,
+                                 &remote_addr_size);
+
+      now_hr_time = pnf_get_current_time_hr(); // moved to here - get closer timestamp???
+
+      if (recvfrom_result > 0) {
+        pnf_nr_handle_p7_message(pnf_p7->rx_message_buffer, recvfrom_result, pnf_p7, now_hr_time);
+        // printf("\npnf_handle_p7_message sfn=%d,slot=%d\n",pnf_p7->sfn,pnf_p7->slot);
+      }
+    } else if (recvfrom_result == 0) {
+      // recv zero length message
+      recvfrom_result =
+          recvfrom(pnf_p7->p7_sock, header_buffer, 0, MSG_DONTWAIT, (struct sockaddr*)&remote_addr, &remote_addr_size);
+    }
 
-		if(recvfrom_result == -1)
-		{
-			if(errno == EAGAIN || errno == EWOULDBLOCK)
-			{
-				// return to the select
-				//NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno);
-			}
-			else
-			{
-				NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno);
-			}
-		}
+    if (recvfrom_result == -1) {
+      if (errno == EAGAIN || errno == EWOULDBLOCK) {
+        // return to the select
+        // NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom would block :%d\n", __FUNCTION__, errno);
+      } else {
+        NFAPI_TRACE(NFAPI_TRACE_WARN, "%s recvfrom failed errno:%d\n", __FUNCTION__, errno);
+      }
+    }
 
-		// need to update the time as we would only use the value from the
-		// select
-	}
-	while(recvfrom_result > 0);
+    // need to update the time as we would only use the value from the
+    // select
+  } while (recvfrom_result > 0);
 }
 
 
diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
index dd91d2fc71f00b940d0c11b75813b7c6b7bf88c8..9b78d80fd39072fee03d7292d81f07569077bfaa 100644
--- a/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
+++ b/nfapi/open-nFAPI/pnf/src/pnf_p7_interface.c
@@ -259,7 +259,7 @@ int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indica
   }
 
   pnf_p7_t* _this = (pnf_p7_t*)(config);
-  return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_slot_indication_scf_t));
+  return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_slot_indication_scf_t));
 }
 
 int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind)
@@ -271,7 +271,7 @@ int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_
 	}
 
 	pnf_p7_t* _this = (pnf_p7_t*)(config);
-	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
+	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
 }
 
 int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind)
@@ -283,7 +283,7 @@ int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indicati
 	}
 
 	pnf_p7_t* _this = (pnf_p7_t*)(config);
-	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
+	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
 }
 
 int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind)
@@ -295,7 +295,7 @@ int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indicati
 	}
 
 	pnf_p7_t* _this = (pnf_p7_t*)(config);
-	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
+	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
 }
 
 int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind)
@@ -307,7 +307,7 @@ int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indicati
 	}
 
 	pnf_p7_t* _this = (pnf_p7_t*)(config);
-	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
+	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
 }
 
 int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind)
@@ -319,5 +319,5 @@ int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indica
 	}
 
 	pnf_p7_t* _this = (pnf_p7_t*)(config);
-	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
+	return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
 }
diff --git a/nfapi/open-nFAPI/vnf/inc/vnf.h b/nfapi/open-nFAPI/vnf/inc/vnf.h
index b16b842606dab220fc4c63e8c1f1786b2a4b491b..26870f5523928e269ade84fcbc1497f731d0bfaf 100644
--- a/nfapi/open-nFAPI/vnf/inc/vnf.h
+++ b/nfapi/open-nFAPI/vnf/inc/vnf.h
@@ -35,7 +35,7 @@ typedef struct
 
 
 int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
-int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
+int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t* msg, uint16_t msg_len);
 
 int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
 
diff --git a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h
index 4fcc99f79b7bf27f6f817557932ee0834d0bb38b..31512124acd9a86fa939feb7f87a05e49919d070 100644
--- a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h
+++ b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h
@@ -137,7 +137,7 @@ nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p
 nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id);
 
 int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
-int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
+int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_t* header);
 
 void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
 void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu);
diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
index decb48e5c8334482029cc3c05a57f34d8c1ca4f2..30d1edfe320919ab1b50a144f35f2c0cd926f696 100644
--- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
+++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
@@ -30,7 +30,7 @@
 extern "C" {
 #endif
 
-#define NFAPI_MAX_PACKED_MESSAGE_SIZE 8192
+#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
 
 /*! The nfapi VNF phy configuration information
  */
@@ -434,7 +434,7 @@ typedef struct nfapi_vnf_config
 	 *  \param resp A data structure for the decoded vendor extention message 
 	 *  \return not currently used.	
 	 */
-	int (*vendor_ext)(nfapi_vnf_config_t* config, int p5_idx, nfapi_p4_p5_message_header_t* msg);
+	int (*vendor_ext)(nfapi_vnf_config_t* config, int p5_idx, void* msg);
 
 	/*! A callback to allocate vendor extension messages
 	 *  \param message_id The message is taken from the message header
@@ -442,12 +442,12 @@ typedef struct nfapi_vnf_config
 	 *					The callee must set this value
 	 *	\return A pointer to an allocated vendor extention message
 	 */
-	nfapi_p4_p5_message_header_t* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
+	void* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
 	
 	/*! A callback to deallocate vendor extension messages
 	 *  \param header A pointer to an allocated vendor extention message
 	 */
-	void (*deallocate_p4_p5_vendor_ext)(nfapi_p4_p5_message_header_t* header);
+	void (*deallocate_p4_p5_vendor_ext)(void* header);
 
 
 
@@ -860,7 +860,7 @@ typedef struct nfapi_vnf_p7_config
 	 *			   using the allocate_p7_vendor_ext callback
 	 *  \return not currently used.
 	 */	
-	int (*vendor_ext)(struct nfapi_vnf_p7_config* config, nfapi_p7_message_header_t* msg);
+	int (*vendor_ext)(struct nfapi_vnf_p7_config* config, void* msg);
 
 	/*! Optional userdata that will be passed back in the callbacks*/
 	void* user_data;
@@ -871,12 +871,12 @@ typedef struct nfapi_vnf_p7_config
 	 *					The callee must set this value
 	 *	\return A pointer to an allocated vendor extention message
 	 */
-	nfapi_p7_message_header_t* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
+	void* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
 	
 	/*! A callback to deallocate a vendor extension message
 	 *  \param header A pointer to an allocated vendor extention message
 	 */
-	void (*deallocate_p7_vendor_ext)(nfapi_p7_message_header_t* header);
+	void (*deallocate_p7_vendor_ext)(void* header);
 
 
 } nfapi_vnf_p7_config_t;
diff --git a/nfapi/open-nFAPI/vnf/src/vnf.c b/nfapi/open-nFAPI/vnf/src/vnf.c
index 631ce2b7e9fb36542418d40ea8f1de675696ac94..cf8a945264c9ed89a75a2d9ef4c6f4323d45fc0f 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf.c
@@ -30,7 +30,7 @@
 #ifdef ENABLE_AERIAL
 #include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
 #include "nfapi/oai_integration/aerial/fapi_vnf_p5.h"
-#include "nr_fapi.h"
+#include "nr_fapi_p5.h"
 #endif
 #include "nfapi/oai_integration/vendor_ext.h"
 
@@ -1063,7 +1063,7 @@ void vnf_handle_vendor_extension(void* pRecvMsg, int recvMsgLen, nfapi_vnf_confi
 
 void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfapi_vnf_config_t* config)
 {
-	nfapi_p4_p5_message_header_t messageHeader;
+	nfapi_nr_p4_p5_message_header_t messageHeader;
 
 	// validate the input params
 	if(pRecvMsg == NULL || recvMsgLen < NFAPI_HEADER_LENGTH || config == NULL)
@@ -1073,7 +1073,7 @@ void vnf_nr_handle_p4_p5_message(void *pRecvMsg, int recvMsgLen, int p5_idx, nfa
 	}
 
 	// unpack the message header
-	if (nfapi_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p4_p5_message_header_t), &config->codec_config) < 0)
+	if (nfapi_nr_p5_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_nr_p4_p5_message_header_t), &config->codec_config) < 0)
 	{
 		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
 		return;
@@ -1255,7 +1255,7 @@ int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_
       // 3. Read the buffer
       // 4. Handle the p5 message
 
-      uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+      uint32_t header_buffer_size = NFAPI_NR_P5_HEADER_LENGTH;
       uint8_t header_buffer[header_buffer_size];
 
       uint32_t stack_buffer_size = 32; // should it be the size of then sctp_notificatoin structure
@@ -1282,8 +1282,8 @@ int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_
           return 0;
         }
 
-        nfapi_p4_p5_message_header_t header;
-        int unpack_result = nfapi_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
+        nfapi_nr_p4_p5_message_header_t header;
+        int unpack_result = nfapi_nr_p5_message_header_unpack(header_buffer, header_buffer_size, &header, sizeof(header), 0);
         if (unpack_result < 0) {
           NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF Failed to decode message header %d\n", unpack_result);
           return 0;
@@ -1518,7 +1518,7 @@ static int vnf_send_p5_msg(nfapi_vnf_pnf_info_t* pnf, const void *msg, int len,
 	return 0;
 }
 
-int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len)
+int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t* msg, uint16_t msg_len)
 {
 	nfapi_vnf_pnf_info_t* pnf = nfapi_vnf_pnf_list_find(&(vnf->_public), p5_idx);
 	
@@ -1547,7 +1547,7 @@ int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_mes
                                                      &vnf->_public.codec_config);
 
       if (packedMessageLength < 0) {
-        NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p5_message_pack failed with return %d\n", packedMessageLength);
+        NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_nr_p5_message_pack failed with return %d\n", packedMessageLength);
         return -1;
       }
       // printf("msg id = 0x%02x, entire message length: %d\n", msg->message_id, packedMessageLength);
diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
index 28c7b71656f1f444a4ff4669a4ca74d7f34055fd..a30efaf47f75af05113dc713a60de7aeafc468c8 100644
--- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c
+++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
@@ -29,6 +29,7 @@
 #include "nfapi/oai_integration/aerial/fapi_nvIPC.h"
 #endif
 #include "vnf_p7.h"
+#include "nr_fapi_p7_utils.h"
 
 #ifdef NDEBUG
 #  warning assert is disabled
@@ -474,14 +475,14 @@ int vnf_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info, u
 	return 0;
 }
 
-int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header)
+int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_t* header)
 {
 
 	nfapi_vnf_p7_connection_info_t* p7_connection = vnf_p7_connection_info_list_find(vnf_p7, header->phy_id);
 	if(p7_connection)
 	{
 		int send_result = 0;
-		uint8_t  buffer[1024 * 32];
+		uint8_t  buffer[1024*1024*3];
 
 		header->m_segment_sequence = NFAPI_P7_SET_MSS(0, 0, p7_connection->sequence_number);
 		
@@ -501,45 +502,45 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t*
 			// todo : worry about blocking writes?
 		
 			// segmenting the transmit
-			int msg_body_len = len - NFAPI_P7_HEADER_LENGTH ; 
-			int seg_body_len = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH ; 
+			int msg_body_len = len - NFAPI_NR_P7_HEADER_LENGTH ;
+			int seg_body_len = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH ;
 			int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); 
 				
 			int segment = 0;
-			int offset = NFAPI_P7_HEADER_LENGTH;
+			int offset = NFAPI_NR_P7_HEADER_LENGTH;
 			uint8_t tx_buffer[vnf_p7->_public.segment_size];
                         NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() MORE THAN ONE SEGMENT phy_id:%d nfapi_p7_message_pack()=len=%d vnf_p7->_public.segment_size:%u\n", __FUNCTION__, header->phy_id, len, vnf_p7->_public.segment_size);
 			for(segment = 0; segment < segment_count; ++segment)
 			{
 				uint8_t last = 0;
-				uint16_t size = vnf_p7->_public.segment_size - NFAPI_P7_HEADER_LENGTH;
+				uint16_t size = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH;
 				if(segment + 1 == segment_count)
 				{
 					last = 1;
 					size = (msg_body_len) - (seg_body_len * segment);
 				}
 
-				uint16_t segment_size = size + NFAPI_P7_HEADER_LENGTH;
+				uint16_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH;
 
 				// Update the header with the m and segement 
-				memcpy(&tx_buffer[0], buffer, NFAPI_P7_HEADER_LENGTH);
+				memcpy(&tx_buffer[0], buffer, NFAPI_NR_P7_HEADER_LENGTH);
 
 				// set the segment length
-				tx_buffer[4] = (segment_size & 0xFF00) >> 8;
-				tx_buffer[5] = (segment_size & 0xFF);
+				tx_buffer[6] = (segment_size & 0xFF00) >> 8;
+				tx_buffer[7] = (segment_size & 0xFF);
 
 				// set the m & segment number
-				tx_buffer[6] = ((!last) << 7) + segment;
+				tx_buffer[8] = ((!last) << 7) + segment;
 
-				memcpy(&tx_buffer[NFAPI_P7_HEADER_LENGTH], &buffer[0] + offset, size);
+				memcpy(&tx_buffer[NFAPI_NR_P7_HEADER_LENGTH], &buffer[0] + offset, size);
 				offset += size;
 
 				if(vnf_p7->_public.checksum_enabled)
 				{
-					nfapi_p7_update_checksum(tx_buffer, segment_size);
+					nfapi_nr_p7_update_checksum(tx_buffer, segment_size);
 				}
 			
-				nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));	
+				nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
 
 				send_result = vnf_send_p7_msg(vnf_p7, p7_connection,  &tx_buffer[0], segment_size);
 
@@ -549,10 +550,10 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t*
 		{
 			if(vnf_p7->_public.checksum_enabled)
 			{
-				nfapi_p7_update_checksum(buffer, len);
+				nfapi_nr_p7_update_checksum(buffer, len);
 			}
 
-			nfapi_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));	
+			nfapi_nr_p7_update_transmit_timestamp(buffer, calculate_transmit_timestamp(p7_connection->sfn, p7_connection->slot, vnf_p7->slot_start_time_hr));
 
 			// simple case that the message fits in a single segement
 			send_result = vnf_send_p7_msg(vnf_p7, p7_connection, &buffer[0], len);
@@ -1084,6 +1085,37 @@ void vnf_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vn
 }
 
 
+void vnf_nr_handle_p7_vendor_extension(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7, uint16_t message_id)
+{
+  if (pRecvMsg == NULL || vnf_p7 == NULL)
+  {
+    NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
+  }
+  else if(vnf_p7->_public.allocate_p7_vendor_ext)
+  {
+    uint16_t msg_size;
+    nfapi_nr_p7_message_header_t* msg = vnf_p7->_public.allocate_p7_vendor_ext(message_id, &msg_size);
+
+    if(msg == 0)
+    {
+      NFAPI_TRACE(NFAPI_TRACE_INFO, "%s failed to allocate vendor extention structure\n", __FUNCTION__);
+      return;
+    }
+
+    int unpack_result = nfapi_nr_p7_message_unpack(pRecvMsg, recvMsgLen, msg, msg_size, &vnf_p7->_public.codec_config);
+
+    if(unpack_result == 0)
+    {
+      if(vnf_p7->_public.vendor_ext)
+        vnf_p7->_public.vendor_ext(&(vnf_p7->_public), msg);
+    }
+
+    if(vnf_p7->_public.deallocate_p7_vendor_ext)
+      vnf_p7->_public.deallocate_p7_vendor_ext(msg);
+
+  }
+}
+
 void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 {
 	uint32_t now_time_hr = vnf_get_current_time_hr();
@@ -1480,6 +1512,7 @@ void vnf_handle_nr_slot_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
 			{
 				(vnf_p7->_public.nr_slot_indication)(&ind);
 			}
+      free_slot_indication(&ind);
 		}
 
 	}
@@ -1506,6 +1539,7 @@ void vnf_handle_nr_rx_data_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t*
 			{
 				(vnf_p7->_public.nr_rx_data_indication)(&ind);
 			}
+      free_rx_data_indication(&ind);
 		}
 	}
 }
@@ -1532,6 +1566,7 @@ void vnf_handle_nr_crc_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
 			{
 				(vnf_p7->_public.nr_crc_indication)(&ind);
 			}
+      free_crc_indication(&ind);
 		}
 	}
 }
@@ -1557,6 +1592,7 @@ void vnf_handle_nr_srs_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
 			{
 				(vnf_p7->_public.nr_srs_indication)(&ind);
 			}
+      free_srs_indication(&ind);
 		}
 	}
 }
@@ -1583,6 +1619,7 @@ void vnf_handle_nr_uci_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_
 			{
 				(vnf_p7->_public.nr_uci_indication)(&ind);
 			}
+      free_uci_indication(&ind);
 		}
 	}
 }
@@ -1609,6 +1646,7 @@ void vnf_handle_nr_rach_indication(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf
 			{
 				(vnf_p7->_public.nr_rach_indication)(&ind);
 			}
+      free_rach_indication(&ind);
 		}
 	}
 }
@@ -2166,7 +2204,7 @@ void vnf_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 
 void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 {
-	nfapi_p7_message_header_t header;
+	nfapi_nr_p7_message_header_t header;
 
 	// validate the input params
 	if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL)
@@ -2176,7 +2214,7 @@ void vnf_nr_dispatch_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7
 	}
 
 	// unpack the message header
-	if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &vnf_p7->_public.codec_config) < 0)
+	if (nfapi_nr_p7_message_header_unpack(pRecvMsg, recvMsgLen, &header, sizeof(header), &vnf_p7->_public.codec_config) < 0)
 	{
 		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
 		return;
@@ -2363,7 +2401,7 @@ void vnf_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 
 void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) 
 {
-	nfapi_p7_message_header_t messageHeader;
+	nfapi_nr_p7_message_header_t messageHeader;
 
 	// validate the input params
 	if(pRecvMsg == NULL || recvMsgLen < 4 || vnf_p7 == NULL)
@@ -2373,7 +2411,7 @@ void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 	}
 
 	// unpack the message header
-	if (nfapi_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_p7_message_header_t), &vnf_p7->_public.codec_config) < 0)
+	if (nfapi_nr_p7_message_header_unpack(pRecvMsg, recvMsgLen, &messageHeader, sizeof(nfapi_nr_p7_message_header_t), &vnf_p7->_public.codec_config) < 0)
 	{
 		NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
 		return;
@@ -2381,7 +2419,7 @@ void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 
 	if(vnf_p7->_public.checksum_enabled)
 	{
-		uint32_t checksum = nfapi_p7_calculate_checksum(pRecvMsg, recvMsgLen);
+		uint32_t checksum = nfapi_nr_p7_calculate_checksum(pRecvMsg, recvMsgLen);
 		if(checksum != messageHeader.checksum)
 		{
 			NFAPI_TRACE(NFAPI_TRACE_ERROR, "Checksum verification failed %d %d msg:%d len:%d\n", checksum, messageHeader.checksum, messageHeader.message_id, recvMsgLen);
@@ -2422,7 +2460,7 @@ void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 				uint16_t length = 0;
 				for(i = 0; i < rx_msg->num_segments_expected; ++i)
 				{
-					length += rx_msg->segments[i].length - (i > 0 ? NFAPI_P7_HEADER_LENGTH : 0);
+					length += rx_msg->segments[i].length - (i > 0 ? NFAPI_NR_P7_HEADER_LENGTH : 0);
 				}
 
 				if(phy->reassembly_buffer_size < length)
@@ -2455,8 +2493,8 @@ void vnf_nr_handle_p7_message(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7)
 					}
 					else
 					{
-						memcpy(phy->reassembly_buffer + offset, rx_msg->segments[i].buffer + NFAPI_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH);
-						offset += rx_msg->segments[i].length - NFAPI_P7_HEADER_LENGTH;
+						memcpy(phy->reassembly_buffer + offset, rx_msg->segments[i].buffer + NFAPI_NR_P7_HEADER_LENGTH, rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH);
+						offset += rx_msg->segments[i].length - NFAPI_NR_P7_HEADER_LENGTH;
 					}
 				}
 
@@ -2488,14 +2526,14 @@ int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7)
 	do
 	{
 		// peek the header
-		uint8_t header_buffer[NFAPI_P7_HEADER_LENGTH];
-		recvfrom_result = recvfrom(vnf_p7->socket, header_buffer, NFAPI_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
+		uint8_t header_buffer[NFAPI_NR_P7_HEADER_LENGTH];
+		recvfrom_result = recvfrom(vnf_p7->socket, header_buffer, NFAPI_NR_P7_HEADER_LENGTH, MSG_DONTWAIT | MSG_PEEK, (struct sockaddr*)&remote_addr, &remote_addr_size);
 
 		if(recvfrom_result > 0)
 		{
 			// get the segment size
-			nfapi_p7_message_header_t header;
-			if(nfapi_p7_message_header_unpack(header_buffer, NFAPI_P7_HEADER_LENGTH, &header, sizeof(header), 0) < 0)
+			nfapi_nr_p7_message_header_t header;
+			if(nfapi_nr_p7_message_header_unpack(header_buffer, NFAPI_NR_P7_HEADER_LENGTH, &header, sizeof(header), 0) < 0)
 			{
 				NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unpack message header failed, ignoring\n");
 				return -1;
diff --git a/nfapi/tests/nr_fapi_test.h b/nfapi/tests/nr_fapi_test.h
index 3c4c67a542b7b613cb96320188dfcd8b45600c10..647cdf94f2963a9a91df429e19e11187c9abf33e 100644
--- a/nfapi/tests/nr_fapi_test.h
+++ b/nfapi/tests/nr_fapi_test.h
@@ -81,6 +81,16 @@ uint16_t rand16_range(uint16_t lower, uint16_t upper)
   return (rand() % (upper - lower + 1)) + lower;
 }
 
+int16_t rands16_range(int16_t lower, int16_t upper)
+{
+  return (rand() % (upper - lower + 1)) + lower;
+}
+
+uint32_t rand32_range(uint32_t lower, uint32_t upper)
+{
+  return (rand() % (upper - lower + 1)) + lower;
+}
+
 int main(int n, char *v[]);
 
 static inline void fapi_test_init_seeded(time_t seed)
diff --git a/nfapi/tests/p5/nr_fapi_config_request_test.c b/nfapi/tests/p5/nr_fapi_config_request_test.c
index 3e098722b235ee879a5b5278999045c187749cd9..f980b3e61ec4081ebebfc8a8dfebb935c6d7c383 100644
--- a/nfapi/tests/p5/nr_fapi_config_request_test.c
+++ b/nfapi/tests/p5/nr_fapi_config_request_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_config_request_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void fill_config_request_tlv(nfapi_nr_config_request_scf_t *nfapi_resp)
@@ -88,8 +79,7 @@ void fill_config_request_tlv(nfapi_nr_config_request_scf_t *nfapi_resp)
   FILL_TLV(nfapi_resp->ssb_config.bch_payload, NFAPI_NR_CONFIG_BCH_PAYLOAD_TAG, rand8());
   nfapi_resp->num_tlv++;
 
-  // NOTE: MUST be between 0 & 4 ( inclusive ) , since this value is used as index to obtain slots per frame
-  FILL_TLV(nfapi_resp->ssb_config.scs_common, NFAPI_NR_CONFIG_SCS_COMMON_TAG, rand8_range(0, 4));
+  FILL_TLV(nfapi_resp->ssb_config.scs_common, NFAPI_NR_CONFIG_SCS_COMMON_TAG, 1 /* 30 kHz */);
   nfapi_resp->num_tlv++;
 
   FILL_TLV(nfapi_resp->prach_config.prach_sequence_length, NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG, rand8());
@@ -185,30 +175,31 @@ void fill_config_request_tlv(nfapi_nr_config_request_scf_t *nfapi_resp)
     nfapi_resp->num_tlv++;
   }
 
-  FILL_TLV(nfapi_resp->tdd_table.tdd_period, NFAPI_NR_CONFIG_TDD_PERIOD_TAG, rand8());
+  FILL_TLV(nfapi_resp->tdd_table.tdd_period, NFAPI_NR_CONFIG_TDD_PERIOD_TAG, 6 /* ms5 */);
   nfapi_resp->num_tlv++;
-  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;
-
-  nfapi_resp->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(
-      slotsperframe[nfapi_resp->ssb_config.scs_common.value] * sizeof(nfapi_nr_max_tdd_periodicity_t));
 
-  for (int i = 0; i < slotsperframe[nfapi_resp->ssb_config.scs_common.value]; i++) {
-    nfapi_resp->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));
+#define SET_SYMBOL_TYPE(TDD_PERIOD_LIST, START, END, TYPE) \
+  for (int SyM = (START); SyM < (END); SyM++) { \
+    FILL_TLV((TDD_PERIOD_LIST)[SyM].slot_config, NFAPI_NR_CONFIG_SLOT_CONFIG_TAG, (TYPE)); \
   }
 
-  for (int i = 0; i < slotsperframe[nfapi_resp->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?
-      FILL_TLV(nfapi_resp->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
-               NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
-               rand8());
-      nfapi_resp->num_tlv++;
+  int slots = 20;
+  int sym = 14;
+  nfapi_resp->tdd_table.max_tdd_periodicity_list = calloc(slots, sizeof(*nfapi_resp->tdd_table.max_tdd_periodicity_list));
+  for (int i = 0; i < slots; i++) {
+    nfapi_nr_max_tdd_periodicity_t* list = &nfapi_resp->tdd_table.max_tdd_periodicity_list[i];
+    list->max_num_of_symbol_per_slot_list = calloc(sym, sizeof(*list->max_num_of_symbol_per_slot_list));
+    // DDDDDDMUUU
+    if ((i >= 0 && i <= 5) || (i >= 10 && i <= 15)) {
+      SET_SYMBOL_TYPE(list->max_num_of_symbol_per_slot_list, 0, sym, 0 /* DL */);
+    } else if (i == 6 || i == 16) {
+      SET_SYMBOL_TYPE(list->max_num_of_symbol_per_slot_list, 0, 4, 0 /* DL */);
+      SET_SYMBOL_TYPE(list->max_num_of_symbol_per_slot_list, 4, 10, 2 /* guard */);
+      SET_SYMBOL_TYPE(list->max_num_of_symbol_per_slot_list, 10, sym, 1 /* UL */);
+    } else {
+      SET_SYMBOL_TYPE(list->max_num_of_symbol_per_slot_list, 0, sym, 1 /* UL */);
     }
+    nfapi_resp->num_tlv += sym;
   }
 
   FILL_TLV(nfapi_resp->measurement_config.rssi_measurement, NFAPI_NR_CONFIG_RSSI_MEASUREMENT_TAG, rand8());
@@ -259,7 +250,7 @@ void test_pack_unpack(nfapi_nr_config_request_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_config_response_test.c b/nfapi/tests/p5/nr_fapi_config_response_test.c
index ae97b93c2ce9cada3be15e3c73ca76f2b848c3c7..bc44b4b6fdeffbc3961b8b4a7c926b4f6c591dfa 100644
--- a/nfapi/tests/p5/nr_fapi_config_response_test.c
+++ b/nfapi/tests/p5/nr_fapi_config_response_test.c
@@ -18,22 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_config_response_test.c
- * \brief Defines a unitary test for the FAPI CONFIG.response message ( 0x03 )
- *        The test consists of filling a message with randomized data, filling each lists as well with random TLVs
- *        After the message is created, is is packed into a byte buffer
- *        After packing, the header is unpacked to mimic SCTP PEEK and the values unpacked checked against the original message
- *        After the header is checked, the whole message is unpacked.
- *        The test ends by checking all of the unpacked message contents against the original message
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void fill_config_response_tlv_list(nfapi_nr_generic_tlv_scf_t *list, uint8_t size)
@@ -106,7 +92,7 @@ void test_pack_unpack(nfapi_nr_config_response_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_error_indication_test.c b/nfapi/tests/p5/nr_fapi_error_indication_test.c
index 97431ca9c3f4289307eeab484bce270c38baa5b8..85ef17b536ad67d17c613a2c346224da597a1027 100644
--- a/nfapi/tests/p5/nr_fapi_error_indication_test.c
+++ b/nfapi/tests/p5/nr_fapi_error_indication_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_error_indication_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void test_pack_unpack(nfapi_nr_error_indication_scf_t *req)
@@ -49,7 +40,7 @@ void test_pack_unpack(nfapi_nr_error_indication_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_param_request_test.c b/nfapi/tests/p5/nr_fapi_param_request_test.c
index 5356160ca4128371bf517c92efedb5f7dcf09d73..d42717eaeb9be5139a5faec29dcd096c1a64ffeb 100644
--- a/nfapi/tests/p5/nr_fapi_param_request_test.c
+++ b/nfapi/tests/p5/nr_fapi_param_request_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_param_request_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void test_pack_unpack(nfapi_nr_param_request_scf_t *req)
@@ -50,7 +41,7 @@ void test_pack_unpack(nfapi_nr_param_request_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_param_response_test.c b/nfapi/tests/p5/nr_fapi_param_response_test.c
index 75ca6d5e31ef0878f009038511da7caaed27062c..1ba14c1655e2fb22814ee594c1f1fec53cad1f9b 100644
--- a/nfapi/tests/p5/nr_fapi_param_response_test.c
+++ b/nfapi/tests/p5/nr_fapi_param_response_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_param_response_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void fill_param_response_tlv(nfapi_nr_param_response_scf_t *nfapi_resp)
@@ -235,14 +226,14 @@ void test_pack_unpack(nfapi_nr_param_response_scf_t *req)
   req->header.message_length = pack_result - NFAPI_HEADER_LENGTH;
   // test the unpacking of the header
   // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
-  nfapi_p4_p5_message_header_t header;
+  nfapi_nr_p4_p5_message_header_t header;
   uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
   uint8_t header_buffer[header_buffer_size];
   for (int idx = 0; idx < header_buffer_size; idx++) {
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_start_request_test.c b/nfapi/tests/p5/nr_fapi_start_request_test.c
index 9384488c46c40ccb188994079c58a2cf4b855e77..9a36528db657407feed62e0b84cb7d70bc3f8793 100644
--- a/nfapi/tests/p5/nr_fapi_start_request_test.c
+++ b/nfapi/tests/p5/nr_fapi_start_request_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_start_request_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void test_pack_unpack(nfapi_nr_start_request_scf_t *req)
@@ -50,7 +41,7 @@ void test_pack_unpack(nfapi_nr_start_request_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_start_response_test.c b/nfapi/tests/p5/nr_fapi_start_response_test.c
index 32ef894981d9fc6ff477413cbec8dd5f8e64e43b..bb3a0967342858386caafac4ff8f853c4ba30e65 100644
--- a/nfapi/tests/p5/nr_fapi_start_response_test.c
+++ b/nfapi/tests/p5/nr_fapi_start_response_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_start_response_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void test_pack_unpack(nfapi_nr_start_response_scf_t *req)
@@ -50,7 +41,7 @@ void test_pack_unpack(nfapi_nr_start_response_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_stop_indication_test.c b/nfapi/tests/p5/nr_fapi_stop_indication_test.c
index ee3946c8e40c6ffb0f14a6d4a48eecdf81d69269..4b5d9d431938f4c15c8181aac2a3f293ce27db39 100644
--- a/nfapi/tests/p5/nr_fapi_stop_indication_test.c
+++ b/nfapi/tests/p5/nr_fapi_stop_indication_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_stop_indication_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void test_pack_unpack(nfapi_nr_stop_indication_scf_t *req)
@@ -50,7 +41,7 @@ void test_pack_unpack(nfapi_nr_stop_indication_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p5/nr_fapi_stop_request_test.c b/nfapi/tests/p5/nr_fapi_stop_request_test.c
index 74311cf94e33efc84473d01838709e2ce549282c..74e5ea31ffbd04bb84cf6231f13dfeaaf4be4a45 100644
--- a/nfapi/tests/p5/nr_fapi_stop_request_test.c
+++ b/nfapi/tests/p5/nr_fapi_stop_request_test.c
@@ -18,17 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_stop_request_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
 #include "nfapi/tests/nr_fapi_test.h"
+#include "nr_fapi_p5.h"
 #include "nr_fapi_p5_utils.h"
 
 void test_pack_unpack(nfapi_nr_stop_request_scf_t *req)
@@ -50,7 +41,7 @@ void test_pack_unpack(nfapi_nr_stop_request_scf_t *req)
     header_buffer[idx] = msg_buf[idx];
   }
   uint8_t *pReadPackedMessage = header_buffer;
-  int unpack_header_result = fapi_nr_p5_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
   DevAssert(unpack_header_result >= 0);
   DevAssert(header.message_id == req->header.message_id);
   DevAssert(header.message_length == req->header.message_length);
diff --git a/nfapi/tests/p7/CMakeLists.txt b/nfapi/tests/p7/CMakeLists.txt
index 7cf1958693a8ad0b9faa480e34eb22a46f653e24..74e90a855705db4d4cceb39588b03800212824ca 100644
--- a/nfapi/tests/p7/CMakeLists.txt
+++ b/nfapi/tests/p7/CMakeLists.txt
@@ -1,8 +1,8 @@
 set(Test_Labels fapi p7)
-set(_fapi_p7_messages "dci_inversion")
+set(_fapi_p7_messages "dci_inversion;dl_tti_request;ul_tti_request;slot_indication;ul_dci_request;tx_data_request;rx_data_indication;crc_indication;uci_indication;srs_indication;rach_indication")
 foreach (fapi_p7_message IN LISTS _fapi_p7_messages)
     add_executable(nr_fapi_${fapi_p7_message}_test nr_fapi_${fapi_p7_message}_test.c)
-    target_link_libraries(nr_fapi_${fapi_p7_message}_test PUBLIC nr_fapi_p5)
+    target_link_libraries(nr_fapi_${fapi_p7_message}_test PUBLIC nr_fapi_p7)
     target_link_libraries(nr_fapi_${fapi_p7_message}_test PRIVATE pthread UTIL ${T_LIB} minimal_lib)
     add_dependencies(tests nr_fapi_${fapi_p7_message}_test)
 
diff --git a/nfapi/tests/p7/dci_payload_utils.h b/nfapi/tests/p7/dci_payload_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..5788a133bcb4766e4ff66305b383ae064d5f9c4c
--- /dev/null
+++ b/nfapi/tests/p7/dci_payload_utils.h
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef OPENAIRINTERFACE_DCI_PAYLOAD_UTILS_H
+#define OPENAIRINTERFACE_DCI_PAYLOAD_UTILS_H
+#include "nfapi/tests/nr_fapi_test.h"
+
+void printbits(const uint64_t n, const uint8_t numBytesToPrint)
+{
+  uint64_t i;
+  uint8_t counter = 0;
+  if (numBytesToPrint == 0) {
+    i = 1UL << (sizeof(n) * 8 - 1);
+  } else {
+    i = 1UL << (numBytesToPrint * 8 - 1);
+  }
+  while (i > 0) {
+    if (n & i)
+      printf("1");
+    else
+      printf("0");
+    i >>= 1;
+    counter++;
+    if (counter % 8 == 0) {
+      printf(" ");
+    }
+  }
+}
+
+/*! \brief Drops unwanted bits from a byte array, leaving only a specified number of payload bits
+ *
+ *  \param payloadSizeBits How many bits the payload is to have, from 1 to 64 (8 * DCI_PAYLOAD_BYTE_LEN)
+ *  \param payload[] A uint8_t array containing the payload bytes with random data
+ *  \details This function creates a bitmask of payloadSizeBits width to truncate the data in payload[] to only have the specified
+ *  number of payload bits\n
+ *  For example, a payload of 39 bits needs 5 bytes, but on the last byte, the last bit is unused, this function makes sure that
+ *  last bit is set to 0, allowing the payload to be then packed and unpacked and successfully compared with the original payload
+ */
+void truncate_unwanted_bits(uint8_t payloadSizeBits, uint8_t payload[])
+{
+  uint8_t payloadSizeBytes = (payloadSizeBits + 7) / 8;
+  printf("Original Value:\t");
+  uint64_t t = 0;
+  memcpy(&t, payload, payloadSizeBytes);
+  printbits(t, payloadSizeBytes);
+  printf("\n");
+  uint64_t bitmask = 1;
+  for (int i = 0; i < payloadSizeBits - 1; i++) {
+    bitmask = bitmask << 1 | 1;
+  }
+  printf("Calculated Bitmask:\t");
+  printbits(bitmask, payloadSizeBytes);
+  printf("\n");
+  t = t & bitmask;
+  printf("Truncated Value:\t");
+  printbits(t, payloadSizeBytes);
+  printf("\n");
+  memcpy(payload, &t, payloadSizeBytes);
+}
+
+/*! \brief Generates a random payload payloadSizeBits long into payload[]
+ *
+ *  \param payloadSizeBits How many bits the payload is to have, from 1 to 64 (8 * DCI_PAYLOAD_BYTE_LEN)
+ *  \param payload[] A uint8_t array to contain the generated payload
+ *  \details This function fills a uint8_t array with payloadSizeBits of random data, by first filling however many bytes are needed
+ *  to contain payloadSizeBits with random data, and then truncating the excess bits
+ */
+void generate_payload(uint8_t payloadSizeBits, uint8_t payload[])
+{
+  for (int i = 0; i < (payloadSizeBits + 7) / 8; ++i) {
+    payload[i] = rand8();
+  }
+  truncate_unwanted_bits(payloadSizeBits, payload);
+}
+
+#endif // OPENAIRINTERFACE_DCI_PAYLOAD_UTILS_H
diff --git a/nfapi/tests/p7/nr_fapi_crc_indication_test.c b/nfapi/tests/p7/nr_fapi_crc_indication_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..472959b0d6aebe63794d774a242f548c976529b4
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_crc_indication_test.c
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_crc_indication_CRC(nfapi_nr_crc_t *crc)
+{
+  crc->handle = rand32();
+  crc->rnti = rand16_range(1, 65535);
+  crc->harq_id = rand8_range(0, 15);
+  crc->tb_crc_status = rand8_range(0, 1);
+  crc->num_cb = rand16();
+  if (crc->num_cb > 0) {
+    crc->cb_crc_status = calloc((crc->num_cb / 8) + 1, sizeof(uint8_t));
+    for (int cb = 0; cb < (crc->num_cb / 8) + 1; ++cb) {
+      crc->cb_crc_status[cb] = rand8();
+    }
+  }
+  crc->ul_cqi = rand8();
+  crc->timing_advance = rand16_range(0, 63);
+  crc->rssi = rand16_range(0, 1280);
+}
+
+static void fill_crc_indication(nfapi_nr_crc_indication_t *msg)
+{
+  msg->sfn = rand16_range(0, 1023);
+  msg->slot = rand16_range(0, 159);
+  msg->number_crcs = rand8_range(1, NFAPI_NR_CRC_IND_MAX_PDU); // Minimum 1 PDUs in order to test at least one
+  msg->crc_list = calloc_or_fail(msg->number_crcs, sizeof(*msg->crc_list));
+  for (int crc_idx = 0; crc_idx < msg->number_crcs; ++crc_idx) {
+    fill_crc_indication_CRC(&msg->crc_list[crc_idx]);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_crc_indication_t *req)
+{
+  size_t message_size = get_crc_indication_size(req);
+  uint8_t *msg_buf = calloc_or_fail(message_size, sizeof(uint8_t));
+  /*uint8_t msg_buf[1024*1024*3];
+  size_t message_size = sizeof(msg_buf);*/
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, message_size, NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_crc_indication_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_crc_indication(&unpacked_req, req));
+  free_crc_indication(&unpacked_req);
+  free(msg_buf);
+}
+
+static void test_copy(const nfapi_nr_crc_indication_t *msg)
+{
+  // Test copy function
+  nfapi_nr_crc_indication_t copy = {0};
+  copy_crc_indication(msg, &copy);
+  DevAssert(eq_crc_indication(msg, &copy));
+  free_crc_indication(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_crc_indication_t *req = calloc_or_fail(1, sizeof(nfapi_nr_crc_indication_t));
+  req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION;
+  // Get the actual allocated size
+  printf("Allocated size before filling: %zu bytes\n", get_crc_indication_size(req));
+  // Fill TX_DATA request
+  fill_crc_indication(req);
+  printf("Allocated size after filling: %zu bytes\n", get_crc_indication_size(req));
+  // Perform tests
+  test_pack_unpack(req);
+  test_copy(req);
+  // All tests successful!
+  free_crc_indication(req);
+  free(req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_dci_inversion_test.c b/nfapi/tests/p7/nr_fapi_dci_inversion_test.c
index 22e883b0cd91b5246c169b4e35cd6be1bc046acb..29c534baa5053da2f885e7319f48ee7b65fec153 100644
--- a/nfapi/tests/p7/nr_fapi_dci_inversion_test.c
+++ b/nfapi/tests/p7/nr_fapi_dci_inversion_test.c
@@ -18,86 +18,8 @@
  * For more information about the OpenAirInterface (OAI) Software Alliance:
  *      contact@openairinterface.org
  */
-/*! \file nfapi/tests/p5/nr_fapi_param_request_test.c
- * \brief
- * \author Ruben S. Silva
- * \date 2024
- * \version 0.1
- * \company OpenAirInterface Software Alliance
- * \email: contact@openairinterface.org, rsilva@allbesmart.pt
- * \note
- * \warning
- */
-#include "nfapi/tests/nr_fapi_test.h"
-#include "nr_fapi_p5.h"
+#include "dci_payload_utils.h"
 #include "nr_fapi.h"
-void printbits(uint64_t n, uint8_t numBytesToPrint)
-{
-  uint64_t i;
-  uint8_t counter = 0;
-  if (numBytesToPrint == 0) {
-    i = 1UL << (sizeof(n) * 8 - 1);
-  } else {
-    i = 1UL << (numBytesToPrint * 8 - 1);
-  }
-  while (i > 0) {
-    if (n & i)
-      printf("1");
-    else
-      printf("0");
-    i >>= 1;
-    counter++;
-    if (counter % 8 == 0) {
-      printf(" ");
-    }
-  }
-}
-
-/*! \brief Drops unwanted bits from a byte array, leaving only a specified number of payload bits
- *
- *  \param payloadSizeBits How many bits the payload is to have, from 1 to 64 (8 * DCI_PAYLOAD_BYTE_LEN)
- *  \param payload[] A uint8_t array containing the payload bytes with random data
- *  \details This function creates a bitmask of payloadSizeBits width to truncate the data in payload[] to only have the specified
- *  number of payload bits\n
- *  For example, a payload of 39 bits needs 5 bytes, but on the last byte, the last bit is unused, this function makes sure that
- *  last bit is set to 0, allowing the payload to be then packed and unpacked and successfully compared with the original payload
- */
-void truncate_unwanted_bits(uint8_t payloadSizeBits, uint8_t payload[])
-{
-  uint8_t payloadSizeBytes = (payloadSizeBits + 7) / 8;
-  printf("Original Value:\t");
-  uint64_t t = 0;
-  memcpy(&t, payload, payloadSizeBytes);
-  printbits(t, payloadSizeBytes);
-  printf("\n");
-  uint64_t bitmask = 1;
-  for (int i = 0; i < payloadSizeBits - 1; i++) {
-    bitmask = bitmask << 1 | 1;
-  }
-  printf("Calculated Bitmask:\t");
-  printbits(bitmask, payloadSizeBytes);
-  printf("\n");
-  t = t & bitmask;
-  printf("Truncated Value:\t");
-  printbits(t, payloadSizeBytes);
-  printf("\n");
-  memcpy(payload, &t, payloadSizeBytes);
-}
-
-/*! \brief Generates a random payload payloadSizeBits long into payload[]
- *
- *  \param payloadSizeBits How many bits the payload is to have, from 1 to 64 (8 * DCI_PAYLOAD_BYTE_LEN)
- *  \param payload[] A uint8_t array to contain the generated payload
- *  \details This function fills a uint8_t array with payloadSizeBits of random data, by first filling however many bytes are needed
- *  to contain payloadSizeBits with random data, and then truncating the excess bits
- */
-void generate_payload(uint8_t payloadSizeBits, uint8_t payload[])
-{
-  for (int i = 0; i < (payloadSizeBits + 7) / 8; ++i) {
-    payload[i] = rand8();
-  }
-  truncate_unwanted_bits(payloadSizeBits, payload);
-}
 
 void test_pack_payload(uint8_t payloadSizeBits, uint8_t payload[])
 {
diff --git a/nfapi/tests/p7/nr_fapi_dl_tti_request_test.c b/nfapi/tests/p7/nr_fapi_dl_tti_request_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..2cc95260f0a4f0107592b013983e4684ba8f13e2
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_dl_tti_request_test.c
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_dl_tti_request_beamforming(nfapi_nr_tx_precoding_and_beamforming_t *precodingAndBeamforming)
+{
+  precodingAndBeamforming->num_prgs = rand16_range(1, NFAPI_MAX_NUM_PRGS);
+  precodingAndBeamforming->prg_size = rand16_range(1, 275);
+  precodingAndBeamforming->dig_bf_interfaces = rand8_range(0,NFAPI_MAX_NUM_BG_IF);
+  for (int prg = 0; prg < precodingAndBeamforming->num_prgs; ++prg) {
+    precodingAndBeamforming->prgs_list[prg].pm_idx = rand16();
+    for (int dbf_if = 0; dbf_if < precodingAndBeamforming->dig_bf_interfaces; ++dbf_if) {
+      precodingAndBeamforming->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx = rand16();
+    }
+  }
+}
+
+static void fill_dl_tti_request_pdcch_pdu(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdu)
+{
+  pdu->BWPSize = rand16();
+  pdu->BWPStart = rand16();
+  pdu->SubcarrierSpacing = rand8();
+  pdu->CyclicPrefix = rand8();
+  pdu->StartSymbolIndex = rand8();
+  pdu->DurationSymbols = rand8();
+  for (int fdr_idx = 0; fdr_idx < 6; ++fdr_idx) {
+    pdu->FreqDomainResource[fdr_idx] = rand8();
+  }
+  pdu->CceRegMappingType = rand8();
+  pdu->RegBundleSize = rand8();
+  pdu->InterleaverSize = rand8();
+  pdu->CoreSetType = rand8();
+  pdu->ShiftIndex = rand8();
+  pdu->precoderGranularity = rand8();
+  pdu->numDlDci = rand8_range(1, MAX_DCI_CORESET);
+  for (int dl_dci = 0; dl_dci < pdu->numDlDci; ++dl_dci) {
+    pdu->dci_pdu[dl_dci].RNTI = rand16();
+    pdu->dci_pdu[dl_dci].ScramblingId = rand16();
+    pdu->dci_pdu[dl_dci].ScramblingRNTI = rand16();
+    pdu->dci_pdu[dl_dci].CceIndex = rand8();
+    pdu->dci_pdu[dl_dci].AggregationLevel = rand8();
+    fill_dl_tti_request_beamforming(&pdu->dci_pdu[dl_dci].precodingAndBeamforming);
+    pdu->dci_pdu[dl_dci].beta_PDCCH_1_0 = rand8();
+    pdu->dci_pdu[dl_dci].powerControlOffsetSS = rand8();
+    pdu->dci_pdu[dl_dci].PayloadSizeBits = rand16_range(0, DCI_PAYLOAD_BYTE_LEN * 8);
+    generate_payload(pdu->dci_pdu[dl_dci].PayloadSizeBits, pdu->dci_pdu[dl_dci].Payload);
+  }
+}
+
+static void fill_dl_tti_request_pdsch_pdu(nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdu)
+{
+  pdu->pduBitmap = rand16_range(0, 2);
+  pdu->rnti = rand16();
+  pdu->pduIndex = rand16();
+  pdu->BWPSize = rand16_range(1, 275);
+  pdu->BWPStart = rand16_range(0, 274);
+  pdu->SubcarrierSpacing = rand8_range(0, 4);
+  pdu->CyclicPrefix = rand8_range(0, 1);
+  pdu->NrOfCodewords = rand8_range(1, 2);
+  for (int cw = 0; cw < pdu->NrOfCodewords; ++cw) {
+    pdu->targetCodeRate[cw] = rand16();
+    pdu->qamModOrder[cw] = rand8();
+    pdu->mcsIndex[cw] = rand8();
+    pdu->mcsTable[cw] = rand8_range(0, 2);
+    pdu->rvIndex[cw] = rand8_range(0, 3);
+    pdu->TBSize[cw] = rand16();
+  }
+  pdu->dataScramblingId = rand16();
+  pdu->nrOfLayers = rand8_range(1, 8);
+  pdu->transmissionScheme = rand8_range(0, 8);
+  pdu->refPoint = rand8_range(0, 1);
+  // dlDmrsSymbPos is a bitmap occupying the 14 LSB
+  pdu->dlDmrsSymbPos = rand16_range(0, 0x3FFF);
+  pdu->dmrsConfigType = rand8_range(0, 1);
+  pdu->dlDmrsScramblingId = rand16();
+  pdu->SCID = rand8_range(0, 1);
+  pdu->numDmrsCdmGrpsNoData = rand8_range(1, 3);
+  // dmrsPorts is a bitmap occupying the 11 LSB
+  pdu->dmrsPorts = rand16_range(0, 0x7FF);
+  pdu->resourceAlloc = rand8_range(0, 1);
+  for (int i = 0; i < 36; ++i) {
+    pdu->rbBitmap[i] = rand8();
+  }
+  pdu->rbStart = rand16_range(0, 274);
+  pdu->rbSize = rand16_range(1, 275);
+  pdu->VRBtoPRBMapping = rand8_range(0, 2);
+  pdu->StartSymbolIndex = rand8_range(0, 13);
+  pdu->NrOfSymbols = rand8_range(1, 14);
+
+  if (pdu->pduBitmap & 0b1) {
+    // PTRSPortIndex is a bitmap occupying the 6 LSB
+    pdu->PTRSPortIndex = rand8_range(0, 0x3F);
+    pdu->PTRSTimeDensity = rand8_range(0, 2);
+    pdu->PTRSFreqDensity = rand8_range(0, 1);
+    pdu->PTRSReOffset = rand8_range(0, 3);
+    pdu->nEpreRatioOfPDSCHToPTRS = rand8_range(0, 3);
+  }
+  fill_dl_tti_request_beamforming(&pdu->precodingAndBeamforming);
+  pdu->powerControlOffset = rand8_range(0, 23);
+  pdu->powerControlOffsetSS = rand8_range(0, 3);
+  // Check pduBitMap bit 1 to add or not CBG parameters
+  if (pdu->pduBitmap & 0b10) {
+    pdu->isLastCbPresent = rand8_range(0, 1);
+    pdu->isInlineTbCrc = rand8_range(0, 1);
+    pdu->dlTbCrc = rand32();
+  }
+  pdu->maintenance_parms_v3.ldpcBaseGraph = rand8();
+  pdu->maintenance_parms_v3.tbSizeLbrmBytes = rand32();
+}
+
+static void fill_dl_tti_request_csi_rs_pdu(nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *pdu)
+{
+  pdu->bwp_size = rand16_range(1, 275);
+  pdu->bwp_start = rand16_range(0, 274);
+  pdu->subcarrier_spacing = rand8_range(0, 4);
+  pdu->cyclic_prefix = rand8_range(0, 1);
+  pdu->start_rb = rand16_range(0, 274);
+  pdu->nr_of_rbs = rand16_range(0, pdu->bwp_size);
+  pdu->csi_type = rand8_range(0, 2);
+  pdu->row = rand8_range(1, 18);
+  // freq_domain is a bitmap up to 12 LSB, depending on row value [TS38.211, sec 7.4.1.5.3]
+  // row = 1 -> b0 to b3
+  // row = 2 -> b0 to b11
+  // row = 4 -> b0 to b2
+  // other rows -> b0 to b5
+  switch (pdu->row) {
+    case 1: // 4 bits
+      pdu->freq_domain = rand16_range(0, 0xF);
+      break;
+    case 2: // 12 bits
+      pdu->freq_domain = rand16_range(0, 0xFFF);
+      break;
+    case 4: // 3 bits
+      pdu->freq_domain = rand16_range(0, 7);
+      break;
+    default: // 6 bits
+      pdu->freq_domain = rand16_range(0, 0x3F);
+      break;
+  }
+  pdu->symb_l0 = rand8_range(0, 13);
+  pdu->symb_l1 = rand8_range(2, 12);
+  pdu->cdm_type = rand8_range(0, 3);
+  pdu->scramb_id = rand16_range(0, 1023);
+  pdu->power_control_offset = rand8_range(0, 23);
+  pdu->power_control_offset_ss = rand8_range(0, 3);
+  fill_dl_tti_request_beamforming(&pdu->precodingAndBeamforming);
+}
+
+static void fill_dl_tti_request_ssb_pdu(nfapi_nr_dl_tti_ssb_pdu_rel15_t *pdu)
+{
+  pdu->PhysCellId = rand16_range(0, 1007);
+  pdu->BetaPss = rand8_range(0, 1);
+  pdu->SsbBlockIndex = rand8_range(0, 63);
+  pdu->SsbSubcarrierOffset = rand8_range(0, 31);
+  pdu->ssbOffsetPointA = rand16_range(0, 2199);
+  pdu->bchPayloadFlag = rand8_range(0, 2);
+  pdu->bchPayload = rand24();
+  fill_dl_tti_request_beamforming(&pdu->precoding_and_beamforming);
+}
+
+static void fill_dl_tti_request(nfapi_nr_dl_tti_request_t *msg)
+{
+  msg->SFN = rand16_range(0, 1023);
+  msg->Slot = rand16_range(0, 159);
+  int available_PDUs = rand8_range(4, 16); // Minimum 4 PDUs in order to test at least one of each
+  msg->dl_tti_request_body.nPDUs = available_PDUs;
+  msg->dl_tti_request_body.nGroup = rand8();
+
+  int pdu = 0;
+  int num_PDCCH = rand8_range(1, available_PDUs - 3);
+
+  available_PDUs -= num_PDCCH;
+  int num_PDSCH = rand8_range(1, available_PDUs - 2);
+
+  available_PDUs -= num_PDSCH;
+  int num_CSI_RS = rand8_range(1, available_PDUs - 1);
+
+  available_PDUs -= num_CSI_RS;
+  int num_SSB = available_PDUs;
+
+  for (int i = 0; i < num_PDCCH; ++pdu, ++i) {
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16();
+    fill_dl_tti_request_pdcch_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].pdcch_pdu.pdcch_pdu_rel15);
+  }
+
+  for (int i = 0; i < num_PDSCH; ++pdu, ++i) {
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16();
+    fill_dl_tti_request_pdsch_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].pdsch_pdu.pdsch_pdu_rel15);
+  }
+
+  for (int i = 0; i < num_CSI_RS; ++pdu, ++i) {
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_CSI_RS_PDU_TYPE;
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16();
+    fill_dl_tti_request_csi_rs_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].csi_rs_pdu.csi_rs_pdu_rel15);
+  }
+
+  for (int i = 0; i < num_SSB; ++pdu, ++i) {
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
+    msg->dl_tti_request_body.dl_tti_pdu_list[pdu].PDUSize = rand16();
+    fill_dl_tti_request_ssb_pdu(&msg->dl_tti_request_body.dl_tti_pdu_list[pdu].ssb_pdu.ssb_pdu_rel15);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_dl_tti_request_t *req)
+{
+  uint8_t msg_buf[1024 * 1024 * 6];
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, sizeof(msg_buf), NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_dl_tti_request_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_dl_tti_request(&unpacked_req, req));
+  free_dl_tti_request(&unpacked_req);
+}
+
+static void test_copy(const nfapi_nr_dl_tti_request_t *msg)
+{
+  // Test copy function
+  nfapi_nr_dl_tti_request_t copy = {0};
+  copy_dl_tti_request(msg, &copy);
+  DevAssert(eq_dl_tti_request(msg, &copy));
+  free_dl_tti_request(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_dl_tti_request_t req = {.header.message_id = NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST};
+  // Fill DL_TTI request
+  fill_dl_tti_request(&req);
+  // Perform tests
+  test_pack_unpack(&req);
+  test_copy(&req);
+  // All tests successful!
+  free_dl_tti_request(&req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_rach_indication_test.c b/nfapi/tests/p7/nr_fapi_rach_indication_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..fd4a0fac32c571e58122274ae0288f4aa3806a41
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_rach_indication_test.c
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_rach_indication_PDU(nfapi_nr_prach_indication_pdu_t *pdu)
+{
+  pdu->phy_cell_id = rand32();
+  pdu->symbol_index = rand8_range(0,13);
+  pdu->slot_index = rand8_range(0,79);
+  pdu->freq_index = rand8_range(0,7);
+  pdu->avg_rssi = rand8();
+  pdu->avg_snr = rand8();
+  pdu->num_preamble = rand8_range(0,63);
+  for (int preamble_idx = 0; preamble_idx < pdu->num_preamble; ++preamble_idx) {
+    nfapi_nr_prach_indication_preamble_t *preamble = &pdu->preamble_list[preamble_idx];
+    preamble->preamble_index = rand8_range(0,63);
+    preamble->timing_advance = rand16_range(0,3846);
+    preamble->preamble_pwr = rand32_range(0, 170000);
+  }
+}
+
+static void fill_rach_indication(nfapi_nr_rach_indication_t *msg)
+{
+  msg->sfn = rand16_range(0, 1023);
+  msg->slot = rand16_range(0, 159);
+  msg->number_of_pdus = rand8_range(1, NFAPI_NR_RACH_IND_MAX_PDU); // Minimum 1 PDUs in order to test at least one
+  msg->pdu_list = calloc_or_fail(msg->number_of_pdus, sizeof(*msg->pdu_list));
+  for (int pdu_idx = 0; pdu_idx < msg->number_of_pdus; ++pdu_idx) {
+    fill_rach_indication_PDU(&msg->pdu_list[pdu_idx]);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_rach_indication_t *req)
+{
+  size_t message_size = get_rach_indication_size(req);
+  uint8_t *msg_buf = calloc_or_fail(message_size, sizeof(uint8_t));
+  /*uint8_t msg_buf[1024*1024*3];
+  size_t message_size = sizeof(msg_buf);*/
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, message_size, NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_rach_indication_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_rach_indication(&unpacked_req, req));
+  free_rach_indication(&unpacked_req);
+  free(msg_buf);
+}
+
+static void test_copy(const nfapi_nr_rach_indication_t *msg)
+{
+  // Test copy function
+  nfapi_nr_rach_indication_t copy = {0};
+  copy_rach_indication(msg, &copy);
+  DevAssert(eq_rach_indication(msg, &copy));
+  free_rach_indication(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_rach_indication_t *req = calloc_or_fail(1, sizeof(nfapi_nr_rach_indication_t));
+  req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION;
+  // Get the actual allocated size
+  printf("Allocated size before filling: %zu bytes\n", get_rach_indication_size(req));
+  // Fill TX_DATA request
+  fill_rach_indication(req);
+  printf("Allocated size after filling: %zu bytes\n", get_rach_indication_size(req));
+  // Perform tests
+  test_pack_unpack(req);
+  test_copy(req);
+  // All tests successful!
+  free_rach_indication(req);
+  free(req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_rx_data_indication_test.c b/nfapi/tests/p7/nr_fapi_rx_data_indication_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f382cf7971f8714a39dd252a2f75ae082f7b0a1
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_rx_data_indication_test.c
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_rx_data_indication_PDU(nfapi_nr_rx_data_pdu_t *pdu)
+{
+  pdu->handle = rand32();
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->harq_id = rand8_range(0, 15);
+  pdu->pdu_length = rand32_range(0, 65535 * 100); // Testing to a maximum of 100 times 2^16, to test 32 bit would take too long
+  pdu->ul_cqi = rand8();
+  pdu->timing_advance = rand16_range(0, 63);
+  pdu->rssi = rand16_range(0, 1280);
+  pdu->pdu = calloc_or_fail(pdu->pdu_length, sizeof(uint8_t));
+  for (int i = 0; i < pdu->pdu_length; ++i) {
+    pdu->pdu[i] = rand8();
+  }
+}
+
+static void fill_rx_data_indication(nfapi_nr_rx_data_indication_t *msg)
+{
+  msg->sfn = rand16_range(0, 1023);
+  msg->slot = rand16_range(0, 159);
+  msg->number_of_pdus = rand8_range(1, NFAPI_NR_RX_DATA_IND_MAX_PDU); // Minimum 1 PDUs in order to test at least one
+  msg->pdu_list = calloc_or_fail(msg->number_of_pdus, sizeof(*msg->pdu_list));
+  for (int pdu_idx = 0; pdu_idx < msg->number_of_pdus; ++pdu_idx) {
+    fill_rx_data_indication_PDU(&msg->pdu_list[pdu_idx]);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_rx_data_indication_t *req)
+{
+  const size_t message_size = get_rx_data_indication_size(req);
+  uint8_t *msg_buf = calloc_or_fail(message_size, sizeof(uint8_t));
+  /*uint8_t msg_buf[1024*1024*3];
+  size_t message_size = sizeof(msg_buf);*/
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, message_size, NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_rx_data_indication_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_rx_data_indication(&unpacked_req, req));
+  free_rx_data_indication(&unpacked_req);
+  free(msg_buf);
+}
+
+static void test_copy(const nfapi_nr_rx_data_indication_t *msg)
+{
+  // Test copy function
+  nfapi_nr_rx_data_indication_t copy = {0};
+  copy_rx_data_indication(msg, &copy);
+  DevAssert(eq_rx_data_indication(msg, &copy));
+  free_rx_data_indication(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_rx_data_indication_t *req = calloc_or_fail(1, sizeof(nfapi_nr_rx_data_indication_t));
+  req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION;
+  // Get the actual allocated size
+  printf("Allocated size before filling: %zu bytes\n", get_rx_data_indication_size(req));
+  // Fill TX_DATA request
+  fill_rx_data_indication(req);
+  printf("Allocated size after filling: %zu bytes\n", get_rx_data_indication_size(req));
+  // Perform tests
+  test_pack_unpack(req);
+  test_copy(req);
+  // All tests successful!
+  free_rx_data_indication(req);
+  free(req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_slot_indication_test.c b/nfapi/tests/p7/nr_fapi_slot_indication_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..96c030479c86c74709e4f5832e0e4e9e0dd64438
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_slot_indication_test.c
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_slot_indication(nfapi_nr_slot_indication_scf_t *msg)
+{
+  msg->sfn = rand16_range(0, 1023);
+  msg->slot = rand16_range(0, 159);
+}
+
+static void test_pack_unpack(nfapi_nr_slot_indication_scf_t *req)
+{
+  uint8_t msg_buf[1024 * 1024 * 2];
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, sizeof(msg_buf), NULL);
+
+  // Should always return 4 (2 bytes sfn + 2 bytes slot )
+  DevAssert(pack_result == 4);
+  // update req message_length value with value calculated in message_pack procedure
+  // req->header.message_length = pack_result;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_slot_indication_scf_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_slot_indication(&unpacked_req, req));
+  free_slot_indication(&unpacked_req);
+}
+
+static void test_copy(const nfapi_nr_slot_indication_scf_t *msg)
+{
+  // Test copy function
+  nfapi_nr_slot_indication_scf_t copy = {0};
+  copy_slot_indication(msg, &copy);
+  DevAssert(eq_slot_indication(msg, &copy));
+  free_slot_indication(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_slot_indication_scf_t req = {.header.message_id = NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION};
+
+  // Fill DL_TTI request
+  fill_slot_indication(&req);
+  // Perform tests
+  test_pack_unpack(&req);
+  test_copy(&req);
+  // All tests successful!
+  free_slot_indication(&req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_srs_indication_test.c b/nfapi/tests/p7/nr_fapi_srs_indication_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..49b73fd8f5c443803587775c4f66ceac268aa2a0
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_srs_indication_test.c
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fil_srs_indication_report_tlv(nfapi_srs_report_tlv_t *tlv)
+{
+  tlv->tag = rand16_range(0,3);
+  tlv->length = rand32_range(0,sizeof(tlv->value));
+  for (int i = 0; i < (tlv->length + 3) / 4; ++i) {
+    tlv->value[i] = rand32();
+  }
+}
+
+static void fill_srs_indication_PDU(nfapi_nr_srs_indication_pdu_t *pdu)
+{
+  pdu->handle = rand32();
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->timing_advance_offset = rand16_range(0, 63);
+  pdu->timing_advance_offset_nsec = rands16_range(-16800, 16800);
+  pdu->srs_usage = rand8_range(0,3);
+  pdu->report_type = rand8_range(0,1);
+  fil_srs_indication_report_tlv(&pdu->report_tlv);
+}
+
+static void fill_srs_indication(nfapi_nr_srs_indication_t *msg)
+{
+  msg->sfn = rand16_range(0, 1023);
+  msg->slot = rand16_range(0, 159);
+  msg->control_length = rand16(); // being ignored number_of_pdusat the moment, report is always sent inline
+  msg->number_of_pdus = rand8_range(1, NFAPI_NR_SRS_IND_MAX_PDU); // Minimum 1 PDUs in order to test at least one
+  msg->pdu_list = calloc_or_fail(msg->number_of_pdus, sizeof(*msg->pdu_list));
+  for (int pdu_idx = 0; pdu_idx < msg->number_of_pdus; ++pdu_idx) {
+    fill_srs_indication_PDU(&msg->pdu_list[pdu_idx]);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_srs_indication_t *req)
+{
+  size_t message_size = get_srs_indication_size(req);
+  uint8_t *msg_buf = calloc_or_fail(message_size, sizeof(uint8_t));
+  /*uint8_t msg_buf[1024*1024*3];
+  size_t message_size = sizeof(msg_buf);*/
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, message_size, NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_srs_indication_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_srs_indication(&unpacked_req, req));
+  free_srs_indication(&unpacked_req);
+  free(msg_buf);
+}
+
+static void test_copy(const nfapi_nr_srs_indication_t *msg)
+{
+  // Test copy function
+  nfapi_nr_srs_indication_t copy = {0};
+  copy_srs_indication(msg, &copy);
+  DevAssert(eq_srs_indication(msg, &copy));
+  free_srs_indication(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_srs_indication_t *req = calloc_or_fail(1, sizeof(nfapi_nr_srs_indication_t));
+  req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION;
+  // Get the actual allocated size
+  printf("Allocated size before filling: %zu bytes\n", get_srs_indication_size(req));
+  // Fill TX_DATA request
+  fill_srs_indication(req);
+  printf("Allocated size after filling: %zu bytes\n", get_srs_indication_size(req));
+  // Perform tests
+  test_pack_unpack(req);
+  test_copy(req);
+  // All tests successful!
+  free_srs_indication(req);
+  free(req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_tx_data_request_test.c b/nfapi/tests/p7/nr_fapi_tx_data_request_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..e67b5bf3ca5cbf635e0a33da179db1c903e5e07a
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_tx_data_request_test.c
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_tx_data_request_PDU(nfapi_nr_pdu_t *pdu)
+{
+  // PDU_Length The total length (in bytes) of the PDU description and PDU data, without the padding bytes.
+  // Minimum length = 4 PDULength + 2 PDUIndex + 4 numTLV + 2 tag + 4 length + 4 value = 20
+  // ( assuming 1 TLV and "empty payload" sends 4 bytes of zeroes - For testing purposes only )
+  // Max Length => 10 bytes PDU Header + 2 * (2 bytes tag, 4 bytes length, 38016*4 bytes value (on value.direct))
+  // = 304150
+  pdu->PDU_index = rand16();
+  pdu->num_TLV = rand8_range(1, NFAPI_NR_MAX_TX_REQUEST_TLV);
+  pdu->PDU_length = rand32_range(20, 10 + pdu->num_TLV * (4 + (38016 * 4)));
+  uint32_t remaining_size = pdu->PDU_length - 10 - (pdu->num_TLV * 4);
+  for (int tlv_idx = 0; tlv_idx < pdu->num_TLV; ++tlv_idx) {
+    nfapi_nr_tx_data_request_tlv_t *tlv = &pdu->TLVs[tlv_idx];
+    tlv->tag = rand16_range(0, 1);
+    uint32_t maxSize = 0;
+    if (tlv->tag == 0) {
+      maxSize = sizeof(tlv->value.direct);
+    } else {
+      maxSize = (remaining_size / pdu->num_TLV);
+    }
+    if (pdu->num_TLV == 1) {
+      tlv->length = remaining_size;
+    } else {
+      if (tlv_idx == pdu->num_TLV - 1) {
+        tlv->length = min(maxSize, sizeof(tlv->value.direct));
+      } else {
+        tlv->length = min(rand32_range(0, maxSize), sizeof(tlv->value.direct));
+        remaining_size -= tlv->length - 4;
+      }
+    }
+    switch (tlv->tag) {
+      case 0:
+        // value.direct
+        if (tlv->length % 4 != 0) {
+          for (int idx = 0; idx < ((tlv->length + 3) / 4) - 1; ++idx) {
+            tlv->value.direct[idx] = rand32();
+          }
+          uint32_t bytesToAdd = 4 - (4 - (tlv->length % 4)) % 4;
+          if (bytesToAdd != 4) {
+            for (int j = 0; j < bytesToAdd; j++) {
+              tlv->value.direct[((tlv->length + 3) / 4) - 1] |= rand8();
+              tlv->value.direct[((tlv->length + 3) / 4) - 1] = tlv->value.direct[((tlv->length + 3) / 4) - 1] << (j * 8);
+            }
+          }
+        } else {
+          // no padding needed
+          for (int idx = 0; idx < (tlv->length + 3) / 4; ++idx) {
+            tlv->value.direct[idx] = rand32();
+          }
+        }
+        break;
+      case 1:
+        // value.ptr
+        tlv->value.ptr = calloc((tlv->length + 3) / 4, sizeof(uint32_t));
+        if (tlv->length % 4 != 0) {
+          for (int idx = 0; idx < ((tlv->length + 3) / 4) - 1; ++idx) {
+            tlv->value.ptr[idx] = rand32();
+          }
+          uint32_t bytesToAdd = 4 - (4 - (tlv->length % 4)) % 4;
+          if (bytesToAdd != 4) {
+            uint32_t value = 0;
+            for (int j = 0; j < bytesToAdd; j++) {
+              value |= rand8() << (j * 8);
+            }
+            tlv->value.ptr[((tlv->length + 3) / 4) - 1] = value;
+          }
+        } else {
+          // no padding needed
+          for (int idx = 0; idx < (tlv->length + 3) / 4; ++idx) {
+            tlv->value.ptr[idx] = rand32();
+          }
+        }
+        break;
+      default:
+        AssertFatal(1 == 0, "Unsupported tag value %d\n", tlv->tag);
+    }
+  }
+}
+
+static void fill_tx_data_request(nfapi_nr_tx_data_request_t *msg)
+{
+  msg->SFN = rand16_range(0, 1023);
+  msg->Slot = rand16_range(0, 159);
+  msg->Number_of_PDUs = rand8_range(1, NFAPI_NR_MAX_TX_REQUEST_PDUS); // Minimum 1 PDUs in order to test at least one
+  for (int pdu_idx = 0; pdu_idx < msg->Number_of_PDUs; ++pdu_idx) {
+    fill_tx_data_request_PDU(&msg->pdu_list[pdu_idx]);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_tx_data_request_t *req)
+{
+  size_t message_size = get_tx_data_request_size(req);
+  uint8_t *msg_buf = calloc_or_fail(message_size, sizeof(uint8_t));
+  /*uint8_t msg_buf[1024*1024*3];
+  size_t message_size = sizeof(msg_buf);*/
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, message_size, NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_tx_data_request_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_tx_data_request(&unpacked_req, req));
+  free_tx_data_request(&unpacked_req);
+  free(msg_buf);
+}
+
+static void test_copy(const nfapi_nr_tx_data_request_t *msg)
+{
+  // Test copy function
+  nfapi_nr_tx_data_request_t copy = {0};
+  copy_tx_data_request(msg, &copy);
+  DevAssert(eq_tx_data_request(msg, &copy));
+  free_tx_data_request(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_tx_data_request_t *req = calloc_or_fail(1, sizeof(nfapi_nr_tx_data_request_t));
+  req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST;
+  // Get the actual allocated size
+  printf("Allocated size before filling: %zu bytes\n", get_tx_data_request_size(req));
+  // Fill TX_DATA request
+  fill_tx_data_request(req);
+  printf("Allocated size after filling: %zu bytes\n", get_tx_data_request_size(req));
+  // Perform tests
+  test_pack_unpack(req);
+  test_copy(req);
+  // All tests successful!
+  free_tx_data_request(req);
+  free(req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_uci_indication_test.c b/nfapi/tests/p7/nr_fapi_uci_indication_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e2dcda6beb3d7a16f4a1c2bcb04b0139b4a1122
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_uci_indication_test.c
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_uci_indication_sr_pdu_0_1(nfapi_nr_sr_pdu_0_1_t *pdu)
+{
+  pdu->sr_indication = rand8_range(0, 1);
+  pdu->sr_confidence_level = rand8_range(0, 1);
+}
+
+static void fill_uci_indication_sr_pdu_2_3_4(nfapi_nr_sr_pdu_2_3_4_t *pdu)
+{
+  pdu->sr_bit_len = rand16_range(1, 8);
+  pdu->sr_payload = calloc(((pdu->sr_bit_len / 8) + 1), sizeof(*pdu->sr_payload));
+  for (int i = 0; i < (pdu->sr_bit_len / 8) + 1; ++i) {
+    pdu->sr_payload[i] = rand8();
+  }
+}
+
+static void fill_uci_indication_harq_pdu_0_1(nfapi_nr_harq_pdu_0_1_t *pdu)
+{
+  pdu->num_harq = rand8_range(1, 2);
+  pdu->harq_confidence_level = rand8_range(0, 1);
+  for (int i = 0; i < pdu->num_harq; ++i) {
+    pdu->harq_list[i].harq_value = rand8_range(0, 2);
+  }
+}
+
+static void fill_uci_indication_harq_pdu_2_3_4(nfapi_nr_harq_pdu_2_3_4_t *pdu)
+{
+  pdu->harq_crc = rand8_range(0, 2);
+  pdu->harq_bit_len = rand16_range(1, 1706);
+  pdu->harq_payload = calloc(((pdu->harq_bit_len / 8) + 1), sizeof(*pdu->harq_payload));
+  for (int i = 0; i < (pdu->harq_bit_len / 8) + 1; ++i) {
+    pdu->harq_payload[i] = rand8();
+  }
+}
+
+static void fill_uci_indication_csi_part1(nfapi_nr_csi_part1_pdu_t *pdu)
+{
+  pdu->csi_part1_crc = rand8_range(0, 2);
+  pdu->csi_part1_bit_len = rand16_range(1, 1706);
+  pdu->csi_part1_payload = calloc(((pdu->csi_part1_bit_len / 8) + 1), sizeof(*pdu->csi_part1_payload));
+  for (int i = 0; i < (pdu->csi_part1_bit_len / 8) + 1; ++i) {
+    pdu->csi_part1_payload[i] = rand8();
+  }
+}
+
+static void fill_uci_indication_csi_part2(nfapi_nr_csi_part2_pdu_t *pdu)
+{
+  pdu->csi_part2_crc = rand8_range(0, 2);
+  pdu->csi_part2_bit_len = rand16_range(1, 1706);
+  pdu->csi_part2_payload = calloc(((pdu->csi_part2_bit_len / 8) + 1), sizeof(*pdu->csi_part2_payload));
+  for (int i = 0; i < (pdu->csi_part2_bit_len / 8) + 1; ++i) {
+    pdu->csi_part2_payload[i] = rand8();
+  }
+}
+
+static void fill_uci_indication_PUSCH(nfapi_nr_uci_pusch_pdu_t *pdu)
+{
+  pdu->pduBitmap = rand8_range(0, 0b1110) & 0b1110; // Bit 0 is always unused
+  pdu->handle = rand32();
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->ul_cqi = rand8();
+  pdu->timing_advance = rand16_range(0, 63);
+  pdu->rssi = rand16_range(0, 1280);
+
+  // Bit 0 not used in PUSCH PDU
+  // HARQ
+  if ((pdu->pduBitmap >> 1) & 0x01) {
+    fill_uci_indication_harq_pdu_2_3_4(&pdu->harq);
+  }
+  // CSI Part 1
+  if ((pdu->pduBitmap >> 2) & 0x01) {
+    fill_uci_indication_csi_part1(&pdu->csi_part1);
+  }
+  // CSI Part 2
+  if ((pdu->pduBitmap >> 3) & 0x01) {
+    fill_uci_indication_csi_part2(&pdu->csi_part2);
+  }
+}
+
+static void fill_uci_indication_PUCCH_0_1(nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu)
+{
+  pdu->pduBitmap = rand8_range(0, 0b11);
+  pdu->handle = rand32();
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->pucch_format = rand8_range(0, 1);
+  pdu->ul_cqi = rand8();
+  pdu->timing_advance = rand16_range(0, 63);
+  pdu->rssi = rand16_range(0, 1280);
+
+  // SR
+  if (pdu->pduBitmap & 0x01) {
+    fill_uci_indication_sr_pdu_0_1(&pdu->sr);
+  }
+  // HARQ
+  if ((pdu->pduBitmap >> 1) & 0x01) {
+    fill_uci_indication_harq_pdu_0_1(&pdu->harq);
+  }
+}
+
+static void fill_uci_indication_PUCCH_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu)
+{
+  pdu->pduBitmap = rand8_range(0, 0b1111);
+  pdu->handle = rand32();
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->pucch_format = rand8_range(0, 2);
+  pdu->ul_cqi = rand8();
+  pdu->timing_advance = rand16_range(0, 63);
+  pdu->rssi = rand16_range(0, 1280);
+  // SR
+  if (pdu->pduBitmap & 0x01) {
+    fill_uci_indication_sr_pdu_2_3_4(&pdu->sr);
+  }
+  // HARQ
+  if ((pdu->pduBitmap >> 1) & 0x01) {
+    fill_uci_indication_harq_pdu_2_3_4(&pdu->harq);
+  }
+  // CSI Part 1
+  if ((pdu->pduBitmap >> 2) & 0x01) {
+    fill_uci_indication_csi_part1(&pdu->csi_part1);
+  }
+  // CSI Part 2
+  if ((pdu->pduBitmap >> 3) & 0x01) {
+    fill_uci_indication_csi_part2(&pdu->csi_part2);
+  }
+}
+
+static void fill_uci_indication_UCI(nfapi_nr_uci_t *uci)
+{
+  uci->pdu_type = rand16_range(NFAPI_NR_UCI_PUSCH_PDU_TYPE, NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE);
+  uci->pdu_size = rand16();
+  switch (uci->pdu_type) {
+    case NFAPI_NR_UCI_PUSCH_PDU_TYPE:
+      fill_uci_indication_PUSCH(&uci->pusch_pdu);
+      break;
+    case NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE:
+      fill_uci_indication_PUCCH_0_1(&uci->pucch_pdu_format_0_1);
+      break;
+    case NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE:
+      fill_uci_indication_PUCCH_2_3_4(&uci->pucch_pdu_format_2_3_4);
+      break;
+    default:
+      AssertFatal(1 == 0, "Unknown UCI.indication PDU Type %d\n", uci->pdu_type);
+      break;
+  }
+}
+
+static void fill_uci_indication(nfapi_nr_uci_indication_t *msg)
+{
+  msg->sfn = rand16_range(0, 1023);
+  msg->slot = rand16_range(0, 159);
+  msg->num_ucis = rand8_range(1, NFAPI_NR_UCI_IND_MAX_PDU); // Minimum 1 PDUs in order to test at least one
+  msg->uci_list = calloc_or_fail(msg->num_ucis, sizeof(*msg->uci_list));
+  for (int crc_idx = 0; crc_idx < msg->num_ucis; ++crc_idx) {
+    fill_uci_indication_UCI(&msg->uci_list[crc_idx]);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_uci_indication_t *req)
+{
+  size_t message_size = get_uci_indication_size(req);
+  uint8_t *msg_buf = calloc_or_fail(message_size, sizeof(uint8_t));
+  /*uint8_t msg_buf[1024*1024*3];
+  size_t message_size = sizeof(msg_buf);*/
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, message_size, NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_uci_indication_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_uci_indication(&unpacked_req, req));
+  free_uci_indication(&unpacked_req);
+  free(msg_buf);
+}
+
+static void test_copy(const nfapi_nr_uci_indication_t *msg)
+{
+  // Test copy function
+  nfapi_nr_uci_indication_t copy = {0};
+  copy_uci_indication(msg, &copy);
+  DevAssert(eq_uci_indication(msg, &copy));
+  free_uci_indication(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_uci_indication_t *req = calloc_or_fail(1, sizeof(nfapi_nr_uci_indication_t));
+  req->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION;
+  // Get the actual allocated size
+  printf("Allocated size before filling: %zu bytes\n", get_uci_indication_size(req));
+  // Fill TX_DATA request
+  fill_uci_indication(req);
+  printf("Allocated size after filling: %zu bytes\n", get_uci_indication_size(req));
+  // Perform tests
+  test_pack_unpack(req);
+  test_copy(req);
+  // All tests successful!
+  free_uci_indication(req);
+  free(req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_ul_dci_request_test.c b/nfapi/tests/p7/nr_fapi_ul_dci_request_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..b1bc910da8d25b306cc3953d4ed3f2e214f687e6
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_ul_dci_request_test.c
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_beamforming(nfapi_nr_tx_precoding_and_beamforming_t *precodingAndBeamforming)
+{
+  precodingAndBeamforming->num_prgs = rand16_range(1, NFAPI_MAX_NUM_PRGS);
+  precodingAndBeamforming->prg_size = rand16_range(1, 275);
+  precodingAndBeamforming->dig_bf_interfaces = rand8_range(0,NFAPI_MAX_NUM_BG_IF);
+  for (int prg = 0; prg < precodingAndBeamforming->num_prgs; ++prg) {
+    precodingAndBeamforming->prgs_list[prg].pm_idx = rand16();
+    for (int dbf_if = 0; dbf_if < precodingAndBeamforming->dig_bf_interfaces; ++dbf_if) {
+      precodingAndBeamforming->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx = rand16();
+    }
+  }
+}
+
+static void fill_ul_dci_request_pdcch_pdu(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdu)
+{
+  pdu->BWPSize = rand16();
+  pdu->BWPStart = rand16();
+  pdu->SubcarrierSpacing = rand8();
+  pdu->CyclicPrefix = rand8();
+  pdu->StartSymbolIndex = rand8();
+  pdu->DurationSymbols = rand8();
+  for (int fdr_idx = 0; fdr_idx < 6; ++fdr_idx) {
+    pdu->FreqDomainResource[fdr_idx] = rand8();
+  }
+  pdu->CceRegMappingType = rand8();
+  pdu->RegBundleSize = rand8();
+  pdu->InterleaverSize = rand8();
+  pdu->CoreSetType = rand8();
+  pdu->ShiftIndex = rand8();
+  pdu->precoderGranularity = rand8();
+  pdu->numDlDci = rand8_range(1, MAX_DCI_CORESET);
+  for (int dl_dci = 0; dl_dci < pdu->numDlDci; ++dl_dci) {
+    pdu->dci_pdu[dl_dci].RNTI = rand16();
+    pdu->dci_pdu[dl_dci].ScramblingId = rand16();
+    pdu->dci_pdu[dl_dci].ScramblingRNTI = rand16();
+    pdu->dci_pdu[dl_dci].CceIndex = rand8();
+    pdu->dci_pdu[dl_dci].AggregationLevel = rand8();
+    fill_beamforming(&pdu->dci_pdu[dl_dci].precodingAndBeamforming);
+    pdu->dci_pdu[dl_dci].beta_PDCCH_1_0 = rand8();
+    pdu->dci_pdu[dl_dci].powerControlOffsetSS = rand8();
+    pdu->dci_pdu[dl_dci].PayloadSizeBits = rand16_range(0, DCI_PAYLOAD_BYTE_LEN * 8);
+    generate_payload(pdu->dci_pdu[dl_dci].PayloadSizeBits, pdu->dci_pdu[dl_dci].Payload);
+  }
+}
+
+static void fill_ul_dci_request_pdu(nfapi_nr_ul_dci_request_pdus_t *pdu)
+{
+  pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE;
+  pdu->PDUSize = rand16();
+  fill_ul_dci_request_pdcch_pdu(&pdu->pdcch_pdu.pdcch_pdu_rel15);
+}
+
+static void fill_ul_dci_request(nfapi_nr_ul_dci_request_t *msg)
+{
+  msg->SFN = rand16_range(0, 1023);
+  msg->Slot = rand16_range(0, 159);
+  msg->numPdus = rand8_range(1, 10); // Minimum 1 PDUs in order to test at least one
+  printf(" NUM PDUS  %d\n", msg->numPdus);
+  for (int pdu_idx = 0; pdu_idx < msg->numPdus; ++pdu_idx) {
+    fill_ul_dci_request_pdu(&msg->ul_dci_pdu_list[pdu_idx]);
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_ul_dci_request_t *req)
+{
+  uint8_t msg_buf[1024 * 1024 * 2];
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, sizeof(msg_buf), NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_ul_dci_request_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_ul_dci_request(&unpacked_req, req));
+  free_ul_dci_request(&unpacked_req);
+}
+
+static void test_copy(const nfapi_nr_ul_dci_request_t *msg)
+{
+  // Test copy function
+  nfapi_nr_ul_dci_request_t copy = {0};
+  copy_ul_dci_request(msg, &copy);
+  DevAssert(eq_ul_dci_request(msg, &copy));
+  free_ul_dci_request(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_ul_dci_request_t req = {.header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST};
+
+  // Fill UL_DCI request
+  fill_ul_dci_request(&req);
+  // Perform tests
+  test_pack_unpack(&req);
+  test_copy(&req);
+  // All tests successful!
+  free_ul_dci_request(&req);
+  return 0;
+}
diff --git a/nfapi/tests/p7/nr_fapi_ul_tti_request_test.c b/nfapi/tests/p7/nr_fapi_ul_tti_request_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..4f65cbfc9ea39357eb846e9904d6536290da690b
--- /dev/null
+++ b/nfapi/tests/p7/nr_fapi_ul_tti_request_test.c
@@ -0,0 +1,461 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.1  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+#include "dci_payload_utils.h"
+#include "nr_fapi_p7.h"
+#include "nr_fapi_p7_utils.h"
+
+static void fill_ul_tti_request_beamforming(nfapi_nr_ul_beamforming_t *beamforming_pdu)
+{
+  beamforming_pdu->trp_scheme = rand8();
+  beamforming_pdu->num_prgs = rand16_range(1, NFAPI_MAX_NUM_PRGS);
+  beamforming_pdu->prg_size = rand16_range(1, 275);
+  beamforming_pdu->dig_bf_interface = rand8_range(1,NFAPI_MAX_NUM_BG_IF);
+
+  for (int prg = 0; prg < beamforming_pdu->num_prgs; ++prg) {
+    for (int dbf_if = 0; dbf_if < beamforming_pdu->dig_bf_interface; ++dbf_if) {
+      beamforming_pdu->prgs_list[prg].dig_bf_interface_list[dbf_if].beam_idx = rand16();
+    }
+  }
+}
+
+static void fill_ul_tti_request_prach_pdu(nfapi_nr_prach_pdu_t *pdu)
+{
+  pdu->phys_cell_id = rand16_range(0, 1007);
+  pdu->num_prach_ocas = rand8_range(1, 7);
+  pdu->prach_format = rand8_range(0, 13);
+  pdu->num_ra = rand8_range(0, 7);
+  pdu->prach_start_symbol = rand8_range(0, 13);
+  pdu->num_cs = rand16_range(0, 419);
+  fill_ul_tti_request_beamforming(&pdu->beamforming);
+}
+
+static void fill_ul_tti_request_pusch_pdu(nfapi_nr_pusch_pdu_t *pdu)
+{
+  pdu->pdu_bit_map = rand16_range(0b0000, 0b1111);
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->handle = rand32();
+  pdu->bwp_size = rand16_range(1, 275);
+  pdu->bwp_start = rand16_range(0, 274);
+  pdu->subcarrier_spacing = rand8_range(0, 4);
+  pdu->cyclic_prefix = rand8_range(0, 1);
+  pdu->target_code_rate = rand16_range(300, 9480);
+  uint8_t transform_precoding = rand8_range(0, 1);
+  uint8_t qam_mod_order_values[] = {1, 2, 4, 6, 8};
+  // Value: 2,4,6,8 if transform precoding is disabled
+  // Value: 1,2,4,6,8 if transform precoding is enabled
+  pdu->qam_mod_order = qam_mod_order_values[rand8_range(1 - pdu->transform_precoding, 4)];
+  pdu->mcs_index = rand8_range(0, 31);
+  pdu->mcs_table = rand8_range(0, 4);
+  pdu->transform_precoding = transform_precoding;
+  pdu->data_scrambling_id = rand16();
+  pdu->nrOfLayers = rand8_range(1, 4);
+  // Bitmap occupying the 14 LSBs
+  pdu->ul_dmrs_symb_pos = rand16_range(0b00000000000000, 0b11111111111111);
+  pdu->dmrs_config_type = rand8_range(0, 1);
+  pdu->ul_dmrs_scrambling_id = rand16();
+  pdu->pusch_identity = rand16_range(0, 1007);
+  pdu->scid = rand8_range(0, 1);
+  pdu->num_dmrs_cdm_grps_no_data = rand8_range(1, 3);
+  // Bitmap occupying the 11 LSBs
+  pdu->dmrs_ports = rand16_range(0b00000000000, 0b11111111111);
+  pdu->resource_alloc = rand8_range(0, 1);
+  for (int i = 0; i < 36; ++i) {
+    pdu->rb_bitmap[i] = rand8();
+  }
+  pdu->rb_start = rand16_range(0, 274);
+  pdu->rb_size = rand16_range(1, 275);
+  pdu->vrb_to_prb_mapping = 0;
+  pdu->frequency_hopping = rand8_range(0, 1);
+  pdu->tx_direct_current_location = rand16_range(0, 4095);
+  pdu->uplink_frequency_shift_7p5khz = rand8_range(0, 1);
+  pdu->start_symbol_index = rand8_range(0, 13);
+  pdu->nr_of_symbols = rand8_range(1, 14);
+
+  // Check if PUSCH_PDU_BITMAP_PUSCH_DATA bit is set
+  if (pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_DATA) {
+    nfapi_nr_pusch_data_t *pusch_data = &pdu->pusch_data;
+    pusch_data->rv_index = rand8_range(0, 3);
+    pusch_data->harq_process_id = rand8_range(0, 15);
+    pusch_data->new_data_indicator = rand8_range(0, 1);
+    // TBSize is 32 bits in width, but the value is from 0 to 65535 ( max for 16 bits )
+    pusch_data->tb_size = rand16();
+    // num_cb set always to 0, due to OAI not supporting CBG
+    pusch_data->num_cb = 0;
+    for (int i = 0; i < (pusch_data->num_cb + 7) / 8; ++i) {
+      pusch_data->cb_present_and_position[i] = 0;
+    }
+  }
+
+  // Check if PUSCH_PDU_BITMAP_PUSCH_UCI bit is set
+  if (pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_UCI) {
+    nfapi_nr_pusch_uci_t *pusch_uci = &pdu->pusch_uci;
+    // For testing purposes "decide" here if it uses small block length or polar
+    pusch_uci->harq_ack_bit_length = rand16_range(0, 1706);
+    if (pusch_uci->harq_ack_bit_length <= 11) {
+      pusch_uci->csi_part1_bit_length = rand16_range(0, 11);
+      pusch_uci->csi_part2_bit_length = rand16_range(0, 11);
+    } else {
+      pusch_uci->csi_part1_bit_length = rand16_range(12, 1706);
+      pusch_uci->csi_part2_bit_length = rand16_range(12, 1706);
+    }
+    pusch_uci->alpha_scaling = rand8_range(0, 3);
+    pusch_uci->beta_offset_harq_ack = rand8_range(0, 15);
+    pusch_uci->beta_offset_csi1 = rand8_range(0, 18);
+    pusch_uci->beta_offset_csi2 = rand8_range(0, 18);
+  }
+
+  // Check if PUSCH_PDU_BITMAP_PUSCH_PTRS bit is set
+  if (pdu->pdu_bit_map & PUSCH_PDU_BITMAP_PUSCH_PTRS) {
+    nfapi_nr_pusch_ptrs_t *pusch_ptrs = &pdu->pusch_ptrs;
+    pusch_ptrs->num_ptrs_ports = rand8_range(1, 2);
+    pusch_ptrs->ptrs_ports_list = calloc(pusch_ptrs->num_ptrs_ports, sizeof(nfapi_nr_ptrs_ports_t));
+    for (int ptrs_port = 0; ptrs_port < pusch_ptrs->num_ptrs_ports; ++ptrs_port) {
+      // Bitmap occupying the 12 LSBs
+      pusch_ptrs->ptrs_ports_list[ptrs_port].ptrs_port_index = rand16_range(0b000000000000, 0b111111111111);
+      pusch_ptrs->ptrs_ports_list[ptrs_port].ptrs_dmrs_port = rand8_range(0, 11);
+      pusch_ptrs->ptrs_ports_list[ptrs_port].ptrs_re_offset = rand8_range(0, 11);
+    }
+    pusch_ptrs->ptrs_time_density = rand8_range(0, 2);
+    pusch_ptrs->ptrs_freq_density = rand8_range(0, 1);
+    pusch_ptrs->ul_ptrs_power = rand8_range(0, 3);
+  }
+
+  // Check if PUSCH_PDU_BITMAP_DFTS_OFDM bit is set
+  if (pdu->pdu_bit_map & PUSCH_PDU_BITMAP_DFTS_OFDM) {
+    nfapi_nr_dfts_ofdm_t *dfts_ofdm = &pdu->dfts_ofdm;
+    dfts_ofdm->low_papr_group_number = rand8_range(0, 29);
+    dfts_ofdm->low_papr_sequence_number = rand16();
+    dfts_ofdm->ul_ptrs_sample_density = rand8_range(1, 8);
+    dfts_ofdm->ul_ptrs_time_density_transform_precoding = rand8_range(1, 4);
+  }
+
+  fill_ul_tti_request_beamforming(&pdu->beamforming);
+  pdu->maintenance_parms_v3.ldpcBaseGraph = rand8();
+  pdu->maintenance_parms_v3.tbSizeLbrmBytes = rand32();
+}
+
+static void fill_ul_tti_request_pucch_pdu(nfapi_nr_pucch_pdu_t *pdu)
+{
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->handle = rand32();
+  pdu->bwp_size = rand16_range(1, 275);
+  pdu->bwp_start = rand16_range(0, 274);
+  pdu->subcarrier_spacing = rand8_range(0, 4);
+  pdu->cyclic_prefix = rand8_range(0, 1);
+  pdu->format_type = rand8_range(0, 4);
+  pdu->multi_slot_tx_indicator = rand8_range(0, 3);
+  pdu->pi_2bpsk = rand8_range(0, 1);
+  pdu->prb_start = rand16_range(0, 274);
+  pdu->prb_size = rand16_range(1, 16);
+  pdu->start_symbol_index = rand8_range(0, 13);
+  if (pdu->format_type == 0 || pdu->format_type == 2) {
+    pdu->nr_of_symbols = rand8_range(1, 2);
+  } else {
+    pdu->nr_of_symbols = rand8_range(4, 14);
+  }
+  pdu->freq_hop_flag = rand8_range(0, 1);
+  pdu->second_hop_prb = rand16_range(0, 274);
+  // Following 4 parameters are Valid for formats 0, 1, 3 and 4, assuming that otherwise, set to 0
+  if (pdu->format_type == 0 || pdu->format_type == 1 || pdu->format_type == 3 || pdu->format_type == 4) {
+    pdu->group_hop_flag = rand8_range(0, 1);
+    pdu->sequence_hop_flag = rand8_range(0, 1);
+    pdu->hopping_id = rand16_range(0, 1023);
+    pdu->initial_cyclic_shift = rand16_range(0, 11);
+  } else {
+    pdu->group_hop_flag = 0;
+    pdu->sequence_hop_flag = 0;
+    pdu->hopping_id = 0;
+    pdu->initial_cyclic_shift = 0;
+  }
+  // Valid for format 2, 3 and 4.
+  if (pdu->format_type == 2 || pdu->format_type == 3 || pdu->format_type == 4) {
+    pdu->data_scrambling_id = rand16_range(0, 1023);
+  } else {
+    pdu->data_scrambling_id = 0;
+  }
+
+  // Valid for format 1.
+  if (pdu->format_type == 1) {
+    pdu->time_domain_occ_idx = rand8_range(0, 6);
+  } else {
+    pdu->time_domain_occ_idx = 0;
+  }
+
+  // the following 2 parameters are Valid for format 4.
+  if (pdu->format_type == 4) {
+    pdu->pre_dft_occ_idx = rand8_range(0, 3);
+    // Value: 2 or 4
+    pdu->pre_dft_occ_len = 2 + (2 * rand8_range(0, 1));
+  } else {
+    pdu->pre_dft_occ_idx = 0;
+    pdu->pre_dft_occ_len = 0;
+  }
+
+  // Valid for formats 3 and 4.
+  if (pdu->format_type == 3 || pdu->format_type == 4) {
+    pdu->add_dmrs_flag = rand8_range(0, 1);
+  } else {
+    pdu->add_dmrs_flag = 0;
+  }
+
+  // Valid for format 2.
+  if (pdu->format_type == 2) {
+    pdu->dmrs_scrambling_id = rand16();
+  } else {
+    pdu->dmrs_scrambling_id = 0;
+  }
+
+  // Valid for format 4.
+  if (pdu->format_type == 4) {
+    pdu->dmrs_cyclic_shift = rand8_range(0, 9);
+  } else {
+    pdu->dmrs_cyclic_shift = 0;
+  }
+
+  // Valid for format 0 and 1
+  if (pdu->format_type == 0 || pdu->format_type == 1) {
+    pdu->sr_flag = rand8_range(0, 1);
+  } else {
+    pdu->sr_flag = 0;
+  }
+  //	Value:
+  //	0 = no HARQ bits
+  //	1->2 = Valid for Formats 0 and 1
+  //	2 -> 1706 = Valid for Formats 2, 3 and 4
+  if (pdu->format_type == 0 || pdu->format_type == 1) {
+    //{0,1,2}
+    pdu->bit_len_harq = rand16_range(0, 2);
+  } else {
+    // {0}∪{2,…,1706}
+    uint16_t bit_len_harq = rand16_range(0, 1705);
+    if (bit_len_harq == 0) {
+      pdu->bit_len_harq = 0;
+    } else {
+      // Shift range {1,…,1705} -> {2,…,1706}
+      pdu->bit_len_harq = bit_len_harq + 1;
+    }
+  }
+
+  // Following 2 parameters are Valid for format 2, 3 and 4.
+  if (pdu->format_type == 2 || pdu->format_type == 3 || pdu->format_type == 4) {
+    pdu->bit_len_csi_part1 = rand16_range(0, 1706);
+    pdu->bit_len_csi_part2 = rand16_range(0, 1706);
+  } else {
+    pdu->bit_len_csi_part1 = 0;
+    pdu->bit_len_csi_part2 = 0;
+  }
+
+  fill_ul_tti_request_beamforming(&pdu->beamforming);
+}
+
+static void fill_ul_tti_request_srs_parameters(nfapi_v4_srs_parameters_t *params, const uint8_t num_symbols){
+  params->srs_bandwidth_size = rand16_range(4, 272);
+  for (int idx = 0; idx < num_symbols; ++idx) {
+    nfapi_v4_srs_parameters_symbols_t *symbol = &params->symbol_list[idx];
+    symbol->srs_bandwidth_start = rand16_range(0,268);
+    symbol->sequence_group = rand8_range(0,29);
+    symbol->sequence_number = rand8_range(0,1);
+  }
+
+#ifdef ENABLE_AERIAL
+  // For Aerial, we always process the 4 reported symbols, not only the ones indicated by num_symbols
+  for (int symbol_idx = num_symbols; symbol_idx < 4; ++symbol_idx) {
+    nfapi_v4_srs_parameters_symbols_t *symbol = &params->symbol_list[idx];
+    symbol->srs_bandwidth_start = rand16_range(0,268);
+    symbol->sequence_group = rand8_range(0,29);
+    symbol->sequence_number = rand8_range(0,1);
+  }
+#endif // ENABLE_AERIAL
+
+  params->usage = rand32_range(0, 0b1111);
+  const uint8_t nUsage = __builtin_popcount(params->usage);
+  for (int idx = 0; idx < nUsage; ++idx) {
+    params->report_type[idx] = rand8_range(0,1);
+  }
+  params->singular_Value_representation = rand8_range(0,1);
+  params->iq_representation = rand8_range(0,1);
+  params->prg_size = rand16_range(1,272);
+  params->num_total_ue_antennas = rand8_range(1, 16);
+  params->ue_antennas_in_this_srs_resource_set = rand32();
+  params->sampled_ue_antennas = rand32();
+  params->report_scope = rand8_range(0,1);
+  params->num_ul_spatial_streams_ports = rand8_range(0, 255);
+  for (int idx = 0; idx < params->num_ul_spatial_streams_ports; ++idx) {
+    params->Ul_spatial_stream_ports[idx] = rand8();
+  }
+}
+
+static void fill_ul_tti_request_srs_pdu(nfapi_nr_srs_pdu_t *pdu)
+{
+  pdu->rnti = rand16_range(1, 65535);
+  pdu->handle = rand32();
+  pdu->bwp_size = rand16_range(1, 275);
+  pdu->bwp_start = rand16_range(0, 274);
+  pdu->subcarrier_spacing = rand8_range(0, 4);
+  pdu->cyclic_prefix = rand8_range(0, 1);
+  pdu->num_ant_ports = rand8_range(0, 2);
+  pdu->num_symbols = rand8_range(0, 2);
+  pdu->num_repetitions = rand8_range(0, 2);
+  pdu->time_start_position = rand8_range(0, 13);
+  pdu->config_index = rand8_range(0, 63);
+  pdu->sequence_id = rand16_range(0, 1023);
+  pdu->bandwidth_index = rand8_range(0, 3);
+  pdu->comb_size = rand8_range(0, 1);
+  // Following 2 parameters value range differs according to comb_size
+  if (pdu->comb_size == 0) {
+    pdu->comb_offset = rand8_range(0, 1);
+    pdu->cyclic_shift = rand8_range(0, 7);
+  } else {
+    pdu->comb_offset = rand8_range(0, 3);
+    pdu->cyclic_shift = rand8_range(0, 11);
+  }
+  pdu->frequency_position = rand8_range(0, 67);
+  pdu->frequency_shift = rand16_range(0, 268);
+  pdu->frequency_hopping = rand8_range(0, 3);
+  pdu->group_or_sequence_hopping = rand8_range(0, 2);
+  pdu->resource_type = rand8_range(0, 2);
+  // Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560
+  const uint16_t t_srs_values[] = {1, 2, 3, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560};
+  pdu->t_srs = t_srs_values[rand16_range(0, 17)];
+  pdu->t_offset = rand16_range(0, 2559);
+  fill_ul_tti_request_beamforming(&pdu->beamforming);
+  fill_ul_tti_request_srs_parameters(&pdu->srs_parameters_v4, 1 << pdu->num_symbols);
+}
+
+static void fill_ul_tti_request(nfapi_nr_ul_tti_request_t *msg)
+{
+  msg->SFN = rand16_range(0, 1023);
+  msg->Slot = rand16_range(0, 159);
+  msg->n_pdus = rand8_range(4, 16); // Minimum 4 PDUs in order to test at least one of each
+
+  printf(" NUM PDUS  %d\n", msg->n_pdus);
+  msg->rach_present = 1; // rand8_range(0, 1); Always set to 1, since there can only be 1 PRACH PDU
+  printf(" NUM RACH PDUS  %d\n", msg->rach_present);
+  uint8_t available_PDUs = msg->n_pdus - msg->rach_present;
+  msg->n_ulsch = rand8_range(1, available_PDUs - 2);
+  printf(" NUM PUSCH PDUS  %d\n", msg->n_ulsch);
+  available_PDUs -= msg->n_ulsch;
+  msg->n_ulcch = rand8_range(1, available_PDUs - 1);
+  printf(" NUM PUCCH PDUS  %d\n", msg->n_ulcch);
+  // The variable available_PDUs now contains the number of SRS PDUs needed to add to reach n_pdus
+  available_PDUs -= msg->n_ulcch;
+  printf(" NUM SRS PDUS  %d\n", available_PDUs);
+  msg->n_group = rand8_range(0, NFAPI_MAX_NUM_GROUPS);
+  printf(" NUM Groups  %d\n", msg->n_group);
+
+  // Add PRACH PDU, if applicable
+
+  if (msg->rach_present == 1) {
+    nfapi_nr_ul_tti_request_number_of_pdus_t *prach_pdu = &msg->pdus_list[0];
+    prach_pdu->pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE;
+    prach_pdu->pdu_size = rand16();
+    fill_ul_tti_request_prach_pdu(&prach_pdu->prach_pdu);
+  }
+
+  // start either at 0 or 1, same value as rach_present
+  int pdu_idx = msg->rach_present;
+  // Assign all PUSCH PDUs
+  for (int i = 0; i < msg->n_ulsch; ++i, ++pdu_idx) {
+    nfapi_nr_ul_tti_request_number_of_pdus_t *pdu = &msg->pdus_list[pdu_idx];
+    pdu->pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE;
+    pdu->pdu_size = rand16();
+    fill_ul_tti_request_pusch_pdu(&pdu->pusch_pdu);
+  }
+  // Assign all PUCCH PDUs
+  for (int i = 0; i < msg->n_ulcch; ++i, ++pdu_idx) {
+    nfapi_nr_ul_tti_request_number_of_pdus_t *pdu = &msg->pdus_list[pdu_idx];
+    pdu->pdu_type = NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE;
+    pdu->pdu_size = rand16();
+    fill_ul_tti_request_pucch_pdu(&pdu->pucch_pdu);
+  }
+
+  // Assing all SRS PDUs
+  for (int i = 0; i < available_PDUs; ++i, ++pdu_idx) {
+    nfapi_nr_ul_tti_request_number_of_pdus_t *pdu = &msg->pdus_list[pdu_idx];
+    pdu->pdu_type = NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE;
+    pdu->pdu_size = rand16();
+    fill_ul_tti_request_srs_pdu(&pdu->srs_pdu);
+  }
+
+  for (int group_idx = 0; group_idx < msg->n_group; ++group_idx) {
+    nfapi_nr_ul_tti_request_number_of_groups_t *group = &msg->groups_list[group_idx];
+    group->n_ue = rand8_range(1, 6);
+    for (int ue = 0; ue < group->n_ue; ++ue) {
+      group->ue_list[ue].pdu_idx = rand8();
+    }
+  }
+}
+
+static void test_pack_unpack(nfapi_nr_ul_tti_request_t *req)
+{
+  uint8_t msg_buf[1024 * 1024 * 2];
+  // first test the packing procedure
+  int pack_result = fapi_nr_p7_message_pack(req, msg_buf, sizeof(msg_buf), NULL);
+
+  DevAssert(pack_result >= 0 + NFAPI_HEADER_LENGTH);
+  // update req message_length value with value calculated in message_pack procedure
+  req->header.message_length = pack_result; //- NFAPI_HEADER_LENGTH;
+  // test the unpacking of the header
+  // copy first NFAPI_HEADER_LENGTH bytes into a new buffer, to simulate SCTP PEEK
+  fapi_message_header_t header;
+  uint32_t header_buffer_size = NFAPI_HEADER_LENGTH;
+  uint8_t header_buffer[header_buffer_size];
+  for (int idx = 0; idx < header_buffer_size; idx++) {
+    header_buffer[idx] = msg_buf[idx];
+  }
+  uint8_t *pReadPackedMessage = header_buffer;
+  int unpack_header_result = fapi_nr_message_header_unpack(&pReadPackedMessage, NFAPI_HEADER_LENGTH, &header, sizeof(header), 0);
+  DevAssert(unpack_header_result >= 0);
+  DevAssert(header.message_id == req->header.message_id);
+  DevAssert(header.message_length == req->header.message_length);
+  // test the unpacking and compare with initial message
+  nfapi_nr_ul_tti_request_t unpacked_req = {0};
+  int unpack_result =
+      fapi_nr_p7_message_unpack(msg_buf, header.message_length + NFAPI_HEADER_LENGTH, &unpacked_req, sizeof(unpacked_req), 0);
+  DevAssert(unpack_result >= 0);
+  DevAssert(eq_ul_tti_request(&unpacked_req, req));
+  free_ul_tti_request(&unpacked_req);
+}
+
+static void test_copy(const nfapi_nr_ul_tti_request_t *msg)
+{
+  // Test copy function
+  nfapi_nr_ul_tti_request_t copy = {0};
+  copy_ul_tti_request(msg, &copy);
+  DevAssert(eq_ul_tti_request(msg, &copy));
+  free_ul_tti_request(&copy);
+}
+
+int main(int n, char *v[])
+{
+  fapi_test_init();
+
+  nfapi_nr_ul_tti_request_t req = {.header.message_id = NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST};
+
+  // Fill DL_TTI request
+  fill_ul_tti_request(&req);
+  // Perform tests
+  test_pack_unpack(&req);
+  test_copy(&req);
+  // All tests successful!
+  free_ul_tti_request(&req);
+  return 0;
+}
diff --git a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
index 3d26a190639f4ddac14cc70895f6b00fbb3558dd..81d4462d2a93f762dee07db415ee02b1d21cc4cb 100644
--- a/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
+++ b/openair1/PHY/CODING/nrLDPC_encoder/ldpc_generate_coefficient.c
@@ -386,7 +386,7 @@ static inline int encode_parity_check_part_orig(unsigned char *c,unsigned char *
       rate=5;
   }
   else {
-    printf("problem with BG\n");
+    printf("problem with BG: is %d\n", BG);
     return(-1);
   }
 
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index 73eda60dcd3042a10445be5362066ace46dbc71f..221e4634085f6fe00527fa4370321eb9700bd0d0 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -660,22 +660,21 @@ static void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, uint32
   }
 }
 
-int fill_srs_reported_symbol_list(nfapi_nr_srs_reported_symbol_t *prgs,
-                                  const nfapi_nr_srs_pdu_t *srs_pdu,
+int fill_srs_reported_symbol(nfapi_nr_srs_reported_symbol_t *reported_symbol,
+                             const nfapi_nr_srs_pdu_t *srs_pdu,
                                   const int N_RB_UL,
                                   const int8_t *snr_per_rb,
                                   const int srs_est) {
-
-  prgs->num_prgs = srs_pdu->beamforming.num_prgs;
-  for(int prg_idx = 0; prg_idx < prgs->num_prgs; prg_idx++) {
+  reported_symbol->num_prgs = srs_pdu->beamforming.num_prgs;
+  for (int prg_idx = 0; prg_idx < reported_symbol->num_prgs; prg_idx++) {
     if (srs_est<0) {
-      prgs->prg_list[prg_idx].rb_snr = 0xFF;
+      reported_symbol->prg_list[prg_idx].rb_snr = 0xFF;
     } else if (snr_per_rb[prg_idx] < -64) {
-      prgs->prg_list[prg_idx].rb_snr = 0;
+      reported_symbol->prg_list[prg_idx].rb_snr = 0;
     } else if (snr_per_rb[prg_idx] > 63) {
-      prgs->prg_list[prg_idx].rb_snr = 0xFE;
+      reported_symbol->prg_list[prg_idx].rb_snr = 0xFE;
     } else {
-      prgs->prg_list[prg_idx].rb_snr = (snr_per_rb[prg_idx] + 64) << 1;
+      reported_symbol->prg_list[prg_idx].rb_snr = (snr_per_rb[prg_idx] + 64) << 1;
     }
   }
 
@@ -1065,7 +1064,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx)
             nr_srs_bf_report.num_symbols = 1 << srs_pdu->num_symbols;
             nr_srs_bf_report.wide_band_snr = srs_est >= 0 ? (gNB->srs->snr + 64) << 1 : 0xFF; // 0xFF will be set if this field is invalid
             nr_srs_bf_report.num_reported_symbols = 1 << srs_pdu->num_symbols;
-            fill_srs_reported_symbol_list(&nr_srs_bf_report.prgs, srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est);
+            fill_srs_reported_symbol(&nr_srs_bf_report.reported_symbol_list[0], srs_pdu, frame_parms->N_RB_UL, snr_per_rb, srs_est);
 
 #ifdef SRS_IND_DEBUG
             LOG_I(NR_PHY, "nr_srs_bf_report.prg_size = %i\n", nr_srs_bf_report.prg_size);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 3c33821b66f66fc57e4cf82bc08c08f7b1483600..e161fa50ab32c2db42cb40a24f41929a0952877b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -725,6 +725,10 @@ static void _nr_rx_sdu(const module_id_t gnb_mod_idP,
           timing_advance,
           sduP,
           rssi);
+    if (harq_pid < 0) {
+      LOG_E(NR_MAC, "UE %04x received ULSCH when feedback UL HARQ %d (unexpected ULSCH transmission)\n", rntiP, harq_pid);
+      return;
+    }
 
     // if not missed detection (10dB threshold for now)
     if (rssi > 0) {
@@ -1401,10 +1405,10 @@ void handle_nr_srs_measurements(const module_id_t module_id,
       const int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold;
       uint16_t *ulprbbl = nr_mac->ulprbbl;
 
-      uint16_t num_rbs = nr_srs_bf_report.prg_size * nr_srs_bf_report.prgs.num_prgs;
+      uint16_t num_rbs = nr_srs_bf_report.prg_size * nr_srs_bf_report.reported_symbol_list[0].num_prgs;
       memset(ulprbbl, 0, num_rbs * sizeof(uint16_t));
       for (int rb = 0; rb < num_rbs; rb++) {
-        int snr = (nr_srs_bf_report.prgs.prg_list[rb / nr_srs_bf_report.prg_size].rb_snr >> 1) - 64;
+        int snr = (nr_srs_bf_report.reported_symbol_list[0].prg_list[rb / nr_srs_bf_report.prg_size].rb_snr >> 1) - 64;
         if (snr < wide_band_snr_dB - ul_prbblack_SNR_threshold) {
           ulprbbl[rb] = 0x3FFF; // all symbols taken
         }
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index fd392ceae8d39be788bddccdc210640b5dfd0af8..507e4191d0e0721b0bdc9137b9654c0ebd292397 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -146,20 +146,17 @@ void handle_nr_uci(NR_UL_IND_t *UL_info)
 
 static bool crc_sfn_slot_matcher(void *wanted, void *candidate)
 {
-  nfapi_p7_message_header_t *msg = candidate;
-  int sfn_sf = *(int*)wanted;
+  nfapi_nr_p7_message_header_t *msg = candidate;
+  int sfn_sf = *(int *)wanted;
 
-  switch (msg->message_id)
-  {
-    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
-    {
+  switch (msg->message_id) {
+    case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: {
       nfapi_nr_crc_indication_t *ind = candidate;
       return NFAPI_SFNSLOT2SFN(sfn_sf) == ind->sfn && NFAPI_SFNSLOT2SLOT(sfn_sf) == ind->slot;
     }
 
     default:
       LOG_E(NR_MAC, "sfn_slot_match bad ID: %d\n", msg->message_id);
-
   }
   return false;
 }