diff --git a/CMakeLists.txt b/CMakeLists.txt
index edd9c18657c236d03390f0ea98202e54521f8d40..e3741d1f9b06db7cad30d425de5043d2d930f4ec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,7 +43,7 @@ include("cmake_targets/CPM.cmake")
 option(CCACHE_ACTIVE "CCache" ON)
 find_program(CCACHE_FOUND ccache)
 if(CCACHE_FOUND AND CCACHE_ACTIVE)
-  if(${CMAKE_VERSION} VERSION_LESS "3.4.0") 
+  if(${CMAKE_VERSION} VERSION_LESS "3.4.0")
     set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
     message(STATUS "Found ccache in ${CCACHE_FOUND}. Using ccache. CMake < 3.4")
   else()
@@ -105,13 +105,13 @@ add_list_string_option(CMAKE_BUILD_TYPE "RelWithDebInfo" "Choose the type of bui
 
 # in case /proc/cpuinfo exists we want to inspect available Intrinsics
 # -so not to go always through SIMDE emulation
-# -so to avoid AVX512 instructions generation by gcc   
+# -so to avoid AVX512 instructions generation by gcc
 if(EXISTS "/proc/cpuinfo" AND NOT CROSS_COMPILE)
   file(STRINGS "/proc/cpuinfo" CPUFLAGS REGEX flags LIMIT_COUNT 1)
 else()
   message(WARNING "did not find /proc/cpuinfo -- not setting any x86-specific compilation variables")
 endif()
- 
+
 eval_boolean(AUTODETECT_AVX512 DEFINED CPUFLAGS AND CPUFLAGS MATCHES "avx512")
 add_boolean_option(AVX512 ${AUTODETECT_AVX512} "Whether AVX512 intrinsics is available on the host processor" ON)
 
@@ -271,6 +271,11 @@ add_boolean_option(UE_AUTOTEST_TRACE   False "Activate UE autotest specific logs
 add_boolean_option(UE_DEBUG_TRACE      False "Activate UE debug trace" ON)
 add_boolean_option(UE_TIMING_TRACE     False "Activate UE timing trace" ON)
 
+add_boolean_option(TRACY_ENABLE OFF "Enable tracy instrumentation" ON)
+if (TRACY_ENABLE)
+  CPMAddPackage("gh:wolfpld/tracy#v0.11.1")
+endif()
+
 set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti)
 add_library(ITTI ${OCP_ITTI}/intertask_interface.cpp)
 target_link_libraries(ITTI PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
@@ -636,7 +641,8 @@ if (cap_FOUND)
   target_link_libraries(UTIL PRIVATE cap)
   target_compile_definitions(UTIL PRIVATE HAVE_LIB_CAP)
 endif()
-target_link_libraries(UTIL PUBLIC ${T_LIB} pthread LOG thread-pool utils)
+target_link_libraries(UTIL PUBLIC ${T_LIB} pthread LOG thread-pool utils barrier actor)
+target_link_libraries(UTIL PUBLIC instrumentation)
 
 set(SECURITY_SRC
   ${OPENAIR3_DIR}/SECU/secu_defs.c
@@ -677,7 +683,7 @@ set(SCHED_NR_SRC
   ${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c
 )
 add_library(SCHED_NR_LIB ${SCHED_NR_SRC})
-target_link_libraries(SCHED_NR_LIB PRIVATE asn1_nr_rrc_hdrs)
+target_link_libraries(SCHED_NR_LIB PRIVATE asn1_nr_rrc_hdrs UTIL)
 
 set(SCHED_SRC_RU
   ${OPENAIR1_DIR}/SCHED/ru_procedures.c
@@ -695,7 +701,7 @@ set(SCHED_SRC_UE
   ${OPENAIR1_DIR}/SCHED_UE/srs_pc.c
 )
 add_library(SCHED_UE_LIB ${SCHED_SRC_UE})
-target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
+target_link_libraries(SCHED_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
 
 set(SCHED_SRC_NR_UE
   ${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -706,7 +712,7 @@ set(SCHED_SRC_NR_UE
   ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c
 )
 add_library(SCHED_NR_UE_LIB ${SCHED_SRC_NR_UE})
-target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
+target_link_libraries(SCHED_NR_UE_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
 
 # nFAPI
 #################################
@@ -717,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)
@@ -742,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()
@@ -758,7 +764,8 @@ set(NFAPI_USER_SRC
   ${NFAPI_USER_DIR}/gnb_ind_vars.c
 )
 add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC})
-target_link_libraries(NFAPI_USER_LIB PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
+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
@@ -1118,7 +1125,7 @@ set(PHY_SRC_UE ${PHY_SRC_UE} ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_llr_comp
 add_library(PHY_COMMON ${PHY_SRC_COMMON})
 target_link_libraries(PHY_COMMON PRIVATE shlib_loader)
 add_dependencies(PHY_COMMON dfts)
-target_link_libraries(PHY_COMMON PRIVATE asn1_lte_rrc_hdrs)
+target_link_libraries(PHY_COMMON PRIVATE asn1_lte_rrc_hdrs PUBLIC UTIL)
 
 add_library(PHY ${PHY_SRC})
 target_link_libraries(PHY PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
@@ -1127,7 +1134,7 @@ pkg_check_modules(blas REQUIRED blas)
 pkg_check_modules(lapacke REQUIRED lapacke)
 
 add_library(PHY_UE ${PHY_SRC_UE})
-target_link_libraries(PHY_UE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs)
+target_link_libraries(PHY_UE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs UTIL)
 # RHEL needs also cblas, but Ubuntu does not have it. So `cblas_LIBRARIES` will
 # be empty for Ubuntu, a no-op
 pkg_check_modules(cblas cblas)
@@ -1135,6 +1142,7 @@ target_link_libraries(PHY_UE PRIVATE ${blas_LIBRARIES} ${cblas_LIBRARIES} ${lapa
 target_include_directories(PHY_UE PRIVATE ${blas_INCLUDE_DIRS} ${lapacke_INCLUDE_DIRS})
 
 add_library(PHY_NR_COMMON ${PHY_NR_SRC_COMMON})
+target_link_libraries(PHY_NR_COMMON PUBLIC UTIL)
 
 add_library(PHY_NR ${PHY_NR_SRC})
 target_link_libraries(PHY_NR nr_phy_common nr_common)
@@ -1144,10 +1152,10 @@ target_link_libraries(PHY_NR_NO_AVX_256 nr_phy_common nr_common)
 target_compile_definitions(PHY_NR_NO_AVX_256 PUBLIC USE_128BIT)
 
 add_library(PHY_NR_UE ${PHY_NR_UE_SRC})
-target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs nr_phy_common nr_common)
+target_link_libraries(PHY_NR_UE PRIVATE asn1_nr_rrc_hdrs nr_phy_common nr_common UTIL)
 
 add_library(PHY_RU ${PHY_SRC_RU})
-target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs)
+target_link_libraries(PHY_RU PRIVATE asn1_lte_rrc_hdrs UTIL)
 
 #Library for mex functions
 #########################3
@@ -1216,7 +1224,7 @@ set(NR_SDAP_SRC
   ${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap.c
   ${OPENAIR2_DIR}/SDAP/nr_sdap/nr_sdap_entity.c
   )
-  
+
 set(L2_SRC
   ${PDCP_DIR}/pdcp.c
   ${PDCP_DIR}/pdcp_fifo.c
@@ -2064,7 +2072,7 @@ if(E2_AGENT)
   target_link_libraries(nr-cuup PRIVATE e2_agent e2_agent_arg e2_ran_func_cuup)
   target_compile_definitions(nr-cuup PRIVATE ${E2AP_VERSION} ${KPM_VERSION} E2_AGENT)
 endif()
-                     
+
 # nr-uesoftmodem is  UE implementation
 #######################################
 
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 14c4ac582a8d5beab8c040d9b3655d1bfd246d7a..229c93b0432659a60fe827d98f8011d5ed224e39 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -2,3 +2,9 @@ add_subdirectory(utils)
 add_subdirectory(config/yaml)
 
 configure_file(oai_version.h.in oai_version.h @ONLY)
+
+add_library(instrumentation INTERFACE instrumentation.h)
+target_include_directories(instrumentation INTERFACE .)
+if (TRACY_ENABLE)
+  target_link_libraries(instrumentation INTERFACE Tracy::TracyClient)
+endif()
diff --git a/common/instrumentation.h b/common/instrumentation.h
new file mode 100644
index 0000000000000000000000000000000000000000..6810761f6981b7e1f8cd680b48399420a4362d9b
--- /dev/null
+++ b/common/instrumentation.h
@@ -0,0 +1,42 @@
+/*
+ * 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 INSTRUMENTATION_H
+#define INSTRUMENTATION_H
+
+#ifdef TRACY_ENABLE
+#include "tracy/TracyC.h"
+#endif
+
+#ifndef TracyCZone
+#define TracyCZone(...)
+#endif
+#ifndef TracyCZoneEnd
+#define TracyCZoneEnd(...)
+#endif
+#ifndef TracyCFrameMark
+#define TracyCFrameMark
+#endif
+#ifndef TracyCPlot
+#define TracyCPlot(...)
+#endif
+
+#endif
diff --git a/common/utils/CMakeLists.txt b/common/utils/CMakeLists.txt
index 7cf067dd14941fba750b65223e068d34399768be..ccb15bfd478b95ccdcf82bb739062f359a0ae544 100644
--- a/common/utils/CMakeLists.txt
+++ b/common/utils/CMakeLists.txt
@@ -19,3 +19,5 @@ target_link_libraries(utils PRIVATE ${T_LIB})
 if (ENABLE_TESTS)
   add_subdirectory(hashtable/tests)
 endif()
+add_subdirectory(barrier)
+add_subdirectory(actor)
diff --git a/common/utils/actor/CMakeLists.txt b/common/utils/actor/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..40057d347eb2b6d2c84781ae5f88a85ff3a0c58a
--- /dev/null
+++ b/common/utils/actor/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_library(actor actor.c)
+target_include_directories(actor PUBLIC ./)
+target_link_libraries(actor PUBLIC thread-pool)
+if (ENABLE_TESTS)
+  add_subdirectory(tests)
+endif()
diff --git a/common/utils/actor/README.md b/common/utils/actor/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..13a577a7a1ed6ee1015d9a7d7551c349c5d81331
--- /dev/null
+++ b/common/utils/actor/README.md
@@ -0,0 +1,13 @@
+# Overview
+
+This is a simple actor implementation (see https://en.wikipedia.org/wiki/Actor_model).
+
+Actor is implemented as a single thread with single producer/consumer queue as input. You can think of it as a single thread threadpool
+
+If you need concurrency, consider allocating more than one actor.
+
+# Thread safety
+
+There is two ways to ensure thread safety between two actors
+ - Use core affinity to set both actor to run on the same core.
+ - Use data separation, like in testcase thread_safety_with_actor_specific_data
diff --git a/common/utils/actor/actor.c b/common/utils/actor/actor.c
new file mode 100644
index 0000000000000000000000000000000000000000..68661ddb6d7c017846b37c656bc47fa0a8b75e2c
--- /dev/null
+++ b/common/utils/actor/actor.c
@@ -0,0 +1,87 @@
+/*
+ * 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 "thread-pool.h"
+#include "actor.h"
+#include "system.h"
+#include "assertions.h"
+
+void *actor_thread(void *arg);
+
+void init_actor(Actor_t *actor, const char *name, int core_affinity)
+{
+  actor->terminate = false;
+  initNotifiedFIFO(&actor->fifo);
+  char actor_name[16];
+  snprintf(actor_name, sizeof(actor_name), "%s%s", name, "_actor");
+  threadCreate(&actor->thread, actor_thread, (void *)actor, actor_name, core_affinity, OAI_PRIORITY_RT_MAX);
+}
+
+/// @brief Main actor thread
+/// @param arg actor pointer
+/// @return NULL
+void *actor_thread(void *arg)
+{
+  Actor_t *actor = arg;
+
+  // Infinite loop to process requests
+  do {
+    notifiedFIFO_elt_t *elt = pullNotifiedFIFO(&actor->fifo);
+    if (elt == NULL) {
+      AssertFatal(actor->terminate, "pullNotifiedFIFO() returned NULL\n");
+      break;
+    }
+
+    elt->processingFunc(NotifiedFifoData(elt));
+    if (elt->reponseFifo) {
+      pushNotifiedFIFO(elt->reponseFifo, elt);
+    } else
+      delNotifiedFIFO_elt(elt);
+  } while (!actor->terminate);
+
+  return NULL;
+}
+
+void destroy_actor(Actor_t *actor)
+{
+  actor->terminate = true;
+  abortNotifiedFIFO(&actor->fifo);
+  pthread_join(actor->thread, NULL);
+}
+
+static void self_destruct_fun(void *arg) {
+  Actor_t *actor = arg;
+  actor->terminate = true;
+  abortNotifiedFIFO(&actor->fifo);
+}
+
+void shutdown_actor(Actor_t *actor)
+{
+  notifiedFIFO_t response_fifo;
+  initNotifiedFIFO(&response_fifo);
+  notifiedFIFO_elt_t *elt = newNotifiedFIFO_elt(0, 0, &response_fifo, self_destruct_fun);
+  elt->msgData = actor;
+  pushNotifiedFIFO(&actor->fifo, elt);
+  elt = pullNotifiedFIFO(&response_fifo);
+  delNotifiedFIFO_elt(elt);
+  abortNotifiedFIFO(&response_fifo);
+  pthread_join(actor->thread, NULL);
+}
diff --git a/common/utils/actor/actor.h b/common/utils/actor/actor.h
new file mode 100644
index 0000000000000000000000000000000000000000..753ba8d00a5932a9d12bb66cfcdcb4610f1fc4fd
--- /dev/null
+++ b/common/utils/actor/actor.h
@@ -0,0 +1,52 @@
+/*
+ * 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 ACTOR_H
+#define ACTOR_H
+#include "thread-pool.h"
+
+#define INIT_ACTOR(ptr, name, core_affinity) init_actor((Actor_t *)ptr, name, core_affinity);
+
+#define DESTROY_ACTOR(ptr) destroy_actor((Actor_t *)ptr);
+
+#define SHUTDOWN_ACTOR(ptr) shutdown_actor((Actor_t *)ptr);
+
+typedef struct Actor_t {
+  notifiedFIFO_t fifo;
+  bool terminate;
+  pthread_t thread;
+} Actor_t;
+
+/// @brief Initialize the actor. Starts actor thread
+/// @param actor
+/// @param name Actor name. Thread name will be derived from it
+/// @param core_affinity Core affinity. Specify -1 for no affinity
+void init_actor(Actor_t *actor, const char *name, int core_affinity);
+
+/// @brief Destroy the actor. Free the memory, stop the thread.
+/// @param actor
+void destroy_actor(Actor_t *actor);
+
+/// @brief Gracefully shutdown the actor, letting all tasks previously started finish
+/// @param actor
+void shutdown_actor(Actor_t *actor);
+
+#endif
diff --git a/common/utils/actor/tests/CMakeLists.txt b/common/utils/actor/tests/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dd4a22a848a884f031ae9ffc910e3bff56c9c029
--- /dev/null
+++ b/common/utils/actor/tests/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_executable(test_actor test_actor.cpp)
+target_link_libraries(test_actor PRIVATE actor GTest::gtest thread-pool LOG)
+add_dependencies(tests test_actor)
+add_test(NAME test_actor
+  COMMAND ./test_actor)
diff --git a/common/utils/actor/tests/test_actor.cpp b/common/utils/actor/tests/test_actor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f613846a2c92ebb4d242c15944684d5f83e4781
--- /dev/null
+++ b/common/utils/actor/tests/test_actor.cpp
@@ -0,0 +1,134 @@
+/*
+ * 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 <stdio.h>
+#include <assert.h>
+#include <threads.h>
+#include <stdlib.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include "common/config/config_userapi.h"
+#include "log.h"
+
+extern "C" {
+#include "actor.h"
+configmodule_interface_t *uniqCfg;
+void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
+{
+  if (assert) {
+    abort();
+  } else {
+    exit(EXIT_SUCCESS);
+  }
+}
+}
+
+int num_processed = 0;
+
+void process(void *arg)
+{
+  num_processed++;
+}
+
+TEST(actor, schedule_one)
+{
+  Actor_t actor;
+  init_actor(&actor, "TEST", -1);
+  notifiedFIFO_elt_t *elt = newNotifiedFIFO_elt(0, 0, NULL, process);
+  pushNotifiedFIFO(&actor.fifo, elt);
+  shutdown_actor(&actor);
+  EXPECT_EQ(num_processed, 1);
+}
+
+TEST(actor, schedule_many)
+{
+  num_processed = 0;
+  Actor_t actor;
+  init_actor(&actor, "TEST", -1);
+  for (int i = 0; i < 100; i++) {
+    notifiedFIFO_elt_t *elt = newNotifiedFIFO_elt(0, 0, NULL, process);
+    pushNotifiedFIFO(&actor.fifo, elt);
+  }
+  shutdown_actor(&actor);
+  EXPECT_EQ(num_processed, 100);
+}
+
+// Thread safety can be ensured through core affinity - if two actors
+// are running on the same core they are thread safe
+TEST(DISABLED_actor, thread_safety_with_core_affinity)
+{
+  num_processed = 0;
+  int core = 0;
+  Actor_t actor;
+  init_actor(&actor, "TEST", core);
+  Actor_t actor2;
+  init_actor(&actor2, "TEST2", core);
+  for (int i = 0; i < 10000; i++) {
+    Actor_t *actor_ptr = i % 2 == 0 ? &actor : &actor2;
+    notifiedFIFO_elt_t *elt = newNotifiedFIFO_elt(0, 0, NULL, process);
+    pushNotifiedFIFO(&actor_ptr->fifo, elt);
+  }
+  shutdown_actor(&actor);
+  shutdown_actor(&actor2);
+  EXPECT_EQ(num_processed, 10000);
+}
+
+// Thread safety can be ensured through data separation, here using C inheritance-like
+// model
+typedef struct TestActor_t {
+  Actor_t actor;
+  int count;
+} TestActor_t;
+
+void process_thread_safe(void *arg)
+{
+  TestActor_t *actor = static_cast<TestActor_t *>(arg);
+  actor->count += 1;
+}
+
+TEST(actor, thread_safety_with_actor_specific_data)
+{
+  num_processed = 0;
+  int core = 0;
+  TestActor_t actor;
+  INIT_ACTOR(&actor, "TEST", core);
+  actor.count = 0;
+  TestActor_t actor2;
+  INIT_ACTOR(&actor2, "TEST2", core);
+  actor2.count = 0;
+  for (int i = 0; i < 10000; i++) {
+    TestActor_t *actor_ptr = i % 2 == 0 ? &actor : &actor2;
+    notifiedFIFO_elt_t *elt = newNotifiedFIFO_elt(0, 0, NULL, process_thread_safe);
+    elt->msgData = actor_ptr;
+    pushNotifiedFIFO(&actor_ptr->actor.fifo, elt);
+  }
+  SHUTDOWN_ACTOR(&actor);
+  SHUTDOWN_ACTOR(&actor2);
+  EXPECT_EQ(actor.count + actor2.count, 10000);
+}
+
+int main(int argc, char **argv)
+{
+  logInit();
+  g_log->log_component[UTIL].level = OAILOG_DEBUG;
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/common/utils/barrier/CMakeLists.txt b/common/utils/barrier/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7957f3e1cfcddb7f95e088d6862af4beb3f49b1b
--- /dev/null
+++ b/common/utils/barrier/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_library(barrier barrier.c)
+target_include_directories(barrier PUBLIC ./)
+target_link_libraries(barrier PUBLIC pthread)
+
+if (ENABLE_TESTS)
+  add_subdirectory(tests)
+endif()
diff --git a/common/utils/barrier/barrier.c b/common/utils/barrier/barrier.c
new file mode 100644
index 0000000000000000000000000000000000000000..574d6be4a387704a74127f826cbce1dce893f8a2
--- /dev/null
+++ b/common/utils/barrier/barrier.c
@@ -0,0 +1,75 @@
+/*
+ * 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 "barrier.h"
+#include "assertions.h"
+
+void dynamic_barrier_init(dynamic_barrier_t* barrier)
+{
+  int ret = pthread_mutex_init(&barrier->barrier_lock, NULL);
+  AssertFatal(ret == 0, "Mutex error %d", ret);
+  barrier->callback = NULL;
+  barrier->callback_arg = NULL;
+  barrier->completed_jobs = 0;
+}
+
+void dynamic_barrier_reset(dynamic_barrier_t* barrier)
+{
+  barrier->callback = NULL;
+  if (barrier->callback_arg != NULL) {
+    free(barrier->callback_arg);
+  }
+  barrier->callback_arg = NULL;
+  barrier->completed_jobs = 0;
+}
+
+void dynamic_barrier_join(dynamic_barrier_t* barrier)
+{
+  int ret = pthread_mutex_lock(&barrier->barrier_lock);
+  AssertFatal(ret == 0, "Mutex error %d", ret);
+  barrier->completed_jobs++;
+  if (barrier->callback) {
+    if (barrier->completed_jobs == barrier->max_joins) {
+      barrier->completed_jobs = 0;
+      barrier->callback(barrier->callback_arg);
+      barrier->callback = NULL;
+      barrier->callback_arg = NULL;
+    }
+  }
+  ret = pthread_mutex_unlock(&barrier->barrier_lock);
+  AssertFatal(ret == 0, "Mutex error %d", ret);
+}
+
+void dynamic_barrier_update(dynamic_barrier_t* barrier, int max_joins, callback_t callback, void* arg)
+{
+  int ret = pthread_mutex_lock(&barrier->barrier_lock);
+  AssertFatal(ret == 0, "Mutex error %d", ret);
+  if (barrier->completed_jobs == max_joins) {
+    barrier->completed_jobs = 0;
+    callback(arg);
+  } else {
+    barrier->max_joins = max_joins;
+    barrier->callback = callback;
+    barrier->callback_arg = arg;
+  }
+  ret = pthread_mutex_unlock(&barrier->barrier_lock);
+  AssertFatal(ret == 0, "Mutex error %d", ret);
+}
diff --git a/common/utils/barrier/barrier.h b/common/utils/barrier/barrier.h
new file mode 100644
index 0000000000000000000000000000000000000000..e27b56e76616ec4f094cec6f021bbc86448b1050
--- /dev/null
+++ b/common/utils/barrier/barrier.h
@@ -0,0 +1,57 @@
+/*
+ * 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 _BARRIER_H_
+#define _BARRIER_H_
+#include <stdint.h>
+#include <pthread.h>
+
+typedef void (*callback_t)(void*);
+
+/// @brief This thread barrier allows modifying the maximum joins after it is initialized
+typedef struct dynamic_barrier_t {
+  pthread_mutex_t barrier_lock;
+  int completed_jobs;
+  int max_joins;
+  callback_t callback;
+  void* callback_arg;
+} dynamic_barrier_t;
+
+/// @brief Initialize the barrier
+/// @param barrier
+void dynamic_barrier_init(dynamic_barrier_t* barrier);
+
+/// @brief Reset the barrier
+/// @param barrier
+void dynamic_barrier_reset(dynamic_barrier_t* barrier);
+
+/// @brief Perform join on the barrier. May run callback if it is already set
+/// @param barrier
+void dynamic_barrier_join(dynamic_barrier_t* barrier);
+
+/// @brief Set callback and max_joins. May run callback if the number of joins is already equal to max_joins
+/// @param barrier
+/// @param max_joins maximum number of joins before barrier triggers
+/// @param callback callback function
+/// @param arg callback function argument
+void dynamic_barrier_update(dynamic_barrier_t* barrier, int max_joins, callback_t callback, void* arg);
+
+#endif
diff --git a/common/utils/barrier/tests/CMakeLists.txt b/common/utils/barrier/tests/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bbe774b5964d2dd62830375465dabc46617f6bae
--- /dev/null
+++ b/common/utils/barrier/tests/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_executable(test_barrier test_barrier.cpp)
+target_link_libraries(test_barrier PRIVATE barrier GTest::gtest)
+add_dependencies(tests test_barrier)
+add_test(NAME test_barrier
+  COMMAND ./test_barrier)
diff --git a/common/utils/barrier/tests/test_barrier.cpp b/common/utils/barrier/tests/test_barrier.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..985b18c2988fd9b27b81217df42e9a59c01961c0
--- /dev/null
+++ b/common/utils/barrier/tests/test_barrier.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 <stdio.h>
+#include <assert.h>
+#include <threads.h>
+#include <stdlib.h>
+#include <gtest/gtest.h>
+
+extern "C" {
+#include "barrier.h"
+void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
+{
+  if (assert) {
+    abort();
+  } else {
+    exit(EXIT_SUCCESS);
+  }
+}
+}
+
+static int trigger_count = 0;
+static int triggered = 0;
+void f(void *arg)
+{
+  triggered = 1;
+  trigger_count++;
+}
+
+TEST(dynamic_barrier, trigger_once)
+{
+  dynamic_barrier_t barrier;
+  triggered = 0;
+  dynamic_barrier_init(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_update(&barrier, 4, f, NULL);
+  EXPECT_EQ(triggered, 1);
+}
+
+TEST(dynamic_barrier, trigger_twice)
+{
+  dynamic_barrier_t barrier;
+  triggered = 0;
+  dynamic_barrier_init(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_update(&barrier, 4, f, NULL);
+  EXPECT_EQ(triggered, 1);
+  triggered = 0;
+  dynamic_barrier_init(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_join(&barrier);
+  dynamic_barrier_update(&barrier, 4, f, NULL);
+  EXPECT_EQ(triggered, 1);
+}
+
+int dynamic_barrier_thread(void *thr_data)
+{
+  dynamic_barrier_t *barrier = (dynamic_barrier_t *)thr_data;
+  dynamic_barrier_join(barrier);
+  return 0;
+}
+
+int dynamic_barrier_update_thread(void *thr_data)
+{
+  dynamic_barrier_t *barrier = (dynamic_barrier_t *)thr_data;
+  dynamic_barrier_update(barrier, 3, f, NULL);
+  return 0;
+}
+
+TEST(dynamic_barrier, multithreaded)
+{
+  thrd_t thr[3];
+  dynamic_barrier_t barrier;
+  trigger_count = 0;
+  for (int i = 0; i < 300; i++) {
+    dynamic_barrier_init(&barrier);
+    thrd_t update_thread;
+    thrd_create(&update_thread, dynamic_barrier_update_thread, &barrier);
+    for (int n = 0; n < 3; ++n)
+      thrd_create(&thr[n], dynamic_barrier_thread, &barrier);
+    for (int n = 0; n < 3; ++n)
+      thrd_join(thr[n], NULL);
+    thrd_join(update_thread, NULL);
+  }
+  assert(trigger_count == 300);
+}
+
+int main(int argc, char **argv)
+{
+  testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/common/utils/nr/CMakeLists.txt b/common/utils/nr/CMakeLists.txt
index 979958d877069e557cdb878717904b7f0b3794f5..c99b9a06a713442cf4bebf7a7204b7fd37e9fc56 100644
--- a/common/utils/nr/CMakeLists.txt
+++ b/common/utils/nr/CMakeLists.txt
@@ -1,6 +1,6 @@
 add_library(nr_common nr_common.c)
 target_include_directories(nr_common PUBLIC .)
-target_link_libraries(nr_common PRIVATE UTIL)
+target_link_libraries(nr_common PUBLIC UTIL)
 if (ENABLE_TESTS)
   add_subdirectory(tests)
 endif()
diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt
index 959812d73a9bda9b4906037935ddaa07ccce855c..a7da081f093a7c53e0db500a2e81ec8e452f12b3 100644
--- a/common/utils/telnetsrv/CMakeLists.txt
+++ b/common/utils/telnetsrv/CMakeLists.txt
@@ -53,7 +53,7 @@ message(STATUS "No specific telnet functions for 4Gue")
 message(STATUS "Add 5Gue specific telnet functions in libtelnetsrv_5Gue.so")
 add_library(telnetsrv_5Gue MODULE telnetsrv_5Gue_measurements.c)
 add_dependencies(telnetsrv telnetsrv_5Gue)
-target_link_libraries(telnetsrv_5Gue PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
+target_link_libraries(telnetsrv_5Gue PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
 
 message(STATUS "Add CI specific telnet functions in libtelnetsrv_ci.so")
 add_library(telnetsrv_ci MODULE telnetsrv_ci.c)
@@ -79,4 +79,3 @@ add_dependencies(telnetsrv telnetsrv_rrc)
 set_target_properties(telnetsrv telnetsrv_enb telnetsrv_5Gue telnetsrv_ci telnetsrv_ciUE telnetsrv_bearer telnetsrv_rrc
                       PROPERTIES LIBRARY_OUTPUT_DIRECTORY ../../..
 )
-
diff --git a/common/utils/threadPool/thread-pool.h b/common/utils/threadPool/thread-pool.h
index b0e1b9e4e88e68e2c46b0c9cfc3bebbf4591193b..31395d7a9b74f5c0697e08321e1d94a0a3530fff 100644
--- a/common/utils/threadPool/thread-pool.h
+++ b/common/utils/threadPool/thread-pool.h
@@ -30,6 +30,7 @@
 #include <stdalign.h>
 #include <pthread.h>
 #include <unistd.h>
+#include <string.h>
 #include <sys/syscall.h>
 #include "assertions.h"
 #include "common/utils/time_meas.h"
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index 21e2f5ca8db8b6f4626f0c7287e97f85e555b90f..454faf1a1ec1677f515e3c961f5d14409d551520 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -136,7 +136,6 @@ These modes of operation are supported:
   - evalution of RSRP report
   - evaluation of CQI report
 - MAC scheduling of SR reception
-- Support of up to 16 UEs (can be increased to 32)
 - Intra-frequency handover
 
 ## gNB RLC
@@ -247,6 +246,11 @@ These modes of operation are supported:
   - Interfaces with PDCP and RLC for data send/receive at the CU and DU respectively (F1-U interface)
   - Interface with SDAP for data send/receive, capture of GTP-U Optional Header, GTP-U Extension Header and PDU Session Container.
 
+## Number of supported UEs
+
+* 16 by default (as defined in `MAX_MOBILES_PER_GNB`)
+* up to 64 if the configured bandwidth is sufficient (at leat 40 MHz)
+
 # OpenAirInterface 5G-NR UE Feature Set #
 
 ##  NR UE PHY Layer ##
diff --git a/doc/nr-ue-design.md b/doc/nr-ue-design.md
index 7ee42335d646a6c2c6476b46da316322e81fcb92..f1cef858e182159a5cb557f68cd8438ea258f8fe 100644
--- a/doc/nr-ue-design.md
+++ b/doc/nr-ue-design.md
@@ -13,13 +13,17 @@ The `UE_thread` function in `nr-ue.c` is the main top level thread that interact
 
 The UE exits when at any point in operation it gets out of synchronization. When the command line option `--non-stop` is used, the UE goes to 'Initial Synchronization' mode when it loses synchronization with gNB. However, this feature is not fully implemented and it is a work in progress at the time of writing this documentation. This will be the default behavior (not a command line option) when the feature is fully implemented.
 
+UE uses actors which are threads dedicated to particular activity. Sync Actor handles initial sync. DL Actors handle DLSCH PHY procedures. UL procedures are processed directly on the threadpool
+
+![design](nr-ue-threads.svg)
+
 ## Initial Synchronization Block
 ```mermaid
 graph TD
     start(Start) -->|UE_thread| rxRu["RU read<br/>(Reads two frames)"]
-    rxRu --> |Tpool thread| sync["SSB detection<br/>(PSS & SSS detection<br/>PBCH decoding<br/>SIB decoding)"]
+    rxRu --> |Sync Actor| sync["SSB detection<br/>(PSS & SSS detection<br/>PBCH decoding<br/>SIB decoding)"]
     rxRu --> |UE_thread| rxRuDummy["RU read<br/>(Dummy read till sync detection to avoid buffer overflow at radio)"]
-    sync --> |Tpool thread| frameSync["Frame synchronization<br/>(Shift received samples to align with frame)"]
+    sync --> |UE_thread| frameSync["Frame synchronization<br/>(Shift received samples to align with frame)"]
     rxRuDummy --> |UE_thread| frameSync
 ```
 ## Regular Slot Processing
@@ -27,9 +31,8 @@ graph TD
 graph TD
     sync["Frame synchronization<br/>(Shift received samples to align with frame)"] -->|UE_thread| hw_read["RU read (slot n)"]
     hw_read --> |UE_thread| rxPreProc["PBCH & PDCCH decoding (slot n)"]
-    hw_read --> |Tpool thread| txProc["Tx processing (slot n+3)<br/>PUSCH encode<br/>PUCCH encode (wait for DLSCH in slot n+3-k1 to finish)<br/>RU write"]
-    rxPreProc --> |Tpool thread| rxProc["PDSCH decoding (slot n)"]
+    hw_read --> |UL Actor| txProc["Tx processing (slot n+3)<br/>PUSCH encode<br/>PUCCH encode (wait for DLSCH in slot n+3-k1 to finish)<br/>RU write"]
+    rxPreProc --> |DL Actor| rxProc["PDSCH decoding (slot n)"]
     rxPreProc --> |UE_thread| join(Merge)
-    txProc --> |Tpool thread| join
     join --> |Go to next slot<br/>UE_thread| hw_read
 ```
diff --git a/doc/nr-ue-threads.svg b/doc/nr-ue-threads.svg
new file mode 100644
index 0000000000000000000000000000000000000000..0ae01ea8aa9dceab38af5c48a55b30dd456ce62e
--- /dev/null
+++ b/doc/nr-ue-threads.svg
@@ -0,0 +1 @@
+<svg version="1.1" viewBox="0.0 0.0 960.0 540.0" fill="none" stroke="none" stroke-linecap="square" stroke-miterlimit="10" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><clipPath id="p.0"><path d="m0 0l960.0 0l0 540.0l-960.0 0l0 -540.0z" clip-rule="nonzero"/></clipPath><g clip-path="url(#p.0)"><path fill="#ffffff" d="m0 0l960.0 0l0 540.0l-960.0 0z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m477.0533 370.51263l-34.967163 0l0 20.126007l-201.50526 0" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m477.0533 370.51263l-34.967163 0l0 20.125977l-195.50526 0" fill-rule="evenodd"/><path fill="#595959" stroke="#595959" stroke-width="1.0" stroke-linecap="butt" d="m246.58089 388.98688l-4.538086 1.6517334l4.538086 1.6517334z" fill-rule="evenodd"/><path fill="#eeeeee" d="m120.417366 74.275314l266.17325 0l0 58.740158l-266.17325 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m120.417366 74.275314l266.17325 0l0 58.740158l-266.17325 0z" fill-rule="evenodd"/><path fill="#000000" d="m169.86107 97.20602l1.765625 0l0 7.71875q0 2.015625 -0.453125 3.203125q-0.453125 1.1875 -1.640625 1.9375q-1.1875 0.734375 -3.125 0.734375q-1.875 0 -3.078125 -0.640625q-1.1875 -0.65625 -1.703125 -1.875q-0.5 -1.234375 -0.5 -3.359375l0 -7.71875l1.765625 0l0 7.71875q0 1.734375 0.3125 2.5625q0.328125 0.8125 1.109375 1.265625q0.796875 0.453125 1.9375 0.453125q1.953125 0 2.78125 -0.890625q0.828125 -0.890625 0.828125 -3.390625l0 -7.71875zm4.738571 13.359375l0 -13.359375l9.65625 0l0 1.578125l-7.875 0l0 4.09375l7.375 0l0 1.5625l-7.375 0l0 4.546875l8.1875 0l0 1.578125l-9.96875 0zm10.693573 3.703125l0 -1.1875l10.859375 0l0 1.1875l-10.859375 0zm15.469467 -5.171875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm1.6051788 1.46875l0 -13.359375l1.640625 0l0 4.796875q1.140625 -1.328125 2.890625 -1.328125q1.078125 0 1.859375 0.421875q0.796875 0.421875 1.140625 1.171875q0.34375 0.75 0.34375 2.171875l0 6.125l-1.640625 0l0 -6.125q0 -1.234375 -0.53125 -1.796875q-0.53125 -0.5625 -1.515625 -0.5625q-0.71875 0 -1.359375 0.390625q-0.640625 0.375 -0.921875 1.015625q-0.265625 0.640625 -0.265625 1.78125l0 5.296875l-1.640625 0zm10.360092 0l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm12.853302 -3.109375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm15.453842 4.578125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm10.469467 4.859375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm17.590256 8.75q-1.359375 -1.703125 -2.296875 -4.0q-0.9375 -2.296875 -0.9375 -4.765625q0 -2.15625 0.703125 -4.140625q0.828125 -2.3125 2.53125 -4.59375l1.171875 0q-1.09375 1.890625 -1.453125 2.703125q-0.546875 1.25 -0.875 2.625q-0.390625 1.703125 -0.390625 3.421875q0 4.375 2.71875 8.75l-1.171875 0zm3.087677 -3.921875l0 -9.671875l1.46875 0l0 1.359375q0.453125 -0.71875 1.203125 -1.140625q0.765625 -0.4375 1.71875 -0.4375q1.078125 0 1.765625 0.453125q0.6875 0.4375 0.96875 1.234375q1.15625 -1.6875 2.984375 -1.6875q1.453125 0 2.21875 0.796875q0.78125 0.796875 0.78125 2.453125l0 6.640625l-1.640625 0l0 -6.09375q0 -0.984375 -0.15625 -1.40625q-0.15625 -0.4375 -0.578125 -0.703125q-0.421875 -0.265625 -0.984375 -0.265625q-1.015625 0 -1.6875 0.6875q-0.671875 0.671875 -0.671875 2.15625l0 5.625l-1.640625 0l0 -6.28125q0 -1.09375 -0.40625 -1.640625q-0.40625 -0.546875 -1.3125 -0.546875q-0.6875 0 -1.28125 0.359375q-0.59375 0.359375 -0.859375 1.0625q-0.25 0.703125 -0.25 2.03125l0 5.015625l-1.640625 0zm21.853302 -1.1875q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm4.2038574 -6.609375l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144806 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm15.512146 0l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm3.5823364 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm8.688202 0q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.297607 8.546875l0 -13.375l1.484375 0l0 1.25q0.53125 -0.734375 1.1875 -1.09375q0.671875 -0.375 1.625 -0.375q1.234375 0 2.171875 0.640625q0.953125 0.625 1.4375 1.796875q0.484375 1.15625 0.484375 2.546875q0 1.484375 -0.53125 2.671875q-0.53125 1.1875 -1.546875 1.828125q-1.015625 0.625 -2.140625 0.625q-0.8125 0 -1.46875 -0.34375q-0.65625 -0.34375 -1.0625 -0.875l0 4.703125l-1.640625 0zm1.484375 -8.484375q0 1.859375 0.75 2.765625q0.765625 0.890625 1.828125 0.890625q1.09375 0 1.875 -0.921875q0.78125 -0.9375 0.78125 -2.875q0 -1.84375 -0.765625 -2.765625q-0.75 -0.921875 -1.8125 -0.921875q-1.046875 0 -1.859375 0.984375q-0.796875 0.96875 -0.796875 2.84375zm9.969452 8.703125l-1.1875 0q2.734375 -4.375 2.734375 -8.75q0 -1.71875 -0.390625 -3.390625q-0.3125 -1.375 -0.875 -2.625q-0.359375 -0.828125 -1.46875 -2.734375l1.1875 0q1.703125 2.28125 2.53125 4.59375q0.6875 1.984375 0.6875 4.140625q0 2.46875 -0.9375 4.765625q-0.9375 2.296875 -2.28125 4.0z" fill-rule="nonzero"/><path fill="#eeeeee" d="m157.13637 303.85385l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m157.13637 303.85385l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path fill="#eeeeee" d="m330.57175 297.29333l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m330.57175 297.29333l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path fill="#000000" d="m347.44937 362.1448l1.65625 -0.140625q0.125 1.0 0.546875 1.640625q0.4375 0.640625 1.34375 1.046875q0.921875 0.390625 2.0625 0.390625q1.0 0 1.78125 -0.296875q0.78125 -0.296875 1.15625 -0.8125q0.375 -0.53125 0.375 -1.15625q0 -0.625 -0.375 -1.09375q-0.359375 -0.46875 -1.1875 -0.796875q-0.546875 -0.203125 -2.390625 -0.640625q-1.828125 -0.453125 -2.5625 -0.84375q-0.96875 -0.5 -1.4375 -1.234375q-0.46875 -0.75 -0.46875 -1.671875q0 -1.0 0.578125 -1.875q0.578125 -0.890625 1.671875 -1.34375q1.109375 -0.453125 2.453125 -0.453125q1.484375 0 2.609375 0.484375q1.140625 0.46875 1.75 1.40625q0.609375 0.921875 0.65625 2.09375l-1.6875 0.125q-0.140625 -1.265625 -0.9375 -1.90625q-0.78125 -0.65625 -2.3125 -0.65625q-1.609375 0 -2.34375 0.59375q-0.734375 0.59375 -0.734375 1.421875q0 0.71875 0.53125 1.171875q0.5 0.46875 2.65625 0.96875q2.15625 0.484375 2.953125 0.84375q1.171875 0.53125 1.71875 1.359375q0.5625 0.828125 0.5625 1.90625q0 1.0625 -0.609375 2.015625q-0.609375 0.9375 -1.75 1.46875q-1.140625 0.515625 -2.578125 0.515625q-1.8125 0 -3.046875 -0.53125q-1.21875 -0.53125 -1.921875 -1.59375q-0.6875 -1.0625 -0.71875 -2.40625zm12.756073 8.015625l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm9.40625 -3.71875l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm16.688232 -3.546875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125z" fill-rule="nonzero"/><path fill="#000000" d="m345.54044 388.44168l5.125 -13.359375l1.90625 0l5.46875 13.359375l-2.015625 0l-1.546875 -4.046875l-5.59375 0l-1.46875 4.046875l-1.875 0zm3.859375 -5.484375l4.53125 0l-1.40625 -3.703125q-0.625 -1.6875 -0.9375 -2.765625q-0.265625 1.28125 -0.71875 2.546875l-1.46875 3.921875zm16.162323 1.9375l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm6.59375 2.078125l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.9958191 -3.375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.281952 4.84375l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0z" fill-rule="nonzero"/><path fill="#b6d7a8" d="m588.2104 201.05766l339.77954 0l0 223.81102l-339.77954 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m588.2104 201.05766l339.77954 0l0 223.81102l-339.77954 0z" fill-rule="evenodd"/><path fill="#000000" d="m602.05414 227.97766l0 -11.78125l-4.40625 0l0 -1.578125l10.578125 0l0 1.578125l-4.40625 0l0 11.78125l-1.765625 0zm7.786621 0l0 -13.359375l1.640625 0l0 4.796875q1.140625 -1.328125 2.890625 -1.328125q1.078125 0 1.859375 0.421875q0.796875 0.421875 1.140625 1.171875q0.34375 0.75 0.34375 2.171875l0 6.125l-1.640625 0l0 -6.125q0 -1.234375 -0.53125 -1.796875q-0.53125 -0.5625 -1.515625 -0.5625q-0.71875 0 -1.359375 0.390625q-0.640625 0.375 -0.921875 1.015625q-0.265625 0.640625 -0.265625 1.78125l0 5.296875l-1.640625 0zm10.360107 0l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm12.8532715 -3.109375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm15.453857 4.578125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm10.469482 4.859375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm14.465271 8.53125l0 -13.375l1.484375 0l0 1.25q0.53125 -0.734375 1.1875 -1.09375q0.671875 -0.375 1.625 -0.375q1.234375 0 2.171875 0.640625q0.953125 0.625 1.4375 1.796875q0.484375 1.15625 0.484375 2.546875q0 1.484375 -0.53125 2.671875q-0.53125 1.1875 -1.546875 1.828125q-1.015625 0.625 -2.140625 0.625q-0.8125 0 -1.46875 -0.34375q-0.65625 -0.34375 -1.0625 -0.875l0 4.703125l-1.640625 0zm1.484375 -8.484375q0 1.859375 0.75 2.765625q0.765625 0.890625 1.828125 0.890625q1.09375 0 1.875 -0.921875q0.78125 -0.9375 0.78125 -2.875q0 -1.84375 -0.765625 -2.765625q-0.75 -0.921875 -1.8125 -0.921875q-1.046875 0 -1.859375 0.984375q-0.796875 0.96875 -0.796875 2.84375zm8.281982 -0.0625q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm8.688171 0q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.250732 4.84375l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0z" fill-rule="nonzero"/><path fill="#eeeeee" d="m602.03986 241.22713l73.543335 0l0 146.45671l-73.543335 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m602.03986 241.22713l73.543335 0l0 146.45671l-73.543335 0z" fill-rule="evenodd"/><path fill="#eeeeee" d="m682.0398 241.22713l73.543335 0l0 146.45671l-73.543335 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m682.0398 241.22713l73.543335 0l0 146.45671l-73.543335 0z" fill-rule="evenodd"/><path fill="#eeeeee" d="m836.3791 241.22713l73.543335 0l0 146.45671l-73.543335 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m836.3791 241.22713l73.543335 0l0 146.45671l-73.543335 0z" fill-rule="evenodd"/><path fill="#ffffff" d="m418.23727 497.07367l0 0c0 -3.745758 3.0365295 -6.7822876 6.7822876 -6.7822876l151.31729 0c1.7988281 0 3.5239258 0.7145691 4.7958374 1.9864807c1.2719116 1.2719421 1.9864502 2.9970398 1.9864502 4.795807l0 27.128357c0 3.7457275 -3.036499 6.7822876 -6.7822876 6.7822876l-151.31729 0c-3.745758 0 -6.7822876 -3.03656 -6.7822876 -6.7822876z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m418.23727 497.07367l0 0c0 -3.745758 3.0365295 -6.7822876 6.7822876 -6.7822876l151.31729 0c1.7988281 0 3.5239258 0.7145691 4.7958374 1.9864807c1.2719116 1.2719421 1.9864502 2.9970398 1.9864502 4.795807l0 27.128357c0 3.7457275 -3.036499 6.7822876 -6.7822876 6.7822876l-151.31729 0c-3.745758 0 -6.7822876 -3.03656 -6.7822876 -6.7822876z" fill-rule="evenodd"/><path fill="#000000" d="m431.7782 514.66724l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.9062805q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.45315552 2.4375 0.7500305q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm13.5625 1.421875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.5781555l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.6719055q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm7.917694 0.28125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25003052q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875305q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm4.188202 4.859375l0 -9.6719055l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.9219055l0 5.0625l-1.625 0zm9.806427 -1.46875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.5781555l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.6719055q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.9489441 -1.421875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.9062805q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.45315552 2.4375 0.7500305q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm18.745789 1.421875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.5781555l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.6719055q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm1.6051941 1.46875l0 -13.3594055l1.640625 0l0 4.796875q1.140625 -1.328125 2.890625 -1.328125q1.078125 0 1.859375 0.421875q0.796875 0.421875 1.140625 1.171875q0.34375 0.75 0.34375 2.171875l0 6.1250305l-1.640625 0l0 -6.1250305q0 -1.234375 -0.53125 -1.796875q-0.53125 -0.5625 -1.515625 -0.5625q-0.71875 0 -1.359375 0.390625q-0.640625 0.375 -0.921875 1.015625q-0.265625 0.640625 -0.265625 1.7812805l0 5.296875l-1.640625 0zm10.360077 0l0 -9.6719055l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.9219055l0 5.0625l-1.625 0zm12.853302 -3.109375l1.6875305 0.203125q-0.40625 1.484375 -1.4844055 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.4531555 1.25 -3.7969055q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.1562805 1.328125q1.234375 1.3125 1.234375 3.7031555q0 0.15625 0 0.4375l-7.2187805 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.6562805l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm15.453827 4.5781555q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25003052q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875305q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm10.469482 4.859375l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.4531555 0.484375 -2.6250305q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.3594055l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.9844055 -0.765625 -2.9062805q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125305zm8.625732 1.9375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.9062805q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.45315552 2.4375 0.7500305q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm14.558289 -1.953125q0 -2.6875305 1.484375 -3.9687805q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.6094055q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.7969055 -0.8125 -2.7187805q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.7656555zm9.297607 4.84375l0 -9.6719055l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.9531555l-1.640625 0l0 -5.8906555q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.5156555l0 5.28125l-1.640625 0z" fill-rule="nonzero"/><path fill="#ffff00" d="m786.2974 90.60562l0 0c0 -5.9490204 4.822632 -10.77166 10.7716675 -10.77166l18.178467 0l0 0l43.42517 0l90.55383 0c2.8568115 0 5.5966187 1.1348724 7.616699 3.1549454c2.0200806 2.0200806 3.1549683 4.7598877 3.1549683 7.6167145l0 26.92913l0 0l0 16.157478l0 0c0 5.9490204 -4.822693 10.771652 -10.7716675 10.771652l-90.55383 0l-30.37445 52.5506l-13.05072 -52.5506l-18.178467 0l0 0c-5.9490356 0 -10.7716675 -4.822632 -10.7716675 -10.771652l0 0l0 -16.157478l0 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m786.2974 90.60562l0 0c0 -5.9490204 4.822632 -10.77166 10.7716675 -10.77166l18.178467 0l0 0l43.42517 0l90.55383 0c2.8568115 0 5.5966187 1.1348724 7.616699 3.1549454c2.0200806 2.0200806 3.1549683 4.7598877 3.1549683 7.6167145l0 26.92913l0 0l0 16.157478l0 0c0 5.9490204 -4.822693 10.771652 -10.7716675 10.771652l-90.55383 0l-30.37445 52.5506l-13.05072 -52.5506l-18.178467 0l0 0c-5.9490356 0 -10.7716675 -4.822632 -10.7716675 -10.771652l0 0l0 -16.157478l0 0z" fill-rule="evenodd"/><path fill="#000000" d="m799.5461 92.94892l0 -9.546875l6.4375 0l0 1.125l-5.171875 0l0 2.96875l4.46875 0l0 1.125l-4.46875 0l0 4.328125l-1.265625 0zm7.9069824 0l0 -9.546875l1.171875 0l0 9.546875l-1.171875 0zm2.5391846 -3.453125q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm11.162476 2.59375q-0.65625 0.5625 -1.265625 0.796875q-0.59375 0.21875 -1.28125 0.21875q-1.140625 0 -1.75 -0.546875q-0.609375 -0.5625 -0.609375 -1.4375q0 -0.5 0.21875 -0.921875q0.234375 -0.421875 0.609375 -0.671875q0.375 -0.25 0.84375 -0.390625q0.34375 -0.078125 1.046875 -0.171875q1.421875 -0.171875 2.09375 -0.40625q0 -0.234375 0 -0.296875q0 -0.71875 -0.328125 -1.015625q-0.453125 -0.390625 -1.34375 -0.390625q-0.8125 0 -1.21875 0.296875q-0.390625 0.28125 -0.578125 1.015625l-1.140625 -0.15625q0.15625 -0.734375 0.515625 -1.1875q0.359375 -0.453125 1.03125 -0.6875q0.671875 -0.25 1.5625 -0.25q0.890625 0 1.4375 0.203125q0.5625 0.203125 0.8125 0.53125q0.265625 0.3125 0.375 0.796875q0.046875 0.296875 0.046875 1.078125l0 1.5625q0 1.625 0.078125 2.0625q0.078125 0.4375 0.296875 0.828125l-1.21875 0q-0.1875 -0.359375 -0.234375 -0.859375zm-0.09375 -2.609375q-0.640625 0.265625 -1.921875 0.4375q-0.71875 0.109375 -1.015625 0.25q-0.296875 0.125 -0.46875 0.375q-0.15625 0.25 -0.15625 0.546875q0 0.46875 0.34375 0.78125q0.359375 0.3125 1.046875 0.3125q0.671875 0 1.203125 -0.296875q0.53125 -0.296875 0.78125 -0.8125q0.1875 -0.390625 0.1875 -1.171875l0 -0.421875zm5.5531006 2.421875l0.171875 1.03125q-0.5 0.109375 -0.890625 0.109375q-0.640625 0 -1.0 -0.203125q-0.34375 -0.203125 -0.484375 -0.53125q-0.140625 -0.328125 -0.140625 -1.390625l0 -3.96875l-0.859375 0l0 -0.90625l0.859375 0l0 -1.71875l1.171875 -0.703125l0 2.421875l1.171875 0l0 0.90625l-1.171875 0l0 4.046875q0 0.5 0.046875 0.640625q0.0625 0.140625 0.203125 0.234375q0.140625 0.078125 0.40625 0.078125q0.203125 0 0.515625 -0.046875zm1.1561279 -7.140625l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm2.9454956 0l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm7.1937256 0.578125l1.140625 0.15625q0.078125 0.53125 0.40625 0.78125q0.4375 0.3125 1.1875 0.3125q0.8125 0 1.25 -0.328125q0.453125 -0.3125 0.609375 -0.90625q0.09375 -0.359375 0.078125 -1.5q-0.765625 0.90625 -1.90625 0.90625q-1.4375 0 -2.21875 -1.03125q-0.78125 -1.03125 -0.78125 -2.46875q0 -0.984375 0.359375 -1.8125q0.359375 -0.84375 1.03125 -1.296875q0.6875 -0.453125 1.609375 -0.453125q1.21875 0 2.015625 0.984375l0 -0.828125l1.078125 0l0 5.96875q0 1.609375 -0.328125 2.28125q-0.328125 0.6875 -1.046875 1.078125q-0.703125 0.390625 -1.75 0.390625q-1.234375 0 -2.0 -0.5625q-0.75 -0.5625 -0.734375 -1.671875zm0.984375 -4.15625q0 1.359375 0.53125 1.984375q0.546875 0.625 1.359375 0.625q0.796875 0 1.34375 -0.625q0.546875 -0.625 0.546875 -1.953125q0 -1.265625 -0.5625 -1.90625q-0.5625 -0.640625 -1.359375 -0.640625q-0.765625 0 -1.3125 0.640625q-0.546875 0.625 -0.546875 1.875zm14.8654175 1.046875l1.15625 0.15625q-0.1875 1.1875 -0.96875 1.859375q-0.78125 0.671875 -1.921875 0.671875q-1.40625 0 -2.28125 -0.921875q-0.859375 -0.9375 -0.859375 -2.65625q0 -1.125 0.375 -1.96875q0.375 -0.84375 1.125 -1.25q0.765625 -0.421875 1.65625 -0.421875q1.125 0 1.84375 0.578125q0.71875 0.5625 0.921875 1.609375l-1.140625 0.171875q-0.171875 -0.703125 -0.59375 -1.046875q-0.40625 -0.359375 -0.984375 -0.359375q-0.890625 0 -1.453125 0.640625q-0.546875 0.640625 -0.546875 2.0q0 1.40625 0.53125 2.03125q0.546875 0.625 1.40625 0.625q0.6875 0 1.140625 -0.421875q0.46875 -0.421875 0.59375 -1.296875zm1.7109375 -0.921875q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm6.6312256 3.453125l0 -6.90625l1.0625 0l0 1.046875q0.40625 -0.734375 0.734375 -0.96875q0.34375 -0.234375 0.765625 -0.234375q0.59375 0 1.203125 0.375l-0.40625 1.078125q-0.4375 -0.25 -0.859375 -0.25q-0.390625 0 -0.703125 0.234375q-0.296875 0.234375 -0.421875 0.640625q-0.203125 0.625 -0.203125 1.359375l0 3.625l-1.171875 0zm9.188416 -2.21875l1.203125 0.140625q-0.28125 1.0625 -1.0625 1.65625q-0.765625 0.578125 -1.96875 0.578125q-1.515625 0 -2.40625 -0.9375q-0.890625 -0.9375 -0.890625 -2.609375q0 -1.75 0.890625 -2.703125q0.90625 -0.96875 2.34375 -0.96875q1.390625 0 2.265625 0.9375q0.875 0.9375 0.875 2.65625q0 0.109375 0 0.3125l-5.15625 0q0.0625 1.140625 0.640625 1.75q0.578125 0.59375 1.4375 0.59375q0.65625 0 1.109375 -0.328125q0.453125 -0.34375 0.71875 -1.078125zm-3.84375 -1.90625l3.859375 0q-0.078125 -0.859375 -0.4375 -1.296875q-0.5625 -0.6875 -1.453125 -0.6875q-0.8125 0 -1.359375 0.546875q-0.546875 0.53125 -0.609375 1.4375zm6.0531006 2.0625l1.15625 -0.1875q0.109375 0.703125 0.546875 1.078125q0.453125 0.359375 1.25 0.359375q0.8125 0 1.203125 -0.328125q0.390625 -0.328125 0.390625 -0.765625q0 -0.390625 -0.359375 -0.625q-0.234375 -0.15625 -1.1875 -0.390625q-1.296875 -0.328125 -1.796875 -0.5625q-0.484375 -0.25 -0.75 -0.65625q-0.25 -0.421875 -0.25 -0.9375q0 -0.453125 0.203125 -0.84375q0.21875 -0.40625 0.578125 -0.671875q0.28125 -0.1875 0.75 -0.328125q0.46875 -0.140625 1.015625 -0.140625q0.8125 0 1.421875 0.234375q0.609375 0.234375 0.90625 0.640625q0.296875 0.390625 0.40625 1.0625l-1.140625 0.15625q-0.078125 -0.53125 -0.453125 -0.828125q-0.375 -0.3125 -1.0625 -0.3125q-0.8125 0 -1.15625 0.265625q-0.34375 0.265625 -0.34375 0.625q0 0.234375 0.140625 0.421875q0.15625 0.1875 0.453125 0.3125q0.171875 0.0625 1.03125 0.296875q1.25 0.328125 1.734375 0.546875q0.5 0.203125 0.78125 0.609375q0.28125 0.40625 0.28125 1.0q0 0.59375 -0.34375 1.109375q-0.34375 0.515625 -1.0 0.796875q-0.640625 0.28125 -1.453125 0.28125q-1.34375 0 -2.046875 -0.5625q-0.703125 -0.5625 -0.90625 -1.65625zm13.085754 4.875q-0.984375 -1.234375 -1.65625 -2.875q-0.65625 -1.640625 -0.65625 -3.390625q0 -1.546875 0.5 -2.96875q0.578125 -1.640625 1.8125 -3.28125l0.828125 0q-0.78125 1.359375 -1.03125 1.9375q-0.40625 0.890625 -0.625 1.875q-0.28125 1.21875 -0.28125 2.4375q0 3.140625 1.9375 6.265625l-0.828125 0zm2.1884155 -2.8125l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm6.9749756 -3.453125q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375z" fill-rule="nonzero"/><path fill="#000000" d="m803.84296 108.08955q-0.65625 0.5625 -1.265625 0.796875q-0.59375 0.21875 -1.28125 0.21875q-1.140625 0 -1.75 -0.546875q-0.609375 -0.5625 -0.609375 -1.4375q0 -0.5 0.21875 -0.921875q0.234375 -0.421875 0.609375 -0.671875q0.375 -0.25 0.84375 -0.390625q0.34375 -0.078125 1.046875 -0.171875q1.421875 -0.171875 2.09375 -0.40625q0 -0.234375 0 -0.296875q0 -0.71875 -0.328125 -1.015625q-0.453125 -0.390625 -1.34375 -0.390625q-0.8125 0 -1.21875 0.296875q-0.390625 0.28125 -0.578125 1.015625l-1.140625 -0.15625q0.15625 -0.734375 0.515625 -1.1875q0.359375 -0.453125 1.03125 -0.6875q0.671875 -0.25 1.5625 -0.25q0.890625 0 1.4375 0.203125q0.5625 0.203125 0.8125 0.53125q0.265625 0.3125 0.375 0.796875q0.046875 0.296875 0.046875 1.078125l0 1.5625q0 1.625 0.078125 2.0625q0.078125 0.4375 0.296875 0.828125l-1.21875 0q-0.1875 -0.359375 -0.234375 -0.859375zm-0.09375 -2.609375q-0.640625 0.265625 -1.921875 0.4375q-0.71875 0.109375 -1.015625 0.25q-0.296875 0.125 -0.46875 0.375q-0.15625 0.25 -0.15625 0.546875q0 0.46875 0.34375 0.78125q0.359375 0.3125 1.046875 0.3125q0.671875 0 1.203125 -0.296875q0.53125 -0.296875 0.78125 -0.8125q0.1875 -0.390625 0.1875 -1.171875l0 -0.421875zm3.2718506 3.46875l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm3.4620972 0l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm3.437378 -8.1875l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm2.9454346 0l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm7.4281006 -8.1875l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm5.5079956 -1.046875l0.171875 1.03125q-0.5 0.109375 -0.890625 0.109375q-0.640625 0 -1.0 -0.203125q-0.34375 -0.203125 -0.484375 -0.53125q-0.140625 -0.328125 -0.140625 -1.390625l0 -3.96875l-0.859375 0l0 -0.90625l0.859375 0l0 -1.71875l1.171875 -0.703125l0 2.421875l1.171875 0l0 0.90625l-1.171875 0l0 4.046875q0 0.5 0.046875 0.640625q0.0625 0.140625 0.203125 0.234375q0.140625 0.078125 0.40625 0.078125q0.203125 0 0.515625 -0.046875zm1.0935669 3.703125l-0.125 -1.09375q0.375 0.109375 0.65625 0.109375q0.390625 0 0.625 -0.140625q0.234375 -0.125 0.390625 -0.359375q0.109375 -0.171875 0.359375 -0.875q0.03125 -0.09375 0.109375 -0.28125l-2.625 -6.921875l1.265625 0l1.4375 4.0q0.28125 0.765625 0.5 1.59375q0.203125 -0.796875 0.46875 -1.578125l1.484375 -4.015625l1.171875 0l-2.625 7.015625q-0.421875 1.140625 -0.65625 1.578125q-0.3125 0.578125 -0.71875 0.84375q-0.40625 0.28125 -0.96875 0.28125q-0.328125 0 -0.75 -0.15625zm7.4765625 0.15625l-0.828125 0q1.9375 -3.125 1.9375 -6.265625q0 -1.21875 -0.28125 -2.421875q-0.21875 -0.984375 -0.609375 -1.875q-0.265625 -0.59375 -1.046875 -1.953125l0.828125 0q1.234375 1.640625 1.8125 3.28125q0.5 1.421875 0.5 2.96875q0 1.75 -0.671875 3.390625q-0.671875 1.640625 -1.640625 2.875zm6.9382324 -6.265625q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm6.6312256 3.453125l0 -6.90625l1.0625 0l0 1.046875q0.40625 -0.734375 0.734375 -0.96875q0.34375 -0.234375 0.765625 -0.234375q0.59375 0 1.203125 0.375l-0.40625 1.078125q-0.4375 -0.25 -0.859375 -0.25q-0.390625 0 -0.703125 0.234375q-0.296875 0.234375 -0.421875 0.640625q-0.203125 0.625 -0.203125 1.359375l0 3.625l-1.171875 0zm12.672607 -0.859375q-0.65625 0.5625 -1.265625 0.796875q-0.59375 0.21875 -1.28125 0.21875q-1.140625 0 -1.75 -0.546875q-0.609375 -0.5625 -0.609375 -1.4375q0 -0.5 0.21875 -0.921875q0.234375 -0.421875 0.609375 -0.671875q0.375 -0.25 0.84375 -0.390625q0.34375 -0.078125 1.046875 -0.171875q1.421875 -0.171875 2.09375 -0.40625q0 -0.234375 0 -0.296875q0 -0.71875 -0.328125 -1.015625q-0.453125 -0.390625 -1.34375 -0.390625q-0.8125 0 -1.21875 0.296875q-0.390625 0.28125 -0.578125 1.015625l-1.140625 -0.15625q0.15625 -0.734375 0.515625 -1.1875q0.359375 -0.453125 1.03125 -0.6875q0.671875 -0.25 1.5625 -0.25q0.890625 0 1.4375 0.203125q0.5625 0.203125 0.8125 0.53125q0.265625 0.3125 0.375 0.796875q0.046875 0.296875 0.046875 1.078125l0 1.5625q0 1.625 0.078125 2.0625q0.078125 0.4375 0.296875 0.828125l-1.21875 0q-0.1875 -0.359375 -0.234375 -0.859375zm-0.09375 -2.609375q-0.640625 0.265625 -1.921875 0.4375q-0.71875 0.109375 -1.015625 0.25q-0.296875 0.125 -0.46875 0.375q-0.15625 0.25 -0.15625 0.546875q0 0.46875 0.34375 0.78125q0.359375 0.3125 1.046875 0.3125q0.671875 0 1.203125 -0.296875q0.53125 -0.296875 0.78125 -0.8125q0.1875 -0.390625 0.1875 -1.171875l0 -0.421875zm3.2718506 3.46875l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm3.4620972 0l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm3.437378 -8.1875l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm2.9454956 0l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm7.4281006 -8.1875l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm5.5079346 -1.046875l0.171875 1.03125q-0.5 0.109375 -0.890625 0.109375q-0.640625 0 -1.0 -0.203125q-0.34375 -0.203125 -0.484375 -0.53125q-0.140625 -0.328125 -0.140625 -1.390625l0 -3.96875l-0.859375 0l0 -0.90625l0.859375 0l0 -1.71875l1.171875 -0.703125l0 2.421875l1.171875 0l0 0.90625l-1.171875 0l0 4.046875q0 0.5 0.046875 0.640625q0.0625 0.140625 0.203125 0.234375q0.140625 0.078125 0.40625 0.078125q0.203125 0 0.515625 -0.046875zm1.0936279 3.703125l-0.125 -1.09375q0.375 0.109375 0.65625 0.109375q0.390625 0 0.625 -0.140625q0.234375 -0.125 0.390625 -0.359375q0.109375 -0.171875 0.359375 -0.875q0.03125 -0.09375 0.109375 -0.28125l-2.625 -6.921875l1.265625 0l1.4375 4.0q0.28125 0.765625 0.5 1.59375q0.203125 -0.796875 0.46875 -1.578125l1.484375 -4.015625l1.171875 0l-2.625 7.015625q-0.421875 1.140625 -0.65625 1.578125q-0.3125 0.578125 -0.71875 0.84375q-0.40625 0.28125 -0.96875 0.28125q-0.328125 0 -0.75 -0.15625z" fill-rule="nonzero"/><path fill="#000000" d="m803.8117 124.94893l0 -0.875q-0.65625 1.03125 -1.9375 1.03125q-0.8125 0 -1.515625 -0.453125q-0.6875 -0.453125 -1.078125 -1.265625q-0.375 -0.828125 -0.375 -1.890625q0 -1.03125 0.34375 -1.875q0.34375 -0.84375 1.03125 -1.28125q0.703125 -0.453125 1.546875 -0.453125q0.625 0 1.109375 0.265625q0.5 0.25 0.796875 0.671875l0 -3.421875l1.171875 0l0 9.546875l-1.09375 0zm-3.703125 -3.453125q0 1.328125 0.5625 1.984375q0.5625 0.65625 1.328125 0.65625q0.765625 0 1.296875 -0.625q0.53125 -0.625 0.53125 -1.90625q0 -1.421875 -0.546875 -2.078125q-0.546875 -0.671875 -1.34375 -0.671875q-0.78125 0 -1.3125 0.640625q-0.515625 0.625 -0.515625 2.0zm11.365601 1.234375l1.203125 0.140625q-0.28125 1.0625 -1.0625 1.65625q-0.765625 0.578125 -1.96875 0.578125q-1.515625 0 -2.40625 -0.9375q-0.890625 -0.9375 -0.890625 -2.609375q0 -1.75 0.890625 -2.703125q0.90625 -0.96875 2.34375 -0.96875q1.390625 0 2.265625 0.9375q0.875 0.9375 0.875 2.65625q0 0.109375 0 0.3125l-5.15625 0q0.0625 1.140625 0.640625 1.75q0.578125 0.59375 1.4375 0.59375q0.65625 0 1.109375 -0.328125q0.453125 -0.34375 0.71875 -1.078125zm-3.84375 -1.90625l3.859375 0q-0.078125 -0.859375 -0.4375 -1.296875q-0.5625 -0.6875 -1.453125 -0.6875q-0.8125 0 -1.359375 0.546875q-0.546875 0.53125 -0.609375 1.4375zm6.5218506 6.78125l0 -9.5625l1.078125 0l0 0.890625q0.375 -0.53125 0.84375 -0.78125q0.484375 -0.265625 1.15625 -0.265625q0.875 0 1.546875 0.453125q0.6875 0.453125 1.03125 1.28125q0.34375 0.828125 0.34375 1.828125q0 1.046875 -0.375 1.90625q-0.375 0.84375 -1.109375 1.296875q-0.71875 0.453125 -1.53125 0.453125q-0.578125 0 -1.046875 -0.25q-0.46875 -0.25 -0.765625 -0.625l0 3.375l-1.171875 0zm1.0625 -6.078125q0 1.34375 0.53125 1.984375q0.546875 0.625 1.3125 0.625q0.78125 0 1.34375 -0.65625q0.5625 -0.65625 0.5625 -2.046875q0 -1.3125 -0.546875 -1.96875q-0.546875 -0.671875 -1.296875 -0.671875q-0.75 0 -1.328125 0.703125q-0.578125 0.703125 -0.578125 2.03125zm11.084351 1.203125l1.203125 0.140625q-0.28125 1.0625 -1.0625 1.65625q-0.765625 0.578125 -1.96875 0.578125q-1.515625 0 -2.40625 -0.9375q-0.890625 -0.9375 -0.890625 -2.609375q0 -1.75 0.890625 -2.703125q0.90625 -0.96875 2.34375 -0.96875q1.390625 0 2.265625 0.9375q0.875 0.9375 0.875 2.65625q0 0.109375 0 0.3125l-5.15625 0q0.0625 1.140625 0.640625 1.75q0.578125 0.59375 1.4375 0.59375q0.65625 0 1.109375 -0.328125q0.453125 -0.34375 0.71875 -1.078125zm-3.84375 -1.90625l3.859375 0q-0.078125 -0.859375 -0.4375 -1.296875q-0.5625 -0.6875 -1.453125 -0.6875q-0.8125 0 -1.359375 0.546875q-0.546875 0.53125 -0.609375 1.4375zm6.5218506 4.125l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm11.896851 0l0 -0.875q-0.65625 1.03125 -1.9375 1.03125q-0.8125 0 -1.515625 -0.453125q-0.6875 -0.453125 -1.078125 -1.265625q-0.375 -0.828125 -0.375 -1.890625q0 -1.03125 0.34375 -1.875q0.34375 -0.84375 1.03125 -1.28125q0.703125 -0.453125 1.546875 -0.453125q0.625 0 1.109375 0.265625q0.5 0.25 0.796875 0.671875l0 -3.421875l1.171875 0l0 9.546875l-1.09375 0zm-3.703125 -3.453125q0 1.328125 0.5625 1.984375q0.5625 0.65625 1.328125 0.65625q0.765625 0 1.296875 -0.625q0.53125 -0.625 0.53125 -1.90625q0 -1.421875 -0.546875 -2.078125q-0.546875 -0.671875 -1.34375 -0.671875q-0.78125 0 -1.3125 0.640625q-0.515625 0.625 -0.515625 2.0zm6.6468506 -4.734375l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm2.9454346 0l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm7.1937256 0.578125l1.140625 0.15625q0.078125 0.53125 0.40625 0.78125q0.4375 0.3125 1.1875 0.3125q0.8125 0 1.25 -0.328125q0.453125 -0.3125 0.609375 -0.90625q0.09375 -0.359375 0.078125 -1.5q-0.765625 0.90625 -1.90625 0.90625q-1.4375 0 -2.21875 -1.03125q-0.78125 -1.03125 -0.78125 -2.46875q0 -0.984375 0.359375 -1.8125q0.359375 -0.84375 1.03125 -1.296875q0.6875 -0.453125 1.609375 -0.453125q1.21875 0 2.015625 0.984375l0 -0.828125l1.078125 0l0 5.96875q0 1.609375 -0.328125 2.28125q-0.328125 0.6875 -1.046875 1.078125q-0.703125 0.390625 -1.75 0.390625q-1.234375 0 -2.0 -0.5625q-0.75 -0.5625 -0.734375 -1.671875zm0.984375 -4.15625q0 1.359375 0.53125 1.984375q0.546875 0.625 1.359375 0.625q0.796875 0 1.34375 -0.625q0.546875 -0.625 0.546875 -1.953125q0 -1.265625 -0.5625 -1.90625q-0.5625 -0.640625 -1.359375 -0.640625q-0.765625 0 -1.3125 0.640625q-0.546875 0.625 -0.546875 1.875zm9.9123535 0.125q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm6.6468506 3.453125l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0z" fill-rule="nonzero"/><path fill="#000000" d="m803.84296 138.41768l1.15625 0.15625q-0.1875 1.1875 -0.96875 1.859375q-0.78125 0.671875 -1.921875 0.671875q-1.40625 0 -2.28125 -0.921875q-0.859375 -0.9375 -0.859375 -2.65625q0 -1.125 0.375 -1.96875q0.375 -0.84375 1.125 -1.25q0.765625 -0.421875 1.65625 -0.421875q1.125 0 1.84375 0.578125q0.71875 0.5625 0.921875 1.609375l-1.140625 0.171875q-0.171875 -0.703125 -0.59375 -1.046875q-0.40625 -0.359375 -0.984375 -0.359375q-0.890625 0 -1.453125 0.640625q-0.546875 0.640625 -0.546875 2.0q0 1.40625 0.53125 2.03125q0.546875 0.625 1.40625 0.625q0.6875 0 1.140625 -0.421875q0.46875 -0.421875 0.59375 -1.296875zm1.7109375 -0.921875q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm6.6468506 3.453125l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm7.6937256 0l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm3.437378 -8.1875l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm2.7266846 0.578125l1.140625 0.15625q0.078125 0.53125 0.40625 0.78125q0.4375 0.3125 1.1875 0.3125q0.8125 0 1.25 -0.328125q0.453125 -0.3125 0.609375 -0.90625q0.09375 -0.359375 0.078125 -1.5q-0.765625 0.90625 -1.90625 0.90625q-1.4375 0 -2.21875 -1.03125q-0.78125 -1.03125 -0.78125 -2.46875q0 -0.984375 0.359375 -1.8125q0.359375 -0.84375 1.03125 -1.296875q0.6875 -0.453125 1.609375 -0.453125q1.21875 0 2.015625 0.984375l0 -0.828125l1.078125 0l0 5.96875q0 1.609375 -0.328125 2.28125q-0.328125 0.6875 -1.046875 1.078125q-0.703125 0.390625 -1.75 0.390625q-1.234375 0 -2.0 -0.5625q-0.75 -0.5625 -0.734375 -1.671875zm0.984375 -4.15625q0 1.359375 0.53125 1.984375q0.546875 0.625 1.359375 0.625q0.796875 0 1.34375 -0.625q0.546875 -0.625 0.546875 -1.953125q0 -1.265625 -0.5625 -1.90625q-0.5625 -0.640625 -1.359375 -0.640625q-0.765625 0 -1.3125 0.640625q-0.546875 0.625 -0.546875 1.875zm11.178101 3.578125l0 -1.015625q-0.8125 1.171875 -2.1875 1.171875q-0.609375 0 -1.140625 -0.234375q-0.53125 -0.234375 -0.796875 -0.578125q-0.25 -0.359375 -0.359375 -0.875q-0.0625 -0.34375 -0.0625 -1.09375l0 -4.28125l1.171875 0l0 3.828125q0 0.921875 0.0625 1.234375q0.109375 0.46875 0.46875 0.734375q0.359375 0.25 0.890625 0.25q0.515625 0 0.984375 -0.265625q0.46875 -0.265625 0.65625 -0.734375q0.1875 -0.46875 0.1875 -1.34375l0 -3.703125l1.171875 0l0 6.90625l-1.046875 0zm2.8656006 0l0 -6.90625l1.0625 0l0 1.046875q0.40625 -0.734375 0.734375 -0.96875q0.34375 -0.234375 0.765625 -0.234375q0.59375 0 1.203125 0.375l-0.40625 1.078125q-0.4375 -0.25 -0.859375 -0.25q-0.390625 0 -0.703125 0.234375q-0.296875 0.234375 -0.421875 0.640625q-0.203125 0.625 -0.203125 1.359375l0 3.625l-1.171875 0zm8.9696045 -0.859375q-0.65625 0.5625 -1.265625 0.796875q-0.59375 0.21875 -1.28125 0.21875q-1.140625 0 -1.75 -0.546875q-0.609375 -0.5625 -0.609375 -1.4375q0 -0.5 0.21875 -0.921875q0.234375 -0.421875 0.609375 -0.671875q0.375 -0.25 0.84375 -0.390625q0.34375 -0.078125 1.046875 -0.171875q1.421875 -0.171875 2.09375 -0.40625q0 -0.234375 0 -0.296875q0 -0.71875 -0.328125 -1.015625q-0.453125 -0.390625 -1.34375 -0.390625q-0.8125 0 -1.21875 0.296875q-0.390625 0.28125 -0.578125 1.015625l-1.140625 -0.15625q0.15625 -0.734375 0.515625 -1.1875q0.359375 -0.453125 1.03125 -0.6875q0.671875 -0.25 1.5625 -0.25q0.890625 0 1.4375 0.203125q0.5625 0.203125 0.8125 0.53125q0.265625 0.3125 0.375 0.796875q0.046875 0.296875 0.046875 1.078125l0 1.5625q0 1.625 0.078125 2.0625q0.078125 0.4375 0.296875 0.828125l-1.21875 0q-0.1875 -0.359375 -0.234375 -0.859375zm-0.09375 -2.609375q-0.640625 0.265625 -1.921875 0.4375q-0.71875 0.109375 -1.015625 0.25q-0.296875 0.125 -0.46875 0.375q-0.15625 0.25 -0.15625 0.546875q0 0.46875 0.34375 0.78125q0.359375 0.3125 1.046875 0.3125q0.671875 0 1.203125 -0.296875q0.53125 -0.296875 0.78125 -0.8125q0.1875 -0.390625 0.1875 -1.171875l0 -0.421875zm5.5531006 2.421875l0.171875 1.03125q-0.5 0.109375 -0.890625 0.109375q-0.640625 0 -1.0 -0.203125q-0.34375 -0.203125 -0.484375 -0.53125q-0.140625 -0.328125 -0.140625 -1.390625l0 -3.96875l-0.859375 0l0 -0.90625l0.859375 0l0 -1.71875l1.171875 -0.703125l0 2.421875l1.171875 0l0 0.90625l-1.171875 0l0 4.046875q0 0.5 0.046875 0.640625q0.0625 0.140625 0.203125 0.234375q0.140625 0.078125 0.40625 0.078125q0.203125 0 0.515625 -0.046875zm0.7030029 -2.40625q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm6.6468506 3.453125l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0z" fill-rule="nonzero"/><path fill="#ffff00" d="m46.449535 255.23361l0 0c0 -6.4099884 5.196316 -11.606293 11.606297 -11.606293l38.679794 0l0 0l21.551178 0l2.7611542 0c3.078186 0 6.0302887 1.2227936 8.206894 3.3993988c2.1766052 2.1766052 3.3993988 5.128708 3.3993988 8.206894l0 29.015747l0 0l0 17.409454l0 0c0 6.409973 -5.196312 11.606293 -11.606293 11.606293l-2.7611542 0l40.169388 23.479767l-61.720566 -23.479767l-38.679794 0l0 0c-6.409981 0 -11.606297 -5.1963196 -11.606297 -11.606293l0 0l0 -17.409454l0 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m46.449535 255.23361l0 0c0 -6.4099884 5.196316 -11.606293 11.606297 -11.606293l38.679794 0l0 0l21.551178 0l2.7611542 0c3.078186 0 6.0302887 1.2227936 8.206894 3.3993988c2.1766052 2.1766052 3.3993988 5.128708 3.3993988 8.206894l0 29.015747l0 0l0 17.409454l0 0c0 6.409973 -5.196312 11.606293 -11.606293 11.606293l-2.7611542 0l40.169388 23.479767l-61.720566 -23.479767l-38.679794 0l0 0c-6.409981 0 -11.606297 -5.1963196 -11.606297 -11.606293l0 0l0 -17.409454l0 0z" fill-rule="evenodd"/><path fill="#000000" d="m59.86453 275.24622l0 -9.546875l1.296875 0l5.015621 7.5l0 -7.5l1.203125 0l0 9.546875l-1.296875 0l-5.015621 -7.5l0 7.5l-1.203125 0zm9.047024 -3.453125q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm14.865463 2.59375q-0.65625 0.5625 -1.265625 0.796875q-0.59375 0.21875 -1.28125 0.21875q-1.140625 0 -1.75 -0.546875q-0.609375 -0.5625 -0.609375 -1.4375q0 -0.5 0.21875 -0.921875q0.234375 -0.421875 0.609375 -0.671875q0.375 -0.25 0.84375 -0.390625q0.34375 -0.078125 1.046875 -0.171875q1.421875 -0.171875 2.09375 -0.40625q0 -0.234375 0 -0.296875q0 -0.71875 -0.328125 -1.015625q-0.453125 -0.390625 -1.34375 -0.390625q-0.8125 0 -1.21875 0.296875q-0.390625 0.28125 -0.578125 1.015625l-1.140625 -0.15625q0.15625 -0.734375 0.515625 -1.1875q0.359375 -0.453125 1.03125 -0.6875q0.671875 -0.25 1.5625 -0.25q0.890625 0 1.4375 0.203125q0.5625 0.203125 0.8125 0.53125q0.265625 0.3125 0.375 0.796875q0.046875 0.296875 0.046875 1.078125l0 1.5625q0 1.625 0.078125 2.0625q0.078125 0.4375 0.296875 0.828125l-1.21875 0q-0.1875 -0.359375 -0.234375 -0.859375zm-0.09375 -2.609375q-0.640625 0.265625 -1.921875 0.4375q-0.71875 0.109375 -1.015625 0.25q-0.296875 0.125 -0.46875 0.375q-0.15625 0.25 -0.15625 0.546875q0 0.46875 0.34375 0.78125q0.359375 0.3125 1.046875 0.3125q0.671875 0 1.203125 -0.296875q0.53125 -0.296875 0.78125 -0.8125q0.1875 -0.390625 0.1875 -1.171875l0 -0.421875zm3.2718506 3.46875l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm3.4620972 0l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm3.4373627 -8.1875l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm2.945465 0l0 -6.90625l1.0625 0l0 0.984375q0.75 -1.140625 2.1875 -1.140625q0.625 0 1.15625 0.21875q0.53125 0.21875 0.78125 0.59375q0.265625 0.359375 0.375 0.859375q0.0625 0.328125 0.0625 1.140625l0 4.25l-1.171875 0l0 -4.203125q0 -0.71875 -0.140625 -1.0625q-0.140625 -0.359375 -0.484375 -0.5625q-0.34375 -0.21875 -0.8125 -0.21875q-0.75 0 -1.296875 0.46875q-0.546875 0.46875 -0.546875 1.796875l0 3.78125l-1.171875 0zm7.4281006 -8.1875l0 -1.359375l1.171875 0l0 1.359375l-1.171875 0zm0 8.1875l0 -6.90625l1.171875 0l0 6.90625l-1.171875 0zm5.507965 -1.046875l0.171875 1.03125q-0.5 0.109375 -0.890625 0.109375q-0.640625 0 -1.0 -0.203125q-0.34375 -0.203125 -0.484375 -0.53125q-0.140625 -0.328125 -0.140625 -1.390625l0 -3.96875l-0.859375 0l0 -0.90625l0.859375 0l0 -1.71875l1.171875 -0.703125l0 2.421875l1.171875 0l0 0.90625l-1.171875 0l0 4.046875q0 0.5 0.046875 0.640625q0.0625 0.140625 0.203125 0.234375q0.140625 0.078125 0.40625 0.078125q0.203125 0 0.515625 -0.046875zm1.0936127 3.703125l-0.125 -1.09375q0.375 0.109375 0.65625 0.109375q0.390625 0 0.625 -0.140625q0.234375 -0.125 0.390625 -0.359375q0.109375 -0.171875 0.359375 -0.875q0.03125 -0.09375 0.109375 -0.28125l-2.625 -6.921875l1.265625 0l1.4375 4.0q0.28125 0.765625 0.5 1.59375q0.203125 -0.796875 0.46875 -1.578125l1.484375 -4.015625l1.171875 0l-2.625 7.015625q-0.421875 1.140625 -0.65625 1.578125q-0.3125 0.578125 -0.71875 0.84375q-0.40625 0.28125 -0.96875 0.28125q-0.328125 0 -0.75 -0.15625z" fill-rule="nonzero"/><path fill="#000000" d="m60.005154 291.24622l0 -6.0l-1.03125 0l0 -0.90625l1.03125 0l0 -0.734375q0 -0.703125 0.125 -1.046875q0.171875 -0.453125 0.59375 -0.734375q0.421875 -0.28125 1.203125 -0.28125q0.484375 0 1.09375 0.109375l-0.1875 1.03125q-0.359375 -0.0625 -0.6875 -0.0625q-0.53125 0 -0.75 0.234375q-0.21875 0.21875 -0.21875 0.84375l0 0.640625l1.34375 0l0 0.90625l-1.34375 0l0 6.0l-1.171875 0zm2.9842377 -3.453125q0 -1.921875 1.0781212 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.3593712 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.2031212 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm6.6312256 3.453125l0 -6.90625l1.0625 0l0 1.046875q0.40625 -0.734375 0.734375 -0.96875q0.34375 -0.234375 0.765625 -0.234375q0.59375 0 1.203125 0.375l-0.40625 1.078125q-0.4375 -0.25 -0.859375 -0.25q-0.390625 0 -0.703125 0.234375q-0.296875 0.234375 -0.421875 0.640625q-0.203125 0.625 -0.203125 1.359375l0 3.625l-1.171875 0zm12.672607 -0.859375q-0.65625 0.5625 -1.265625 0.796875q-0.59375 0.21875 -1.28125 0.21875q-1.140625 0 -1.75 -0.546875q-0.609375 -0.5625 -0.609375 -1.4375q0 -0.5 0.21875 -0.921875q0.234375 -0.421875 0.609375 -0.671875q0.375 -0.25 0.84375 -0.390625q0.34375 -0.078125 1.046875 -0.171875q1.421875 -0.171875 2.09375 -0.40625q0 -0.234375 0 -0.296875q0 -0.71875 -0.328125 -1.015625q-0.453125 -0.390625 -1.34375 -0.390625q-0.8125 0 -1.21875 0.296875q-0.390625 0.28125 -0.578125 1.015625l-1.140625 -0.15625q0.15625 -0.734375 0.515625 -1.1875q0.359375 -0.453125 1.03125 -0.6875q0.671875 -0.25 1.5625 -0.25q0.890625 0 1.4375 0.203125q0.5625 0.203125 0.8125 0.53125q0.265625 0.3125 0.375 0.796875q0.046875 0.296875 0.046875 1.078125l0 1.5625q0 1.625 0.078125 2.0625q0.078125 0.4375 0.296875 0.828125l-1.21875 0q-0.1875 -0.359375 -0.234375 -0.859375zm-0.09375 -2.609375q-0.640625 0.265625 -1.921875 0.4375q-0.71875 0.109375 -1.015625 0.25q-0.296875 0.125 -0.46875 0.375q-0.15625 0.25 -0.15625 0.546875q0 0.46875 0.34375 0.78125q0.359375 0.3125 1.046875 0.3125q0.671875 0 1.203125 -0.296875q0.53125 -0.296875 0.78125 -0.8125q0.1875 -0.390625 0.1875 -1.171875l0 -0.421875zm7.5062256 0.9375l1.15625 0.15625q-0.1875 1.1875 -0.96875 1.859375q-0.78125 0.671875 -1.921875 0.671875q-1.40625 0 -2.28125 -0.921875q-0.859375 -0.9375 -0.859375 -2.65625q0 -1.125 0.375 -1.96875q0.375 -0.84375 1.125 -1.25q0.765625 -0.421875 1.65625 -0.421875q1.125 0 1.84375 0.578125q0.71875 0.5625 0.921875 1.609375l-1.140625 0.171875q-0.171875 -0.703125 -0.59375 -1.046875q-0.40625 -0.359375 -0.984375 -0.359375q-0.890625 0 -1.453125 0.640625q-0.546875 0.640625 -0.546875 2.0q0 1.40625 0.53125 2.03125q0.546875 0.625 1.40625 0.625q0.6875 0 1.140625 -0.421875q0.46875 -0.421875 0.59375 -1.296875zm4.7109375 1.484375l0.171875 1.03125q-0.5 0.109375 -0.890625 0.109375q-0.640625 0 -1.0 -0.203125q-0.34375 -0.203125 -0.484375 -0.53125q-0.140625 -0.328125 -0.140625 -1.390625l0 -3.96875l-0.859375 0l0 -0.90625l0.859375 0l0 -1.71875l1.171875 -0.703125l0 2.421875l1.171875 0l0 0.90625l-1.171875 0l0 4.046875q0 0.5 0.046875 0.640625q0.0625 0.140625 0.203125 0.234375q0.140625 0.078125 0.40625 0.078125q0.203125 0 0.515625 -0.046875zm0.7029877 -2.40625q0 -1.921875 1.078125 -2.84375q0.890625 -0.765625 2.171875 -0.765625q1.421875 0 2.328125 0.9375q0.90625 0.921875 0.90625 2.578125q0 1.328125 -0.40625 2.09375q-0.390625 0.765625 -1.15625 1.1875q-0.765625 0.421875 -1.671875 0.421875q-1.453125 0 -2.359375 -0.921875q-0.890625 -0.9375 -0.890625 -2.6875zm1.203125 0q0 1.328125 0.578125 1.984375q0.59375 0.65625 1.46875 0.65625q0.875 0 1.453125 -0.65625q0.578125 -0.671875 0.578125 -2.03125q0 -1.28125 -0.59375 -1.9375q-0.578125 -0.65625 -1.4375 -0.65625q-0.875 0 -1.46875 0.65625q-0.578125 0.65625 -0.578125 1.984375zm6.6312256 3.453125l0 -6.90625l1.0625 0l0 1.046875q0.40625 -0.734375 0.734375 -0.96875q0.34375 -0.234375 0.765625 -0.234375q0.59375 0 1.203125 0.375l-0.40625 1.078125q-0.4375 -0.25 -0.859375 -0.25q-0.390625 0 -0.703125 0.234375q-0.296875 0.234375 -0.421875 0.640625q-0.203125 0.625 -0.203125 1.359375l0 3.625l-1.171875 0zm3.9852448 -2.0625l1.15625 -0.1875q0.109375 0.703125 0.546875 1.078125q0.453125 0.359375 1.25 0.359375q0.8125 0 1.203125 -0.328125q0.390625 -0.328125 0.390625 -0.765625q0 -0.390625 -0.359375 -0.625q-0.234375 -0.15625 -1.1875 -0.390625q-1.296875 -0.328125 -1.796875 -0.5625q-0.484375 -0.25 -0.75 -0.65625q-0.25 -0.421875 -0.25 -0.9375q0 -0.453125 0.203125 -0.84375q0.21875 -0.40625 0.578125 -0.671875q0.28125 -0.1875 0.75 -0.328125q0.46875 -0.140625 1.015625 -0.140625q0.8125 0 1.421875 0.234375q0.609375 0.234375 0.90625 0.640625q0.296875 0.390625 0.40625 1.0625l-1.140625 0.15625q-0.078125 -0.53125 -0.453125 -0.828125q-0.375 -0.3125 -1.0625 -0.3125q-0.8125 0 -1.15625 0.265625q-0.34375 0.265625 -0.34375 0.625q0 0.234375 0.140625 0.421875q0.15625 0.1875 0.453125 0.3125q0.171875 0.0625 1.03125 0.296875q1.25 0.328125 1.734375 0.546875q0.5 0.203125 0.78125 0.609375q0.28125 0.40625 0.28125 1.0q0 0.59375 -0.34375 1.109375q-0.34375 0.515625 -1.0 0.796875q-0.640625 0.28125 -1.453125 0.28125q-1.34375 0 -2.046875 -0.5625q-0.703125 -0.5625 -0.90625 -1.65625z" fill-rule="nonzero"/><path fill="#ffffff" d="m460.45285 90.08796l0 0c0 -3.7457504 3.0365295 -6.7822876 6.7822876 -6.7822876l134.21494 0c1.7988281 0 3.5239258 0.71456146 4.7958374 1.9864883c1.2719116 1.2719269 1.9864502 2.9970245 1.9864502 4.7957993l0 27.128342c0 3.7457504 -3.036499 6.7822876 -6.7822876 6.7822876l-134.21494 0c-3.745758 0 -6.7822876 -3.0365372 -6.7822876 -6.7822876z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m460.45285 90.08796l0 0c0 -3.7457504 3.0365295 -6.7822876 6.7822876 -6.7822876l134.21494 0c1.7988281 0 3.5239258 0.71456146 4.7958374 1.9864883c1.2719116 1.2719269 1.9864502 2.9970245 1.9864502 4.7957993l0 27.128342c0 3.7457504 -3.036499 6.7822876 -6.7822876 6.7822876l-134.21494 0c-3.745758 0 -6.7822876 -3.0365372 -6.7822876 -6.7822876z" fill-rule="evenodd"/><path fill="#000000" d="m512.1151 96.6815l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm13.5625 1.421875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm7.9176636 0.28125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm4.1882324 4.859375l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm9.8064575 -1.46875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.9489136 -1.421875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125z" fill-rule="nonzero"/><path fill="#000000" d="m474.92142 125.27525l0 -13.375l1.484375 0l0 1.25q0.53125 -0.734375 1.1875 -1.09375q0.671875 -0.375 1.625 -0.375q1.234375 0 2.171875 0.640625q0.953125 0.625 1.4375 1.796875q0.484375 1.15625 0.484375 2.546875q0 1.484375 -0.53125 2.671875q-0.53125 1.1875 -1.546875 1.828125q-1.015625 0.625 -2.140625 0.625q-0.8125 0 -1.46875 -0.34375q-0.65625 -0.34375 -1.0625 -0.875l0 4.703125l-1.640625 0zm1.484375 -8.484375q0 1.859375 0.75 2.765625q0.765625 0.890625 1.828125 0.890625q1.09375 0 1.875 -0.921875q0.78125 -0.9375 0.78125 -2.875q0 -1.84375 -0.765625 -2.765625q-0.75 -0.921875 -1.8125 -0.921875q-1.046875 0 -1.859375 0.984375q-0.796875 0.96875 -0.796875 2.84375zm8.875702 4.78125l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm5.618927 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.610107 1.296875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm9.6405945 0.4375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.3749695 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.2655945 -1.34375 3.2655945 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm8.485107 2.875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm9.328125 0l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm9.59375 -1.40625l1.65625 -0.140625q0.125 1.0 0.546875 1.640625q0.4375 0.640625 1.34375 1.046875q0.921875 0.390625 2.0625 0.390625q1.0 0 1.78125 -0.296875q0.78125 -0.296875 1.15625 -0.8125q0.375 -0.53125 0.375 -1.15625q0 -0.625 -0.375 -1.09375q-0.359375 -0.46875 -1.1875 -0.796875q-0.546875 -0.203125 -2.390625 -0.640625q-1.828125 -0.453125 -2.5625 -0.84375q-0.96875 -0.5 -1.4375 -1.234375q-0.46875 -0.75 -0.46875 -1.671875q0 -1.0 0.578125 -1.875q0.578125 -0.890625 1.671875 -1.34375q1.109375 -0.453125 2.453125 -0.453125q1.484375 0 2.609375 0.484375q1.140625 0.46875 1.75 1.40625q0.609375 0.921875 0.65625 2.09375l-1.6875 0.125q-0.140625 -1.265625 -0.9375 -1.90625q-0.78125 -0.65625 -2.3125 -0.65625q-1.609375 0 -2.34375 0.59375q-0.734375 0.59375 -0.734375 1.421875q0 0.71875 0.53125 1.171875q0.5 0.46875 2.65625 0.96875q2.15625 0.484375 2.953125 0.84375q1.171875 0.53125 1.71875 1.359375q0.5625 0.828125 0.5625 1.90625q0 1.0625 -0.609375 2.015625q-0.609375 0.9375 -1.75 1.46875q-1.140625 0.515625 -2.578125 0.515625q-1.8125 0 -3.046875 -0.53125q-1.21875 -0.53125 -1.921875 -1.59375q-0.6875 -1.0625 -0.71875 -2.40625zm12.7873535 4.296875l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm3.5822754 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm12.875732 3.375l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm5.2145386 1.46875l0 -11.78125l-4.40625 0l0 -1.578125l10.578125 0l0 1.578125l-4.40625 0l0 11.78125l-1.765625 0zm6.630371 0l5.171875 -6.953125l-4.5625 -6.40625l2.109375 0l2.421875 3.4375q0.75 1.0625 1.078125 1.625q0.4375 -0.71875 1.046875 -1.515625l2.6875 -3.546875l1.921875 0l-4.6875 6.296875l5.0625 7.0625l-2.1875 0l-3.359375 -4.765625q-0.28125 -0.40625 -0.59375 -0.890625q-0.4375 0.734375 -0.625 1.0l-3.359375 4.65625l-2.125 0z" fill-rule="nonzero"/><path fill="#eeeeee" d="m89.20461 9.160635l67.77953 0l0 12.661417l-67.77953 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m89.20461 9.160635l67.77953 0l0 12.661417l-67.77953 0z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m779.01306 278.6972l135.1496 0l0 48.472443l-135.1496 0z" fill-rule="evenodd"/><path fill="#595959" d="m790.80994 310.7372l0 -2.40625l2.40625 0l0 2.40625l-2.40625 0zm8.015625 0l0 -2.40625l2.390625 0l0 2.40625l-2.390625 0zm7.984375 0l0 -2.40625l2.421875 0l0 2.40625l-2.421875 0z" fill-rule="nonzero"/><path fill="#ffffff" d="m492.90643 440.06082l0 0c-8.774078 0 -15.886871 -7.112793 -15.886871 -15.886902l0 -107.28131c0 -4.2134705 1.6737671 -8.254364 4.6531677 -11.233734c2.97937 -2.97937 7.0202637 -4.6531677 11.233704 -4.6531677l6.525421 0c8.774109 0 15.886932 7.1128235 15.886932 15.886902l0 107.28131c0 8.774109 -7.1128235 15.886902 -15.886932 15.886902z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m492.90643 440.06082l0 0c-8.774078 0 -15.886871 -7.112793 -15.886871 -15.886902l0 -107.28131c0 -4.2134705 1.6737671 -8.254364 4.6531677 -11.233734c2.97937 -2.97937 7.0202637 -4.6531677 11.233704 -4.6531677l6.525421 0c8.774109 0 15.886932 7.1128235 15.886932 15.886902l0 107.28131c0 8.774109 -7.1128235 15.886902 -15.886932 15.886902z" fill-rule="evenodd"/><path fill="#000000" d="m501.6204 409.78796l1.453125 -0.234375q0.140625 0.6875 0.140625 1.234375q0 0.890625 -0.28125 1.390625q-0.28125 0.484375 -0.734375 0.6875q-0.46875 0.203125 -1.9375 0.203125l-5.578125 0l0 1.203125l-1.265625 0l0 -1.203125l-2.390625 0l-0.984375 -1.625l3.375 0l0 -1.65625l1.265625 0l0 1.65625l5.671875 0q0.6875 0 0.890625 -0.078125q0.203125 -0.09375 0.328125 -0.28125q0.109375 -0.203125 0.109375 -0.578125q0 -0.265625 -0.0625 -0.71875zm0.28125 -7.917694q0.765625 0.921875 1.09375 1.765625q0.3125 0.828125 0.3125 1.796875q0 1.59375 -0.78125 2.453125q-0.78125 0.859375 -1.984375 0.859375q-0.71875 0 -1.296875 -0.328125q-0.59375 -0.328125 -0.9375 -0.84375q-0.359375 -0.53125 -0.546875 -1.1875q-0.125 -0.46875 -0.25 -1.453125q-0.234375 -1.984375 -0.5625 -2.921875q-0.34375 -0.015625 -0.421875 -0.015625q-1.0 0 -1.421875 0.46875q-0.546875 0.625 -0.546875 1.875q0 1.15625 0.40625 1.703125q0.40625 0.546875 1.421875 0.8125l-0.21875 1.609375q-1.015625 -0.21875 -1.640625 -0.71875q-0.640625 -0.5 -0.984375 -1.453125q-0.34375 -0.953125 -0.34375 -2.1875q0 -1.25 0.296875 -2.015625q0.28125 -0.78125 0.734375 -1.140625q0.4375 -0.375 1.109375 -0.515625q0.421875 -0.078125 1.515625 -0.078125l2.1875 0q2.28125 0 2.890625 -0.109375q0.59375 -0.109375 1.15625 -0.40625l0 1.703125q-0.515625 0.265625 -1.1875 0.328125zm-3.671875 0.140625q0.375 0.890625 0.625 2.671875q0.140625 1.015625 0.328125 1.4375q0.1875 0.421875 0.53125 0.65625q0.34375 0.21875 0.78125 0.21875q0.65625 0 1.09375 -0.5q0.4375 -0.5 0.4375 -1.453125q0 -0.9375 -0.40625 -1.671875q-0.421875 -0.75 -1.140625 -1.09375q-0.5625 -0.265625 -1.640625 -0.265625l-0.609375 0zm1.96875 -3.547577l-0.25 -1.625q0.96875 -0.125 1.5 -0.75q0.515625 -0.625 0.515625 -1.75q0 -1.125 -0.453125 -1.671875q-0.46875 -0.546875 -1.09375 -0.546875q-0.546875 0 -0.875 0.484375q-0.21875 0.328125 -0.546875 1.671875q-0.46875 1.8125 -0.796875 2.515625q-0.328125 0.6875 -0.90625 1.046875q-0.59375 0.359375 -1.3125 0.359375q-0.640625 0 -1.1875 -0.296875q-0.5625 -0.296875 -0.921875 -0.8125q-0.28125 -0.375 -0.46875 -1.03125q-0.203125 -0.671875 -0.203125 -1.421875q0 -1.140625 0.328125 -2.0q0.328125 -0.859375 0.890625 -1.265625q0.5625 -0.421875 1.5 -0.578125l0.21875 1.609375q-0.75 0.109375 -1.171875 0.640625q-0.421875 0.515625 -0.421875 1.46875q0 1.140625 0.375 1.625q0.375 0.46875 0.875 0.46875q0.3125 0 0.578125 -0.1875q0.265625 -0.203125 0.4375 -0.640625q0.09375 -0.234375 0.421875 -1.4375q0.453125 -1.75 0.75 -2.4375q0.296875 -0.6875 0.859375 -1.078125q0.5625 -0.390625 1.40625 -0.390625q0.828125 0 1.546875 0.484375q0.71875 0.46875 1.125 1.375q0.390625 0.90625 0.390625 2.046875q0 1.875 -0.78125 2.875q-0.78125 0.984375 -2.328125 1.25zm2.890625 -9.984375l-13.359375 0l0 -1.640625l7.625 0l-3.9375 -3.890625l0 -2.109375l3.59375 3.6875l6.078125 -4.0625l0 2.015625l-4.953125 3.203125l1.125 1.15625l3.828125 0l0 1.640625zm0 -14.495819l-9.671875 0l0 -1.46875l1.46875 0q-1.03125 -0.5625 -1.359375 -1.03125q-0.328125 -0.48434448 -0.328125 -1.0624695q0 -0.828125 0.53125 -1.6875l1.515625 0.5625q-0.359375 0.609375 -0.359375 1.203125q0 0.546875 0.328125 0.9687195q0.328125 0.421875 0.890625 0.609375q0.875 0.28125 1.921875 0.28125l5.0625 0l0 1.625zm-3.109375 -12.8532715l0.203125 -1.6875q1.484375 0.40625 2.3125 1.484375q0.8125 1.078125 0.8125 2.765625q0 2.125 -1.296875 3.375q-1.3125 1.234375 -3.671875 1.234375q-2.453125 0 -3.796875 -1.25q-1.34375 -1.265625 -1.34375 -3.265625q0 -1.9375 1.328125 -3.15625q1.3125 -1.234375 3.703125 -1.234375q0.15625 0 0.4375 0l0 7.21875q1.59375 -0.09375 2.453125 -0.90625q0.84375 -0.8125 0.84375 -2.015625q0 -0.90625 -0.46875 -1.546875q-0.484375 -0.640625 -1.515625 -1.015625zm-2.65625 5.390625l0 -5.40625q-1.21875 0.109375 -1.828125 0.625q-0.953125 0.78125 -0.953125 2.03125q0 1.125 0.765625 1.90625q0.75 0.765625 2.015625 0.84375zm4.296875 -12.719482l1.453125 -0.234375q0.140625 0.6875 0.140625 1.234375q0 0.890625 -0.28125 1.390625q-0.28125 0.484375 -0.734375 0.6875q-0.46875 0.203125 -1.9375 0.203125l-5.578125 0l0 1.203125l-1.265625 0l0 -1.203125l-2.390625 0l-0.984375 -1.625l3.375 0l0 -1.65625l1.265625 0l0 1.65625l5.671875 0q0.6875 0 0.890625 -0.078125q0.203125 -0.09375 0.328125 -0.28125q0.109375 -0.203125 0.109375 -0.578125q0 -0.265625 -0.0625 -0.71875zm1.46875 -7.9332886l-1.421875 0q1.640625 1.125 1.640625 3.0625q0 0.859375 -0.328125 1.609375q-0.328125 0.734375 -0.828125 1.09375q-0.5 0.359375 -1.21875 0.5q-0.46875 0.109375 -1.53125 0.109375l-5.984375 0l0 -1.640625l5.359375 0q1.28125 0 1.734375 -0.109375q0.640625 -0.15625 1.015625 -0.65625q0.375 -0.5 0.375 -1.234375q0 -0.734375 -0.375 -1.375q-0.390625 -0.65625 -1.03125 -0.921875q-0.65625 -0.265625 -1.890625 -0.265625l-5.1875 0l0 -1.640625l9.671875 0l0 1.46875zm0 -4.0319824l-9.671875 0l0 -1.46875l1.46875 0q-1.03125 -0.5625 -1.359375 -1.03125q-0.328125 -0.484375 -0.328125 -1.0625q0 -0.828125 0.53125 -1.6875l1.515625 0.5625q-0.359375 0.609375 -0.359375 1.203125q0 0.546875 0.328125 0.96875q0.328125 0.421875 0.890625 0.609375q0.875 0.28125 1.921875 0.28125l5.0625 0l0 1.625zm0 -6.228302l-9.671875 0l0 -1.46875l1.375 0q-1.59375 -1.0625 -1.59375 -3.078125q0 -0.875 0.3125 -1.609375q0.3125 -0.734375 0.828125 -1.09375q0.5 -0.375 1.203125 -0.515625q0.453125 -0.09375 1.59375 -0.09375l5.953125 0l0 1.640625l-5.890625 0q-1.0 0 -1.484375 0.203125q-0.5 0.1875 -0.796875 0.671875q-0.296875 0.484375 -0.296875 1.140625q0 1.046875 0.671875 1.8125q0.65625 0.75 2.515625 0.75l5.28125 0l0 1.640625z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m139.39944 0l403.43307 0l0 32.31496l-403.43307 0z" fill-rule="evenodd"/><path fill="#595959" d="m160.58578 16.943125l0 -0.9375l2.875 0l0 0.9375l-2.875 0zm8.915512 1.453125l0.125 0.828125q-0.390625 0.09375 -0.703125 0.09375q-0.5 0 -0.78125 -0.15625q-0.28125 -0.171875 -0.40625 -0.4375q-0.109375 -0.265625 -0.109375 -1.109375l0 -3.171875l-0.6875 0l0 -0.734375l0.6875 0l0 -1.359375l0.9375 -0.5625l0 1.921875l0.9375 0l0 0.734375l-0.9375 0l0 3.234375q0 0.390625 0.046875 0.515625q0.046875 0.109375 0.15625 0.1875q0.109375 0.0625 0.328125 0.0625q0.15625 0 0.40625 -0.046875zm0.9137726 0.84375l0 -7.625l0.9375 0l0 2.734375q0.65625 -0.765625 1.65625 -0.765625q0.609375 0 1.0625 0.25q0.453125 0.234375 0.640625 0.671875q0.203125 0.421875 0.203125 1.234375l0 3.5l-0.9375 0l0 -3.5q0 -0.703125 -0.3125 -1.015625q-0.296875 -0.328125 -0.859375 -0.328125q-0.40625 0 -0.78125 0.21875q-0.359375 0.21875 -0.515625 0.59375q-0.15625 0.359375 -0.15625 1.015625l0 3.015625l-0.9375 0zm5.9108734 0l0 -5.53125l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.890625l-0.9375 0zm7.3454895 -1.78125l0.96875 0.125q-0.234375 0.84375 -0.859375 1.3125q-0.609375 0.46875 -1.578125 0.46875q-1.203125 0 -1.921875 -0.75q-0.703125 -0.75 -0.703125 -2.09375q0 -1.390625 0.71875 -2.15625q0.71875 -0.78125 1.859375 -0.78125q1.109375 0 1.8125 0.765625q0.703125 0.75 0.703125 2.125q0 0.078125 0 0.234375l-4.125 0q0.046875 0.921875 0.515625 1.40625q0.46875 0.484375 1.15625 0.484375q0.515625 0 0.875 -0.265625q0.359375 -0.28125 0.578125 -0.875zm-3.078125 -1.515625l3.09375 0q-0.0625 -0.6875 -0.359375 -1.046875q-0.453125 -0.53125 -1.15625 -0.53125q-0.640625 0 -1.09375 0.4375q-0.4375 0.421875 -0.484375 1.140625zm8.832748 2.609375q-0.53125 0.453125 -1.015625 0.640625q-0.46875 0.171875 -1.015625 0.171875q-0.921875 0 -1.40625 -0.4375q-0.484375 -0.453125 -0.484375 -1.140625q0 -0.40625 0.171875 -0.734375q0.1875 -0.34375 0.484375 -0.546875q0.3125 -0.203125 0.6875 -0.3125q0.265625 -0.0625 0.828125 -0.140625q1.125 -0.125 1.671875 -0.3125q0 -0.203125 0 -0.25q0 -0.578125 -0.265625 -0.8125q-0.359375 -0.3125 -1.0625 -0.3125q-0.65625 0 -0.984375 0.234375q-0.3125 0.234375 -0.453125 0.8125l-0.921875 -0.125q0.125 -0.578125 0.40625 -0.9375q0.296875 -0.375 0.828125 -0.5625q0.546875 -0.203125 1.25 -0.203125q0.71875 0 1.15625 0.171875q0.4375 0.171875 0.640625 0.421875q0.21875 0.25 0.296875 0.640625q0.046875 0.234375 0.046875 0.859375l0 1.25q0 1.296875 0.0625 1.65625q0.0625 0.34375 0.234375 0.65625l-0.96875 0q-0.15625 -0.296875 -0.1875 -0.6875zm-0.078125 -2.078125q-0.515625 0.203125 -1.53125 0.34375q-0.578125 0.078125 -0.828125 0.1875q-0.234375 0.109375 -0.359375 0.3125q-0.125 0.1875 -0.125 0.4375q0 0.375 0.28125 0.625q0.28125 0.25 0.828125 0.25q0.53125 0 0.953125 -0.234375q0.421875 -0.234375 0.625 -0.65625q0.15625 -0.3125 0.15625 -0.9375l0 -0.328125zm5.9733734 2.765625l0 -0.703125q-0.515625 0.828125 -1.546875 0.828125q-0.65625 0 -1.21875 -0.359375q-0.546875 -0.375 -0.859375 -1.015625q-0.296875 -0.65625 -0.296875 -1.5q0 -0.828125 0.28125 -1.5q0.28125 -0.6875 0.828125 -1.046875q0.546875 -0.359375 1.234375 -0.359375q0.5 0 0.890625 0.21875q0.390625 0.203125 0.625 0.546875l0 -2.734375l0.9375 0l0 7.625l-0.875 0zm-2.953125 -2.75q0 1.046875 0.4375 1.578125q0.453125 0.53125 1.0625 0.53125q0.609375 0 1.03125 -0.5q0.4375 -0.515625 0.4375 -1.53125q0 -1.140625 -0.4375 -1.671875q-0.4375 -0.53125 -1.078125 -0.53125q-0.609375 0 -1.03125 0.515625q-0.421875 0.5 -0.421875 1.609375z" fill-rule="nonzero"/><path fill="#ffffff" d="m293.44656 207.26974l0 0c0 -4.6242065 3.7486877 -8.372864 8.372894 -8.372864l131.03378 0c2.2206116 0 4.350281 0.8821411 5.9205017 2.4523468c1.570221 1.570221 2.452362 3.6998901 2.452362 5.920517l0 33.49048c0 4.6242065 -3.7486572 8.372879 -8.372864 8.372879l-131.03378 0c-4.6242065 0 -8.372894 -3.7486725 -8.372894 -8.372879z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m293.44656 207.26974l0 0c0 -4.6242065 3.7486877 -8.372864 8.372894 -8.372864l131.03378 0c2.2206116 0 4.350281 0.8821411 5.9205017 2.4523468c1.570221 1.570221 2.452362 3.6998901 2.452362 5.920517l0 33.49048c0 4.6242065 -3.7486572 8.372879 -8.372864 8.372879l-131.03378 0c-4.6242065 0 -8.372894 -3.7486725 -8.372894 -8.372879z" fill-rule="evenodd"/><path fill="#000000" d="m345.10886 217.04436l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm13.5625 1.421875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm7.9176636 0.28125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm4.188202 4.859375l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm9.806427 -1.46875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.9489441 -1.421875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125z" fill-rule="nonzero"/><path fill="#000000" d="m335.02545 228.5756l1.765625 0l0 7.71875q0 2.015625 -0.453125 3.203125q-0.453125 1.1875 -1.640625 1.9375q-1.1875 0.734375 -3.125 0.734375q-1.875 0 -3.078125 -0.640625q-1.1875 -0.65625 -1.703125 -1.875q-0.5 -1.234375 -0.5 -3.359375l0 -7.71875l1.765625 0l0 7.71875q0 1.734375 0.3125 2.5625q0.328125 0.8125 1.109375 1.265625q0.796875 0.453125 1.9375 0.453125q1.953125 0 2.78125 -0.890625q0.828125 -0.890625 0.828125 -3.390625l0 -7.71875zm4.738556 13.359375l0 -13.359375l9.65625 0l0 1.578125l-7.875 0l0 4.09375l7.375 0l0 1.5625l-7.375 0l0 4.546875l8.1875 0l0 1.578125l-9.96875 0zm10.693573 3.703125l0 -1.1875l10.859375 0l0 1.1875l-10.859375 0zm11.235107 -6.59375l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm9.90625 6.609375l-0.1875 -1.53125q0.546875 0.140625 0.9375 0.140625q0.546875 0 0.875 -0.1875q0.328125 -0.171875 0.546875 -0.5q0.15625 -0.25 0.5 -1.21875q0.046875 -0.140625 0.140625 -0.40625l-3.671875 -9.6875l1.765625 0l2.015625 5.59375q0.390625 1.078125 0.703125 2.25q0.28125 -1.125 0.671875 -2.203125l2.078125 -5.640625l1.640625 0l-3.6875 9.828125q-0.59375 1.609375 -0.921875 2.203125q-0.4375 0.8125 -1.0 1.1875q-0.5625 0.375 -1.34375 0.375q-0.484375 0 -1.0625 -0.203125zm9.40625 -3.71875l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm16.688202 -3.546875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm3.015625 3.546875l0 -13.359375l1.640625 0l0 4.796875q1.140625 -1.328125 2.890625 -1.328125q1.078125 0 1.859375 0.421875q0.796875 0.421875 1.140625 1.171875q0.34375 0.75 0.34375 2.171875l0 6.125l-1.640625 0l0 -6.125q0 -1.234375 -0.53125 -1.796875q-0.53125 -0.5625 -1.515625 -0.5625q-0.71875 0 -1.359375 0.390625q-0.640625 0.375 -0.921875 1.015625q-0.265625 0.640625 -0.265625 1.78125l0 5.296875l-1.640625 0z" fill-rule="nonzero"/><path fill="#eeeeee" d="m159.69286 307.29163l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m159.69286 307.29163l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path fill="#eeeeee" d="m163.22864 311.44962l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m163.22864 311.44962l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path fill="#eeeeee" d="m167.03758 317.41028l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m167.03758 317.41028l73.543304 0l0 146.4567l-73.543304 0z" fill-rule="evenodd"/><path fill="#000000" d="m193.3224 386.55862l0 -13.359375l4.609375 0q1.546875 0 2.375 0.203125q1.140625 0.25 1.953125 0.953125q1.0625 0.890625 1.578125 2.28125q0.53125 1.390625 0.53125 3.171875q0 1.515625 -0.359375 2.703125q-0.359375 1.171875 -0.921875 1.9375q-0.546875 0.765625 -1.203125 1.21875q-0.65625 0.4375 -1.59375 0.671875q-0.9375 0.21875 -2.140625 0.21875l-4.828125 0zm1.765625 -1.578125l2.859375 0q1.3125 0 2.0625 -0.234375q0.75 -0.25 1.203125 -0.703125q0.625 -0.625 0.96875 -1.6875q0.359375 -1.0625 0.359375 -2.578125q0 -2.09375 -0.6875 -3.21875q-0.6875 -1.125 -1.671875 -1.5q-0.703125 -0.28125 -2.28125 -0.28125l-2.8125 0l0 10.203125zm11.629196 1.578125l0 -13.359375l1.78125 0l0 11.78125l6.5625 0l0 1.578125l-8.34375 0z" fill-rule="nonzero"/><path fill="#000000" d="m177.34222 408.55862l5.125 -13.359375l1.90625 0l5.46875 13.359375l-2.015625 0l-1.546875 -4.046875l-5.59375 0l-1.46875 4.046875l-1.875 0zm3.859375 -5.484375l4.53125 0l-1.40625 -3.703125q-0.625 -1.6875 -0.9375 -2.765625q-0.265625 1.28125 -0.71875 2.546875l-1.46875 3.921875zm16.162323 1.9375l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm6.59375 2.078125l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.99580383 -3.375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm9.281967 4.84375l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm5.572052 -2.890625l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125z" fill-rule="nonzero"/><path fill="#ffff00" d="m0 491.0498l0 0c0 -5.406891 4.383144 -9.790039 9.790027 -9.790039l94.67717 0l48.897217 -38.0542l-4.1255646 38.0542l20.05774 0c2.5964813 0 5.086609 1.0314636 6.922592 2.8674316c1.8359833 1.8359985 2.8674316 4.3261414 2.8674316 6.9226074l0 0l0 0l0 14.685028l0 24.475067c0 5.4069214 -4.383133 9.790039 -9.790024 9.790039l-20.05774 0l-44.771652 0l0 0l-94.67717 0c-5.406883 0 -9.790027 -4.3831177 -9.790027 -9.790039l0 -24.475067l0 -14.685028l0 0z" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m0 491.0498l0 0c0 -5.406891 4.383144 -9.790039 9.790027 -9.790039l94.67717 0l48.897217 -38.0542l-4.1255646 38.0542l20.05774 0c2.5964813 0 5.086609 1.0314636 6.922592 2.8674316c1.8359833 1.8359985 2.8674316 4.3261414 2.8674316 6.9226074l0 0l0 0l0 14.685028l0 24.475067c0 5.4069214 -4.383133 9.790039 -9.790024 9.790039l-20.05774 0l-44.771652 0l0 0l-94.67717 0c-5.406883 0 -9.790027 -4.3831177 -9.790027 -9.790039l0 -24.475067l0 -14.685028l0 0z" fill-rule="evenodd"/><path fill="#000000" d="m15.304901 501.36984l0 -1.828125l-3.296875 0l0 -0.859375l3.46875 -4.9375l0.765625 0l0 4.9375l1.03125 0l0 0.859375l-1.03125 0l0 1.828125l-0.9375 0zm0 -2.6875l0 -3.4375l-2.375 3.4375l2.375 0zm6.277771 2.6875l0 -7.625l2.625 0q0.890625 0 1.359375 0.109375q0.65625 0.140625 1.109375 0.546875q0.609375 0.5 0.90625 1.296875q0.296875 0.796875 0.296875 1.8125q0 0.875 -0.203125 1.546875q-0.203125 0.671875 -0.515625 1.109375q-0.3125 0.4375 -0.703125 0.6875q-0.375 0.25 -0.90625 0.390625q-0.53125 0.125 -1.21875 0.125l-2.75 0zm1.0 -0.90625l1.625 0q0.765625 0 1.1875 -0.140625q0.4375 -0.140625 0.6875 -0.390625q0.359375 -0.359375 0.5625 -0.953125q0.203125 -0.609375 0.203125 -1.484375q0 -1.1875 -0.40625 -1.828125q-0.390625 -0.65625 -0.953125 -0.875q-0.40625 -0.15625 -1.296875 -0.15625l-1.609375 0l0 5.828125zm6.6487274 0.90625l0 -7.625l1.015625 0l0 6.71875l3.75 0l0 0.90625l-4.765625 0zm12.022568 -0.6875q-0.53125 0.453125 -1.015625 0.640625q-0.46875 0.171875 -1.015625 0.171875q-0.921875 0 -1.40625 -0.4375q-0.484375 -0.453125 -0.484375 -1.140625q0 -0.40625 0.171875 -0.734375q0.1875 -0.34375 0.484375 -0.546875q0.3125 -0.203125 0.6875 -0.3125q0.265625 -0.0625 0.828125 -0.140625q1.125 -0.125 1.671875 -0.3125q0 -0.203125 0 -0.25q0 -0.578125 -0.265625 -0.8125q-0.359375 -0.3125 -1.0625 -0.3125q-0.65625 0 -0.984375 0.234375q-0.3125 0.234375 -0.453125 0.8125l-0.921875 -0.125q0.125 -0.578125 0.40625 -0.9375q0.296875 -0.375 0.828125 -0.5625q0.546875 -0.203125 1.25 -0.203125q0.71875 0 1.15625 0.171875q0.4375 0.171875 0.640625 0.421875q0.21875 0.25 0.296875 0.640625q0.046875 0.234375 0.046875 0.859375l0 1.25q0 1.296875 0.0625 1.65625q0.0625 0.34375 0.234375 0.65625l-0.96875 0q-0.15625 -0.296875 -0.1875 -0.6875zm-0.078125 -2.078125q-0.515625 0.203125 -1.53125 0.34375q-0.578125 0.078125 -0.828125 0.1875q-0.234375 0.109375 -0.359375 0.3125q-0.125 0.1875 -0.125 0.4375q0 0.375 0.28125 0.625q0.28125 0.25 0.828125 0.25q0.53125 0 0.953125 -0.234375q0.421875 -0.234375 0.625 -0.65625q0.15625 -0.3125 0.15625 -0.9375l0 -0.328125zm6.0046234 0.734375l0.921875 0.125q-0.15625 0.953125 -0.78125 1.5q-0.625 0.53125 -1.53125 0.53125q-1.125 0 -1.8125 -0.734375q-0.6875 -0.75 -0.6875 -2.125q0 -0.90625 0.296875 -1.578125q0.296875 -0.671875 0.890625 -1.0q0.609375 -0.34375 1.328125 -0.34375q0.890625 0 1.46875 0.46875q0.578125 0.453125 0.734375 1.28125l-0.90625 0.140625q-0.140625 -0.546875 -0.46875 -0.828125q-0.328125 -0.28125 -0.796875 -0.28125q-0.703125 0 -1.15625 0.515625q-0.4375 0.5 -0.4375 1.59375q0 1.109375 0.421875 1.625q0.4375 0.5 1.125 0.5q0.546875 0 0.90625 -0.34375q0.375 -0.34375 0.484375 -1.046875zm3.765625 1.1875l0.125 0.828125q-0.390625 0.09375 -0.703125 0.09375q-0.5 0 -0.78125 -0.15625q-0.28125 -0.171875 -0.40625 -0.4375q-0.109375 -0.265625 -0.109375 -1.109375l0 -3.171875l-0.6875 0l0 -0.734375l0.6875 0l0 -1.359375l0.9375 -0.5625l0 1.921875l0.9375 0l0 0.734375l-0.9375 0l0 3.234375q0 0.390625 0.046875 0.515625q0.046875 0.109375 0.15625 0.1875q0.109375 0.0625 0.328125 0.0625q0.15625 0 0.40625 -0.046875zm0.5700226 -1.921875q0 -1.53125 0.84375 -2.265625q0.71875 -0.625 1.734375 -0.625q1.140625 0 1.859375 0.75q0.734375 0.75 0.734375 2.0625q0 1.0625 -0.328125 1.6875q-0.3125 0.609375 -0.921875 0.953125q-0.609375 0.328125 -1.34375 0.328125q-1.15625 0 -1.875 -0.734375q-0.703125 -0.75 -0.703125 -2.15625zm0.953125 0q0 1.0625 0.46875 1.59375q0.46875 0.53125 1.15625 0.53125q0.703125 0 1.15625 -0.53125q0.46875 -0.53125 0.46875 -1.625q0 -1.015625 -0.46875 -1.546875q-0.453125 -0.53125 -1.15625 -0.53125q-0.6875 0 -1.15625 0.53125q-0.46875 0.515625 -0.46875 1.578125zm5.3014984 2.765625l0 -5.53125l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.890625l-0.9375 0zm3.1892395 -1.65625l0.921875 -0.140625q0.078125 0.5625 0.4375 0.859375q0.359375 0.296875 1.0 0.296875q0.640625 0 0.953125 -0.265625q0.3125 -0.265625 0.3125 -0.625q0 -0.3125 -0.28125 -0.5q-0.1875 -0.125 -0.953125 -0.3125q-1.03125 -0.265625 -1.4375 -0.453125q-0.390625 -0.1875 -0.59375 -0.515625q-0.203125 -0.34375 -0.203125 -0.75q0 -0.359375 0.171875 -0.671875q0.171875 -0.328125 0.453125 -0.53125q0.21875 -0.15625 0.59375 -0.265625q0.390625 -0.125 0.8125 -0.125q0.65625 0 1.140625 0.1875q0.5 0.1875 0.734375 0.515625q0.234375 0.3125 0.3125 0.859375l-0.90625 0.125q-0.0625 -0.4375 -0.375 -0.671875q-0.296875 -0.234375 -0.828125 -0.234375q-0.65625 0 -0.9375 0.21875q-0.265625 0.203125 -0.265625 0.484375q0 0.1875 0.109375 0.328125q0.125 0.15625 0.359375 0.25q0.140625 0.0625 0.828125 0.25q1.0 0.265625 1.390625 0.4375q0.390625 0.15625 0.609375 0.484375q0.234375 0.3125 0.234375 0.796875q0 0.46875 -0.28125 0.890625q-0.265625 0.40625 -0.78125 0.640625q-0.515625 0.21875 -1.171875 0.21875q-1.078125 0 -1.640625 -0.4375q-0.5625 -0.453125 -0.71875 -1.34375zm8.663773 1.65625l0 -5.53125l0.84375 0l0 0.78125q0.25 -0.40625 0.6875 -0.65625q0.4375 -0.25 0.984375 -0.25q0.609375 0 1.0 0.265625q0.390625 0.25 0.5625 0.703125q0.65625 -0.96875 1.703125 -0.96875q0.828125 0 1.265625 0.46875q0.4375 0.453125 0.4375 1.390625l0 3.796875l-0.921875 0l0 -3.484375q0 -0.5625 -0.09375 -0.796875q-0.09375 -0.25 -0.34375 -0.40625q-0.234375 -0.15625 -0.546875 -0.15625q-0.59375 0 -0.984375 0.390625q-0.375 0.390625 -0.375 1.25l0 3.203125l-0.9375 0l0 -3.59375q0 -0.625 -0.234375 -0.9375q-0.21875 -0.3125 -0.75 -0.3125q-0.390625 0 -0.734375 0.21875q-0.328125 0.203125 -0.484375 0.609375q-0.140625 0.390625 -0.140625 1.15625l0 2.859375l-0.9375 0zm12.6579895 -1.78125l0.96875 0.125q-0.234375 0.84375 -0.859375 1.3125q-0.609375 0.46875 -1.578125 0.46875q-1.203125 0 -1.921875 -0.75q-0.703125 -0.75 -0.703125 -2.09375q0 -1.390625 0.71875 -2.15625q0.71875 -0.78125 1.859375 -0.78125q1.109375 0 1.8125 0.765625q0.703125 0.75 0.703125 2.125q0 0.078125 0 0.234375l-4.125 0q0.046875 0.921875 0.515625 1.40625q0.46875 0.484375 1.15625 0.484375q0.515625 0 0.875 -0.265625q0.359375 -0.28125 0.578125 -0.875zm-3.078125 -1.515625l3.09375 0q-0.0625 -0.6875 -0.359375 -1.046875q-0.453125 -0.53125 -1.15625 -0.53125q-0.640625 0 -1.09375 0.4375q-0.4375 0.421875 -0.484375 1.140625zm8.832748 2.609375q-0.53125 0.453125 -1.015625 0.640625q-0.46875 0.171875 -1.015625 0.171875q-0.921875 0 -1.40625 -0.4375q-0.484375 -0.453125 -0.484375 -1.140625q0 -0.40625 0.171875 -0.734375q0.1875 -0.34375 0.484375 -0.546875q0.3125 -0.203125 0.6875 -0.3125q0.265625 -0.0625 0.828125 -0.140625q1.125 -0.125 1.671875 -0.3125q0 -0.203125 0 -0.25q0 -0.578125 -0.265625 -0.8125q-0.359375 -0.3125 -1.0625 -0.3125q-0.65625 0 -0.984375 0.234375q-0.3125 0.234375 -0.453125 0.8125l-0.921875 -0.125q0.125 -0.578125 0.40625 -0.9375q0.296875 -0.375 0.828125 -0.5625q0.546875 -0.203125 1.25 -0.203125q0.71875 0 1.15625 0.171875q0.4375 0.171875 0.640625 0.421875q0.21875 0.25 0.296875 0.640625q0.046875 0.234375 0.046875 0.859375l0 1.25q0 1.296875 0.0625 1.65625q0.0625 0.34375 0.234375 0.65625l-0.96875 0q-0.15625 -0.296875 -0.1875 -0.6875zm-0.078125 -2.078125q-0.515625 0.203125 -1.53125 0.34375q-0.578125 0.078125 -0.828125 0.1875q-0.234375 0.109375 -0.359375 0.3125q-0.125 0.1875 -0.125 0.4375q0 0.375 0.28125 0.625q0.28125 0.25 0.828125 0.25q0.53125 0 0.953125 -0.234375q0.421875 -0.234375 0.625 -0.65625q0.15625 -0.3125 0.15625 -0.9375l0 -0.328125zm2.3952484 2.765625l0 -5.53125l0.84375 0l0 0.796875q0.609375 -0.921875 1.75 -0.921875q0.5 0 0.921875 0.1875q0.421875 0.171875 0.625 0.46875q0.21875 0.296875 0.296875 0.6875q0.046875 0.265625 0.046875 0.921875l0 3.390625l-0.9375 0l0 -3.359375q0 -0.578125 -0.109375 -0.859375q-0.109375 -0.28125 -0.390625 -0.453125q-0.265625 -0.171875 -0.640625 -0.171875q-0.59375 0 -1.03125 0.390625q-0.4375 0.375 -0.4375 1.4375l0 3.015625l-0.9375 0zm5.5514984 -1.65625l0.921875 -0.140625q0.078125 0.5625 0.4375 0.859375q0.359375 0.296875 1.0 0.296875q0.640625 0 0.953125 -0.265625q0.3125 -0.265625 0.3125 -0.625q0 -0.3125 -0.28125 -0.5q-0.1875 -0.125 -0.953125 -0.3125q-1.03125 -0.265625 -1.4375 -0.453125q-0.390625 -0.1875 -0.59375 -0.515625q-0.203125 -0.34375 -0.203125 -0.75q0 -0.359375 0.171875 -0.671875q0.171875 -0.328125 0.453125 -0.53125q0.21875 -0.15625 0.59375 -0.265625q0.390625 -0.125 0.8125 -0.125q0.65625 0 1.140625 0.1875q0.5 0.1875 0.734375 0.515625q0.234375 0.3125 0.3125 0.859375l-0.90625 0.125q-0.0625 -0.4375 -0.375 -0.671875q-0.296875 -0.234375 -0.828125 -0.234375q-0.65625 0 -0.9375 0.21875q-0.265625 0.203125 -0.265625 0.484375q0 0.1875 0.109375 0.328125q0.125 0.15625 0.359375 0.25q0.140625 0.0625 0.828125 0.25q1.0 0.265625 1.390625 0.4375q0.390625 0.15625 0.609375 0.484375q0.234375 0.3125 0.234375 0.796875q0 0.46875 -0.28125 0.890625q-0.265625 0.40625 -0.78125 0.640625q-0.515625 0.21875 -1.171875 0.21875q-1.078125 0 -1.640625 -0.4375q-0.5625 -0.453125 -0.71875 -1.34375zm8.882523 1.65625l0 -4.796875l-0.828125 0l0 -0.734375l0.828125 0l0 -0.578125q0 -0.5625 0.109375 -0.828125q0.125 -0.375 0.46875 -0.59375q0.34375 -0.234375 0.953125 -0.234375q0.390625 0 0.875 0.09375l-0.140625 0.828125q-0.296875 -0.0625 -0.546875 -0.0625q-0.421875 0 -0.609375 0.1875q-0.171875 0.1875 -0.171875 0.6875l0 0.5l1.078125 0l0 0.734375l-1.078125 0l0 4.796875l-0.9375 0zm2.3981476 -2.765625q0 -1.53125 0.84375 -2.265625q0.71875 -0.625 1.734375 -0.625q1.140625 0 1.859375 0.75q0.734375 0.75 0.734375 2.0625q0 1.0625 -0.328125 1.6875q-0.3125 0.609375 -0.921875 0.953125q-0.609375 0.328125 -1.34375 0.328125q-1.15625 0 -1.875 -0.734375q-0.703125 -0.75 -0.703125 -2.15625zm0.953125 0q0 1.0625 0.46875 1.59375q0.46875 0.53125 1.15625 0.53125q0.703125 0 1.15625 -0.53125q0.46875 -0.53125 0.46875 -1.625q0 -1.015625 -0.46875 -1.546875q-0.453125 -0.53125 -1.15625 -0.53125q-0.6875 0 -1.15625 0.53125q-0.46875 0.515625 -0.46875 1.578125zm8.942123 2.765625l0 -0.8125q-0.65625 0.9375 -1.75 0.9375q-0.5 0 -0.921875 -0.1875q-0.421875 -0.1875 -0.625 -0.46875q-0.203125 -0.28125 -0.296875 -0.703125q-0.046875 -0.265625 -0.046875 -0.875l0 -3.421875l0.9375 0l0 3.0625q0 0.734375 0.046875 1.0q0.09375 0.359375 0.375 0.578125q0.296875 0.203125 0.703125 0.203125q0.421875 0 0.796875 -0.203125q0.375 -0.21875 0.515625 -0.59375q0.15625 -0.375 0.15625 -1.078125l0 -2.96875l0.9375 0l0 5.53125l-0.828125 0zm2.2858734 0l0 -5.53125l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.890625l-0.9375 0zm8.571762 -0.84375l0.125 0.828125q-0.390625 0.09375 -0.703125 0.09375q-0.5 0 -0.78125 -0.15625q-0.28125 -0.171875 -0.40625 -0.4375q-0.109375 -0.265625 -0.109375 -1.109375l0 -3.171875l-0.6875 0l0 -0.734375l0.6875 0l0 -1.359375l0.9375 -0.5625l0 1.921875l0.9375 0l0 0.734375l-0.9375 0l0 3.234375q0 0.390625 0.046875 0.515625q0.046875 0.109375 0.15625 0.1875q0.109375 0.0625 0.328125 0.0625q0.15625 0 0.40625 -0.046875zm0.9137726 0.84375l0 -7.625l0.9375 0l0 2.734375q0.65625 -0.765625 1.65625 -0.765625q0.609375 0 1.0625 0.25q0.453125 0.234375 0.640625 0.671875q0.203125 0.421875 0.203125 1.234375l0 3.5l-0.9375 0l0 -3.5q0 -0.703125 -0.3125 -1.015625q-0.296875 -0.328125 -0.859375 -0.328125q-0.40625 0 -0.78125 0.21875q-0.359375 0.21875 -0.515625 0.59375q-0.15625 0.359375 -0.15625 1.015625l0 3.015625l-0.9375 0zm5.9108734 0l0 -5.53125l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.890625l-0.9375 0zm7.3454895 -1.78125l0.96875 0.125q-0.234375 0.84375 -0.859375 1.3125q-0.609375 0.46875 -1.578125 0.46875q-1.203125 0 -1.921875 -0.75q-0.703125 -0.75 -0.703125 -2.09375q0 -1.390625 0.71875 -2.15625q0.71875 -0.78125 1.859375 -0.78125q1.109375 0 1.8125 0.765625q0.703125 0.75 0.703125 2.125q0 0.078125 0 0.234375l-4.125 0q0.046875 0.921875 0.515625 1.40625q0.46875 0.484375 1.15625 0.484375q0.515625 0 0.875 -0.265625q0.359375 -0.28125 0.578125 -0.875zm-3.078125 -1.515625l3.09375 0q-0.0625 -0.6875 -0.359375 -1.046875q-0.453125 -0.53125 -1.15625 -0.53125q-0.640625 0 -1.09375 0.4375q-0.4375 0.421875 -0.484375 1.140625zm8.832748 2.609375q-0.53125 0.453125 -1.015625 0.640625q-0.46875 0.171875 -1.015625 0.171875q-0.921875 0 -1.40625 -0.4375q-0.484375 -0.453125 -0.484375 -1.140625q0 -0.40625 0.171875 -0.734375q0.1875 -0.34375 0.484375 -0.546875q0.3125 -0.203125 0.6875 -0.3125q0.265625 -0.0625 0.828125 -0.140625q1.125 -0.125 1.671875 -0.3125q0 -0.203125 0 -0.25q0 -0.578125 -0.265625 -0.8125q-0.359375 -0.3125 -1.0625 -0.3125q-0.65625 0 -0.984375 0.234375q-0.3125 0.234375 -0.453125 0.8125l-0.921875 -0.125q0.125 -0.578125 0.40625 -0.9375q0.296875 -0.375 0.828125 -0.5625q0.546875 -0.203125 1.25 -0.203125q0.71875 0 1.15625 0.171875q0.4375 0.171875 0.640625 0.421875q0.21875 0.25 0.296875 0.640625q0.046875 0.234375 0.046875 0.859375l0 1.25q0 1.296875 0.0625 1.65625q0.0625 0.34375 0.234375 0.65625l-0.96875 0q-0.15625 -0.296875 -0.1875 -0.6875zm-0.078125 -2.078125q-0.515625 0.203125 -1.53125 0.34375q-0.578125 0.078125 -0.828125 0.1875q-0.234375 0.109375 -0.359375 0.3125q-0.125 0.1875 -0.125 0.4375q0 0.375 0.28125 0.625q0.28125 0.25 0.828125 0.25q0.53125 0 0.953125 -0.234375q0.421875 -0.234375 0.625 -0.65625q0.15625 -0.3125 0.15625 -0.9375l0 -0.328125zm5.9733734 2.765625l0 -0.703125q-0.515625 0.828125 -1.546875 0.828125q-0.65625 0 -1.21875 -0.359375q-0.546875 -0.375 -0.859375 -1.015625q-0.296875 -0.65625 -0.296875 -1.5q0 -0.828125 0.28125 -1.5q0.28125 -0.6875 0.828125 -1.046875q0.546875 -0.359375 1.234375 -0.359375q0.5 0 0.890625 0.21875q0.390625 0.203125 0.625 0.546875l0 -2.734375l0.9375 0l0 7.625l-0.875 0zm-2.953125 -2.75q0 1.046875 0.4375 1.578125q0.453125 0.53125 1.0625 0.53125q0.609375 0 1.03125 -0.5q0.4375 -0.515625 0.4375 -1.53125q0 -1.140625 -0.4375 -1.671875q-0.4375 -0.53125 -1.078125 -0.53125q-0.609375 0 -1.03125 0.515625q-0.421875 0.5 -0.421875 1.609375zm4.9264984 1.09375l0.921875 -0.140625q0.078125 0.5625 0.4375 0.859375q0.359375 0.296875 1.0 0.296875q0.640625 0 0.953125 -0.265625q0.3125 -0.265625 0.3125 -0.625q0 -0.3125 -0.28125 -0.5q-0.1875 -0.125 -0.953125 -0.3125q-1.03125 -0.265625 -1.4375 -0.453125q-0.390625 -0.1875 -0.59375 -0.515625q-0.203125 -0.34375 -0.203125 -0.75q0 -0.359375 0.171875 -0.671875q0.171875 -0.328125 0.453125 -0.53125q0.21875 -0.15625 0.59375 -0.265625q0.390625 -0.125 0.8125 -0.125q0.65625 0 1.140625 0.1875q0.5 0.1875 0.734375 0.515625q0.234375 0.3125 0.3125 0.859375l-0.90625 0.125q-0.0625 -0.4375 -0.375 -0.671875q-0.296875 -0.234375 -0.828125 -0.234375q-0.65625 0 -0.9375 0.21875q-0.265625 0.203125 -0.265625 0.484375q0 0.1875 0.109375 0.328125q0.125 0.15625 0.359375 0.25q0.140625 0.0625 0.828125 0.25q1.0 0.265625 1.390625 0.4375q0.390625 0.15625 0.609375 0.484375q0.234375 0.3125 0.234375 0.796875q0 0.46875 -0.28125 0.890625q-0.265625 0.40625 -0.78125 0.640625q-0.515625 0.21875 -1.171875 0.21875q-1.078125 0 -1.640625 -0.4375q-0.5625 -0.453125 -0.71875 -1.34375z" fill-rule="nonzero"/><path fill="#000000" d="m16.179901 512.3386l0.921875 0.125q-0.15625 0.953125 -0.78125 1.5q-0.625 0.53125 -1.53125 0.53125q-1.125 0 -1.8125 -0.734375q-0.6875 -0.75 -0.6875 -2.1250305q0 -0.90625 0.296875 -1.578125q0.296875 -0.671875 0.890625 -1.0q0.609375 -0.34375 1.328125 -0.34375q0.890625 0 1.46875 0.46875q0.578125 0.453125 0.734375 1.28125l-0.90625 0.140625q-0.140625 -0.546875 -0.46875 -0.828125q-0.328125 -0.28125 -0.796875 -0.28125q-0.703125 0 -1.15625 0.515625q-0.4375 0.5 -0.4375 1.59375q0 1.1094055 0.421875 1.6250305q0.4375 0.5 1.125 0.5q0.546875 0 0.90625 -0.34375q0.375 -0.34375 0.484375 -1.046875zm5.328125 1.34375q-0.53125 0.453125 -1.015625 0.640625q-0.46875 0.171875 -1.015625 0.171875q-0.921875 0 -1.40625 -0.4375q-0.484375 -0.453125 -0.484375 -1.140625q0 -0.40625 0.171875 -0.734375q0.1875 -0.34378052 0.484375 -0.5469055q0.3125 -0.203125 0.6875 -0.3125q0.265625 -0.0625 0.828125 -0.140625q1.125 -0.125 1.671875 -0.3125q0 -0.203125 0 -0.25q0 -0.578125 -0.265625 -0.8125q-0.359375 -0.3125 -1.0625 -0.3125q-0.65625 0 -0.984375 0.234375q-0.3125 0.234375 -0.453125 0.8125l-0.921875 -0.125q0.125 -0.578125 0.40625 -0.9375q0.296875 -0.375 0.828125 -0.5625q0.546875 -0.203125 1.25 -0.203125q0.71875 0 1.15625 0.171875q0.4375 0.171875 0.640625 0.421875q0.21875 0.25 0.296875 0.640625q0.046875 0.234375 0.046875 0.859375l0 1.2500305q0 1.296875 0.0625 1.65625q0.0625 0.34375 0.234375 0.65625l-0.96875 0q-0.15625 -0.296875 -0.1875 -0.6875zm-0.078125 -2.0781555q-0.515625 0.203125 -1.53125 0.34375q-0.578125 0.07815552 -0.828125 0.18753052q-0.234375 0.109375 -0.359375 0.3125q-0.125 0.1875 -0.125 0.4375q0 0.375 0.28125 0.625q0.28125 0.25 0.828125 0.25q0.53125 0 0.953125 -0.234375q0.421875 -0.234375 0.625 -0.65625q0.15625 -0.3125 0.15625 -0.9375305l0 -0.328125zm2.3952484 2.7656555l0 -5.5312805l0.84375 0l0 0.796875q0.609375 -0.921875 1.75 -0.921875q0.5 0 0.921875 0.1875q0.421875 0.171875 0.625 0.46875q0.21875 0.296875 0.296875 0.6875q0.046875 0.265625 0.046875 0.921875l0 3.3906555l-0.9375 0l0 -3.3594055q0 -0.578125 -0.109375 -0.859375q-0.109375 -0.28125 -0.390625 -0.453125q-0.265625 -0.171875 -0.640625 -0.171875q-0.59375 0 -1.03125 0.390625q-0.4375 0.375 -0.4375 1.4375l0 3.0156555l-0.9375 0zm8.871521 0l0 -5.5312805l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.8906555l-0.9375 0zm7.1892395 0l0 -0.8125q-0.65625 0.9375 -1.75 0.9375q-0.5 0 -0.921875 -0.1875q-0.421875 -0.1875 -0.625 -0.46875q-0.203125 -0.28125 -0.296875 -0.703125q-0.046875 -0.265625 -0.046875 -0.875l0 -3.4219055l0.9375 0l0 3.0625q0 0.7344055 0.046875 1.0000305q0.09375 0.359375 0.375 0.578125q0.296875 0.203125 0.703125 0.203125q0.421875 0 0.796875 -0.203125q0.375 -0.21875 0.515625 -0.59375q0.15625 -0.375 0.15625 -1.0781555l0 -2.96875l0.9375 0l0 5.5312805l-0.828125 0zm2.3014984 0l0 -5.5312805l0.84375 0l0 0.796875q0.609375 -0.921875 1.75 -0.921875q0.5 0 0.921875 0.1875q0.421875 0.171875 0.625 0.46875q0.21875 0.296875 0.296875 0.6875q0.046875 0.265625 0.046875 0.921875l0 3.3906555l-0.9375 0l0 -3.3594055q0 -0.578125 -0.109375 -0.859375q-0.109375 -0.28125 -0.390625 -0.453125q-0.265625 -0.171875 -0.640625 -0.171875q-0.59375 0 -1.03125 0.390625q-0.4375 0.375 -0.4375 1.4375l0 3.0156555l-0.9375 0zm8.887146 -6.5469055l0 -1.078125l0.9375 0l0 1.078125l-0.9375 0zm0 6.5469055l0 -5.5312805l0.9375 0l0 5.5312805l-0.9375 0zm2.3674774 0l0 -5.5312805l0.84375 0l0 0.796875q0.609375 -0.921875 1.75 -0.921875q0.5 0 0.921875 0.1875q0.421875 0.171875 0.625 0.46875q0.21875 0.296875 0.296875 0.6875q0.046875 0.265625 0.046875 0.921875l0 3.3906555l-0.9375 0l0 -3.3594055q0 -0.578125 -0.109375 -0.859375q-0.109375 -0.28125 -0.390625 -0.453125q-0.265625 -0.171875 -0.640625 -0.171875q-0.59375 0 -1.03125 0.390625q-0.4375 0.375 -0.4375 1.4375l0 3.0156555l-0.9375 0zm8.887146 2.125l0 -7.6562805l0.859375 0l0 0.71875q0.296875 -0.421875 0.671875 -0.625q0.390625 -0.21875 0.921875 -0.21875q0.703125 0 1.25 0.375q0.546875 0.359375 0.8125 1.03125q0.28125 0.65625 0.28125 1.453125q0 0.8437805 -0.3125 1.5312805q-0.296875 0.671875 -0.875 1.03125q-0.578125 0.359375 -1.21875 0.359375q-0.46875 0 -0.84375 -0.1875q-0.375 -0.203125 -0.609375 -0.515625l0 2.703125l-0.9375 0zm0.84375 -4.8594055q0 1.0625305 0.4375 1.5781555q0.4375 0.515625 1.046875 0.515625q0.625 0 1.0625 -0.53125q0.453125 -0.53125 0.453125 -1.6406555q0 -1.046875 -0.4375 -1.578125q-0.4375 -0.53125 -1.046875 -0.53125q-0.59375 0 -1.0625 0.5625q-0.453125 0.5625 -0.453125 1.625zm8.692123 2.0469055q-0.53125 0.453125 -1.015625 0.640625q-0.46875 0.171875 -1.015625 0.171875q-0.921875 0 -1.40625 -0.4375q-0.484375 -0.453125 -0.484375 -1.140625q0 -0.40625 0.171875 -0.734375q0.1875 -0.34378052 0.484375 -0.5469055q0.3125 -0.203125 0.6875 -0.3125q0.265625 -0.0625 0.828125 -0.140625q1.125 -0.125 1.671875 -0.3125q0 -0.203125 0 -0.25q0 -0.578125 -0.265625 -0.8125q-0.359375 -0.3125 -1.0625 -0.3125q-0.65625 0 -0.984375 0.234375q-0.3125 0.234375 -0.453125 0.8125l-0.921875 -0.125q0.125 -0.578125 0.40625 -0.9375q0.296875 -0.375 0.828125 -0.5625q0.546875 -0.203125 1.25 -0.203125q0.71875 0 1.15625 0.171875q0.4375 0.171875 0.640625 0.421875q0.21875 0.25 0.296875 0.640625q0.046875 0.234375 0.046875 0.859375l0 1.2500305q0 1.296875 0.0625 1.65625q0.0625 0.34375 0.234375 0.65625l-0.96875 0q-0.15625 -0.296875 -0.1875 -0.6875zm-0.078125 -2.0781555q-0.515625 0.203125 -1.53125 0.34375q-0.578125 0.07815552 -0.828125 0.18753052q-0.234375 0.109375 -0.359375 0.3125q-0.125 0.1875 -0.125 0.4375q0 0.375 0.28125 0.625q0.28125 0.25 0.828125 0.25q0.53125 0 0.953125 -0.234375q0.421875 -0.234375 0.625 -0.65625q0.15625 -0.3125 0.15625 -0.9375305l0 -0.328125zm2.3796234 2.7656555l0 -5.5312805l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.8906555l-0.9375 0zm7.1736145 -0.6875q-0.53125 0.453125 -1.015625 0.640625q-0.46875 0.171875 -1.015625 0.171875q-0.921875 0 -1.40625 -0.4375q-0.484375 -0.453125 -0.484375 -1.140625q0 -0.40625 0.171875 -0.734375q0.1875 -0.34378052 0.484375 -0.5469055q0.3125 -0.203125 0.6875 -0.3125q0.265625 -0.0625 0.828125 -0.140625q1.125 -0.125 1.671875 -0.3125q0 -0.203125 0 -0.25q0 -0.578125 -0.265625 -0.8125q-0.359375 -0.3125 -1.0625 -0.3125q-0.65625 0 -0.984375 0.234375q-0.3125 0.234375 -0.453125 0.8125l-0.921875 -0.125q0.125 -0.578125 0.40625 -0.9375q0.296875 -0.375 0.828125 -0.5625q0.546875 -0.203125 1.25 -0.203125q0.71875 0 1.15625 0.171875q0.4375 0.171875 0.640625 0.421875q0.21875 0.25 0.296875 0.640625q0.046875 0.234375 0.046875 0.859375l0 1.2500305q0 1.296875 0.0625 1.65625q0.0625 0.34375 0.234375 0.65625l-0.96875 0q-0.15625 -0.296875 -0.1875 -0.6875zm-0.078125 -2.0781555q-0.515625 0.203125 -1.53125 0.34375q-0.578125 0.07815552 -0.828125 0.18753052q-0.234375 0.109375 -0.359375 0.3125q-0.125 0.1875 -0.125 0.4375q0 0.375 0.28125 0.625q0.28125 0.25 0.828125 0.25q0.53125 0 0.953125 -0.234375q0.421875 -0.234375 0.625 -0.65625q0.15625 -0.3125 0.15625 -0.9375305l0 -0.328125zm2.3796234 2.7656555l0 -7.6250305l0.9375 0l0 7.6250305l-0.9375 0zm2.3674774 0l0 -7.6250305l0.9375 0l0 7.6250305l-0.9375 0zm6.1643524 -1.78125l0.96875 0.125q-0.234375 0.84375 -0.859375 1.3125q-0.609375 0.46875 -1.578125 0.46875q-1.203125 0 -1.921875 -0.75q-0.703125 -0.75 -0.703125 -2.0937805q0 -1.390625 0.71875 -2.15625q0.71875 -0.78125 1.859375 -0.78125q1.109375 0 1.8125 0.765625q0.703125 0.75 0.703125 2.125q0 0.078125 0 0.234375l-4.125 0q0.046875 0.9219055 0.515625 1.4062805q0.46875 0.484375 1.15625 0.484375q0.515625 0 0.875 -0.265625q0.359375 -0.28125 0.578125 -0.875zm-3.078125 -1.5156555l3.09375 0q-0.0625 -0.6875 -0.359375 -1.046875q-0.453125 -0.53125 -1.15625 -0.53125q-0.640625 0 -1.09375 0.4375q-0.4375 0.421875 -0.484375 1.140625zm5.2077484 3.2969055l0 -7.6250305l0.9375 0l0 7.6250305l-0.9375 0zm2.6487274 0l0 -1.0625l1.0625 0l0 1.0625l-1.0625 0zm4.3483734 0l2.921875 -7.6250305l1.09375 0l3.125 7.6250305l-1.15625 0l-0.890625 -2.3125l-3.1875 0l-0.828125 2.3125l-1.078125 0zm2.203125 -3.1250305l2.578125 0l-0.796875 -2.125q-0.359375 -0.953125 -0.53125 -1.578125q-0.15625 0.734375 -0.421875 1.453125l-0.828125 2.25zm9.2326355 1.0937805l0.921875 0.125q-0.15625 0.953125 -0.78125 1.5q-0.625 0.53125 -1.53125 0.53125q-1.125 0 -1.8125 -0.734375q-0.6875 -0.75 -0.6875 -2.1250305q0 -0.90625 0.296875 -1.578125q0.296875 -0.671875 0.890625 -1.0q0.609375 -0.34375 1.328125 -0.34375q0.890625 0 1.46875 0.46875q0.578125 0.453125 0.734375 1.28125l-0.90625 0.140625q-0.140625 -0.546875 -0.46875 -0.828125q-0.328125 -0.28125 -0.796875 -0.28125q-0.703125 0 -1.15625 0.515625q-0.4375 0.5 -0.4375 1.59375q0 1.1094055 0.421875 1.6250305q0.4375 0.5 1.125 0.5q0.546875 0 0.90625 -0.34375q0.375 -0.34375 0.484375 -1.046875zm3.765625 1.1875l0.125 0.828125q-0.390625 0.09375 -0.703125 0.09375q-0.5 0 -0.78125 -0.15625q-0.28125 -0.171875 -0.40625 -0.4375q-0.109375 -0.265625 -0.109375 -1.109375l0 -3.1719055l-0.6875 0l0 -0.734375l0.6875 0l0 -1.359375l0.9375 -0.5625l0 1.921875l0.9375 0l0 0.734375l-0.9375 0l0 3.2344055q0 0.390625 0.046875 0.515625q0.046875 0.109375 0.15625 0.1875q0.109375 0.0625 0.328125 0.0625q0.15625 0 0.40625 -0.046875zm0.5700226 -1.9219055q0 -1.53125 0.84375 -2.265625q0.71875 -0.625 1.734375 -0.625q1.140625 0 1.859375 0.75q0.734375 0.75 0.734375 2.0625q0 1.0625305 -0.328125 1.6875305q-0.3125 0.609375 -0.921875 0.953125q-0.609375 0.328125 -1.34375 0.328125q-1.15625 0 -1.875 -0.734375q-0.703125 -0.75 -0.703125 -2.1562805zm0.953125 0q0 1.0625305 0.46875 1.5937805q0.46875 0.53125 1.15625 0.53125q0.703125 0 1.15625 -0.53125q0.46875 -0.53125 0.46875 -1.6250305q0 -1.015625 -0.46875 -1.546875q-0.453125 -0.53125 -1.15625 -0.53125q-0.6875 0 -1.15625 0.53125q-0.46875 0.515625 -0.46875 1.578125zm5.3014984 2.7656555l0 -5.5312805l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.8906555l-0.9375 0zm6.524887 -6.5469055l0 -1.078125l0.9375 0l0 1.078125l-0.9375 0zm0 6.5469055l0 -5.5312805l0.9375 0l0 5.5312805l-0.9375 0zm1.9924774 -1.65625l0.921875 -0.140625q0.078125 0.5625 0.4375 0.859375q0.359375 0.296875 1.0 0.296875q0.640625 0 0.953125 -0.265625q0.3125 -0.265625 0.3125 -0.625q0 -0.3125 -0.28125 -0.5q-0.1875 -0.125 -0.953125 -0.3125q-1.03125 -0.26565552 -1.4375 -0.45315552q-0.390625 -0.1875 -0.59375 -0.515625q-0.203125 -0.34375 -0.203125 -0.75q0 -0.359375 0.171875 -0.671875q0.171875 -0.328125 0.453125 -0.53125q0.21875 -0.15625 0.59375 -0.265625q0.390625 -0.125 0.8125 -0.125q0.65625 0 1.140625 0.1875q0.5 0.1875 0.734375 0.515625q0.234375 0.3125 0.3125 0.859375l-0.90625 0.125q-0.0625 -0.4375 -0.375 -0.671875q-0.296875 -0.234375 -0.828125 -0.234375q-0.65625 0 -0.9375 0.21875q-0.265625 0.203125 -0.265625 0.484375q0 0.1875 0.109375 0.328125q0.125 0.15625 0.359375 0.25q0.140625 0.0625 0.828125 0.25q1.0 0.265625 1.390625 0.4375q0.390625 0.15625 0.609375 0.484375q0.234375 0.31253052 0.234375 0.7969055q0 0.46875 -0.28125 0.890625q-0.265625 0.40625 -0.78125 0.640625q-0.515625 0.21875 -1.171875 0.21875q-1.078125 0 -1.640625 -0.4375q-0.5625 -0.453125 -0.71875 -1.34375z" fill-rule="nonzero"/><path fill="#000000" d="m12.195526 525.7136l0.921875 -0.140625q0.078125 0.5625 0.4375 0.859375q0.359375 0.296875 1.0 0.296875q0.640625 0 0.953125 -0.265625q0.3125 -0.265625 0.3125 -0.625q0 -0.3125 -0.28125 -0.5q-0.1875 -0.125 -0.953125 -0.3125q-1.03125 -0.265625 -1.4375 -0.453125q-0.390625 -0.1875 -0.59375 -0.515625q-0.203125 -0.34375 -0.203125 -0.75q0 -0.359375 0.171875 -0.671875q0.171875 -0.328125 0.453125 -0.53125q0.21875 -0.15625 0.59375 -0.265625q0.390625 -0.125 0.8125 -0.125q0.65625 0 1.140625 0.1875q0.5 0.1875 0.734375 0.515625q0.234375 0.3125 0.3125 0.859375l-0.90625 0.125q-0.0625 -0.4375 -0.375 -0.671875q-0.296875 -0.234375 -0.828125 -0.234375q-0.65625 0 -0.9375 0.21875q-0.265625 0.203125 -0.265625 0.484375q0 0.1875 0.109375 0.328125q0.125 0.15625 0.359375 0.25q0.140625 0.0625 0.828125 0.25q1.0 0.265625 1.390625 0.4375q0.390625 0.15625 0.609375 0.484375q0.234375 0.3125 0.234375 0.796875q0 0.46875 -0.28125 0.890625q-0.265625 0.40625 -0.78125 0.640625q-0.515625 0.21875 -1.171875 0.21875q-1.078125 0 -1.640625 -0.4375q-0.5625 -0.453125 -0.71875 -1.34375zm9.484375 -0.125l0.96875 0.125q-0.234375 0.84375 -0.859375 1.3125q-0.609375 0.46875 -1.578125 0.46875q-1.203125 0 -1.921875 -0.75q-0.703125 -0.75 -0.703125 -2.09375q0 -1.390625 0.71875 -2.15625q0.71875 -0.78125 1.859375 -0.78125q1.109375 0 1.8125 0.765625q0.703125 0.75 0.703125 2.125q0 0.078125 0 0.234375l-4.125 0q0.046875 0.921875 0.515625 1.40625q0.46875 0.484375 1.15625 0.484375q0.515625 0 0.875 -0.265625q0.359375 -0.28125 0.578125 -0.875zm-3.078125 -1.515625l3.09375 0q-0.0625 -0.6875 -0.359375 -1.046875q-0.453125 -0.53125 -1.15625 -0.53125q-0.640625 0 -1.09375 0.4375q-0.4375 0.421875 -0.484375 1.140625zm5.2077484 3.296875l0 -7.625l0.9375 0l0 7.625l-0.9375 0zm6.1643524 -1.78125l0.96875 0.125q-0.234375 0.84375 -0.859375 1.3125q-0.609375 0.46875 -1.578125 0.46875q-1.203125 0 -1.921875 -0.75q-0.703125 -0.75 -0.703125 -2.09375q0 -1.390625 0.71875 -2.15625q0.71875 -0.78125 1.859375 -0.78125q1.109375 0 1.8125 0.765625q0.703125 0.75 0.703125 2.125q0 0.078125 0 0.234375l-4.125 0q0.046875 0.921875 0.515625 1.40625q0.46875 0.484375 1.15625 0.484375q0.515625 0 0.875 -0.265625q0.359375 -0.28125 0.578125 -0.875zm-3.078125 -1.515625l3.09375 0q-0.0625 -0.6875 -0.359375 -1.046875q-0.453125 -0.53125 -1.15625 -0.53125q-0.640625 0 -1.09375 0.4375q-0.4375 0.421875 -0.484375 1.140625zm8.832748 1.265625l0.921875 0.125q-0.15625 0.953125 -0.78125 1.5q-0.625 0.53125 -1.53125 0.53125q-1.125 0 -1.8125 -0.734375q-0.6875 -0.75 -0.6875 -2.125q0 -0.90625 0.296875 -1.578125q0.296875 -0.671875 0.890625 -1.0q0.609375 -0.34375 1.328125 -0.34375q0.890625 0 1.46875 0.46875q0.578125 0.453125 0.734375 1.28125l-0.90625 0.140625q-0.140625 -0.546875 -0.46875 -0.828125q-0.328125 -0.28125 -0.796875 -0.28125q-0.703125 0 -1.15625 0.515625q-0.4375 0.5 -0.4375 1.59375q0 1.109375 0.421875 1.625q0.4375 0.5 1.125 0.5q0.546875 0 0.90625 -0.34375q0.375 -0.34375 0.484375 -1.046875zm3.765625 1.1875l0.125 0.828125q-0.390625 0.09375 -0.703125 0.09375q-0.5 0 -0.78125 -0.15625q-0.28125 -0.171875 -0.40625 -0.4375q-0.109375 -0.265625 -0.109375 -1.109375l0 -3.171875l-0.6875 0l0 -0.734375l0.6875 0l0 -1.359375l0.9375 -0.5625l0 1.921875l0.9375 0l0 0.734375l-0.9375 0l0 3.234375q0 0.390625 0.046875 0.515625q0.046875 0.109375 0.15625 0.1875q0.109375 0.0625 0.328125 0.0625q0.15625 0 0.40625 -0.046875zm4.6950226 -0.9375l0.96875 0.125q-0.234375 0.84375 -0.859375 1.3125q-0.609375 0.46875 -1.578125 0.46875q-1.203125 0 -1.921875 -0.75q-0.703125 -0.75 -0.703125 -2.09375q0 -1.390625 0.71875 -2.15625q0.71875 -0.78125 1.859375 -0.78125q1.109375 0 1.8125 0.765625q0.703125 0.75 0.703125 2.125q0 0.078125 0 0.234375l-4.125 0q0.046875 0.921875 0.515625 1.40625q0.46875 0.484375 1.15625 0.484375q0.515625 0 0.875 -0.265625q0.359375 -0.28125 0.578125 -0.875zm-3.078125 -1.515625l3.09375 0q-0.0625 -0.6875 -0.359375 -1.046875q-0.453125 -0.53125 -1.15625 -0.53125q-0.640625 0 -1.09375 0.4375q-0.4375 0.421875 -0.484375 1.140625zm8.801498 3.296875l0 -0.703125q-0.515625 0.828125 -1.546875 0.828125q-0.65625 0 -1.21875 -0.359375q-0.546875 -0.375 -0.859375 -1.015625q-0.296875 -0.65625 -0.296875 -1.5q0 -0.828125 0.28125 -1.5q0.28125 -0.6875 0.828125 -1.046875q0.546875 -0.359375 1.234375 -0.359375q0.5 0 0.890625 0.21875q0.390625 0.203125 0.625 0.546875l0 -2.734375l0.9375 0l0 7.625l-0.875 0zm-2.953125 -2.75q0 1.046875 0.4375 1.578125q0.453125 0.53125 1.0625 0.53125q0.609375 0 1.03125 -0.5q0.4375 -0.515625 0.4375 -1.53125q0 -1.140625 -0.4375 -1.671875q-0.4375 -0.53125 -1.078125 -0.53125q-0.609375 0 -1.03125 0.515625q-0.421875 0.5 -0.421875 1.609375zm9.121521 2.75l-0.859375 0l0 -7.625l0.9375 0l0 2.71875q0.59375 -0.75 1.5 -0.75q0.515625 0 0.96875 0.21875q0.453125 0.203125 0.75 0.578125q0.296875 0.359375 0.453125 0.890625q0.171875 0.53125 0.171875 1.125q0 1.421875 -0.703125 2.203125q-0.703125 0.765625 -1.6875 0.765625q-0.96875 0 -1.53125 -0.8125l0 0.6875zm0 -2.796875q0 0.984375 0.265625 1.421875q0.4375 0.734375 1.1875 0.734375q0.625 0 1.0625 -0.53125q0.453125 -0.546875 0.453125 -1.59375q0 -1.078125 -0.4375 -1.59375q-0.421875 -0.515625 -1.03125 -0.515625q-0.609375 0 -1.0625 0.53125q-0.4375 0.53125 -0.4375 1.546875zm5.0202484 4.921875l-0.09375 -0.875q0.296875 0.078125 0.53125 0.078125q0.3125 0 0.5 -0.109375q0.1875 -0.09375 0.3125 -0.28125q0.078125 -0.140625 0.28125 -0.703125q0.03125 -0.078125 0.078125 -0.21875l-2.09375 -5.546875l1.015625 0l1.140625 3.203125q0.234375 0.609375 0.40625 1.28125q0.15625 -0.640625 0.375 -1.265625l1.1875 -3.21875l0.9375 0l-2.109375 5.625q-0.328125 0.90625 -0.515625 1.25q-0.25 0.46875 -0.578125 0.6875q-0.3125 0.21875 -0.765625 0.21875q-0.265625 0 -0.609375 -0.125zm8.320023 -2.125l0 -5.53125l0.84375 0l0 0.84375q0.328125 -0.59375 0.59375 -0.78125q0.28125 -0.1875 0.609375 -0.1875q0.46875 0 0.953125 0.3125l-0.3125 0.859375q-0.34375 -0.203125 -0.6875 -0.203125q-0.3125 0 -0.5625 0.1875q-0.234375 0.1875 -0.34375 0.515625q-0.15625 0.5 -0.15625 1.09375l0 2.890625l-0.9375 0zm2.9392395 0l2.015625 -2.875l-1.859375 -2.65625l1.171875 0l0.84375 1.296875q0.234375 0.375 0.390625 0.625q0.21875 -0.34375 0.40625 -0.609375l0.9375 -1.3125l1.125 0l-1.921875 2.609375l2.0625 2.921875l-1.15625 0l-1.125 -1.71875l-0.296875 -0.46875l-1.453125 2.1875l-1.140625 0zm5.09375 2.125l0 -0.6875l6.203125 0l0 0.6875l-6.203125 0zm6.4108734 -3.78125l0.921875 -0.140625q0.078125 0.5625 0.4375 0.859375q0.359375 0.296875 1.0 0.296875q0.640625 0 0.953125 -0.265625q0.3125 -0.265625 0.3125 -0.625q0 -0.3125 -0.28125 -0.5q-0.1875 -0.125 -0.953125 -0.3125q-1.03125 -0.265625 -1.4375 -0.453125q-0.390625 -0.1875 -0.59375 -0.515625q-0.203125 -0.34375 -0.203125 -0.75q0 -0.359375 0.171875 -0.671875q0.171875 -0.328125 0.453125 -0.53125q0.21875 -0.15625 0.59375 -0.265625q0.390625 -0.125 0.8125 -0.125q0.65625 0 1.140625 0.1875q0.5 0.1875 0.734375 0.515625q0.234375 0.3125 0.3125 0.859375l-0.90625 0.125q-0.0625 -0.4375 -0.375 -0.671875q-0.296875 -0.234375 -0.828125 -0.234375q-0.65625 0 -0.9375 0.21875q-0.265625 0.203125 -0.265625 0.484375q0 0.1875 0.109375 0.328125q0.125 0.15625 0.359375 0.25q0.140625 0.0625 0.828125 0.25q1.0 0.265625 1.390625 0.4375q0.390625 0.15625 0.609375 0.484375q0.234375 0.3125 0.234375 0.796875q0 0.46875 -0.28125 0.890625q-0.265625 0.40625 -0.78125 0.640625q-0.515625 0.21875 -1.171875 0.21875q-1.078125 0 -1.640625 -0.4375q-0.5625 -0.453125 -0.71875 -1.34375zm5.6875 1.65625l0 -7.625l0.9375 0l0 7.625l-0.9375 0zm2.0393524 -2.765625q0 -1.53125 0.84375 -2.265625q0.71875 -0.625 1.734375 -0.625q1.140625 0 1.859375 0.75q0.734375 0.75 0.734375 2.0625q0 1.0625 -0.328125 1.6875q-0.3125 0.609375 -0.921875 0.953125q-0.609375 0.328125 -1.34375 0.328125q-1.15625 0 -1.875 -0.734375q-0.703125 -0.75 -0.703125 -2.15625zm0.953125 0q0 1.0625 0.46875 1.59375q0.46875 0.53125 1.15625 0.53125q0.703125 0 1.15625 -0.53125q0.46875 -0.53125 0.46875 -1.625q0 -1.015625 -0.46875 -1.546875q-0.453125 -0.53125 -1.15625 -0.53125q-0.6875 0 -1.15625 0.53125q-0.46875 0.515625 -0.46875 1.578125zm7.3639984 1.921875l0.125 0.828125q-0.390625 0.09375 -0.703125 0.09375q-0.5 0 -0.78125 -0.15625q-0.28125 -0.171875 -0.40625 -0.4375q-0.109375 -0.265625 -0.109375 -1.109375l0 -3.171875l-0.6875 0l0 -0.734375l0.6875 0l0 -1.359375l0.9375 -0.5625l0 1.921875l0.9375 0l0 0.734375l-0.9375 0l0 3.234375q0 0.390625 0.046875 0.515625q0.046875 0.109375 0.15625 0.1875q0.109375 0.0625 0.328125 0.0625q0.15625 0 0.40625 -0.046875zm3.7962952 -4.953125q0 -0.8125 0.40625 -1.390625q0.40625 -0.578125 1.1875 -0.578125q0.71875 0 1.1875 0.515625q0.46875 0.515625 0.46875 1.515625q0 0.96875 -0.484375 1.5q-0.46875 0.515625 -1.15625 0.515625q-0.6875 0 -1.15625 -0.515625q-0.453125 -0.515625 -0.453125 -1.5625zm1.625 -1.3125q-0.34375 0 -0.578125 0.296875q-0.234375 0.296875 -0.234375 1.109375q0 0.734375 0.234375 1.03125q0.234375 0.296875 0.578125 0.296875q0.359375 0 0.578125 -0.296875q0.234375 -0.296875 0.234375 -1.109375q0 -0.734375 -0.234375 -1.03125q-0.234375 -0.296875 -0.578125 -0.296875zm0 7.390625l4.171875 -8.046875l0.765625 0l-4.15625 8.046875l-0.78125 0zm3.296875 -2.078125q0 -0.8125 0.40625 -1.375q0.421875 -0.578125 1.203125 -0.578125q0.71875 0 1.1875 0.515625q0.46875 0.515625 0.46875 1.5q0 0.96875 -0.46875 1.5q-0.46875 0.515625 -1.171875 0.515625q-0.703125 0 -1.171875 -0.515625q-0.453125 -0.515625 -0.453125 -1.5625zm1.640625 -1.3125q-0.359375 0 -0.59375 0.3125q-0.21875 0.296875 -0.21875 1.09375q0 0.734375 0.234375 1.046875q0.234375 0.296875 0.578125 0.296875q0.359375 0 0.578125 -0.296875q0.234375 -0.3125 0.234375 -1.109375q0 -0.75 -0.234375 -1.046875q-0.234375 -0.296875 -0.578125 -0.296875zm8.6857605 3.109375l0 -1.828125l-3.296875 0l0 -0.859375l3.46875 -4.9375l0.765625 0l0 4.9375l1.03125 0l0 0.859375l-1.03125 0l0 1.828125l-0.9375 0zm0 -2.6875l0 -3.4375l-2.375 3.4375l2.375 0z" fill-rule="nonzero"/><path fill="#ffffff" d="m131.73615 206.8332l0 0c0 -5.4069824 4.3832245 -9.790222 9.790222 -9.790222l124.57703 0c2.596527 0 5.0867004 1.0314789 6.9227295 2.8674927c1.836029 1.836029 2.8674927 4.3262024 2.8674927 6.9227295l0 39.159714c0 5.4069977 -4.3832397 9.790222 -9.790222 9.790222l-124.57703 0l0 0c-5.4069977 0 -9.790222 -4.3832245 -9.790222 -9.790222z" fill-rule="evenodd"/><path stroke="#000000" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m131.73615 206.8332l0 0c0 -5.4069824 4.3832245 -9.790222 9.790222 -9.790222l124.57703 0c2.596527 0 5.0867004 1.0314789 6.9227295 2.8674927c1.836029 1.836029 2.8674927 4.3262024 2.8674927 6.9227295l0 39.159714c0 5.4069977 -4.3832397 9.790222 -9.790222 9.790222l-124.57703 0l0 0c-5.4069977 0 -9.790222 -4.3832245 -9.790222 -9.790222z" fill-rule="evenodd"/><path fill="#000000" d="m181.58737 219.44244l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm13.5625 1.421875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm7.917679 0.28125q-0.921875 0.765625 -1.765625 1.09375q-0.828125 0.3125 -1.796875 0.3125q-1.59375 0 -2.453125 -0.78125q-0.859375 -0.78125 -0.859375 -1.984375q0 -0.71875 0.328125 -1.296875q0.328125 -0.59375 0.84375 -0.9375q0.53125 -0.359375 1.1875 -0.546875q0.46875 -0.125 1.453125 -0.25q1.984375 -0.234375 2.921875 -0.5625q0.015625 -0.34375 0.015625 -0.421875q0 -1.0 -0.46875 -1.421875q-0.625 -0.546875 -1.875 -0.546875q-1.15625 0 -1.703125 0.40625q-0.546875 0.40625 -0.8125 1.421875l-1.609375 -0.21875q0.21875 -1.015625 0.71875 -1.640625q0.5 -0.640625 1.453125 -0.984375q0.953125 -0.34375 2.1875 -0.34375q1.25 0 2.015625 0.296875q0.78125 0.28125 1.140625 0.734375q0.375 0.4375 0.515625 1.109375q0.078125 0.421875 0.078125 1.515625l0 2.1875q0 2.28125 0.109375 2.890625q0.109375 0.59375 0.40625 1.15625l-1.703125 0q-0.265625 -0.515625 -0.328125 -1.1875zm-0.140625 -3.671875q-0.890625 0.375 -2.671875 0.625q-1.015625 0.140625 -1.4375 0.328125q-0.421875 0.1875 -0.65625 0.53125q-0.21875 0.34375 -0.21875 0.78125q0 0.65625 0.5 1.09375q0.5 0.4375 1.453125 0.4375q0.9375 0 1.671875 -0.40625q0.75 -0.421875 1.09375 -1.140625q0.265625 -0.5625 0.265625 -1.640625l0 -0.609375zm4.188217 4.859375l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm9.806427 -1.46875l0.234375 1.453125q-0.6875 0.140625 -1.234375 0.140625q-0.890625 0 -1.390625 -0.28125q-0.484375 -0.28125 -0.6875 -0.734375q-0.203125 -0.46875 -0.203125 -1.9375l0 -5.578125l-1.203125 0l0 -1.265625l1.203125 0l0 -2.390625l1.625 -0.984375l0 3.375l1.65625 0l0 1.265625l-1.65625 0l0 5.671875q0 0.6875 0.078125 0.890625q0.09375 0.203125 0.28125 0.328125q0.203125 0.109375 0.578125 0.109375q0.265625 0 0.71875 -0.0625zm0.94892883 -1.421875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125z" fill-rule="nonzero"/><path fill="#000000" d="m153.75652 244.33307l0 -1.21875q-0.90625 1.4375 -2.703125 1.4375q-1.15625 0 -2.125 -0.640625q-0.96875 -0.640625 -1.5 -1.78125q-0.53125 -1.140625 -0.53125 -2.625q0 -1.453125 0.484375 -2.625q0.484375 -1.1875 1.4375 -1.8125q0.96875 -0.625 2.171875 -0.625q0.875 0 1.546875 0.375q0.6875 0.359375 1.109375 0.953125l0 -4.796875l1.640625 0l0 13.359375l-1.53125 0zm-5.171875 -4.828125q0 1.859375 0.78125 2.78125q0.78125 0.921875 1.84375 0.921875q1.078125 0 1.828125 -0.875q0.75 -0.890625 0.75 -2.6875q0 -1.984375 -0.765625 -2.90625q-0.765625 -0.9375 -1.890625 -0.9375q-1.078125 0 -1.8125 0.890625q-0.734375 0.890625 -0.734375 2.8125zm9.235092 4.828125l0 -13.359375l1.640625 0l0 13.359375l-1.640625 0zm2.6760712 3.703125l0 -1.1875l10.859375 0l0 1.1875l-10.859375 0zm11.891342 0l0 -13.375l1.484375 0l0 1.25q0.53125 -0.734375 1.1875 -1.09375q0.671875 -0.375 1.625 -0.375q1.234375 0 2.171875 0.640625q0.953125 0.625 1.4375 1.796875q0.484375 1.15625 0.484375 2.546875q0 1.484375 -0.53125 2.671875q-0.53125 1.1875 -1.546875 1.828125q-1.015625 0.625 -2.140625 0.625q-0.8125 0 -1.46875 -0.34375q-0.65625 -0.34375 -1.0625 -0.875l0 4.703125l-1.640625 0zm1.484375 -8.484375q0 1.859375 0.75 2.765625q0.765625 0.890625 1.828125 0.890625q1.09375 0 1.875 -0.921875q0.78125 -0.9375 0.78125 -2.875q0 -1.84375 -0.765625 -2.765625q-0.75 -0.921875 -1.8125 -0.921875q-1.046875 0 -1.859375 0.984375q-0.796875 0.96875 -0.796875 2.84375zm8.875717 4.78125l0 -9.671875l1.46875 0l0 1.46875q0.5625 -1.03125 1.03125 -1.359375q0.484375 -0.328125 1.0625 -0.328125q0.828125 0 1.6875 0.53125l-0.5625 1.515625q-0.609375 -0.359375 -1.203125 -0.359375q-0.546875 0 -0.96875 0.328125q-0.421875 0.328125 -0.609375 0.890625q-0.28125 0.875 -0.28125 1.921875l0 5.0625l-1.625 0zm5.618927 -4.84375q0 -2.6875 1.484375 -3.96875q1.25 -1.078125 3.046875 -1.078125q2.0 0 3.265625 1.3125q1.265625 1.296875 1.265625 3.609375q0 1.859375 -0.5625 2.9375q-0.5625 1.0625 -1.640625 1.65625q-1.0625 0.59375 -2.328125 0.59375q-2.03125 0 -3.28125 -1.296875q-1.25 -1.3125 -1.25 -3.765625zm1.6875 0q0 1.859375 0.796875 2.796875q0.8125 0.921875 2.046875 0.921875q1.21875 0 2.03125 -0.921875q0.8125 -0.9375 0.8125 -2.84375q0 -1.796875 -0.8125 -2.71875q-0.8125 -0.921875 -2.03125 -0.921875q-1.234375 0 -2.046875 0.921875q-0.796875 0.90625 -0.796875 2.765625zm15.610092 1.296875l1.609375 0.21875q-0.265625 1.65625 -1.359375 2.609375q-1.078125 0.9375 -2.671875 0.9375q-1.984375 0 -3.1875 -1.296875q-1.203125 -1.296875 -1.203125 -3.71875q0 -1.578125 0.515625 -2.75q0.515625 -1.171875 1.578125 -1.75q1.0625 -0.59375 2.3125 -0.59375q1.578125 0 2.578125 0.796875q1.0 0.796875 1.28125 2.265625l-1.59375 0.234375q-0.234375 -0.96875 -0.8125 -1.453125q-0.578125 -0.5 -1.390625 -0.5q-1.234375 0 -2.015625 0.890625q-0.78125 0.890625 -0.78125 2.8125q0 1.953125 0.75 2.84375q0.75 0.875 1.953125 0.875q0.96875 0 1.609375 -0.59375q0.65625 -0.59375 0.828125 -1.828125zm9.640625 0.4375l1.6875 0.203125q-0.40625 1.484375 -1.484375 2.3125q-1.078125 0.8125 -2.765625 0.8125q-2.125 0 -3.375 -1.296875q-1.234375 -1.3125 -1.234375 -3.671875q0 -2.453125 1.25 -3.796875q1.265625 -1.34375 3.265625 -1.34375q1.9375 0 3.15625 1.328125q1.234375 1.3125 1.234375 3.703125q0 0.15625 0 0.4375l-7.21875 0q0.09375 1.59375 0.90625 2.453125q0.8125 0.84375 2.015625 0.84375q0.90625 0 1.546875 -0.46875q0.640625 -0.484375 1.015625 -1.515625zm-5.390625 -2.65625l5.40625 0q-0.109375 -1.21875 -0.625 -1.828125q-0.78125 -0.953125 -2.03125 -0.953125q-1.125 0 -1.90625 0.765625q-0.765625 0.75 -0.84375 2.015625zm8.485092 2.875l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm9.328125 0l1.625 -0.25q0.125 0.96875 0.75 1.5q0.625 0.515625 1.75 0.515625q1.125 0 1.671875 -0.453125q0.546875 -0.46875 0.546875 -1.09375q0 -0.546875 -0.484375 -0.875q-0.328125 -0.21875 -1.671875 -0.546875q-1.8125 -0.46875 -2.515625 -0.796875q-0.6875 -0.328125 -1.046875 -0.90625q-0.359375 -0.59375 -0.359375 -1.3125q0 -0.640625 0.296875 -1.1875q0.296875 -0.5625 0.8125 -0.921875q0.375 -0.28125 1.03125 -0.46875q0.671875 -0.203125 1.421875 -0.203125q1.140625 0 2.0 0.328125q0.859375 0.328125 1.265625 0.890625q0.421875 0.5625 0.578125 1.5l-1.609375 0.21875q-0.109375 -0.75 -0.640625 -1.171875q-0.515625 -0.421875 -1.46875 -0.421875q-1.140625 0 -1.625 0.375q-0.46875 0.375 -0.46875 0.875q0 0.3125 0.1875 0.578125q0.203125 0.265625 0.640625 0.4375q0.234375 0.09375 1.4375 0.421875q1.75 0.453125 2.4375 0.75q0.6875 0.296875 1.078125 0.859375q0.390625 0.5625 0.390625 1.40625q0 0.828125 -0.484375 1.546875q-0.46875 0.71875 -1.375 1.125q-0.90625 0.390625 -2.046875 0.390625q-1.875 0 -2.875 -0.78125q-0.984375 -0.78125 -1.25 -2.328125zm9.984375 -8.578125l0 -1.890625l1.640625 0l0 1.890625l-1.640625 0zm0 11.46875l0 -9.671875l1.640625 0l0 9.671875l-1.640625 0zm4.144821 0l0 -9.671875l1.46875 0l0 1.375q1.0625 -1.59375 3.078125 -1.59375q0.875 0 1.609375 0.3125q0.734375 0.3125 1.09375 0.828125q0.375 0.5 0.515625 1.203125q0.09375 0.453125 0.09375 1.59375l0 5.953125l-1.640625 0l0 -5.890625q0 -1.0 -0.203125 -1.484375q-0.1875 -0.5 -0.671875 -0.796875q-0.484375 -0.296875 -1.140625 -0.296875q-1.046875 0 -1.8125 0.671875q-0.75 0.65625 -0.75 2.515625l0 5.28125l-1.640625 0zm10.063217 0.796875l1.59375 0.234375q0.109375 0.75 0.5625 1.078125q0.609375 0.453125 1.671875 0.453125q1.1406403 0 1.7500153 -0.453125q0.625 -0.453125 0.84375 -1.265625q0.125 -0.5 0.109375 -2.109375q-1.0625 1.265625 -2.6718903 1.265625q-2.0 0 -3.09375 -1.4375q-1.09375 -1.4375 -1.09375 -3.453125q0 -1.390625 0.5 -2.5625q0.515625 -1.171875 1.453125 -1.796875q0.953125 -0.640625 2.25 -0.640625q1.7031403 0 2.8125153 1.375l0 -1.15625l1.515625 0l0 8.359375q0 2.265625 -0.46875 3.203125q-0.453125 0.9375 -1.453125 1.484375q-0.984375 0.546875 -2.4531403 0.546875q-1.71875 0 -2.796875 -0.78125q-1.0625 -0.765625 -1.03125 -2.34375zm1.359375 -5.8125q0 1.90625 0.75 2.78125q0.765625 0.875 1.90625 0.875q1.1250153 0 1.8906403 -0.859375q0.765625 -0.875 0.765625 -2.734375q0 -1.78125 -0.796875 -2.671875q-0.78125 -0.90625 -1.8906403 -0.90625q-1.09375 0 -1.859375 0.890625q-0.765625 0.875 -0.765625 2.625z" fill-rule="nonzero"/><path fill="#000000" fill-opacity="0.0" d="m386.5906 103.64539l36.93576 0l0 0.06299591l36.922485 0" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m386.5906 103.64539l36.93576 0l0 0.06299591l36.922485 0" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m608.23236 103.65213l149.85828 0l0 97.41733" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m608.23236 103.65213l149.85828 0l0 91.41733" fill-rule="evenodd"/><path fill="#595959" stroke="#595959" stroke-width="1.0" stroke-linecap="butt" d="m756.4389 195.06946l1.6517334 4.538086l1.6517334 -4.538086z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m253.50398 133.01547l0 32.00743l-49.70079 0l0 32.024063" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m253.50398 133.01547l0 32.00743l-49.70079 0l0 32.024063" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m203.81488 255.78314l0 30.826904l0.06298828 0l0 30.810883" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m203.81488 255.78314l0 30.826904l0.06298828 0l0 24.810883" fill-rule="evenodd"/><path fill="#595959" stroke="#595959" stroke-width="1.0" stroke-linecap="butt" d="m202.22614 311.42093l1.6517334 4.538086l1.6517334 -4.538086z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m253.50398 133.01547l0 32.93631l113.82677 0l0 32.95346" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m253.50398 133.01547l0 32.93631l113.82677 0l0 32.95346" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m367.33633 249.1331l0 24.07344l0.06298828 0l0 24.084045" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m367.33633 249.1331l0 24.07344l0.06298828 0l0 18.084045" fill-rule="evenodd"/><path fill="#595959" stroke="#595959" stroke-width="1.0" stroke-linecap="butt" d="m365.7476 291.2906l1.6517334 4.538086l1.6517334 -4.538086z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m203.80923 463.86697l0 46.771667l214.4252 0" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m203.80923 463.86697l0 46.771667l214.4252 0" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m583.11914 510.63785l174.99213 0l0 -85.763794" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m583.1192 510.63785l174.99213 0l0 -79.763794" fill-rule="evenodd"/><path fill="#595959" stroke="#595959" stroke-width="1.0" stroke-linecap="butt" d="m759.76306 430.87405l-1.6517334 -4.538086l-1.6517334 4.538086z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m367.34338 443.75003l0 23.274658l133.32285 0l0 23.27652" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m367.34338 443.75003l0 23.274658l133.32285 0l0 23.27652" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m477.01956 370.53326l-36.4494 0l0 0.06298828l-36.46399 0" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m477.01956 370.53326l-36.4494 0l0 0.06298828l-30.46399 0" fill-rule="evenodd"/><path fill="#595959" stroke="#595959" stroke-width="1.0" stroke-linecap="butt" d="m410.10617 368.94452l-4.538086 1.6517334l4.538086 1.6517334z" fill-rule="evenodd"/><path fill="#000000" fill-opacity="0.0" d="m588.2006 312.98996l-36.440918 0l0 57.543304l-36.440918 0" fill-rule="evenodd"/><path stroke="#595959" stroke-width="1.0" stroke-linejoin="round" stroke-linecap="butt" d="m588.2006 312.98996l-36.440918 0l0 57.543304l-36.440918 0" fill-rule="evenodd"/></g></svg>
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/executables/nr-ru.c b/executables/nr-ru.c
index 5a4002e609c30da3ccc2343bdf057465b8eba1bd..dd31088ff8724641c49704130f2da40dbf45da9c 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -621,7 +621,6 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
                                      rxp,
                                      samples_per_slot,
                                      ru->nb_rx);
-    gNBscopeCopy(ru, gNbTimeDomainSamples, rxp[0], sizeof(c16_t), 1, samples_per_slot, 0);
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
@@ -692,6 +691,11 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
     *slot  = proc->tti_rx;
   }
 
+  if (!emulate_rf) {
+    metadata mt = {.slot = *slot, .frame = *frame};
+    gNBscopeCopyWithMetadata(ru, gNbTimeDomainSamples, rxp[0], sizeof(c16_t), 1, samples_per_slot, 0, &mt);
+  }
+
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, (proc->timestamp_rx+ru->ts_offset)&0xffffffff );
 
   if (rxs != samples_per_slot) {
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index a7661b0c061f199951f01be93178f5108c441e9b..0aa966340be155f5cee47b1bf2ca40e618952664 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -39,6 +39,7 @@
 #include "RRC/NR/MESSAGES/asn1_msg.h"
 #include "openair1/PHY/TOOLS/phy_scope_interface.h"
 #include "PHY/MODULATION/nr_modulation.h"
+#include "instrumentation.h"
 
 /*
  *  NR SLOT PROCESSING SEQUENCE
@@ -99,6 +100,11 @@
 
 static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
 
+static void start_process_slot_tx(void* arg) {
+  notifiedFIFO_elt_t *newTx = arg;
+  pushTpool(&(get_nrUE_params()->Tpool), newTx);
+}
+
 static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len)
 {
   const char *begin = output;
@@ -480,62 +486,17 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
 
 void processSlotTX(void *arg)
 {
+  TracyCZone(ctx, true);
   nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
   const UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
   PHY_VARS_NR_UE *UE = rxtxD->UE;
   nr_phy_data_tx_t phy_data = {0};
   bool sl_tx_action = false;
 
-  // Force sequential execution, even if we launch in // for all slots
-  // at least ULstatus variable is a pure race condition that is quickly detected by assert() in the code because one thread sets it
-  // to active, so the other thread try to steal&run the ul work
-  if (rxtxD->stream_status == STREAM_STATUS_SYNCED) {
-    notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
-    delNotifiedFIFO_elt(res);
-  }
-
   if (UE->if_inst)
     UE->if_inst->slot_indication(UE->Mod_id);
 
-  LOG_D(PHY,
-        "SlotTx %d.%d => slot type %d, wait: %d \n",
-        proc->frame_tx,
-        proc->nr_slot_tx,
-        proc->tx_slot_type,
-        rxtxD->tx_wait_for_dlsch);
   if (proc->tx_slot_type == NR_UPLINK_SLOT || proc->tx_slot_type == NR_MIXED_SLOT) {
-    if (rxtxD->tx_wait_for_dlsch)
-      LOG_D(PHY, "enter wait for tx, slot %d, nb events to wait %d; ", proc->nr_slot_tx, rxtxD->tx_wait_for_dlsch);
-    // wait for rx slots to send indication (if any) that DLSCH decoding is finished
-    for(int i=0; i < rxtxD->tx_wait_for_dlsch; i++) {
-      notifiedFIFO_elt_t *res = pullNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
-      delNotifiedFIFO_elt(res);
-    }
-    LOG_D(PHY, "completed wait for tx, slot %d\n", proc->nr_slot_tx);
-
-    /*
-      This herafter code is costing some perfomance for a check that should be useless
-      But, we face today several bugs arround the matching between events in UE->tx_resume_ind_fifo[slot]
-      and the corresponding tx_wait_for_dlsch[slot]
-      The algorithm is we accumlate the actions that should end before processing a tx slot in tx_wait_for_dlsch[slot]
-      later, other threads push events in UE->tx_resume_ind_fifo[slot]
-      so, the tx encoding starts only when related actions are done (mainly DLSCH ACK/NACK to encode PUCCH)
-      if there is a bug that misses to send a event in UE->tx_resume_ind_fifo[slot], the process hangs, we detect the issue
-      if there is a bug that makes a extra event in UE->tx_resume_ind_fifo[slot], and if we drop the hereafter check
-      the system runs with random race conditions, very hard to debug
-
-      Likely we should later remove completly UE->tx_resume_ind_fifo with notifications,
-      instead,
-      we may run in place the processSlotTX() when the conditions are met (when a decreasing tx_wait_for_dlsch[slot] will become 0)
-      It will remove the condition signals (for a thread safe semaphore or counter) and make the system simpler
-    */
-    notifiedFIFO_elt_t *res = pollNotifiedFIFO(UE->tx_resume_ind_fifo + proc->nr_slot_tx);
-    if (res)
-      LOG_E(NR_PHY,
-            "Internal error: extra event on Tx waiting queue for slot %d, event comes from rx slot %d\n",
-            proc->nr_slot_tx,
-            *(int *)NotifiedFifoData(res));
-
     if (UE->sl_mode == 2 && proc->tx_slot_type == NR_SIDELINK_SLOT) {
       // trigger L2 to run ue_sidelink_scheduler thru IF module
       if (UE->if_inst != NULL && UE->if_inst->sl_indication != NULL) {
@@ -584,14 +545,12 @@ void processSlotTX(void *arg)
     }
   }
 
-  notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL);
-  int *msgData = (int *)NotifiedFifoData(newElt);
   int slots_per_frame = (UE->sl_mode == 2) ? UE->SL_UE_PHY_PARAMS.sl_frame_params.slots_per_frame
                                            : UE->frame_parms.slots_per_frame;
-  int newslot = (proc->nr_slot_tx + 1) % slots_per_frame;
-  *msgData = newslot;
-  pushNotifiedFIFO(UE->tx_resume_ind_fifo + newslot, newElt);
+  int next_slot = (proc->nr_slot_tx + 1) % slots_per_frame;
+  dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot]);
   RU_write(rxtxD, sl_tx_action);
+  TracyCZoneEnd(ctx);
 }
 
 static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
@@ -600,6 +559,7 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
                                nr_phy_data_t *phy_data,
                                bool *stats_printed)
 {
+  TracyCZone(ctx, true);
   int sampleShift = INT_MAX;
   NR_DL_FRAME_PARMS *fp = &UE->frame_parms;
   if (UE->sl_mode == 2)
@@ -690,10 +650,12 @@ static int UE_dl_preprocessing(PHY_VARS_NR_UE *UE,
   } else
     ue_ta_procedures(UE, proc->nr_slot_tx, proc->frame_tx);
 
+  TracyCZoneEnd(ctx);
   return sampleShift;
 }
 
 void UE_dl_processing(void *arg) {
+  TracyCZone(ctx, true);;
   nr_rxtx_thread_data_t *rxtxD = (nr_rxtx_thread_data_t *) arg;
   UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
   PHY_VARS_NR_UE    *UE   = rxtxD->UE;
@@ -701,6 +663,8 @@ void UE_dl_processing(void *arg) {
 
   if (!UE->sl_mode)
     pdsch_processing(UE, proc, phy_data);
+
+  TracyCZoneEnd(ctx);
 }
 
 void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
@@ -841,7 +805,7 @@ void *UE_thread(void *arg)
 
   int num_ind_fifo = nb_slot_frame;
   for(int i = 0; i < num_ind_fifo; i++) {
-    initNotifiedFIFO(UE->tx_resume_ind_fifo + i);
+    dynamic_barrier_init(&UE->process_slot_tx_barriers[i]);
   }
   int shiftForNextFrame = 0;
   int intialSyncOffset = 0;
@@ -916,7 +880,7 @@ void *UE_thread(void *arg)
       }
       syncMsg->UE = UE;
       memset(&syncMsg->proc, 0, sizeof(syncMsg->proc));
-      pushTpool(&(get_nrUE_params()->Tpool), Msg);
+      pushNotifiedFIFO(&UE->sync_actor.fifo, Msg);
       trashed_frames = 0;
       syncRunning = true;
       continue;
@@ -956,15 +920,14 @@ void *UE_thread(void *arg)
       // We have resynchronized, maybe after RF loss so we need to purge any existing context
       memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch));
       for (int i = 0; i < num_ind_fifo; i++) {
-        notifiedFIFO_elt_t *res;
-        while ((res = pollNotifiedFIFO(UE->tx_resume_ind_fifo + i)))
-          delNotifiedFIFO_elt(res);
+        dynamic_barrier_reset(&UE->process_slot_tx_barriers[i]);
       }
       continue;
     }
 
     // start of normal case, the UE is in sync
     absolute_slot++;
+    TracyCFrameMark;
 
     int slot_nr = absolute_slot % nb_slot_frame;
     nr_rxtx_thread_data_t curMsg = {0};
@@ -1046,7 +1009,7 @@ void *UE_thread(void *arg)
     int ret = UE_dl_preprocessing(UE, &curMsgRx->proc, tx_wait_for_dlsch, &curMsgRx->phy_data, &stats_printed);
     if (ret != INT_MAX)
       shiftForNextFrame = ret;
-    pushTpool(&(get_nrUE_params()->Tpool), newRx);
+    pushNotifiedFIFO(&UE->dl_actors[curMsg.proc.nr_slot_rx % NUM_DL_ACTORS].fifo, newRx);
 
     // Start TX slot processing here. It runs in parallel with RX slot processing
     // in current code, DURATION_RX_TO_TX constant is the limit to get UL data to encode from a RX slot
@@ -1056,11 +1019,16 @@ void *UE_thread(void *arg)
     curMsgTx->writeBlockSize = writeBlockSize;
     curMsgTx->proc.timestamp_tx = writeTimestamp;
     curMsgTx->UE = UE;
-    curMsgTx->tx_wait_for_dlsch = tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx];
     curMsgTx->stream_status = stream_status;
+
+    int sync_to_previous_thread = stream_status == STREAM_STATUS_SYNCED ? 1 : 0;
+    int slot = curMsgTx->proc.nr_slot_tx;
+    dynamic_barrier_update(&UE->process_slot_tx_barriers[slot],
+                           tx_wait_for_dlsch[slot] + sync_to_previous_thread,
+                           start_process_slot_tx,
+                           newTx);
     stream_status = STREAM_STATUS_SYNCED;
-    tx_wait_for_dlsch[curMsgTx->proc.nr_slot_tx] = 0;
-    pushTpool(&(get_nrUE_params()->Tpool), newTx);
+    tx_wait_for_dlsch[slot] = 0;
   }
 
   return NULL;
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index 8a9f0c626f2ca1b464933f118092adb1bbcc6301..07d3e532f51ac427f2e2d1ff74f5859e068a4bce 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -88,6 +88,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include <openair1/PHY/MODULATION/nr_modulation.h>
 #include "openair2/GNB_APP/gnb_paramdef.h"
 #include "pdcp.h"
+#include "actor.h"
 
 extern const char *duplex_mode[];
 THREAD_STRUCT thread_struct;
@@ -495,6 +496,10 @@ int main(int argc, char **argv)
         }
 
         UE[CC_id]->sl_mode = get_softmodem_params()->sl_mode;
+        init_actor(&UE[CC_id]->sync_actor, "SYNC_", -1);
+        for (int i = 0; i < NUM_DL_ACTORS; i++) {
+          init_actor(&UE[CC_id]->dl_actors[i], "DL_", -1);
+        }
         init_nr_ue_vars(UE[CC_id], inst);
 
         if (UE[CC_id]->sl_mode) {
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_decoder/nrLDPC_decoder_offload.c b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c
index 77a120970994958f41e887dfa6c072ae5c72fe9d..fd222f40b4c402807d4f2462225055b9c7f194ee 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_decoder_offload.c
@@ -595,23 +595,22 @@ static int retrieve_ldpc_dec_op(struct rte_bbdev_dec_op **ops, const uint16_t n,
 
 static int retrieve_ldpc_enc_op(struct rte_bbdev_enc_op **ops, const uint16_t n, uint8_t *p_out, nrLDPC_params_per_cb_t *perCB)
 {
-  struct rte_bbdev_op_data *output;
-  struct rte_mbuf *m;
-  unsigned int i;
-  char *data;
-  uint8_t *out;
   int offset = 0;
-  for (i = 0; i < n; ++i) {
-    output = &ops[i]->ldpc_enc.output;
-    m = output->data;
+  for (int i = 0; i < n; ++i) {
+    struct rte_bbdev_op_data *output = &ops[i]->ldpc_enc.output;
+    struct rte_mbuf *m = output->data;
     uint16_t data_len = rte_pktmbuf_data_len(m) - output->offset;
-    out = &p_out[offset];
-    data = m->buf_addr;
-    for (int byte = 0; byte < data_len; byte++)
-      for (int bit = 0; bit < 8; bit++)
-        out[byte * 8 + bit] = (data[m->data_off + byte] >> (7 - bit)) & 1;
+    uint8_t *out = &p_out[offset];
+    const char *data = m->buf_addr + m->data_off;
+    const char *end = data + data_len;
+    while (data < end) {
+      uint8_t byte = *data++;  // get the current byte
+      for (int bit = 7; bit >= 0; --bit) {
+        *out++ = (byte >> bit) & 1;  // extract each bit
+      }
+    }
     offset += perCB[i].E_cb;
-    rte_pktmbuf_free(ops[i]->ldpc_enc.output.data);
+    rte_pktmbuf_free(m);
     rte_pktmbuf_free(ops[i]->ldpc_enc.input.data);
   }
   return 0;
diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
index d713340a19a3b6441a1d8700fd27217984f666cd..43bf68f48d38a47bdf8bd174d07c9517631700b8 100644
--- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
+++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPCdecoder_defs.h
@@ -99,7 +99,8 @@
 /** Maximum number of possible input LLR = NR_LDPC_NCOL_BG1*NR_LDPC_ZMAX */
 #define NR_LDPC_MAX_NUM_LLR 27000
 
-#define NR_LDPC_MAX_NUM_CB 72
+/** Maximum number of segments per TB = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS */
+#define NR_LDPC_MAX_NUM_CB 144
 
 // ==============================================================================
 // GLOBAL CONSTANT VARIABLES
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/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index daf6eafa42e8098eb994f01b090724116d1cf996..6b278f899f88f27b3525f2122c258ca3e8c8c62a 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -25,7 +25,6 @@
 #include "PHY/defs_eNB.h"
 #include "PHY/defs_UE.h"
 #include "PHY/defs_gNB.h"
-#include "PHY/defs_nr_UE.h"
 
 #include "LTE_SystemInformationBlockType2.h"
 //#include "RadioResourceConfigCommonSIB.h"
diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
index acdd291343d5eb5d4b70415d06df63fbb59e5e23..e8570a3bbcd3b0c7e74c399b264ca61f00f666d6 100644
--- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
+++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c
@@ -480,7 +480,6 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
 
 #endif
 
-  int nbAarx = 0;
   int nest_count = 0;
   uint64_t noise_amp2 = 0;
   delay_t *delay = &gNB->ulsch[ul_id].delay;
@@ -503,9 +502,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
   initNotifiedFIFO(&respPuschAarx);
   start_meas(&gNB->pusch_channel_estimation_antenna_processing_stats);
   int numAntennas = gNB->dmrs_num_antennas_per_thread;
-  for (int aarx = 0; aarx < gNB->frame_parms.nb_antennas_rx; aarx += numAntennas) {
+  int num_jobs = CEILIDIV(gNB->frame_parms.nb_antennas_rx, numAntennas);
+  for (int job_id = 0; job_id < num_jobs; job_id++) {
     union puschAntennaReqUnion id = {.s = {ul_id, 0}};
-    id.p = 1 + aarx;
+    id.p = 1 + job_id * numAntennas;
     notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(puschAntennaProc_t),
                                                   id.p,
                                                   &respPuschAarx,
@@ -517,7 +517,7 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
     rdata->nl = nl;
     rdata->p = p;
     rdata->symbol = symbol;
-    rdata->aarx = aarx;
+    rdata->aarx = job_id * numAntennas;
     rdata->numAntennas = numAntennas;
     rdata->bwp_start_subcarrier = bwp_start_subcarrier;
     rdata->pusch_pdu = pusch_pdu;
@@ -532,15 +532,19 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
     rdata->chest_freq = gNB->chest_freq;
     rdata->rxdataF = gNB->common_vars.rxdataF;
     // Call the nr_pusch_antenna_processing function
-    pushTpool(&gNB->threadPool, req);
-    nbAarx++;
-
-    LOG_D(PHY, "Added Antenna (count %d) to process, in pipe\n", nbAarx);
+    if (job_id == num_jobs - 1) {
+      // Run the last job inline
+      nr_pusch_antenna_processing(rdata);
+      delNotifiedFIFO_elt(req);
+    } else {
+      pushTpool(&gNB->threadPool, req);
+    }
+    LOG_D(PHY, "Added Antenna (count %d/%d) to process, in pipe\n", job_id, num_jobs);
   } // Antenna Loop
 
-  while (nbAarx > 0) {
+  while (num_jobs - 1 > 0) {
     notifiedFIFO_elt_t *req = pullTpool(&respPuschAarx, &gNB->threadPool);
-    nbAarx--;
+    num_jobs--;
     delNotifiedFIFO_elt(req);
   }
 
diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
index 32ce0acba2527a7ac08bcc07d8f8a7d9a5fd5815..44bb20115db5fadc59423f6f129eb2d6c50526e0 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c
@@ -232,7 +232,7 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
 {
   NR_gNB_ULSCH_t *ulsch = &phy_vars_gNB->ulsch[ULSCH_id];
   NR_UL_gNB_HARQ_t *harq_process = ulsch->harq_process;
-  int16_t z_ol[NR_LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
+  int16_t z_ol[LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
   int8_t l_ol[NR_LDPC_MAX_NUM_CB * LDPC_MAX_CB_SIZE] __attribute__((aligned(16)));
   const int kc = decParams->BG == 2 ? 52 : 68;
   uint32_t A = (harq_process->TBS) << 3;
@@ -247,8 +247,8 @@ int decode_offload(PHY_VARS_gNB *phy_vars_gNB,
 
   for (int r = 0; r < harq_process->C; r++) {
     decParams->perCB[r].E_cb = nr_get_E(G, harq_process->C, decParams->Qm, pusch_pdu->nrOfLayers, r);
-    memcpy(&z_ol[offset], ulsch_llr + r_offset, decParams->perCB[r].E_cb * sizeof(*z_ol));
-    simde__m128i *pv_ol128 = (simde__m128i *)&z_ol[offset];
+    memcpy(z_ol, ulsch_llr + r_offset, decParams->perCB[r].E_cb * sizeof(int16_t));
+    simde__m128i *pv_ol128 = (simde__m128i *)z_ol;
     simde__m128i *pl_ol128 = (simde__m128i *)&l_ol[offset];
     for (int i = 0, j = 0; j < ((kc * harq_process->Z) >> 4) + 1; i += 2, j++) {
       pl_ol128[j] = simde_mm_packs_epi16(pv_ol128[i], pv_ol128[i + 1]);
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
index 53c302e789d8ba4901a2be8c9bbaf396eacaa02f..23560568cfd515053efa7855773c6954c1cad3b5 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -33,6 +33,7 @@
 #include "T.h"
 #include <openair1/PHY/TOOLS/phy_scope_interface.h>
 #include "nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h"
+#include "instrumentation.h"
 
 
 extern openair0_config_t openair0_cfg[];
@@ -658,6 +659,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
                                bool sidelink,
                                uint Nid)
 {
+  TracyCZone(ctx, true);
   int Ns = proc->nr_slot_rx;
   c16_t pilot[200] __attribute__((aligned(16)));
   //int slot_pbch;
@@ -830,6 +832,7 @@ int nr_pbch_channel_estimation(const NR_DL_FRAME_PARMS *fp,
     }
   }
 
+  TracyCZoneEnd(ctx);
   return(0);
 }
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 82819551e4b56ad627627df0b571f2b7badb906b..5dbab85f124a9ed6e952d360f00a7626d9d655e0 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -38,6 +38,7 @@
 #include <openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h>
 #include <openair1/PHY/TOOLS/phy_scope_interface.h>
 #include "openair1/PHY/NR_REFSIG/nr_refsig_common.h"
+#include "instrumentation.h"
 //#define DEBUG_PBCH
 //#define DEBUG_PBCH_ENCODING
 
@@ -365,6 +366,7 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
                int rxdataFSize,
                const struct complex16 rxdataF[][rxdataFSize])
 {
+  TracyCZone(ctx, true);
   int max_h=0;
   int symbol;
   uint8_t Lmax=frame_parms->Lmax;
@@ -539,5 +541,6 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
       ue->if_inst->dl_indication(&dl_indication);
   }
 
+  TracyCZoneEnd(ctx);
   return 0;
 }
diff --git a/openair1/PHY/TOOLS/CMakeLists.txt b/openair1/PHY/TOOLS/CMakeLists.txt
index ada3d8c86336f2cce55ac6a576029c154b3be904..574899f3e70c43e6e901aaa637c49c74324bb2bb 100644
--- a/openair1/PHY/TOOLS/CMakeLists.txt
+++ b/openair1/PHY/TOOLS/CMakeLists.txt
@@ -53,7 +53,7 @@ if(ENABLE_UESCOPE OR ENABLE_ENBSCOPE OR ENABLE_NRSCOPE)
   target_link_libraries(uescope PUBLIC forms PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
 
   add_library(nrscope MODULE nr_phy_scope.c)
-  target_link_libraries(nrscope PUBLIC forms PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs)
+  target_link_libraries(nrscope PUBLIC forms PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs UTIL)
 
   # all libraries should be written to root build dir (default creates the same hierarchie under build as existing for sources)
   set_target_properties(enbscope uescope nrscope 
diff --git a/openair1/PHY/TOOLS/imscope/CMakeLists.txt b/openair1/PHY/TOOLS/imscope/CMakeLists.txt
index 60b2dc69cebe4817e10a895df89ae70bb9090906..26eb85510088c889be6d319f7f764e7f49da25c0 100644
--- a/openair1/PHY/TOOLS/imscope/CMakeLists.txt
+++ b/openair1/PHY/TOOLS/imscope/CMakeLists.txt
@@ -1,5 +1,5 @@
 
-CPMAddPackage("gh:ocornut/imgui#v1.90.9")
+CPMAddPackage("gh:ocornut/imgui#v1.91.3-docking")
 add_library(imgui
   ${imgui_SOURCE_DIR}/imgui_draw.cpp
   ${imgui_SOURCE_DIR}/imgui.cpp
@@ -32,3 +32,4 @@ target_include_directories(implot PUBLIC ${implot_SOURCE_DIR})
 add_library(imscope MODULE imscope.cpp ../phy_scope_interface.c)
 target_link_libraries(imscope PUBLIC imgui_glfw_backend glfw imgui_opengl_renderer OpenGL::OpenGL implot UTIL)
 set_target_properties(imscope PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+configure_file(imgui.ini ${CMAKE_BINARY_DIR}/imscope-init.ini COPYONLY)
diff --git a/openair1/PHY/TOOLS/imscope/imgui.ini b/openair1/PHY/TOOLS/imscope/imgui.ini
new file mode 100644
index 0000000000000000000000000000000000000000..3fc08b6f7c1dc838290c7abc5853c40ce6725fb0
--- /dev/null
+++ b/openair1/PHY/TOOLS/imscope/imgui.ini
@@ -0,0 +1,99 @@
+[Window][Debug##Default]
+Pos=60,60
+Size=400,400
+Collapsed=0
+
+[Window][NR KPI]
+Pos=0,19
+Size=1133,667
+Collapsed=0
+DockId=0x00000005,0
+
+[Window][Dear ImGui Demo]
+Pos=531,19
+Size=529,667
+Collapsed=0
+DockId=0x00000002,0
+
+[Window][ImPlot Demo]
+Pos=531,19
+Size=529,667
+Collapsed=0
+DockId=0x00000002,0
+
+[Window][WindowOverViewport_11111111]
+Pos=0,19
+Size=1280,701
+Collapsed=0
+
+[Window][Status bar]
+Pos=0,688
+Size=1280,32
+Collapsed=0
+DockId=0x00000004,0
+
+[Window][Global scope settings]
+Pos=1038,19
+Size=242,667
+Collapsed=0
+DockId=0x00000006,0
+
+[Window][UE KPI]
+Pos=532,19
+Size=528,667
+Collapsed=0
+DockId=0x00000008,0
+
+[Window][UE PDSCH IQ]
+Pos=0,19
+Size=530,667
+Collapsed=0
+DockId=0x00000005,1
+
+[Window][Time domain samples]
+Pos=0,19
+Size=1036,667
+Collapsed=0
+DockId=0x00000005,0
+
+[Window][Time domain samples - before sync]
+Pos=0,19
+Size=530,667
+Collapsed=0
+DockId=0x00000005,2
+
+[Window][Broadcast channel]
+Pos=0,19
+Size=530,667
+Collapsed=0
+DockId=0x00000005,3
+
+[Window][RX IQ]
+Pos=532,19
+Size=528,667
+Collapsed=0
+DockId=0x00000008,0
+
+[Window][PUSCH SLOT IQ]
+Pos=0,19
+Size=1036,667
+Collapsed=0
+DockId=0x00000005,1
+
+[Window][PUSCH LLRs]
+Pos=0,19
+Size=1036,667
+Collapsed=0
+DockId=0x00000005,2
+
+[Docking][Data]
+DockSpace         ID=0x7C6B3D9B Window=0xA87D555D Pos=0,19 Size=1280,701 Split=Y Selected=0x71C89FCB
+  DockNode        ID=0x00000003 Parent=0x7C6B3D9B SizeRef=1280,667 Split=X
+    DockNode      ID=0x00000001 Parent=0x00000003 SizeRef=1319,720 Split=X Selected=0x6627CA6C
+      DockNode    ID=0x00000007 Parent=0x00000001 SizeRef=530,667 Split=X Selected=0x93FDECFF
+        DockNode  ID=0x00000005 Parent=0x00000007 SizeRef=1036,334 CentralNode=1 Selected=0x93FDECFF
+        DockNode  ID=0x00000006 Parent=0x00000007 SizeRef=242,334 Selected=0xFAA8D9D5
+      DockNode    ID=0x00000008 Parent=0x00000001 SizeRef=528,667 Selected=0x6627CA6C
+    DockNode      ID=0x00000002 Parent=0x00000003 SizeRef=529,720 Selected=0xB903C8C9
+  DockNode        ID=0x00000004 Parent=0x7C6B3D9B SizeRef=1280,32 HiddenTabBar=1 Selected=0xD9B9B9C7
+
diff --git a/openair1/PHY/TOOLS/imscope/imscope.cpp b/openair1/PHY/TOOLS/imscope/imscope.cpp
index 054fcdad79b9651ed979ffbc43f9304ca51ed12f..84ae7d85f4113466bba9afe836587031d83fca52 100644
--- a/openair1/PHY/TOOLS/imscope/imscope.cpp
+++ b/openair1/PHY/TOOLS/imscope/imscope.cpp
@@ -107,7 +107,7 @@ typedef struct IQData {
   float max_power;
   float timestamp;
   int nonzero_count;
-  int len;
+  int len = 0;
   metadata meta;
 
   bool TryCollect(ImScopeData *imscope_data, float time, float epsilon)
@@ -213,11 +213,13 @@ class IQHist {
   float epsilon = 0.0;
   bool auto_adjust_range = true;
   int plot_type = 0;
+  bool disable_scatterplot;
 
  public:
-  IQHist(const char *label_)
+  IQHist(const char *label_, bool _disable_scatterplot = false)
   {
     label = label_;
+    disable_scatterplot = _disable_scatterplot;
   };
   bool ShouldReadData(void)
   {
@@ -264,10 +266,11 @@ class IQHist {
       ImGui::DragFloat("%% nonzero elements", &min_nonzero_percentage, 1, 0.0, 100);
       ImGui::DragFloat("epsilon", &epsilon, 1, 0.0, 3000);
     }
-    const char *items[] = {"Histogram", "Scatter", "RMS"};
-    ImGui::Combo("Select plot type", &plot_type, items, sizeof(items) / sizeof(items[0]));
+    const char *items[] = {"Histogram", "RMS", "Scatter"};
+    ImGui::Combo("Select plot type", &plot_type, items, disable_scatterplot ? 2 : 3);
     if (plot_type == 0) {
-      if (ImPlot::BeginPlot(label.c_str(), {(float)ImGui::GetWindowWidth() * 0.3f, (float)ImGui::GetWindowWidth() * 0.3f})) {
+      float x = ImGui::CalcItemWidth();
+      if (ImPlot::BeginPlot(label.c_str(), {x, x})) {
         ImPlot::PlotHistogram2D(label.c_str(),
                                 iq_data->real.data(),
                                 iq_data->imag.data(),
@@ -277,8 +280,9 @@ class IQHist {
                                 ImPlotRect(-range, range, -range, range));
         ImPlot::EndPlot();
       }
-    } else if (plot_type == 1) {
-      if (ImPlot::BeginPlot(label.c_str(), {(float)ImGui::GetWindowWidth() * 0.3f, (float)ImGui::GetWindowWidth() * 0.3f})) {
+    } else if (plot_type == 2) {
+      float x = ImGui::CalcItemWidth();
+      if (ImPlot::BeginPlot(label.c_str(), {x, x})) {
         int points_drawn = 0;
         while (points_drawn < iq_data->len) {
           // Limit the amount of data plotted with PlotScatter call (issue with vertices/draw call)
@@ -292,7 +296,7 @@ class IQHist {
         }
         ImPlot::EndPlot();
       }
-    } else if (plot_type == 2) {
+    } else if (plot_type == 1) {
       if (ImPlot::BeginPlot(label.c_str())) {
         ImPlot::PlotLine(label.c_str(), iq_data->power.data(), iq_data->len);
         ImPlot::EndPlot();
@@ -457,6 +461,7 @@ struct ScrollingBuffer {
 
 void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
 {
+  ImGui::Begin("UE KPI");
   if (ImPlot::BeginPlot("##Scrolling", ImVec2(-1, 150))) {
     static float history = 10.0f;
     ImGui::SliderFloat("History", &history, 1, 30, "%.1f s");
@@ -479,7 +484,9 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
     ImPlot::PlotLine("mcs", &mcs.Data[0].x, &mcs.Data[0].y, mcs.Data.size(), 0, 0, 2 * sizeof(float));
     ImPlot::EndPlot();
   }
-  if (ImGui::TreeNode("PDSCH IQ")) {
+  ImGui::End();
+
+  if (ImGui::Begin("UE PDSCH IQ")) {
     static auto iq_data = new IQData();
     static auto pdsch_iq_hist = new IQHist("PDSCH IQ");
     bool new_data = false;
@@ -487,29 +494,36 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
       new_data = iq_data->TryCollect(&scope_array[pdschRxdataF_comp], t, pdsch_iq_hist->GetEpsilon());
     }
     pdsch_iq_hist->Draw(iq_data, t, new_data);
-    ImGui::TreePop();
   }
-  if (ImGui::TreeNode("Time domain samples")) {
+  ImGui::End();
+
+  if (ImGui::Begin("Time domain samples")) {
     static auto iq_data = new IQData();
-    static auto time_domain_iq = new IQHist("Time domain samples");
+    // Issue with imgui deferring draw calls until the end of the frame - cases segfault if scatterplot has too many points
+    bool disable_scatterplot = true;
+    static auto time_domain_iq = new IQHist("Time domain samples", disable_scatterplot);
     bool new_data = false;
     if (time_domain_iq->ShouldReadData()) {
       new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamples], t, time_domain_iq->GetEpsilon());
     }
     time_domain_iq->Draw(iq_data, t, new_data);
-    ImGui::TreePop();
   }
-  if (ImGui::TreeNode("Time domain samples - before sync")) {
+  ImGui::End();
+
+  if (ImGui::Begin("Time domain samples - before sync")) {
     static auto iq_data = new IQData();
-    static auto time_domain_iq = new IQHist("Time domain samples - before sync");
+    // Issue with imgui deferring draw calls until the end of the frame - cases segfault if scatterplot has too many points
+    bool disable_scatterplot = true;
+    static auto time_domain_iq = new IQHist("Time domain samples - before sync", disable_scatterplot);
     bool new_data = false;
     if (time_domain_iq->ShouldReadData()) {
       new_data = iq_data->TryCollect(&scope_array[ueTimeDomainSamplesBeforeSync], t, time_domain_iq->GetEpsilon());
     }
     time_domain_iq->Draw(iq_data, t, new_data);
-    ImGui::TreePop();
   }
-  if (ImGui::TreeNode("Broadcast channel")) {
+  ImGui::End();
+
+  if (ImGui::Begin("Broadcast channel")) {
     ImGui::Text("RSRP %d", ue->measurements.ssb_rsrp_dBm[ue->frame_parms.ssb_index]);
     if (ImGui::TreeNode("IQ")) {
       static auto iq_data = new IQData();
@@ -541,32 +555,33 @@ void ShowUeScope(PHY_VARS_NR_UE *ue, float t)
       llr_plot->Draw(t, ue->sl_mode ? psbchLlr : pbchLlr, "Broadcast LLR");
       ImGui::TreePop();
     }
-    ImGui::TreePop();
-  }
-  if (ImGui::TreeNode("RX IQ")) {
-    static auto common_rx_iq_heatmap = new IQSlotHeatmap(&scope_array[commonRxdataF], "common RX IQ");
-    common_rx_iq_heatmap->Draw(t,
-                               ue->frame_parms.ofdm_symbol_size,
-                               ue->frame_parms.symbols_per_slot,
-                               ue->frame_parms.first_carrier_offset,
-                               ue->frame_parms.N_RB_DL);
-    ImGui::TreePop();
   }
+  ImGui::End();
+
+  // if (ImGui::Begin("RX IQ")) {
+  //   static auto common_rx_iq_heatmap = new IQSlotHeatmap(&scope_array[commonRxdataF], "common RX IQ");
+  //   common_rx_iq_heatmap->Draw(t,
+  //                              ue->frame_parms.ofdm_symbol_size,
+  //                              ue->frame_parms.symbols_per_slot,
+  //                              ue->frame_parms.first_carrier_offset,
+  //                              ue->frame_parms.N_RB_DL);
+  // }
+  // ImGui::End();
 }
 
 void ShowGnbScope(PHY_VARS_gNB *gNB, float t)
 {
-  if (ImGui::TreeNode("RX IQ")) {
-    static auto gnb_heatmap = new IQSlotHeatmap(&scope_array[gNBRxdataF], "common RX IQ");
-
-    gnb_heatmap->Draw(t,
-                      gNB->frame_parms.ofdm_symbol_size,
-                      gNB->frame_parms.symbols_per_slot,
-                      gNB->frame_parms.first_carrier_offset,
-                      gNB->frame_parms.N_RB_UL);
-    ImGui::TreePop();
-  }
-  if (ImGui::TreeNode("PUSCH SLOT IQ")) {
+  // if (ImGui::TreeNode("RX IQ")) {
+  //   static auto gnb_heatmap = new IQSlotHeatmap(&scope_array[gNBRxdataF], "common RX IQ");
+
+  //   gnb_heatmap->Draw(t,
+  //                     gNB->frame_parms.ofdm_symbol_size,
+  //                     gNB->frame_parms.symbols_per_slot,
+  //                     gNB->frame_parms.first_carrier_offset,
+  //                     gNB->frame_parms.N_RB_UL);
+  //   ImGui::TreePop();
+  // }
+  if (ImGui::Begin("PUSCH SLOT IQ")) {
     static auto pusch_iq = new IQData();
     static auto pusch_iq_display = new IQHist("PUSCH compensated IQ");
     bool new_data = false;
@@ -574,23 +589,27 @@ void ShowGnbScope(PHY_VARS_gNB *gNB, float t)
       new_data = pusch_iq->TryCollect(&scope_array[gNBPuschRxIq], t, pusch_iq_display->GetEpsilon());
     }
     pusch_iq_display->Draw(pusch_iq, t, new_data);
-    ImGui::TreePop();
   }
-  if (ImGui::TreeNode("PUSCH LLRs")) {
+  ImGui::End();
+
+  if (ImGui::Begin("PUSCH LLRs")) {
     static auto pusch_llr_plot = new LLRPlot();
     pusch_llr_plot->Draw(t, gNBPuschLlr, "PUSCH LLR");
-    ImGui::TreePop();
   }
-  if (ImGui::TreeNode("Time domain samples")) {
+  ImGui::End();
+
+  if (ImGui::Begin("Time domain samples")) {
     static auto iq_data = new IQData();
-    static auto time_domain_iq = new IQHist("Time domain samples");
+    // Issue with imgui deferring draw calls until the end of the frame - cases segfault if scatterplot has too many points
+    bool disable_scatterplot = true;
+    static auto time_domain_iq = new IQHist("Time domain samples", disable_scatterplot);
     bool new_data = false;
     if (time_domain_iq->ShouldReadData()) {
       new_data = iq_data->TryCollect(&scope_array[gNbTimeDomainSamples], t, time_domain_iq->GetEpsilon());
     }
     time_domain_iq->Draw(iq_data, t, new_data);
-    ImGui::TreePop();
   }
+  ImGui::End();
 }
 
 void *imscope_thread(void *data_void_ptr)
@@ -636,6 +655,7 @@ void *imscope_thread(void *data_void_ptr)
   ImGuiIO &io = ImGui::GetIO();
   (void)io;
   io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
+  io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
 
   // Setup Dear ImGui style
   ImGui::StyleColorsDark();
@@ -659,7 +679,8 @@ void *imscope_thread(void *data_void_ptr)
   static int target_fps = 24;
 
   bool is_ue = (get_softmodem_optmask() & SOFTMODEM_5GUE_BIT) > 0;
-  while (!glfwWindowShouldClose(window)) {
+  bool close_window = false;
+  while (!glfwWindowShouldClose(window) && close_window == false) {
     // Poll and handle events (inputs, window resize, etc.)
     // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
     // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy
@@ -672,33 +693,62 @@ void *imscope_thread(void *data_void_ptr)
     // Start the Dear ImGui frame
     ImGui_ImplOpenGL3_NewFrame();
     ImGui_ImplGlfw_NewFrame();
+
+    static bool reset_ini_settings = false;
+    if (reset_ini_settings)
+    {
+      ImGui::LoadIniSettingsFromDisk("imscope-init.ini");
+      reset_ini_settings = false;
+    }
     ImGui::NewFrame();
 
     int display_w, display_h;
     glfwGetFramebufferSize(window, &display_w, &display_h);
 
     static float t = 0;
-
-    t += ImGui::GetIO().DeltaTime;
-    ImGui::SetNextWindowPos({0, 0});
-    ImGui::SetNextWindowSize({(float)display_w, (float)display_h});
-    ImGui::Begin("NR KPI", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);
-    if (ImGui::TreeNode("Global settings")) {
-      ImGui::ShowFontSelector("Font");
-      ImGui::ShowStyleSelector("ImGui Style");
-      ImPlot::ShowStyleSelector("ImPlot Style");
-      ImPlot::ShowColormapSelector("ImPlot Colormap");
-      ImGui::SliderInt("FPS target", &target_fps, 12, 60);
-      if (ImGui::IsItemHovered()) {
-        ImGui::SetTooltip("Reduces scope flickering in unfrozen mode. Can reduce impact on perfromance of the modem");
+    static bool show_imgui_demo_window = false;
+    static bool show_implot_demo_window = false;
+    ImGui::DockSpaceOverViewport();
+    if (ImGui::BeginMainMenuBar()) {
+      if (ImGui::BeginMenu("File")) {
+        if (ImGui::MenuItem("Close scope")) {
+          close_window = true;
+        }
+        ImGui::EndMenu();
       }
-      ImGui::TreePop();
+      if (ImGui::BeginMenu("Options")) {
+        ImGui::Checkbox("Show imgui demo window", &show_imgui_demo_window);
+        ImGui::Checkbox("Show implot demo window", &show_implot_demo_window);
+        ImGui::EndMenu();
+      }
+      if (ImGui::BeginMenu("Layout")) {
+        if (ImGui::MenuItem("Reset")) {
+           reset_ini_settings = true;
+        }
+        ImGui::EndMenu();
+      }
+      ImGui::EndMainMenuBar();
     }
-    iq_procedure_timer.UpdateAverage(t);
+
+    ImGui::Begin("Status bar");
     ImGui::Text("Total time used by IQ capture procedures per milisecond: %.2f [us]/[ms]", iq_procedure_timer.average / 1000);
     if (ImGui::IsItemHovered()) {
       ImGui::SetTooltip("Total time used in PHY threads for copying out IQ data for the scope, in uS, averaged over 1 ms");
     }
+    ImGui::End();
+
+    ImGui::Begin("Global scope settings");
+    ImGui::ShowStyleSelector("ImGui Style");
+    ImPlot::ShowStyleSelector("ImPlot Style");
+    ImPlot::ShowColormapSelector("ImPlot Colormap");
+    ImGui::SliderInt("FPS target", &target_fps, 12, 60);
+    if (ImGui::IsItemHovered()) {
+      ImGui::SetTooltip("Reduces scope flickering in unfrozen mode. Can reduce impact on perfromance of the modem");
+    }
+    ImGui::End();
+
+    t += ImGui::GetIO().DeltaTime;
+    iq_procedure_timer.UpdateAverage(t);
 
     if (is_ue) {
       PHY_VARS_NR_UE *ue = (PHY_VARS_NR_UE *)data_void_ptr;
@@ -708,11 +758,12 @@ void *imscope_thread(void *data_void_ptr)
       PHY_VARS_gNB *gNB = scope_params->gNB;
       ShowGnbScope(gNB, t);
     }
-    ImGui::End();
 
     // For reference
-    ImPlot::ShowDemoWindow();
-    ImGui::ShowDemoWindow();
+    if (show_implot_demo_window)
+      ImPlot::ShowDemoWindow();
+    if (show_imgui_demo_window)
+      ImGui::ShowDemoWindow();
 
     // Rendering
     ImGui::Render();
@@ -880,7 +931,8 @@ void unlockScopeData(enum scopeDataType type)
     total_size += scope_data.data_copied_per_offset[i];
   }
   if (total_size != (uint64_t)scope_data.scope_graph_data->dataSize) {
-    LOG_E(PHY, "Scope is missing data - not all data that was expected was copied - possibly missed copyDataUnsafeWithOffset call\n");
+    LOG_E(PHY,
+          "Scope is missing data - not all data that was expected was copied - possibly missed copyDataUnsafeWithOffset call\n");
   }
   scope_data.is_data_ready = true;
   scope_data.write_mutex.unlock();
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 7178faefd12f1e9266a1463ca8b92373225fa1e0..182450f0e77348436c729e88f9dc6679f7e87de3 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -50,6 +50,8 @@
 #include "common_lib.h"
 #include "fapi_nr_ue_interface.h"
 #include "assertions.h"
+#include "barrier.h"
+#include "actor.h"
 //#include "openair1/SCHED_NR_UE/defs.h"
 
 #ifdef MEX
@@ -74,16 +76,6 @@
 #define openair_free(y,x) free((y))
 #define PAGE_SIZE 4096
 
-#ifdef NR_UNIT_TEST
-  #define FILE_NAME                " "
-  #define LINE_FILE                (0)
-  #define NR_TST_PHY_PRINTF(...)   printf(__VA_ARGS__)
-#else
-  #define FILE_NAME                (__FILE__)
-  #define LINE_FILE                (__LINE__)
-  #define NR_TST_PHY_PRINTF(...)
-#endif
-
 #define PAGE_MASK 0xfffff000
 #define virt_to_phys(x) (x)
 #define openair_sched_exit() exit(-1)
@@ -91,6 +83,7 @@
 #define bzero(s,n) (memset((s),0,(n)))
 /// suppress compiler warning for unused arguments
 #define UNUSED(x) (void)x;
+#define NUM_DL_ACTORS 4
 
 #include "impl_defs_top.h"
 #include "impl_defs_nr.h"
@@ -530,7 +523,7 @@ typedef struct PHY_VARS_NR_UE_s {
   void *phy_sim_pdsch_dl_ch_estimates_ext;
   uint8_t *phy_sim_dlsch_b;
 
-  notifiedFIFO_t tx_resume_ind_fifo[NR_MAX_SLOTS_PER_FRAME];
+  dynamic_barrier_t process_slot_tx_barriers[NR_MAX_SLOTS_PER_FRAME];
 
   // Gain change required for automation RX gain change
   int adjust_rxgain;
@@ -538,6 +531,8 @@ typedef struct PHY_VARS_NR_UE_s {
   // Sidelink parameters
   sl_nr_sidelink_mode_t sl_mode;
   sl_nr_ue_phy_params_t SL_UE_PHY_PARAMS;
+  Actor_t sync_actor;
+  Actor_t dl_actors[NUM_DL_ACTORS];
 } PHY_VARS_NR_UE;
 
 typedef struct {
diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c
index 250dcc2f953ab0d9392373e75dde4186ccc69c5b..da7cc26e1adc5f5afc37836e8a163044396f0995 100644
--- a/openair1/SCHED_NR/phy_frame_config_nr.c
+++ b/openair1/SCHED_NR/phy_frame_config_nr.c
@@ -31,10 +31,19 @@
 
 #include "PHY/defs_nr_common.h"
 #include "PHY/defs_gNB.h"
-#include "PHY/defs_nr_UE.h"
 #include "SCHED_NR/phy_frame_config_nr.h"
 #include "common/utils/nr/nr_common.h"
 
+#ifdef NR_UNIT_TEST
+  #define FILE_NAME                " "
+  #define LINE_FILE                (0)
+  #define NR_TST_PHY_PRINTF(...)   printf(__VA_ARGS__)
+#else
+  #define FILE_NAME                (__FILE__)
+  #define LINE_FILE                (__LINE__)
+  #define NR_TST_PHY_PRINTF(...)
+#endif
+
 /*******************************************************************
 *
 * NAME :         set_tdd_configuration
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/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index a737b5246eacfa1229858f475a96cf57ed275190..aab41da209c0da3301254732fd006928c24e6e1d 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -75,6 +75,7 @@ fifo_dump_emos_UE emos_dump_UE;
 #include "UTIL/OPT/opt.h"
 #include "intertask_interface.h"
 #include "T.h"
+#include "instrumentation.h"
 
 static const unsigned int gain_table[31] = {100,  112,  126,  141,  158,  178,  200,  224,  251, 282,  316,
                                             359,  398,  447,  501,  562,  631,  708,  794,  891, 1000, 1122,
@@ -378,6 +379,7 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
                                  struct complex16 dl_ch_estimates[][estimateSz],
                                  c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
+  TracyCZone(ctx, true);
   int ret = 0;
   DevAssert(ue);
 
@@ -422,6 +424,7 @@ static int nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
     LOG_E(PHY, "[UE %d] frame %d, nr_slot_rx %d, Error decoding PBCH!\n", ue->Mod_id, frame_rx, nr_slot_rx);
   }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
+  TracyCZoneEnd(ctx);
   return ret;
 }
 
@@ -632,18 +635,6 @@ static int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
   return 0;
 }
 
-// This function release the Tx working thread for one pending information, like dlsch ACK/NACK
-static void send_dl_done_to_tx_thread(notifiedFIFO_t *nf, int rx_slot)
-{
-  if (nf) {
-    notifiedFIFO_elt_t *newElt = newNotifiedFIFO_elt(sizeof(int), 0, NULL, NULL);
-    // We put rx slot only for tracing purpose
-    int *msgData = (int *) NotifiedFifoData(newElt);
-    *msgData = rx_slot;
-    pushNotifiedFIFO(nf, newElt);
-  }
-}
-
 static uint32_t compute_csi_rm_unav_res(fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config)
 {
   uint32_t unav_res = 0;
@@ -737,7 +728,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     // don't wait anymore
     LOG_E(NR_PHY, "Internal error  nr_ue_dlsch_procedure() called but no active cw on slot %d, harq %d\n", nr_slot_rx, harq_pid);
     const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame;
-    send_dl_done_to_tx_thread(ue->tx_resume_ind_fifo + ack_nack_slot, proc->nr_slot_rx);
+    dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]);
     return false;
   }
 
@@ -873,7 +864,7 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
   // DLSCH decoding finished! don't wait anymore in Tx process, we know if we should answer ACK/NACK PUCCH
   if (dlsch[0].rnti_type == TYPE_C_RNTI_) {
     const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame;
-    send_dl_done_to_tx_thread(ue->tx_resume_ind_fifo + ack_nack_slot, proc->nr_slot_rx);
+    dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]);
   }
 
   if (ue->phy_sim_dlsch_b)
@@ -894,6 +885,7 @@ static bool is_ssb_index_transmitted(const PHY_VARS_NR_UE *ue, const int index)
 
 int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_data_t *phy_data)
 {
+  TracyCZone(ctx, true);
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   int gNB_id = proc->gNB_id;
@@ -1044,6 +1036,7 @@ int pbch_pdcch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_
   LOG_D(PHY, "[UE %d] Frame %d, nr_slot_rx %d: found %d DCIs\n", ue->Mod_id, frame_rx, nr_slot_rx, dci_cnt);
   phy_pdcch_config->nb_search_space = 0;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDCCH, VCD_FUNCTION_OUT);
+  TracyCZoneEnd(ctx);
   return sampleShift;
 }
 
@@ -1138,6 +1131,7 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN);
     // it returns -1 in case of internal failure, or 0 in case of normal result
     int ret_pdsch = nr_ue_pdsch_procedures(ue, proc, dlsch, llr, rxdataF, G);
+    TracyCPlot("pdsch mcs", dlsch->dlsch_config.mcs);
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT);
 
@@ -1152,9 +1146,8 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_
       nr_ue_dlsch_procedures(ue, proc, dlsch, llr, G);
     else {
       LOG_E(NR_PHY, "Demodulation impossible, internal error\n");
-      send_dl_done_to_tx_thread(
-          ue->tx_resume_ind_fifo + (proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame,
-          proc->nr_slot_rx);
+      int ack_nack_slot = (proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame;
+      dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]);
       LOG_W(NR_PHY, "nr_ue_pdsch_procedures failed in slot %d\n", proc->nr_slot_rx);
     }
 
diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h
index f2fd64252c0fa1956dabd36569972d48622643fb..3d096c33e0b9804b14405d3ff8880810111f1552 100644
--- a/openair2/COMMON/e1ap_messages_types.h
+++ b/openair2/COMMON/e1ap_messages_types.h
@@ -27,19 +27,19 @@
 #include <netinet/in.h>
 #include <netinet/sctp.h>
 #include "common/ngran_types.h"
-#include "f1ap_messages_types.h"
-#include "ngap_messages_types.h"
+#include "common/platform_types.h"
+#include "common/5g_platform_types.h"
 
+/* Definitions according to 3GPP TS 38.463 */
 #define E1AP_MAX_NUM_TRANSAC_IDS 4
 #define E1AP_MAX_NUM_PLMNS 4
 #define E1AP_MAX_NUM_SLICES 1024
 #define E1AP_MAX_NUM_CELL_GROUPS 4
-#define E1AP_MAX_NUM_QOS_FLOWS 4
-#define E1AP_MAX_NUM_NGRAN_DRB 4
+#define E1AP_MAX_NUM_QOS_FLOWS 64
 #define E1AP_MAX_NUM_PDU_SESSIONS 4
-#define E1AP_MAX_NUM_DRBS 4
-#define E1AP_MAX_NUM_DRBS 4
+#define E1AP_MAX_NUM_DRBS 32
 #define E1AP_MAX_NUM_UP_PARAM 4
+#define E1AP_SECURITY_KEY_SIZE 16 // keys have 128 bits length
 
 #define E1AP_REGISTER_REQ(mSGpTR)                         (mSGpTR)->ittiMsg.e1ap_register_req
 #define E1AP_SETUP_REQ(mSGpTR)                            (mSGpTR)->ittiMsg.e1ap_setup_req
@@ -61,6 +61,17 @@ typedef enum BEARER_CONTEXT_STATUS_e {
   BEARER_RESUME,
 } BEARER_CONTEXT_STATUS_t;
 
+typedef enum activity_notification_level_e {
+  ANL_DRB = 0,
+  ANL_PDU_SESSION,
+  ANL_UE,
+} activity_notification_level_t;
+
+typedef enum cell_group_id_e {
+  MCG = 0,
+  SCG,
+} cell_group_id_t;
+
 typedef struct PLMN_ID_s {
   int mcc;
   int mnc;
@@ -107,10 +118,6 @@ typedef struct e1ap_setup_fail_s {
   long transac_id;
 } e1ap_setup_fail_t;
 
-typedef struct cell_group_s {
-  long id;
-} cell_group_t;
-
 typedef struct up_params_s {
   in_addr_t tlAddress;
   long teId;
@@ -144,22 +151,27 @@ typedef struct drb_to_setup_s {
   in_addr_t tlAddress;
   long teId;
   int numCellGroups;
-  cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
+  cell_group_id_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
 } drb_to_setup_t;
 
 typedef struct qos_characteristics_s {
   union {
     struct {
-      long fiveqi;
-      long qos_priority_level;
+      uint16_t fiveqi;
+      uint8_t qos_priority_level;
     } non_dynamic;
     struct {
-      long fiveqi; // -1 -> optional
-      long qos_priority_level;
-      long packet_delay_budget;
+      // Range 5QI [0 - 255]
+      uint16_t fiveqi;
+      /* Range [0 - 15]
+       15 = "no priority," 1-14 = decreasing priority (1 highest), 0 = logical error if received */
+      uint8_t qos_priority_level;
+      // Range [0, 1023]: Upper bound for packet delay in 0.5ms units
+      uint16_t packet_delay_budget;
       struct {
-        long per_scalar;
-        long per_exponent;
+        // PER = Scalar x 10^-k (k: 0-9)
+        uint8_t per_scalar;
+        uint8_t per_exponent;
       } packet_error_rate;
     } dynamic;
   };
@@ -168,8 +180,10 @@ typedef struct qos_characteristics_s {
 
 typedef struct ngran_allocation_retention_priority_s {
   uint16_t priority_level;
-  long preemption_capability;
-  long preemption_vulnerability;
+  // Pre-emption capability on other QoS flows
+  uint8_t preemption_capability;
+  // Vulnerability of the QoS flow to pre-emption of other QoS flows
+  uint8_t preemption_vulnerability;
 } ngran_allocation_retention_priority_t;
 
 typedef struct qos_flow_level_qos_parameters_s {
@@ -203,13 +217,31 @@ typedef struct DRB_nGRAN_to_setup_s {
 
   /* Cell Group Information (clause 9.3.1.11) */
   int numCellGroups;
-  cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
+  cell_group_id_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
 
   /* DRB QoS Flows Parameters (clause 9.3.1.26) */
   int numQosFlow2Setup;
   qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
 } DRB_nGRAN_to_setup_t, DRB_nGRAN_to_mod_t;
 
+typedef enum e1ap_indication_e {
+  SECURITY_REQUIRED = 0,
+  SECURITY_PREFERRED,
+  SECURITY_NOT_NEEDED
+} e1ap_indication_t;
+
+typedef struct security_indication_s {
+  e1ap_indication_t integrityProtectionIndication;
+  e1ap_indication_t confidentialityProtectionIndication;
+  // Maximum Integrity Protected Data Rate
+  long maxIPrate;
+} security_indication_t;
+
+typedef struct UP_TL_information_s {
+  in_addr_t tlAddress;
+  int32_t teId;
+} UP_TL_information_t;
+
 /**
  * PDU Session Resource To Setup List (clause 9.3.3.10)
  * PDU Session Resource To Modify List (clause 9.3.3.11)
@@ -218,18 +250,12 @@ typedef struct pdu_session_to_setup_s {
   long sessionId;
   long sessionType;
   e1ap_nssai_t nssai;
-  long integrityProtectionIndication;
-  long confidentialityProtectionIndication;
-  in_addr_t tlAddress;
-  in_addr_t tlAddress_dl;
-  int32_t teId;
-  int32_t teId_dl;
-  int tl_port;
-  int tl_port_dl;
+  security_indication_t securityIndication;
+  UP_TL_information_t UP_TL_information;
   long numDRB2Setup;
-  DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB];
+  DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_DRBS];
   long numDRB2Modify;
-  DRB_nGRAN_to_mod_t DRBnGRanModList[E1AP_MAX_NUM_NGRAN_DRB];
+  DRB_nGRAN_to_mod_t DRBnGRanModList[E1AP_MAX_NUM_DRBS];
 } pdu_session_to_setup_t, pdu_session_to_mod_t;
 
 /**
@@ -239,15 +265,15 @@ typedef struct pdu_session_to_setup_s {
  */
 typedef struct e1ap_bearer_setup_req_s {
   uint32_t gNB_cu_cp_ue_id;
-  uint32_t gNB_cu_up_ue_id;
+  uint32_t gNB_cu_up_ue_id; // Bearer Context Modification Request only
   uint64_t cipheringAlgorithm;
   uint64_t integrityProtectionAlgorithm;
-  char     encryptionKey[128];
-  char     integrityProtectionKey[128];
+  char encryptionKey[E1AP_SECURITY_KEY_SIZE];
+  char integrityProtectionKey[E1AP_SECURITY_KEY_SIZE];
   long     ueDlAggMaxBitRate;
   PLMN_ID_t servingPLMNid;
   BEARER_CONTEXT_STATUS_t bearerContextStatus;
-  long activityNotificationLevel;
+  activity_notification_level_t activityNotificationLevel;
   int numPDUSessions;
   pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
   int numPDUSessionsMod;
@@ -293,16 +319,16 @@ typedef struct pdu_session_setup_s {
   in_addr_t tlAddress;
   long teId;
   int numDRBSetup;
-  DRB_nGRAN_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB];
+  DRB_nGRAN_setup_t DRBnGRanList[E1AP_MAX_NUM_DRBS];
   int numDRBFailed;
-  DRB_nGRAN_failed_t DRBnGRanFailedList[E1AP_MAX_NUM_NGRAN_DRB];
+  DRB_nGRAN_failed_t DRBnGRanFailedList[E1AP_MAX_NUM_DRBS];
 } pdu_session_setup_t;
 
 typedef struct pdu_session_modif_s {
   long id;
   // setup as part of PDU session modification not supported yet
   int numDRBModified;
-  DRB_nGRAN_modified_t DRBnGRanModList[E1AP_MAX_NUM_NGRAN_DRB];
+  DRB_nGRAN_modified_t DRBnGRanModList[E1AP_MAX_NUM_DRBS];
 } pdu_session_modif_t;
 
 typedef struct e1ap_bearer_setup_resp_s {
diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h
index cdba1c5e2de40795db098e79bbcae0738689478f..2ac5652a9f8f84b0751adb1643a6d9e665028205 100644
--- a/openair2/COMMON/ngap_messages_types.h
+++ b/openair2/COMMON/ngap_messages_types.h
@@ -29,6 +29,7 @@
 
 #ifndef NGAP_MESSAGES_TYPES_H_
 #define NGAP_MESSAGES_TYPES_H_
+#include "common/5g_platform_types.h"
 #include "common/platform_constants.h"
 #include "common/platform_types.h"
 #include "common/5g_platform_types.h"
diff --git a/openair2/E1AP/CMakeLists.txt b/openair2/E1AP/CMakeLists.txt
index c7657eed5aa115d230ebb11bcfceda451e916c3b..5849a32fe56b88a133f15268d8c938284a755821 100644
--- a/openair2/E1AP/CMakeLists.txt
+++ b/openair2/E1AP/CMakeLists.txt
@@ -1,7 +1,12 @@
 add_subdirectory(MESSAGES)
+add_subdirectory(lib)
 
 add_library(e1ap e1ap.c e1ap_common.c)
 target_link_libraries(e1ap
-                      PUBLIC asn1_e1ap f1ap
+                      PUBLIC asn1_e1ap e1ap_lib
                       PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs asn1_f1ap UTIL e1_if)
 target_include_directories(e1ap PUBLIC ${CMAKE_CURRENT_DIR})
+
+if(ENABLE_TESTS)
+  add_subdirectory(tests)
+endif()
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index 1e28ebd52a8204bbc173236e59128c11d8f3b6c5..79b326593b00271e94296a84658a14306b348ec6 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -33,6 +33,7 @@
 #include "e1ap_default_values.h"
 #include "gtp_itf.h"
 #include "openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h"
+#include "lib/e1ap_bearer_context_management.h"
 
 #define E1AP_NUM_MSG_HANDLERS 14
 typedef int (*e1ap_message_processing_t)(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p);
@@ -572,296 +573,17 @@ int e1ap_handle_RELEASE_ACKNOWLEDGE(instance_t instance, sctp_assoc_t assoc_id,
   return -1;
 }
 
-/*
-  BEARER CONTEXT SETUP REQUEST
-*/
-
-static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bearerCxt, E1AP_E1AP_PDU_t *pdu)
-{
-  pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
-  asn1cCalloc(pdu->choice.initiatingMessage, msg);
-  msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup;
-  msg->criticality   = E1AP_Criticality_reject;
-  msg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest;
-  E1AP_BearerContextSetupRequest_t *out = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
-  /* mandatory */
-  /* c1. gNB-CU-UP UE E1AP ID */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC1);
-  ieC1->id                         = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
-  ieC1->criticality                = E1AP_Criticality_reject;
-  ieC1->value.present              = E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
-  ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id;
-  /* mandatory */
-  /* c2. Security Information */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC2);
-  ieC2->id                         = E1AP_ProtocolIE_ID_id_SecurityInformation;
-  ieC2->criticality                = E1AP_Criticality_reject;
-  ieC2->value.present              = E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation;
-  ieC2->value.choice.SecurityInformation.securityAlgorithm.cipheringAlgorithm = bearerCxt->cipheringAlgorithm;
-  OCTET_STRING_fromBuf(&ieC2->value.choice.SecurityInformation.uPSecuritykey.encryptionKey,
-                       bearerCxt->encryptionKey, 16);
-
-  asn1cCallocOne(ieC2->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm, bearerCxt->integrityProtectionAlgorithm);
-  asn1cCalloc(ieC2->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey, protKey);
-  OCTET_STRING_fromBuf(protKey, bearerCxt->integrityProtectionKey, 16);
-  /* mandatory */
-  /* c3. UE DL Aggregate Maximum Bit Rate */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC3);
-  ieC3->id                         = E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate;
-  ieC3->criticality                = E1AP_Criticality_reject;
-  ieC3->value.present              = E1AP_BearerContextSetupRequestIEs__value_PR_BitRate;
-  asn_long2INTEGER(&ieC3->value.choice.BitRate, bearerCxt->ueDlAggMaxBitRate);
-  /* mandatory */
-  /* c4. Serving PLMN */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC4);
-  ieC4->id                         = E1AP_ProtocolIE_ID_id_Serving_PLMN;
-  ieC4->criticality                = E1AP_Criticality_ignore;
-  ieC4->value.present              = E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity;
-  PLMN_ID_t *servingPLMN = &bearerCxt->servingPLMNid;
-  MCC_MNC_TO_PLMNID(servingPLMN->mcc, servingPLMN->mnc, servingPLMN->mnc_digit_length, &ieC4->value.choice.PLMN_Identity);
-  /* mandatory */
-  /* Activity Notification Level */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC5);
-  ieC5->id                         = E1AP_ProtocolIE_ID_id_ActivityNotificationLevel;
-  ieC5->criticality                = E1AP_Criticality_reject;
-  ieC5->value.present              = E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel;
-  ieC5->value.choice.ActivityNotificationLevel = E1AP_ActivityNotificationLevel_pdu_session;// TODO: Remove hard coding
-  /* mandatory */
-  /*  */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC6);
-  ieC6->id            = E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest;
-  ieC6->criticality   = E1AP_Criticality_reject;
-  ieC6->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest;
-  ieC6->value.choice.System_BearerContextSetupRequest.present = E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest;
-  E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P19_t));
-  ieC6->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list;
-  asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupRequest_t, msgNGRAN);
-  msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List;
-  msgNGRAN->criticality = E1AP_Criticality_reject;
-  msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List;
-  E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
-  for (pdu_session_to_setup_t *i = bearerCxt->pduSession; i < bearerCxt->pduSession + bearerCxt->numPDUSessions; i++) {
-    asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Setup_Item_t, ieC6_1);
-    ieC6_1->pDU_Session_ID = i->sessionId;
-    ieC6_1->pDU_Session_Type = i->sessionType;
-
-    INT8_TO_OCTET_STRING(i->nssai.sst, &ieC6_1->sNSSAI.sST);
-    if (i->nssai.sd != 0xffffff) {
-      ieC6_1->sNSSAI.sD = malloc(sizeof(*ieC6_1->sNSSAI.sD));
-      AssertFatal(ieC6_1->sNSSAI.sD != NULL, "out of memory\n");
-      INT24_TO_OCTET_STRING(i->nssai.sd, ieC6_1->sNSSAI.sD);
-    }
-
-    ieC6_1->securityIndication.integrityProtectionIndication = i->integrityProtectionIndication;
-    ieC6_1->securityIndication.confidentialityProtectionIndication = i->confidentialityProtectionIndication;
-
-    ieC6_1->nG_UL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
-    asn1cCalloc(ieC6_1->nG_UL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel);
-    TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress);
-    INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID);
-
-    for (DRB_nGRAN_to_setup_t *j = i->DRBnGRanList; j < i->DRBnGRanList + i->numDRB2Setup; j++) {
-      asn1cSequenceAdd(ieC6_1->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1);
-      ieC6_1_1->dRB_ID = j->id;
-      /* SDAP config */
-      ieC6_1_1->sDAP_Configuration.defaultDRB = j->sdap_config.defaultDRB ? E1AP_DefaultDRB_true : E1AP_DefaultDRB_false;
-      ieC6_1_1->sDAP_Configuration.sDAP_Header_UL = j->sdap_config.sDAP_Header_UL;
-      ieC6_1_1->sDAP_Configuration.sDAP_Header_DL = j->sdap_config.sDAP_Header_DL;
-      /* PDCP Config */
-      ieC6_1_1->pDCP_Configuration.pDCP_SN_Size_UL = j->pdcp_config.pDCP_SN_Size_UL;
-      ieC6_1_1->pDCP_Configuration.pDCP_SN_Size_DL = j->pdcp_config.pDCP_SN_Size_DL;
-      asn1cCallocOne(ieC6_1_1->pDCP_Configuration.discardTimer, j->pdcp_config.discardTimer);
-      E1AP_T_ReorderingTimer_t *roTimer = calloc(1, sizeof(E1AP_T_ReorderingTimer_t));
-      ieC6_1_1->pDCP_Configuration.t_ReorderingTimer = roTimer;
-      roTimer->t_Reordering = j->pdcp_config.reorderingTimer;
-      ieC6_1_1->pDCP_Configuration.rLC_Mode = j->pdcp_config.rLC_Mode;
-      /* Cell Group config */
-      for (cell_group_t *k = j->cellGroupList; k < j->cellGroupList + j->numCellGroups; k++) {
-        asn1cSequenceAdd(ieC6_1_1->cell_Group_Information.list, E1AP_Cell_Group_Information_Item_t, ieC6_1_1_1);
-        ieC6_1_1_1->cell_Group_ID = k->id;
-      }
-      /* QoS Flows */
-      for (qos_flow_to_setup_t *k = j->qosFlows; k < j->qosFlows + j->numQosFlow2Setup; k++) {
-        asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1);
-        ieC6_1_1_1->qoS_Flow_Identifier = k->qfi;
-        /* QoS Characteristics */
-        qos_characteristics_t *qos_char_in = &k->qos_params.qos_characteristics;
-        if (qos_char_in->qos_type == NON_DYNAMIC) { // non Dynamic 5QI
-          ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
-          asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI, non_Dynamic_5QI);
-          non_Dynamic_5QI->fiveQI = qos_char_in->non_dynamic.fiveqi;
-        } else { // dynamic 5QI
-          ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_dynamic_5QI;
-          asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI, dynamic_5QI);
-          dynamic_5QI->qoSPriorityLevel = qos_char_in->dynamic.qos_priority_level;
-          dynamic_5QI->packetDelayBudget = qos_char_in->dynamic.packet_delay_budget;
-          dynamic_5QI->packetErrorRate.pER_Scalar = qos_char_in->dynamic.packet_error_rate.per_scalar;
-          dynamic_5QI->packetErrorRate.pER_Exponent = qos_char_in->dynamic.packet_error_rate.per_exponent;
-        }
-        /* QoS Retention Priority */
-        ngran_allocation_retention_priority_t *rent_priority_in = &k->qos_params.alloc_reten_priority;
-        ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = rent_priority_in->priority_level;
-        ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability =
-            rent_priority_in->preemption_capability;
-        ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability =
-            rent_priority_in->preemption_vulnerability;
-      }
-    }
-  }
-  return 0;
-}
-
 void e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_bearer_setup_req_t *const bearerCxt)
 {
-  E1AP_E1AP_PDU_t pdu = {0};
-  fill_BEARER_CONTEXT_SETUP_REQUEST(bearerCxt, &pdu);
-  e1ap_encode_send(CPtype, assoc_id, &pdu, 0, __func__);
-}
-
-static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *resp, E1AP_E1AP_PDU_t *pdu)
-{
-  /* Create */
-  /* 0. pdu Type */
-  pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome;
-  asn1cCalloc(pdu->choice.successfulOutcome, msg);
-  msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup;
-  msg->criticality = E1AP_Criticality_reject;
-  msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse;
-  E1AP_BearerContextSetupResponse_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse;
-  /* mandatory */
-  /* c1. gNB-CU-CP UE E1AP ID */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC1);
-  ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
-  ieC1->criticality = E1AP_Criticality_reject;
-  ieC1->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
-  ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_cp_ue_id;
-  /* mandatory */
-  /* c2. gNB-CU-UP UE E1AP ID */
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC2);
-  ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
-  ieC2->criticality = E1AP_Criticality_reject;
-  ieC2->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
-  ieC2->value.choice.GNB_CU_CP_UE_E1AP_ID = resp->gNB_cu_up_ue_id;
-
-  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC3);
-  ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse;
-  ieC3->criticality = E1AP_Criticality_reject;
-  ieC3->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse;
-  /*if (0) { // EUTRAN
-    ieC3->value.choice.System_BearerContextSetupResponse.present =
-  E1AP_System_BearerContextSetupResponse_PR_e_UTRAN_BearerContextSetupResponse;
-  E1AP_ProtocolIE_Container_4932P21_t *msgEUTRAN_list = calloc(1,
-  sizeof(E1AP_ProtocolIE_Container_4932P21_t));
-    ieC3->value.choice.System_BearerContextSetupResponse.choice.e_UTRAN_BearerContextSetupResponse
-  = (struct E1AP_ProtocolIE_Container *) msgEUTRAN_list;
-  asn1cSequenceAdd(msgEUTRAN_list->list,
-  E1AP_EUTRAN_BearerContextSetupResponse_t, msgEUTRAN); msgEUTRAN->id =
-  E1AP_ProtocolIE_ID_id_DRB_Setup_List_EUTRAN; msgEUTRAN->criticality =
-  E1AP_Criticality_reject; msgEUTRAN->value.present =
-  E1AP_EUTRAN_BearerContextSetupResponse__value_PR_DRB_Setup_List_EUTRAN;
-    E1AP_DRB_Setup_List_EUTRAN_t *drbSetup =
-  &msgEUTRAN->value.choice.DRB_Setup_List_EUTRAN;
-
-    for (drb_setup_t *i=resp->DRBList; i < resp->DRBList+resp->numDRBs; i++) {
-      asn1cSequenceAdd(drbSetup->list, E1AP_DRB_Setup_Item_EUTRAN_t, ieC3_1);
-      ieC3_1->dRB_ID = i->drbId;
-
-      ieC3_1->s1_DL_UP_TNL_Information.present =
-  E1AP_UP_TNL_Information_PR_gTPTunnel;
-      asn1cCalloc(ieC3_1->s1_DL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel);
-      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress,
-  &gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(i->teId,
-  &gTPTunnel->gTP_TEID);
-
-      for (up_params_t *j=i->UpParamList; j < i->UpParamList+i->numUpParam; j++)
-  { asn1cSequenceAdd(ieC3_1->uL_UP_Transport_Parameters.list,
-  E1AP_UP_Parameters_Item_t, ieC3_1_1); ieC3_1_1->uP_TNL_Information.present =
-  E1AP_UP_TNL_Information_PR_gTPTunnel;
-        asn1cCalloc(ieC3_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
-        TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(j->tlAddress,
-  &gTPTunnel->transportLayerAddress); INT32_TO_OCTET_STRING(j->teId,
-  &gTPTunnel->gTP_TEID);
-      }
-    }
-  } else */
-  {
-    ieC3->value.choice.System_BearerContextSetupResponse.present =
-        E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse;
-    E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P22_t));
-    ieC3->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse =
-        (struct E1AP_ProtocolIE_Container *)msgNGRAN_list;
-    asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupResponse_t, msgNGRAN);
-    msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List;
-    msgNGRAN->criticality = E1AP_Criticality_reject;
-    msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List;
-    E1AP_PDU_Session_Resource_Setup_List_t *pduSetup = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List;
-
-    for (const pdu_session_setup_t *i = resp->pduSession; i < resp->pduSession + resp->numPDUSessions; i++) {
-      asn1cSequenceAdd(pduSetup->list, E1AP_PDU_Session_Resource_Setup_Item_t, ieC3_1);
-      ieC3_1->pDU_Session_ID = i->id;
-
-      ieC3_1->nG_DL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
-      asn1cCalloc(ieC3_1->nG_DL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel);
-      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(i->tlAddress, &gTPTunnel->transportLayerAddress);
-      INT32_TO_OCTET_STRING(i->teId, &gTPTunnel->gTP_TEID);
-
-      for (const DRB_nGRAN_setup_t *j = i->DRBnGRanList; j < i->DRBnGRanList + i->numDRBSetup; j++) {
-        asn1cSequenceAdd(ieC3_1->dRB_Setup_List_NG_RAN.list, E1AP_DRB_Setup_Item_NG_RAN_t, ieC3_1_1);
-        ieC3_1_1->dRB_ID = j->id;
-
-        for (const up_params_t *k = j->UpParamList; k < j->UpParamList + j->numUpParam; k++) {
-          asn1cSequenceAdd(ieC3_1_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1_1);
-          ieC3_1_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
-          asn1cCalloc(ieC3_1_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
-          TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tlAddress, &gTPTunnel->transportLayerAddress);
-          INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID);
-        }
-
-        for (const qos_flow_setup_t *k = j->qosFlows; k < j->qosFlows + j->numQosFlowSetup; k++) {
-          asn1cSequenceAdd(ieC3_1_1->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, ieC3_1_1_1);
-          ieC3_1_1_1->qoS_Flow_Identifier = k->qfi;
-        }
-      }
-
-      if (i->numDRBFailed > 0)
-        ieC3_1->dRB_Failed_List_NG_RAN = calloc(1, sizeof(E1AP_DRB_Failed_List_NG_RAN_t));
-
-      for (const DRB_nGRAN_failed_t *j = i->DRBnGRanFailedList; j < i->DRBnGRanFailedList + i->numDRBFailed; j++) {
-        asn1cSequenceAdd(ieC3_1->dRB_Failed_List_NG_RAN->list, E1AP_DRB_Failed_Item_NG_RAN_t, ieC3_1_1);
-        ieC3_1_1->dRB_ID = j->id;
-
-        ieC3_1_1->cause.present = j->cause_type;
-        switch (ieC3_1_1->cause.present) {
-          case E1AP_Cause_PR_radioNetwork:
-            ieC3_1_1->cause.choice.radioNetwork = j->cause;
-            break;
-
-          case E1AP_Cause_PR_transport:
-            ieC3_1_1->cause.choice.transport = j->cause;
-            break;
-
-          case E1AP_Cause_PR_protocol:
-            ieC3_1_1->cause.choice.protocol = j->cause;
-            break;
-
-          case E1AP_Cause_PR_misc:
-            ieC3_1_1->cause.choice.misc = j->cause;
-            break;
-
-          default:
-            LOG_E(E1AP, "DRB setup failure cause out of expected range\n");
-            break;
-        }
-      }
-    }
-  }
+  E1AP_E1AP_PDU_t *pdu = encode_E1_bearer_context_setup_request(bearerCxt);
+  e1ap_encode_send(CPtype, assoc_id, pdu, 0, __func__);
 }
 
 void e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, const e1ap_bearer_setup_resp_t *resp)
 {
-  E1AP_E1AP_PDU_t pdu = {0};
-  fill_BEARER_CONTEXT_SETUP_RESPONSE(resp, &pdu);
-  e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__);
+  // Encode
+  E1AP_E1AP_PDU_t *pdu = encode_E1_bearer_context_setup_response(resp);
+  e1ap_encode_send(UPtype, assoc_id, pdu, 0, __func__);
 }
 
 int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance)
@@ -870,287 +592,27 @@ int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance)
   return -1;
 }
 
-static void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *bearerCxt)
-{
-  const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
-  E1AP_BearerContextSetupRequestIEs_t *ie;
-
-  LOG_D(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
-
-  for (int i = 0; i < in->protocolIEs.list.count; i++) {
-    ie = in->protocolIEs.list.array[i];
-
-    switch(ie->id) {
-      case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
-        bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
-        break;
-
-      case E1AP_ProtocolIE_ID_id_SecurityInformation:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation);
-        bearerCxt->cipheringAlgorithm = ie->value.choice.SecurityInformation.securityAlgorithm.cipheringAlgorithm;
-        memcpy(bearerCxt->encryptionKey,
-               ie->value.choice.SecurityInformation.uPSecuritykey.encryptionKey.buf,
-               ie->value.choice.SecurityInformation.uPSecuritykey.encryptionKey.size);
-        if (ie->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm) {
-          bearerCxt->integrityProtectionAlgorithm = *ie->value.choice.SecurityInformation.securityAlgorithm.integrityProtectionAlgorithm;
-        }
-        if (ie->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey) {
-          memcpy(bearerCxt->integrityProtectionKey,
-                 ie->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey->buf,
-                 ie->value.choice.SecurityInformation.uPSecuritykey.integrityProtectionKey->size);
-        }
-        break;
-
-      case E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_BitRate);
-        asn_INTEGER2long(&ie->value.choice.BitRate, &bearerCxt->ueDlAggMaxBitRate);
-        break;
-
-      case E1AP_ProtocolIE_ID_id_Serving_PLMN:
-        DevAssert(ie->criticality == E1AP_Criticality_ignore);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity);
-        PLMNID_TO_MCC_MNC(&ie->value.choice.PLMN_Identity,
-                          bearerCxt->servingPLMNid.mcc,
-                          bearerCxt->servingPLMNid.mnc,
-                          bearerCxt->servingPLMNid.mnc_digit_length);
-        break;
-
-      case E1AP_ProtocolIE_ID_id_ActivityNotificationLevel:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel);
-        bearerCxt->activityNotificationLevel = ie->value.choice.ActivityNotificationLevel;
-        break;
-
-      case E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest);
-        DevAssert(ie->value.choice.System_BearerContextSetupRequest.present ==
-                    E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest);
-        DevAssert(ie->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest);
-        E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P19_t *) ie->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest;
-        E1AP_NG_RAN_BearerContextSetupRequest_t *msgNGRAN = msgNGRAN_list->list.array[0];
-        DevAssert(msgNGRAN_list->list.count == 1);
-        DevAssert(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List);
-        DevAssert(msgNGRAN->value.present == E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List);
-
-        E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2SetupList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
-        bearerCxt->numPDUSessions = pdu2SetupList->list.count;
-        for (int i = 0; i < pdu2SetupList->list.count; i++) {
-          pdu_session_to_setup_t *pdu_session = bearerCxt->pduSession + i;
-          E1AP_PDU_Session_Resource_To_Setup_Item_t *pdu2Setup = pdu2SetupList->list.array[i];
-
-          pdu_session->sessionId = pdu2Setup->pDU_Session_ID;
-          pdu_session->sessionType = pdu2Setup->pDU_Session_Type;
-
-          OCTET_STRING_TO_INT8(&pdu2Setup->sNSSAI.sST, pdu_session->nssai.sst);
-          pdu_session->nssai.sd = 0xffffff;
-          if (pdu2Setup->sNSSAI.sD != NULL)
-            OCTET_STRING_TO_INT24(pdu2Setup->sNSSAI.sD, pdu_session->nssai.sd);
-
-          pdu_session->integrityProtectionIndication = pdu2Setup->securityIndication.integrityProtectionIndication;
-          pdu_session->confidentialityProtectionIndication = pdu2Setup->securityIndication.confidentialityProtectionIndication;
-
-          if (pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel) { // Optional IE
-            DevAssert(pdu2Setup->nG_UL_UP_TNL_Information.present ==
-                      E1AP_UP_TNL_Information_PR_gTPTunnel);
-            BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel->transportLayerAddress,
-                                                       pdu_session->tlAddress);
-            OCTET_STRING_TO_INT32(&pdu2Setup->nG_UL_UP_TNL_Information.choice.gTPTunnel->gTP_TEID, pdu_session->teId);
-          }
-
-          E1AP_DRB_To_Setup_List_NG_RAN_t *drb2SetupList = &pdu2Setup->dRB_To_Setup_List_NG_RAN;
-          pdu_session->numDRB2Setup = drb2SetupList->list.count;
-          for (int j = 0; j < drb2SetupList->list.count; j++) {
-            DRB_nGRAN_to_setup_t *drb = pdu_session->DRBnGRanList + j;
-            E1AP_DRB_To_Setup_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j];
-
-            drb->id = drb2Setup->dRB_ID;
-            /* SDAP */
-            drb->sdap_config.defaultDRB = drb2Setup->sDAP_Configuration.defaultDRB == E1AP_DefaultDRB_true;
-            drb->sdap_config.sDAP_Header_UL = drb2Setup->sDAP_Configuration.sDAP_Header_UL;
-            drb->sdap_config.sDAP_Header_DL = drb2Setup->sDAP_Configuration.sDAP_Header_DL;
-            /* PDCP */
-            drb->pdcp_config.pDCP_SN_Size_UL = drb2Setup->pDCP_Configuration.pDCP_SN_Size_UL;
-            drb->pdcp_config.pDCP_SN_Size_DL = drb2Setup->pDCP_Configuration.pDCP_SN_Size_DL;
-            if (drb2Setup->pDCP_Configuration.discardTimer) {
-              drb->pdcp_config.discardTimer = *drb2Setup->pDCP_Configuration.discardTimer;
-            }
-            if (drb2Setup->pDCP_Configuration.t_ReorderingTimer) {
-              drb->pdcp_config.reorderingTimer = drb2Setup->pDCP_Configuration.t_ReorderingTimer->t_Reordering;
-            }
-            drb->pdcp_config.rLC_Mode = drb2Setup->pDCP_Configuration.rLC_Mode;
-
-            E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information;
-            drb->numCellGroups = cellGroupList->list.count;
-            for (int k = 0; k < cellGroupList->list.count; k++) {
-              E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k];
-
-              drb->cellGroupList[k].id = cg2Setup->cell_Group_ID;
-            }
-
-            E1AP_QoS_Flow_QoS_Parameter_List_t *qos2SetupList = &drb2Setup->qos_flow_Information_To_Be_Setup;
-            drb->numQosFlow2Setup = qos2SetupList->list.count;
-            for (int k = 0; k < qos2SetupList->list.count; k++) {
-              qos_flow_to_setup_t *qos_flow = drb->qosFlows + k;
-              E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k];
-
-              qos_flow->qfi = qos2Setup->qoS_Flow_Identifier;
-
-              qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
-              if (qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.present == E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
-                qos_char->qos_type = NON_DYNAMIC;
-                qos_char->non_dynamic.fiveqi =
-                    qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI;
-              } else {
-                E1AP_Dynamic5QIDescriptor_t *dynamic5QI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI;
-                qos_char->qos_type = DYNAMIC;
-                qos_char->dynamic.qos_priority_level = dynamic5QI->qoSPriorityLevel;
-                qos_char->dynamic.packet_delay_budget = dynamic5QI->packetDelayBudget;
-                qos_char->dynamic.packet_error_rate.per_scalar = dynamic5QI->packetErrorRate.pER_Scalar;
-                qos_char->dynamic.packet_error_rate.per_exponent = dynamic5QI->packetErrorRate.pER_Exponent;
-              }
-
-              ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority;
-              rent_priority->priority_level = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel;
-              rent_priority->preemption_capability =
-                  qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability;
-              rent_priority->preemption_vulnerability =
-                  qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability;
-            }
-          }
-        }
-        break;
-
-      default:
-        LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
-        break;
-    }
-  }
-}
-
 int e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *e1_inst, const E1AP_E1AP_PDU_t *pdu)
 {
-  DevAssert(pdu != NULL);
-  DevAssert(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage);
-  DevAssert(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextSetup);
-  DevAssert(pdu->choice.initiatingMessage->criticality == E1AP_Criticality_reject);
-  DevAssert(pdu->choice.initiatingMessage->value.present == E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest);
-
+  // Decode E1AP message
   e1ap_bearer_setup_req_t bearerCxt = {0};
-  extract_BEARER_CONTEXT_SETUP_REQUEST(pdu, &bearerCxt);
-
+  if (!decode_E1_bearer_context_setup_request(pdu, &bearerCxt)) {
+    LOG_E(E1AP, "Failed to decode E1 Bearer Context Setup Request\n");
+    return -1;
+  }
   e1_bearer_context_setup(&bearerCxt);
   return 0;
 }
 
-void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_resp_t *bearerCxt)
-{
-  const E1AP_BearerContextSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse;
-  E1AP_BearerContextSetupResponseIEs_t *ie;
-
-  LOG_D(E1AP, "Bearer context setup response number of IEs %d\n", in->protocolIEs.list.count);
-
-  for (int i = 0; i < in->protocolIEs.list.count; i++) {
-    ie = in->protocolIEs.list.array[i];
-
-    switch(ie->id) {
-      case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
-        bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
-        break;
-
-      case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
-        bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
-        break;
-
-      case E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse:
-        DevAssert(ie->criticality == E1AP_Criticality_reject);
-        DevAssert(ie->value.present == E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse);
-        DevAssert(ie->value.choice.System_BearerContextSetupResponse.present
-                  == E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse);
-        E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list =
-            (E1AP_ProtocolIE_Container_4932P22_t *)
-                ie->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse;
-        DevAssert(msgNGRAN_list->list.count == 1);
-        E1AP_NG_RAN_BearerContextSetupResponse_t *msgNGRAN = msgNGRAN_list->list.array[0];
-        DevAssert(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List);
-        DevAssert(msgNGRAN->criticality == E1AP_Criticality_reject);
-        DevAssert(msgNGRAN->value.present == E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List);
-        E1AP_PDU_Session_Resource_Setup_List_t *pduSetupList = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List;
-        bearerCxt->numPDUSessions = pduSetupList->list.count;
-
-        for (int i = 0; i < pduSetupList->list.count; i++) {
-          pdu_session_setup_t *pduSetup = bearerCxt->pduSession + i;
-          E1AP_PDU_Session_Resource_Setup_Item_t *pdu_session = pduSetupList->list.array[i];
-          pduSetup->id = pdu_session->pDU_Session_ID;
-
-          if (pdu_session->nG_DL_UP_TNL_Information.choice.gTPTunnel) {
-            DevAssert(pdu_session->nG_DL_UP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel);
-            BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(
-                &pdu_session->nG_DL_UP_TNL_Information.choice.gTPTunnel->transportLayerAddress,
-                pduSetup->tlAddress);
-            OCTET_STRING_TO_INT32(&pdu_session->nG_DL_UP_TNL_Information.choice.gTPTunnel->gTP_TEID, pduSetup->teId);
-          }
-
-          pduSetup->numDRBSetup = pdu_session->dRB_Setup_List_NG_RAN.list.count;
-          for (int j = 0; j < pdu_session->dRB_Setup_List_NG_RAN.list.count; j++) {
-            DRB_nGRAN_setup_t *drbSetup = pduSetup->DRBnGRanList + j;
-            E1AP_DRB_Setup_Item_NG_RAN_t *drb = pdu_session->dRB_Setup_List_NG_RAN.list.array[j];
-
-            drbSetup->id = drb->dRB_ID;
-
-            drbSetup->numUpParam = drb->uL_UP_Transport_Parameters.list.count;
-            for (int k = 0; k < drb->uL_UP_Transport_Parameters.list.count; k++) {
-              up_params_t *UL_UP_param = drbSetup->UpParamList + k;
-              E1AP_UP_Parameters_Item_t *in_UL_UP_param = drb->uL_UP_Transport_Parameters.list.array[k];
-
-              DevAssert(in_UL_UP_param->uP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel);
-              E1AP_GTPTunnel_t *gTPTunnel = in_UL_UP_param->uP_TNL_Information.choice.gTPTunnel;
-              if (gTPTunnel) {
-                BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gTPTunnel->transportLayerAddress, UL_UP_param->tlAddress);
-                OCTET_STRING_TO_INT32(&gTPTunnel->gTP_TEID, UL_UP_param->teId);
-              } else {
-                AssertFatal(false, "gTPTunnel information in required\n");
-              }
-            }
-
-            // Qos Flow Information
-            drbSetup->numQosFlowSetup = drb->flow_Setup_List.list.count;
-            for (int q = 0; q < drb->flow_Setup_List.list.count; q++) {
-              qos_flow_setup_t *qosflowSetup = &drbSetup->qosFlows[q];
-              E1AP_QoS_Flow_Item_t *in_qosflowSetup = drb->flow_Setup_List.list.array[q];
-              qosflowSetup->qfi = in_qosflowSetup->qoS_Flow_Identifier;
-            }
-          }
-        }
-        break;
-
-      // TODO: remaining IE handlers
-
-      default:
-        LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
-        break;
-    }
-  }
-}
-
 int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *pdu)
 {
-  DevAssert(pdu->present == E1AP_E1AP_PDU_PR_successfulOutcome);
-  DevAssert(pdu->choice.successfulOutcome->procedureCode == E1AP_ProcedureCode_id_bearerContextSetup);
-  DevAssert(pdu->choice.successfulOutcome->criticality == E1AP_Criticality_reject);
-  DevAssert(pdu->choice.successfulOutcome->value.present == E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse);
-
   MessageDef *msg = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_RESP);
+  // Decode
   e1ap_bearer_setup_resp_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_RESP(msg);
-  extract_BEARER_CONTEXT_SETUP_RESPONSE(pdu, bearerCxt);
+  if (!decode_E1_bearer_context_setup_response(pdu, bearerCxt)) {
+    LOG_E(E1AP, "Failed to decode Bearer Context Setup Response\n");
+    return -1;
+  }
   msg->ittiMsgHeader.originInstance = assoc_id;
   // Fixme: instance is the NGAP instance, no good way to set it here
   instance_t instance = 0;
@@ -1976,6 +1438,7 @@ void *E1AP_CUCP_task(void *arg)
 
       case E1AP_BEARER_CONTEXT_SETUP_REQ:
         e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(assoc_id, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
+        free_e1ap_context_setup_request(&E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
         break;
 
       case E1AP_BEARER_CONTEXT_MODIFICATION_REQ:
@@ -2042,6 +1505,7 @@ void *E1AP_CUUP_task(void *arg)
         const e1ap_upcp_inst_t *inst = getCxtE1(myInstance);
         AssertFatal(inst, "no E1 instance found for instance %ld\n", myInstance);
         e1apCUUP_send_BEARER_CONTEXT_SETUP_RESPONSE(inst->cuup.assoc_id, resp);
+        free_e1ap_context_setup_response(resp);
       } break;
 
       case E1AP_BEARER_CONTEXT_MODIFICATION_RESP: {
diff --git a/openair2/E1AP/lib/CMakeLists.txt b/openair2/E1AP/lib/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6e766581fa8d01e8f8478d5eb4198262a5638650
--- /dev/null
+++ b/openair2/E1AP/lib/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_library(e1ap_lib OBJECT
+            e1ap_bearer_context_management.c
+)
+
+target_link_libraries(e1ap_lib PRIVATE asn1_e1ap)
+target_include_directories(e1ap_lib PUBLIC
+                           ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
diff --git a/openair2/E1AP/lib/e1ap_bearer_context_management.c b/openair2/E1AP/lib/e1ap_bearer_context_management.c
new file mode 100644
index 0000000000000000000000000000000000000000..5e359512ed3ba5e7e1087b1040a5ff0e9db7646a
--- /dev/null
+++ b/openair2/E1AP/lib/e1ap_bearer_context_management.c
@@ -0,0 +1,971 @@
+/*
+ * 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 e1ap_bearer_context_management.c
+ * \brief E1AP library for E1 Bearer Context Management
+ * \author Guido Casati
+ * \date 2024
+ * \version 0.1
+ */
+
+#include <string.h>
+
+#include "common/utils/assertions.h"
+#include "openair3/UTILS/conversions.h"
+#include "common/utils/oai_asn1.h"
+#include "common/utils/utils.h"
+
+#include "e1ap_lib_common.h"
+#include "e1ap_bearer_context_management.h"
+#include "e1ap_lib_includes.h"
+
+/* ====================================
+ *   E1AP Bearer Context Setup Request
+ * ==================================== */
+
+/**
+ * @brief Equality check for bearer_context_pdcp_config_t
+ */
+static bool eq_pdcp_config(const bearer_context_pdcp_config_t *a, const bearer_context_pdcp_config_t *b)
+{
+  _E1_EQ_CHECK_LONG(a->pDCP_SN_Size_UL, b->pDCP_SN_Size_UL);
+  _E1_EQ_CHECK_LONG(a->pDCP_SN_Size_DL, b->pDCP_SN_Size_DL);
+  _E1_EQ_CHECK_LONG(a->rLC_Mode, b->rLC_Mode);
+  _E1_EQ_CHECK_LONG(a->reorderingTimer, b->reorderingTimer);
+  _E1_EQ_CHECK_LONG(a->discardTimer, b->discardTimer);
+  _E1_EQ_CHECK_INT(a->pDCP_Reestablishment, b->pDCP_Reestablishment);
+  return true;
+}
+
+/**
+ * @brief Equality check for bearer_context_sdap_config_t
+ */
+static bool eq_sdap_config(const bearer_context_sdap_config_t *a, const bearer_context_sdap_config_t *b)
+{
+  _E1_EQ_CHECK_LONG(a->defaultDRB, b->defaultDRB);
+  _E1_EQ_CHECK_LONG(a->sDAP_Header_UL, b->sDAP_Header_UL);
+  _E1_EQ_CHECK_LONG(a->sDAP_Header_DL, b->sDAP_Header_DL);
+  return true;
+}
+
+/**
+ * @brief Equality check for qos_flow_to_setup_t
+ */
+static bool eq_qos_flow(const qos_flow_to_setup_t *a, const qos_flow_to_setup_t *b)
+{
+  _E1_EQ_CHECK_LONG(a->qfi, b->qfi);
+  const ngran_allocation_retention_priority_t *arp_a = &a->qos_params.alloc_reten_priority;
+  const ngran_allocation_retention_priority_t *arp_b = &b->qos_params.alloc_reten_priority;
+  _E1_EQ_CHECK_INT(arp_a->preemption_capability, arp_b->preemption_capability);
+  _E1_EQ_CHECK_INT(arp_a->preemption_vulnerability, arp_b->preemption_vulnerability);
+  _E1_EQ_CHECK_INT(arp_a->priority_level, arp_b->priority_level);
+  const qos_characteristics_t *qos_a = &a->qos_params.qos_characteristics;
+  const qos_characteristics_t *qos_b = &b->qos_params.qos_characteristics;
+  _E1_EQ_CHECK_INT(qos_a->qos_type, qos_b->qos_type);
+  _E1_EQ_CHECK_INT(qos_a->dynamic.fiveqi, qos_b->dynamic.fiveqi);
+  _E1_EQ_CHECK_INT(qos_a->dynamic.packet_delay_budget, qos_b->dynamic.packet_delay_budget);
+  _E1_EQ_CHECK_INT(qos_a->dynamic.packet_error_rate.per_exponent, qos_b->dynamic.packet_error_rate.per_exponent);
+  _E1_EQ_CHECK_INT(qos_a->dynamic.packet_error_rate.per_scalar, qos_b->dynamic.packet_error_rate.per_scalar);
+  _E1_EQ_CHECK_INT(qos_a->dynamic.qos_priority_level, qos_b->dynamic.qos_priority_level);
+  _E1_EQ_CHECK_INT(qos_a->non_dynamic.fiveqi, qos_b->non_dynamic.fiveqi);
+  _E1_EQ_CHECK_INT(qos_a->non_dynamic.qos_priority_level, qos_b->non_dynamic.qos_priority_level);
+  return true;
+}
+
+/**
+ * @brief Equality check for DRB_nGRAN_to_setup_t
+ */
+static bool eq_drb_to_setup(const DRB_nGRAN_to_setup_t *a, const DRB_nGRAN_to_setup_t *b)
+{
+  bool result = true;
+  _E1_EQ_CHECK_LONG(a->id, b->id);
+  _E1_EQ_CHECK_INT(a->numCellGroups, b->numCellGroups);
+  for (int i = 0; i < a->numCellGroups; i++) {
+    _E1_EQ_CHECK_INT(a->cellGroupList[i], b->cellGroupList[i]);
+  }
+  _E1_EQ_CHECK_INT(a->numQosFlow2Setup, b->numQosFlow2Setup);
+  for (int i = 0; i < a->numQosFlow2Setup; i++) {
+    result &= eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]);
+  }
+  result &= eq_pdcp_config(&a->pdcp_config, &b->pdcp_config);
+  result &= eq_sdap_config(&a->sdap_config, &b->sdap_config);
+  return result;
+}
+
+/**
+ * @brief Equality check for DRB_nGRAN_to_mod_t
+ */
+static bool eq_drb_to_mod(const DRB_nGRAN_to_mod_t *a, const DRB_nGRAN_to_mod_t *b)
+{
+  bool result = true;
+  _E1_EQ_CHECK_LONG(a->id, b->id);
+  _E1_EQ_CHECK_INT(a->numCellGroups, b->numCellGroups);
+  for (int i = 0; i < a->numCellGroups; i++) {
+    _E1_EQ_CHECK_INT(a->cellGroupList[i], b->cellGroupList[i]);
+  }
+  _E1_EQ_CHECK_INT(a->numQosFlow2Setup, b->numQosFlow2Setup);
+  for (int i = 0; i < a->numQosFlow2Setup; i++) {
+    result &= eq_qos_flow(&a->qosFlows[i], &b->qosFlows[i]);
+  }
+  _E1_EQ_CHECK_INT(a->tlAddress, b->tlAddress);
+  _E1_EQ_CHECK_INT(a->teId, b->teId);
+  _E1_EQ_CHECK_INT(a->numDlUpParam, b->numDlUpParam);
+  for (int i = 0; i < a->numDlUpParam; i++) {
+    _E1_EQ_CHECK_INT(a->DlUpParamList[i].cell_group_id, b->DlUpParamList[i].cell_group_id);
+    _E1_EQ_CHECK_LONG(a->DlUpParamList[i].teId, b->DlUpParamList[i].teId);
+    _E1_EQ_CHECK_INT(a->DlUpParamList[i].tlAddress, b->DlUpParamList[i].tlAddress);
+  }
+  result &= eq_pdcp_config(&a->pdcp_config, &b->pdcp_config);
+  result &= eq_sdap_config(&a->sdap_config, &b->sdap_config);
+  return result;
+}
+
+/* PDU Session To Setup Item */
+
+static bool e1_encode_pdu_session_to_setup_item(E1AP_PDU_Session_Resource_To_Setup_Item_t *item, const pdu_session_to_setup_t *in)
+{
+  item->pDU_Session_ID = in->sessionId;
+  item->pDU_Session_Type = in->sessionType;
+  // SNSSAI
+  INT8_TO_OCTET_STRING(in->nssai.sst, &item->sNSSAI.sST);
+  if (in->nssai.sd != 0xffffff) {
+    item->sNSSAI.sD = malloc_or_fail(sizeof(*item->sNSSAI.sD));
+    INT24_TO_OCTET_STRING(in->nssai.sd, item->sNSSAI.sD);
+  }
+  // Security Indication
+  E1AP_SecurityIndication_t *siOut = &item->securityIndication;
+  const security_indication_t *siIn = &in->securityIndication;
+  siOut->integrityProtectionIndication = siIn->integrityProtectionIndication;
+  siOut->confidentialityProtectionIndication = siIn->confidentialityProtectionIndication;
+  if (siIn->integrityProtectionIndication != SECURITY_NOT_NEEDED) {
+    asn1cCalloc(siOut->maximumIPdatarate, ipDataRate);
+    ipDataRate->maxIPrate = siIn->maxIPrate;
+  }
+  // TNL Information
+  item->nG_UL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
+  asn1cCalloc(item->nG_UL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel);
+  const UP_TL_information_t *UP_TL_information = &in->UP_TL_information;
+  TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(UP_TL_information->tlAddress, &gTPTunnel->transportLayerAddress);
+  INT32_TO_OCTET_STRING(UP_TL_information->teId, &gTPTunnel->gTP_TEID);
+  // DRB to setup
+  for (const DRB_nGRAN_to_setup_t *j = in->DRBnGRanList; j < in->DRBnGRanList + in->numDRB2Setup; j++) {
+    asn1cSequenceAdd(item->dRB_To_Setup_List_NG_RAN.list, E1AP_DRB_To_Setup_Item_NG_RAN_t, ieC6_1_1);
+    ieC6_1_1->dRB_ID = j->id;
+    // SDAP Config
+    E1AP_SDAP_Configuration_t *sdap = &ieC6_1_1->sDAP_Configuration;
+    sdap->defaultDRB = j->sdap_config.defaultDRB ? E1AP_DefaultDRB_true : E1AP_DefaultDRB_false;
+    sdap->sDAP_Header_UL = j->sdap_config.sDAP_Header_UL;
+    sdap->sDAP_Header_DL = j->sdap_config.sDAP_Header_DL;
+    // PDCP Config
+    E1AP_PDCP_Configuration_t *pdcp = &ieC6_1_1->pDCP_Configuration;
+    pdcp->pDCP_SN_Size_UL = j->pdcp_config.pDCP_SN_Size_UL;
+    pdcp->pDCP_SN_Size_DL = j->pdcp_config.pDCP_SN_Size_DL;
+    asn1cCallocOne(pdcp->discardTimer, j->pdcp_config.discardTimer);
+    E1AP_T_ReorderingTimer_t *roTimer = calloc_or_fail(1, sizeof(*roTimer));
+    pdcp->t_ReorderingTimer = roTimer;
+    roTimer->t_Reordering = j->pdcp_config.reorderingTimer;
+    pdcp->rLC_Mode = j->pdcp_config.rLC_Mode;
+    // Cell Group
+    for (const cell_group_id_t *k = j->cellGroupList; k < j->cellGroupList + j->numCellGroups; k++) {
+      asn1cSequenceAdd(ieC6_1_1->cell_Group_Information.list, E1AP_Cell_Group_Information_Item_t, ieC6_1_1_1);
+      ieC6_1_1_1->cell_Group_ID = *k;
+    }
+    // QoS Flows
+    for (const qos_flow_to_setup_t *k = j->qosFlows; k < j->qosFlows + j->numQosFlow2Setup; k++) {
+      asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1);
+      ieC6_1_1_1->qoS_Flow_Identifier = k->qfi;
+      // QoS Characteristics
+      const qos_characteristics_t *qos_char_in = &k->qos_params.qos_characteristics;
+      if (qos_char_in->qos_type == NON_DYNAMIC) { // non Dynamic 5QI
+        ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
+        asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI, non_Dynamic_5QI);
+        non_Dynamic_5QI->fiveQI = qos_char_in->non_dynamic.fiveqi;
+      } else { // dynamic 5QI
+        ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_dynamic_5QI;
+        asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI, dynamic_5QI);
+        dynamic_5QI->qoSPriorityLevel = qos_char_in->dynamic.qos_priority_level;
+        dynamic_5QI->packetDelayBudget = qos_char_in->dynamic.packet_delay_budget;
+        dynamic_5QI->packetErrorRate.pER_Scalar = qos_char_in->dynamic.packet_error_rate.per_scalar;
+        dynamic_5QI->packetErrorRate.pER_Exponent = qos_char_in->dynamic.packet_error_rate.per_exponent;
+      }
+      // QoS Retention Priority
+      const ngran_allocation_retention_priority_t *rent_priority_in = &k->qos_params.alloc_reten_priority;
+      E1AP_NGRANAllocationAndRetentionPriority_t *arp = &ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority;
+      arp->priorityLevel = rent_priority_in->priority_level;
+      arp->pre_emptionCapability = rent_priority_in->preemption_capability;
+      arp->pre_emptionVulnerability = rent_priority_in->preemption_vulnerability;
+    }
+  }
+  return true;
+}
+
+static bool e1_decode_pdu_session_to_setup_item(pdu_session_to_setup_t *out, E1AP_PDU_Session_Resource_To_Setup_Item_t *item)
+{
+  // PDU Session ID (M)
+  out->sessionId = item->pDU_Session_ID;
+  // PDU Session Type (M)
+  out->sessionType = item->pDU_Session_Type;
+  /* S-NSSAI (M) */
+  // SST (M)
+  OCTET_STRING_TO_INT8(&item->sNSSAI.sST, out->nssai.sst);
+  out->nssai.sd = 0xffffff;
+  // SD (O)
+  if (item->sNSSAI.sD != NULL)
+    OCTET_STRING_TO_INT24(item->sNSSAI.sD, out->nssai.sd);
+  /* Security Indication (M) */
+  E1AP_SecurityIndication_t *securityIndication = &item->securityIndication;
+  // Integrity Protection Indication (M)
+  security_indication_t *sec = &out->securityIndication;
+  sec->integrityProtectionIndication = securityIndication->integrityProtectionIndication;
+  // Confidentiality Protection Indication (M)
+  sec->confidentialityProtectionIndication = securityIndication->confidentialityProtectionIndication;
+  // Maximum Integrity Protected Data Rate (Conditional)
+  if (sec->integrityProtectionIndication != SECURITY_NOT_NEEDED) {
+    if (securityIndication->maximumIPdatarate)
+      sec->maxIPrate = securityIndication->maximumIPdatarate->maxIPrate;
+    else {
+      PRINT_ERROR("Received integrityProtectionIndication but maximumIPdatarate IE is missing\n");
+      return false;
+    }
+  }
+  /* NG UL UP Transport Layer Information (M) (9.3.2.1 of 3GPP TS 38.463) */
+  // GTP Tunnel
+  struct E1AP_GTPTunnel *gTPTunnel = item->nG_UL_UP_TNL_Information.choice.gTPTunnel;
+  if (!gTPTunnel) {
+    PRINT_ERROR("Missing mandatory IE item->nG_UL_UP_TNL_Information.choice.gTPTunnel\n");
+    return false;
+  }
+  _E1_EQ_CHECK_INT(item->nG_UL_UP_TNL_Information.present, E1AP_UP_TNL_Information_PR_gTPTunnel);
+  // Transport Layer Address
+  UP_TL_information_t *UP_TL_information = &out->UP_TL_information;
+  BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gTPTunnel->transportLayerAddress, UP_TL_information->tlAddress);
+  // GTP-TEID
+  OCTET_STRING_TO_INT32(&gTPTunnel->gTP_TEID, UP_TL_information->teId);
+  // DRB To Setup List ( > 1 item )
+  E1AP_DRB_To_Setup_List_NG_RAN_t *drb2SetupList = &item->dRB_To_Setup_List_NG_RAN;
+  _E1_EQ_CHECK_GENERIC(drb2SetupList->list.count > 0, "%d", drb2SetupList->list.count, 0);
+  out->numDRB2Setup = drb2SetupList->list.count;
+  _E1_EQ_CHECK_INT(out->numDRB2Setup, 1); // can only handle one DRB per PDU session
+  for (int j = 0; j < drb2SetupList->list.count; j++) {
+    DRB_nGRAN_to_setup_t *drb = out->DRBnGRanList + j;
+    E1AP_DRB_To_Setup_Item_NG_RAN_t *drb2Setup = drb2SetupList->list.array[j];
+    // DRB ID (M)
+    drb->id = drb2Setup->dRB_ID;
+    // >SDAP Configuration (M)
+    E1AP_SDAP_Configuration_t *sdap = &drb2Setup->sDAP_Configuration;
+    drb->sdap_config.defaultDRB = sdap->defaultDRB == E1AP_DefaultDRB_true;
+    drb->sdap_config.sDAP_Header_UL = sdap->sDAP_Header_UL;
+    drb->sdap_config.sDAP_Header_DL = sdap->sDAP_Header_DL;
+    // PDCP Configuration (M)
+    E1AP_PDCP_Configuration_t *pdcp = &drb2Setup->pDCP_Configuration;
+    drb->pdcp_config.pDCP_SN_Size_UL = pdcp->pDCP_SN_Size_UL;
+    drb->pdcp_config.pDCP_SN_Size_DL = pdcp->pDCP_SN_Size_DL;
+    if (pdcp->discardTimer) {
+      drb->pdcp_config.discardTimer = *pdcp->discardTimer;
+    }
+    if (pdcp->t_ReorderingTimer) {
+      drb->pdcp_config.reorderingTimer = pdcp->t_ReorderingTimer->t_Reordering;
+    }
+    drb->pdcp_config.rLC_Mode = pdcp->rLC_Mode;
+    // Cell Group Information (M) ( > 1 item )
+    E1AP_Cell_Group_Information_t *cellGroupList = &drb2Setup->cell_Group_Information;
+    _E1_EQ_CHECK_GENERIC(cellGroupList->list.count > 0, "%d", cellGroupList->list.count, 0);
+    drb->numCellGroups = cellGroupList->list.count;
+    for (int k = 0; k < cellGroupList->list.count; k++) {
+      E1AP_Cell_Group_Information_Item_t *cg2Setup = cellGroupList->list.array[k];
+      // Cell Group ID
+      drb->cellGroupList[k] = cg2Setup->cell_Group_ID;
+    }
+    // QoS Flows Information To Be Setup (M)
+    E1AP_QoS_Flow_QoS_Parameter_List_t *qos2SetupList = &drb2Setup->qos_flow_Information_To_Be_Setup;
+    drb->numQosFlow2Setup = qos2SetupList->list.count;
+    for (int k = 0; k < qos2SetupList->list.count; k++) {
+      qos_flow_to_setup_t *qos_flow = drb->qosFlows + k;
+      E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k];
+      // QoS Flow Identifier (M)
+      qos_flow->qfi = qos2Setup->qoS_Flow_Identifier;
+      qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
+      // QoS Flow Level QoS Parameters (M)
+      E1AP_QoSFlowLevelQoSParameters_t *qosParams = &qos2Setup->qoSFlowLevelQoSParameters;
+      E1AP_QoS_Characteristics_t *qoS_Characteristics = &qosParams->qoS_Characteristics;
+      switch (qoS_Characteristics->present) {
+        case E1AP_QoS_Characteristics_PR_non_Dynamic_5QI:
+          qos_char->qos_type = NON_DYNAMIC;
+          qos_char->non_dynamic.fiveqi = qoS_Characteristics->choice.non_Dynamic_5QI->fiveQI;
+          break;
+        case E1AP_QoS_Characteristics_PR_dynamic_5QI: {
+          E1AP_Dynamic5QIDescriptor_t *dynamic5QI = qoS_Characteristics->choice.dynamic_5QI;
+          qos_char->qos_type = DYNAMIC;
+          qos_char->dynamic.qos_priority_level = dynamic5QI->qoSPriorityLevel;
+          qos_char->dynamic.packet_delay_budget = dynamic5QI->packetDelayBudget;
+          qos_char->dynamic.packet_error_rate.per_scalar = dynamic5QI->packetErrorRate.pER_Scalar;
+          qos_char->dynamic.packet_error_rate.per_exponent = dynamic5QI->packetErrorRate.pER_Exponent;
+          break;
+        }
+        default:
+          PRINT_ERROR("Unexpected QoS Characteristics type: %d\n", qoS_Characteristics->present);
+          return false;
+          break;
+      }
+      // NG-RAN Allocation and Retention Priority (M)
+      ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority;
+      E1AP_NGRANAllocationAndRetentionPriority_t *aRP = &qosParams->nGRANallocationRetentionPriority;
+      rent_priority->priority_level = aRP->priorityLevel;
+      rent_priority->preemption_capability = aRP->pre_emptionCapability;
+      rent_priority->preemption_vulnerability = aRP->pre_emptionVulnerability;
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief Equality check for PDU session item to modify/setup
+ */
+static bool eq_pdu_session_item(const pdu_session_to_setup_t *a, const pdu_session_to_setup_t *b)
+{
+  _E1_EQ_CHECK_LONG(a->sessionId, b->sessionId);
+  _E1_EQ_CHECK_LONG(a->sessionType, b->sessionType);
+  _E1_EQ_CHECK_INT(a->UP_TL_information.tlAddress, b->UP_TL_information.tlAddress);
+  _E1_EQ_CHECK_INT(a->UP_TL_information.teId, b->UP_TL_information.teId);
+  _E1_EQ_CHECK_LONG(a->numDRB2Setup, b->numDRB2Setup);
+  if (a->numDRB2Setup != b->numDRB2Setup)
+    return false;
+  for (int i = 0; i < a->numDRB2Setup; i++)
+    if (!eq_drb_to_setup(&a->DRBnGRanList[i], &b->DRBnGRanList[i]))
+      return false;
+  _E1_EQ_CHECK_LONG(a->numDRB2Modify, b->numDRB2Modify);
+  if (a->numDRB2Modify != b->numDRB2Modify)
+    return false;
+  for (int i = 0; i < a->numDRB2Modify; i++)
+    if (!eq_drb_to_mod(&a->DRBnGRanModList[i], &b->DRBnGRanModList[i]))
+      return false;
+  return true;
+}
+
+static bool cp_pdu_session_item(pdu_session_to_setup_t *cp, const pdu_session_to_setup_t *msg)
+{
+  // Copy basic fields
+  *cp = *msg;
+  // Copy DRB to Setup List
+  for (int j = 0; j < msg->numDRB2Setup; j++) {
+    cp->DRBnGRanList[j].id = msg->DRBnGRanList[j].id;
+    cp->DRBnGRanList[j].sdap_config = msg->DRBnGRanList[j].sdap_config;
+    cp->DRBnGRanList[j].pdcp_config = msg->DRBnGRanList[j].pdcp_config;
+    cp->DRBnGRanList[j].tlAddress = msg->DRBnGRanList[j].tlAddress;
+    cp->DRBnGRanList[j].teId = msg->DRBnGRanList[j].teId;
+    cp->DRBnGRanList[j].numDlUpParam = msg->DRBnGRanList[j].numDlUpParam;
+    // Copy DL UP Params List
+    for (int k = 0; k < msg->DRBnGRanList[j].numDlUpParam; k++) {
+      cp->DRBnGRanList[j].DlUpParamList[k] = msg->DRBnGRanList[j].DlUpParamList[k];
+    }
+    cp->DRBnGRanList[j].numCellGroups = msg->DRBnGRanList[j].numCellGroups;
+    // Copy Cell Group List
+    for (int k = 0; k < msg->DRBnGRanList[j].numCellGroups; k++) {
+      cp->DRBnGRanList[j].cellGroupList[k] = msg->DRBnGRanList[j].cellGroupList[k];
+    }
+    cp->DRBnGRanList[j].numQosFlow2Setup = msg->DRBnGRanList[j].numQosFlow2Setup;
+    // Copy QoS Flow To Setup List
+    for (int k = 0; k < msg->DRBnGRanList[j].numQosFlow2Setup; k++) {
+      cp->DRBnGRanList[j].qosFlows[k].qfi = msg->DRBnGRanList[j].qosFlows[k].qfi;
+      cp->DRBnGRanList[j].qosFlows[k].qos_params = msg->DRBnGRanList[j].qosFlows[k].qos_params;
+    }
+  }
+  // Copy DRB to Modify List
+  for (int j = 0; j < msg->numDRB2Modify; j++) {
+    cp->DRBnGRanModList[j] = msg->DRBnGRanModList[j];
+  }
+  return true;
+}
+
+/**
+ * @brief E1AP Bearer Context Setup Request encoding (9.2.2 of 3GPP TS 38.463)
+ */
+E1AP_E1AP_PDU_t *encode_E1_bearer_context_setup_request(const e1ap_bearer_setup_req_t *msg)
+{
+  E1AP_E1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
+
+  pdu->present = E1AP_E1AP_PDU_PR_initiatingMessage;
+  asn1cCalloc(pdu->choice.initiatingMessage, initMsg);
+  initMsg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup;
+  initMsg->criticality = E1AP_Criticality_reject;
+  initMsg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest;
+  E1AP_BearerContextSetupRequest_t *out = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
+  /* mandatory */
+  /* c1. gNB-CU-UP UE E1AP ID */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC1);
+  ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
+  ieC1->criticality = E1AP_Criticality_reject;
+  ieC1->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
+  ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = msg->gNB_cu_cp_ue_id;
+  /* mandatory */
+  /* c2. Security Information */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC2);
+  ieC2->id = E1AP_ProtocolIE_ID_id_SecurityInformation;
+  ieC2->criticality = E1AP_Criticality_reject;
+  ieC2->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation;
+  E1AP_SecurityAlgorithm_t *securityAlgorithm = &ieC2->value.choice.SecurityInformation.securityAlgorithm;
+  E1AP_UPSecuritykey_t *uPSecuritykey = &ieC2->value.choice.SecurityInformation.uPSecuritykey;
+  securityAlgorithm->cipheringAlgorithm = msg->cipheringAlgorithm;
+  OCTET_STRING_fromBuf(&uPSecuritykey->encryptionKey, msg->encryptionKey, E1AP_SECURITY_KEY_SIZE);
+  asn1cCallocOne(securityAlgorithm->integrityProtectionAlgorithm, msg->integrityProtectionAlgorithm);
+  asn1cCalloc(uPSecuritykey->integrityProtectionKey, protKey);
+  OCTET_STRING_fromBuf(protKey, msg->integrityProtectionKey, E1AP_SECURITY_KEY_SIZE);
+  /* mandatory */
+  /* c3. UE DL Aggregate Maximum Bit Rate */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC3);
+  ieC3->id = E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate;
+  ieC3->criticality = E1AP_Criticality_reject;
+  ieC3->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_BitRate;
+  asn_long2INTEGER(&ieC3->value.choice.BitRate, msg->ueDlAggMaxBitRate);
+  /* mandatory */
+  /* c4. Serving PLMN */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC4);
+  ieC4->id = E1AP_ProtocolIE_ID_id_Serving_PLMN;
+  ieC4->criticality = E1AP_Criticality_ignore;
+  ieC4->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity;
+  const PLMN_ID_t *servingPLMN = &msg->servingPLMNid;
+  MCC_MNC_TO_PLMNID(servingPLMN->mcc, servingPLMN->mnc, servingPLMN->mnc_digit_length, &ieC4->value.choice.PLMN_Identity);
+  /* mandatory */
+  /* Activity Notification Level */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC5);
+  ieC5->id = E1AP_ProtocolIE_ID_id_ActivityNotificationLevel;
+  ieC5->criticality = E1AP_Criticality_reject;
+  ieC5->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel;
+  ieC5->value.choice.ActivityNotificationLevel = E1AP_ActivityNotificationLevel_pdu_session; // TODO: Remove hard coding
+  /* mandatory */
+  /*  */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupRequestIEs_t, ieC6);
+  ieC6->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest;
+  ieC6->criticality = E1AP_Criticality_reject;
+  ieC6->value.present = E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest;
+  ieC6->value.choice.System_BearerContextSetupRequest.present =
+      E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest;
+  E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list = calloc_or_fail(1, sizeof(*msgNGRAN_list));
+  ieC6->value.choice.System_BearerContextSetupRequest.choice.nG_RAN_BearerContextSetupRequest =
+      (struct E1AP_ProtocolIE_Container *)msgNGRAN_list;
+  asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupRequest_t, msgNGRAN);
+  msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List;
+  msgNGRAN->criticality = E1AP_Criticality_reject;
+  msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List;
+  E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
+  for (int i = 0; i < msg->numPDUSessions; i++) {
+    const pdu_session_to_setup_t *pdu_session = &msg->pduSession[i];
+    asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Setup_Item_t, ieC6_1);
+    e1_encode_pdu_session_to_setup_item(ieC6_1, pdu_session);
+  }
+  return pdu;
+}
+
+/**
+ * @brief E1AP Bearer Context Setup Request memory management
+ */
+void free_e1ap_context_setup_request(e1ap_bearer_setup_req_t *msg)
+{
+  // Do nothing
+}
+
+/**
+ * @brief E1AP Bearer Context Setup Request decoding
+ *        gNB-CU-CP → gNB-CU-UP (9.2.2.1 of 3GPP TS 38.463)
+ */
+bool decode_E1_bearer_context_setup_request(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *out)
+{
+  DevAssert(pdu != NULL);
+
+  // Check message type
+  _E1_EQ_CHECK_INT(pdu->present,E1AP_E1AP_PDU_PR_initiatingMessage);
+  _E1_EQ_CHECK_INT(pdu->choice.initiatingMessage->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
+  _E1_EQ_CHECK_INT(pdu->choice.initiatingMessage->criticality, E1AP_Criticality_reject);
+  _E1_EQ_CHECK_INT(pdu->choice.initiatingMessage->value.present, E1AP_InitiatingMessage__value_PR_BearerContextSetupRequest);
+
+  const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
+  E1AP_BearerContextSetupRequestIEs_t *ie;
+
+  // Check mandatory IEs first
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID, true);
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_SecurityInformation, true);
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate, true);
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_Serving_PLMN, true);
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_ActivityNotificationLevel, true);
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupRequestIEs_t, ie, in, E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest, true);
+
+  // Loop over all IEs
+  for (int i = 0; i < in->protocolIEs.list.count; i++) {
+    ie = in->protocolIEs.list.array[i];
+    AssertFatal(ie != NULL, "in->protocolIEs.list.array[i] shall not be null");
+    switch (ie->id) {
+      case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
+        out->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_SecurityInformation:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_SecurityInformation);
+        E1AP_SecurityInformation_t *SecurityInformation = &ie->value.choice.SecurityInformation;
+        E1AP_SecurityAlgorithm_t *securityAlgorithm = &SecurityInformation->securityAlgorithm;
+        E1AP_EncryptionKey_t *encryptionKey = &SecurityInformation->uPSecuritykey.encryptionKey;
+        E1AP_IntegrityProtectionKey_t *integrityProtectionKey = SecurityInformation->uPSecuritykey.integrityProtectionKey;
+
+        out->cipheringAlgorithm = securityAlgorithm->cipheringAlgorithm;
+        memcpy(out->encryptionKey, encryptionKey->buf, encryptionKey->size);
+        if (securityAlgorithm->integrityProtectionAlgorithm)
+          out->integrityProtectionAlgorithm = *securityAlgorithm->integrityProtectionAlgorithm;
+        if (integrityProtectionKey)
+          memcpy(out->integrityProtectionKey, integrityProtectionKey->buf, integrityProtectionKey->size);
+        break;
+
+      case E1AP_ProtocolIE_ID_id_UEDLAggregateMaximumBitRate:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_BitRate);
+        asn_INTEGER2long(&ie->value.choice.BitRate, &out->ueDlAggMaxBitRate);
+        break;
+
+      case E1AP_ProtocolIE_ID_id_Serving_PLMN:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_PLMN_Identity);
+        PLMNID_TO_MCC_MNC(&ie->value.choice.PLMN_Identity,
+                          out->servingPLMNid.mcc,
+                          out->servingPLMNid.mnc,
+                          out->servingPLMNid.mnc_digit_length);
+        break;
+
+      case E1AP_ProtocolIE_ID_id_ActivityNotificationLevel:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel);
+        DevAssert(ie->value.present == E1AP_BearerContextSetupRequestIEs__value_PR_ActivityNotificationLevel);
+        out->activityNotificationLevel = ie->value.choice.ActivityNotificationLevel;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_System_BearerContextSetupRequest:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupRequestIEs__value_PR_System_BearerContextSetupRequest);
+        E1AP_System_BearerContextSetupRequest_t *System_BearerContextSetupRequest =
+            &ie->value.choice.System_BearerContextSetupRequest;
+        switch (System_BearerContextSetupRequest->present) {
+          case E1AP_System_BearerContextSetupRequest_PR_NOTHING:
+            PRINT_ERROR("System Bearer Context Setup Request: no choice present\n");
+            break;
+          case E1AP_System_BearerContextSetupRequest_PR_e_UTRAN_BearerContextSetupRequest:
+            AssertError(System_BearerContextSetupRequest->present == E1AP_System_BearerContextSetupRequest_PR_e_UTRAN_BearerContextSetupRequest,
+                        return false, "E1AP_System_BearerContextSetupRequest_PR_e_UTRAN_BearerContextSetupRequest in E1 Setup Request not supported");
+            break;
+          case E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest:
+            // Handle nG-RAN Bearer Context Setup Request
+            _E1_EQ_CHECK_INT(System_BearerContextSetupRequest->present,
+                             E1AP_System_BearerContextSetupRequest_PR_nG_RAN_BearerContextSetupRequest);
+            AssertFatal(System_BearerContextSetupRequest->choice.nG_RAN_BearerContextSetupRequest != NULL,
+                        "System_BearerContextSetupRequest->choice.nG_RAN_BearerContextSetupRequest shall not be null");
+            break;
+          default:
+            PRINT_ERROR("System Bearer Context Setup Request: No valid choice present.\n");
+            break;
+        }
+
+        E1AP_ProtocolIE_Container_4932P19_t *msgNGRAN_list =
+            (E1AP_ProtocolIE_Container_4932P19_t *)System_BearerContextSetupRequest->choice.nG_RAN_BearerContextSetupRequest;
+        E1AP_NG_RAN_BearerContextSetupRequest_t *msgNGRAN = msgNGRAN_list->list.array[0];
+        // NG-RAN
+        _E1_EQ_CHECK_INT(msgNGRAN_list->list.count, 1); // only one RAN is expected
+        _E1_EQ_CHECK_LONG(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Setup_List);
+        _E1_EQ_CHECK_INT(msgNGRAN->value.present,
+                         E1AP_NG_RAN_BearerContextSetupRequest__value_PR_PDU_Session_Resource_To_Setup_List);
+        // PDU Session Resource To Setup List (9.3.3.2 of 3GPP TS 38.463)
+        E1AP_PDU_Session_Resource_To_Setup_List_t *pdu2SetupList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Setup_List;
+        out->numPDUSessions = pdu2SetupList->list.count;
+        // Loop through all PDU sessions
+        for (int i = 0; i < pdu2SetupList->list.count; i++) {
+          pdu_session_to_setup_t *pdu_session = out->pduSession + i;
+          E1AP_PDU_Session_Resource_To_Setup_Item_t *pdu2Setup = pdu2SetupList->list.array[i];
+          if (!e1_decode_pdu_session_to_setup_item(pdu_session, pdu2Setup)) {
+            PRINT_ERROR("Failed to decode PDU Session to setup item %d\n", i);
+            return false;
+          }
+        }
+        break;
+      default:
+        PRINT_ERROR("Handle for this IE %ld is not implemented (or) invalid IE detected\n", ie->id);
+        break;
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief Deep copy function for E1 BEARER CONTEXT SETUP REQUEST
+ */
+e1ap_bearer_setup_req_t cp_bearer_context_setup_request(const e1ap_bearer_setup_req_t *msg)
+{
+  e1ap_bearer_setup_req_t cp = {0};
+  // Copy basi fields
+  cp = *msg;
+  strncpy(cp.encryptionKey, msg->encryptionKey, sizeof(cp.encryptionKey));
+  strncpy(cp.integrityProtectionKey, msg->integrityProtectionKey, sizeof(cp.integrityProtectionKey));
+  // Copy PDU Sessions
+  for (int i = 0; i < msg->numPDUSessions; i++)
+    cp_pdu_session_item(&cp.pduSession[i], &msg->pduSession[i]);
+  return cp;
+}
+
+/**
+ * @brief E1AP Bearer Context Setup Request equality check
+ */
+bool eq_bearer_context_setup_request(const e1ap_bearer_setup_req_t *a, const e1ap_bearer_setup_req_t *b)
+{
+  // Primitive data types
+  _E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
+  _E1_EQ_CHECK_LONG(a->cipheringAlgorithm, b->cipheringAlgorithm);
+  _E1_EQ_CHECK_LONG(a->integrityProtectionAlgorithm, b->integrityProtectionAlgorithm);
+  _E1_EQ_CHECK_LONG(a->ueDlAggMaxBitRate, b->ueDlAggMaxBitRate);
+  _E1_EQ_CHECK_INT(a->activityNotificationLevel, b->activityNotificationLevel);
+  _E1_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
+  _E1_EQ_CHECK_INT(a->numPDUSessionsMod, b->numPDUSessionsMod);
+  // PLMN
+  _E1_EQ_CHECK_INT(a->servingPLMNid.mcc, b->servingPLMNid.mcc);
+  _E1_EQ_CHECK_INT(a->servingPLMNid.mnc, b->servingPLMNid.mnc);
+  _E1_EQ_CHECK_INT(a->servingPLMNid.mnc_digit_length, b->servingPLMNid.mnc_digit_length);
+  // Security Keys
+  _E1_EQ_CHECK_STR(a->encryptionKey, b->encryptionKey);
+  _E1_EQ_CHECK_STR(a->integrityProtectionKey, b->integrityProtectionKey);
+  // PDU Sessions
+  if (a->numPDUSessions != b->numPDUSessions)
+    return false;
+  for (int i = 0; i < a->numPDUSessions; i++)
+    if (!eq_pdu_session_item(&a->pduSession[i], &b->pduSession[i]))
+      return false;
+  if (a->numPDUSessionsMod != b->numPDUSessionsMod)
+    return false;
+  for (int i = 0; i < a->numPDUSessionsMod; i++)
+    if (!eq_pdu_session_item(&a->pduSessionMod[i], &b->pduSessionMod[i]))
+      return false;
+  return true;
+}
+
+/* ======================================
+ *   E1AP Bearer Context Setup Response
+ * ====================================== */
+
+/* PDU Session Resource Setup Item */
+
+/**
+ * @brief Decode an item of the E1 PDU Session Resource Setup List (9.3.3.5 of 3GPP TS 38.463)
+ */
+static bool e1_decode_pdu_session_setup_item(pdu_session_setup_t *pduSetup, E1AP_PDU_Session_Resource_Setup_Item_t *in)
+{
+  // PDU Session ID
+  pduSetup->id = in->pDU_Session_ID;
+  pduSetup->numDRBSetup = in->dRB_Setup_List_NG_RAN.list.count;
+  // NG DL UP Transport Layer Information (M)
+  E1AP_UP_TNL_Information_t *DL_UP_TNL_Info = &in->nG_DL_UP_TNL_Information;
+  if (DL_UP_TNL_Info->choice.gTPTunnel) {
+    _E1_EQ_CHECK_INT(DL_UP_TNL_Info->present, E1AP_UP_TNL_Information_PR_gTPTunnel);
+    BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&DL_UP_TNL_Info->choice.gTPTunnel->transportLayerAddress, pduSetup->tlAddress);
+    OCTET_STRING_TO_INT32(&DL_UP_TNL_Info->choice.gTPTunnel->gTP_TEID, pduSetup->teId);
+  }
+  // DRB Setup List (1..<maxnoofDRBs>)
+  for (int j = 0; j < in->dRB_Setup_List_NG_RAN.list.count; j++) {
+    DRB_nGRAN_setup_t *drbSetup = pduSetup->DRBnGRanList + j;
+    E1AP_DRB_Setup_Item_NG_RAN_t *drb = in->dRB_Setup_List_NG_RAN.list.array[j];
+    // DRB ID (M)
+    drbSetup->id = drb->dRB_ID;
+    // UL UP Parameters (M)
+    drbSetup->numUpParam = drb->uL_UP_Transport_Parameters.list.count;
+    for (int k = 0; k < drb->uL_UP_Transport_Parameters.list.count; k++) {
+      up_params_t *UL_UP_param = drbSetup->UpParamList + k;
+      // UP Parameters List (1..<maxnoofUPParameters>)
+      E1AP_UP_Parameters_Item_t *UL_UP_item = drb->uL_UP_Transport_Parameters.list.array[k];
+      // UP Transport Layer Information (M)
+      DevAssert(UL_UP_item->uP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel);
+      // GTP Tunnel (M)
+      E1AP_GTPTunnel_t *gTPTunnel = UL_UP_item->uP_TNL_Information.choice.gTPTunnel;
+      AssertError(gTPTunnel != NULL, return false, "gTPTunnel information in required in UP Transport Layer Information\n");
+      if (gTPTunnel) {
+        BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gTPTunnel->transportLayerAddress, UL_UP_param->tlAddress);
+        OCTET_STRING_TO_INT32(&gTPTunnel->gTP_TEID, UL_UP_param->teId);
+      } else {
+      }
+      // Cell Group ID (M)
+      UL_UP_param->cell_group_id = UL_UP_item->cell_Group_ID;
+    }
+    // Flow Setup List (M)
+    drbSetup->numQosFlowSetup = drb->flow_Setup_List.list.count;
+    for (int q = 0; q < drb->flow_Setup_List.list.count; q++) {
+      qos_flow_setup_t *qosflowSetup = &drbSetup->qosFlows[q];
+      E1AP_QoS_Flow_Item_t *in_qosflowSetup = drb->flow_Setup_List.list.array[q];
+      qosflowSetup->qfi = in_qosflowSetup->qoS_Flow_Identifier;
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief Encode an item of the E1 PDU Session Resource Setup List (9.3.3.5 of 3GPP TS 38.463)
+ */
+static bool e1_encode_pdu_session_setup_item(E1AP_PDU_Session_Resource_Setup_Item_t *item, const pdu_session_setup_t *in)
+{
+  // PDU Session ID (M)
+  item->pDU_Session_ID = in->id;
+  // NG DL UP Transport Layer Information (M)
+  item->nG_DL_UP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
+  asn1cCalloc(item->nG_DL_UP_TNL_Information.choice.gTPTunnel, gTPTunnel);
+  TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(in->tlAddress, &gTPTunnel->transportLayerAddress);
+  INT32_TO_OCTET_STRING(in->teId, &gTPTunnel->gTP_TEID);
+  // DRB Setup List (1..<maxnoofDRBs>)
+  for (const DRB_nGRAN_setup_t *j = in->DRBnGRanList; j < in->DRBnGRanList + in->numDRBSetup; j++) {
+    asn1cSequenceAdd(item->dRB_Setup_List_NG_RAN.list, E1AP_DRB_Setup_Item_NG_RAN_t, ieC3_1_1);
+    // DRB ID (M)
+    ieC3_1_1->dRB_ID = j->id;
+    // UL UP Parameters (M)
+    for (const up_params_t *k = j->UpParamList; k < j->UpParamList + j->numUpParam; k++) {
+      asn1cSequenceAdd(ieC3_1_1->uL_UP_Transport_Parameters.list, E1AP_UP_Parameters_Item_t, ieC3_1_1_1);
+      ieC3_1_1_1->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
+      asn1cCalloc(ieC3_1_1_1->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
+      TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tlAddress, &gTPTunnel->transportLayerAddress);
+      INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID);
+    }
+    // Flow Setup List(M)
+    for (const qos_flow_setup_t *k = j->qosFlows; k < j->qosFlows + j->numQosFlowSetup; k++) {
+      asn1cSequenceAdd(ieC3_1_1->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, ieC3_1_1_1);
+      ieC3_1_1_1->qoS_Flow_Identifier = k->qfi;
+    }
+  }
+  // DRB Failed List (O)
+  if (in->numDRBFailed > 0)
+    item->dRB_Failed_List_NG_RAN = calloc_or_fail(1, sizeof(*item->dRB_Failed_List_NG_RAN));
+  // DRB Failed Item
+  for (const DRB_nGRAN_failed_t *j = in->DRBnGRanFailedList; j < in->DRBnGRanFailedList + in->numDRBFailed; j++) {
+    asn1cSequenceAdd(item->dRB_Failed_List_NG_RAN->list, E1AP_DRB_Failed_Item_NG_RAN_t, ieC3_1_1);
+    // DRB ID (M)
+    ieC3_1_1->dRB_ID = j->id;
+    // Cause (M)
+    ieC3_1_1->cause.present = j->cause_type;
+    switch (ieC3_1_1->cause.present) {
+      case E1AP_Cause_PR_radioNetwork:
+        ieC3_1_1->cause.choice.radioNetwork = j->cause;
+        break;
+      case E1AP_Cause_PR_transport:
+        ieC3_1_1->cause.choice.transport = j->cause;
+        break;
+      case E1AP_Cause_PR_protocol:
+        ieC3_1_1->cause.choice.protocol = j->cause;
+        break;
+      case E1AP_Cause_PR_misc:
+        ieC3_1_1->cause.choice.misc = j->cause;
+        break;
+      default:
+        PRINT_ERROR("DRB setup failure cause out of expected range\n");
+        break;
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief Encode E1 Bearer Context Setup Response (9.2.2.2 of 3GPP TS 38.463)
+ */
+E1AP_E1AP_PDU_t *encode_E1_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *in)
+{
+  E1AP_E1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
+  // PDU Type
+  pdu->present = E1AP_E1AP_PDU_PR_successfulOutcome;
+  asn1cCalloc(pdu->choice.successfulOutcome, msg);
+  msg->procedureCode = E1AP_ProcedureCode_id_bearerContextSetup;
+  msg->criticality = E1AP_Criticality_reject;
+  msg->value.present = E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse;
+  E1AP_BearerContextSetupResponse_t *out = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse;
+  // gNB-CU-CP UE E1AP ID (M)
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC1);
+  ieC1->id = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
+  ieC1->criticality = E1AP_Criticality_reject;
+  ieC1->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
+  ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = in->gNB_cu_cp_ue_id;
+  // gNB-CU-UP UE E1AP ID (M)
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC2);
+  ieC2->id = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
+  ieC2->criticality = E1AP_Criticality_reject;
+  ieC2->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
+  ieC2->value.choice.GNB_CU_CP_UE_E1AP_ID = in->gNB_cu_up_ue_id;
+  // Message Type (M)
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextSetupResponseIEs_t, ieC3);
+  ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse;
+  ieC3->criticality = E1AP_Criticality_reject;
+  ieC3->value.present = E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse;
+  // CHOICE System: default NG-RAN (M)
+  ieC3->value.choice.System_BearerContextSetupResponse.present =
+      E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse;
+  E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list = calloc_or_fail(1, sizeof(*msgNGRAN_list));
+  ieC3->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse =
+      (struct E1AP_ProtocolIE_Container *)msgNGRAN_list;
+  asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextSetupResponse_t, msgNGRAN);
+  msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List;
+  msgNGRAN->criticality = E1AP_Criticality_reject;
+  msgNGRAN->value.present = E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List;
+  E1AP_PDU_Session_Resource_Setup_List_t *pduSetup = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List;
+  for (const pdu_session_setup_t *i = in->pduSession; i < in->pduSession + in->numPDUSessions; i++) {
+    asn1cSequenceAdd(pduSetup->list, E1AP_PDU_Session_Resource_Setup_Item_t, ieC3_1);
+    e1_encode_pdu_session_setup_item(ieC3_1, i);
+  }
+  return pdu;
+}
+
+/**
+ * @brief Decode E1 Bearer Context Setup Response (9.2.2.2 of 3GPP TS 38.463)
+ */
+bool decode_E1_bearer_context_setup_response(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_resp_t *out)
+{
+  // Check message type
+  _E1_EQ_CHECK_INT(pdu->present, E1AP_E1AP_PDU_PR_successfulOutcome);
+  _E1_EQ_CHECK_INT(pdu->choice.successfulOutcome->procedureCode, E1AP_ProcedureCode_id_bearerContextSetup);
+  _E1_EQ_CHECK_INT(pdu->choice.successfulOutcome->criticality, E1AP_Criticality_reject);
+  _E1_EQ_CHECK_INT(pdu->choice.successfulOutcome->value.present, E1AP_SuccessfulOutcome__value_PR_BearerContextSetupResponse);
+
+  const E1AP_BearerContextSetupResponse_t *in = &pdu->choice.successfulOutcome->value.choice.BearerContextSetupResponse;
+  E1AP_BearerContextSetupResponseIEs_t *ie;
+  // Check mandatory IEs first
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupResponseIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID, true);
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupResponseIEs_t, ie, in, E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID, true);
+  E1AP_LIB_FIND_IE(E1AP_BearerContextSetupResponseIEs_t, ie, in, E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse, true);
+  // Loop over all IEs
+  for (int i = 0; i < in->protocolIEs.list.count; i++) {
+    ie = in->protocolIEs.list.array[i];
+
+    switch (ie->id) {
+      case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_CP_UE_E1AP_ID);
+        out->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_GNB_CU_UP_UE_E1AP_ID);
+        out->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_System_BearerContextSetupResponse:
+        _E1_EQ_CHECK_INT(ie->value.present, E1AP_BearerContextSetupResponseIEs__value_PR_System_BearerContextSetupResponse);
+        switch (ie->value.choice.System_BearerContextSetupResponse.present) {
+          case E1AP_System_BearerContextSetupResponse_PR_nG_RAN_BearerContextSetupResponse: {
+            E1AP_ProtocolIE_Container_4932P22_t *msgNGRAN_list =
+                (E1AP_ProtocolIE_Container_4932P22_t *)
+                    ie->value.choice.System_BearerContextSetupResponse.choice.nG_RAN_BearerContextSetupResponse;
+            _E1_EQ_CHECK_INT(msgNGRAN_list->list.count, 1);
+            E1AP_NG_RAN_BearerContextSetupResponse_t *msgNGRAN = msgNGRAN_list->list.array[0];
+            _E1_EQ_CHECK_INT(msgNGRAN->id, E1AP_ProtocolIE_ID_id_PDU_Session_Resource_Setup_List);
+            _E1_EQ_CHECK_INT(msgNGRAN->value.present,
+                             E1AP_NG_RAN_BearerContextSetupResponse__value_PR_PDU_Session_Resource_Setup_List);
+            E1AP_PDU_Session_Resource_Setup_List_t *pduSetupList = &msgNGRAN->value.choice.PDU_Session_Resource_Setup_List;
+            out->numPDUSessions = pduSetupList->list.count;
+            for (int i = 0; i < pduSetupList->list.count; i++) {
+              pdu_session_setup_t *pduSetup = out->pduSession + i;
+              E1AP_PDU_Session_Resource_Setup_Item_t *pdu_session = pduSetupList->list.array[i];
+              e1_decode_pdu_session_setup_item(pduSetup, pdu_session);
+            }
+          } break;
+
+          case E1AP_System_BearerContextSetupResponse_PR_e_UTRAN_BearerContextSetupResponse:
+            PRINT_ERROR("DRB Setup List E-UTRAN not supported in E1 Setup Response\n");
+            return false;
+            break;
+
+          default:
+            PRINT_ERROR("Unknown DRB Setup List in E1 Setup Response\n");
+            return false;
+            break;
+        }
+        break;
+
+      default:
+        PRINT_ERROR("Handle for this IE is not implemented (or) invalid IE detected\n");
+        return false;
+        break;
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief Deep copy function for E1 BEARER CONTEXT SETUP RESPONSE
+ */
+e1ap_bearer_setup_resp_t cp_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *msg)
+{
+  e1ap_bearer_setup_resp_t cp = {0};
+  // Copy basic fields
+  cp = *msg;
+  // Copy PDU Sessions Setup
+  for (int i = 0; i < msg->numPDUSessions; i++) {
+    cp.pduSession[i] = msg->pduSession[i];
+    // Copy DRB Setup
+    for (int j = 0; j < msg->pduSession[i].numDRBSetup; j++) {
+      cp.pduSession[i].DRBnGRanList[j] = msg->pduSession[i].DRBnGRanList[j];
+      for (int k = 0; k < msg->pduSession[i].DRBnGRanList[j].numQosFlowSetup; k++) {
+        cp.pduSession[i].DRBnGRanList[j].qosFlows[k] = msg->pduSession[i].DRBnGRanList[j].qosFlows[k];
+      }
+    }
+    cp.pduSession[i].numDRBFailed = msg->pduSession[i].numDRBFailed;
+    // Copy DRB Failed
+    for (int j = 0; j < msg->pduSession[i].numDRBFailed; j++) {
+      cp.pduSession[i].DRBnGRanFailedList[j] = msg->pduSession[i].DRBnGRanFailedList[j];
+    }
+  }
+  return cp;
+}
+
+/**
+ * @brief E1AP Bearer Context Setup Response equality check
+ */
+bool eq_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *a, const e1ap_bearer_setup_resp_t *b)
+{
+  // Check basic members
+  _E1_EQ_CHECK_INT(a->gNB_cu_cp_ue_id, b->gNB_cu_cp_ue_id);
+  _E1_EQ_CHECK_INT(a->gNB_cu_up_ue_id, b->gNB_cu_up_ue_id);
+  _E1_EQ_CHECK_INT(a->numPDUSessions, b->numPDUSessions);
+  // Check PDU Sessions Setup
+  if (a->numPDUSessions != b->numPDUSessions)
+    return false;
+  for (int i = 0; i < a->numPDUSessions; i++) {
+    const pdu_session_setup_t *ps_a = &a->pduSession[i];
+    const pdu_session_setup_t *ps_b = &b->pduSession[i];
+    _E1_EQ_CHECK_LONG(ps_a->id, ps_b->id);
+    _E1_EQ_CHECK_INT(ps_a->tlAddress, ps_b->tlAddress);
+    _E1_EQ_CHECK_LONG(ps_a->teId, ps_b->teId);
+    _E1_EQ_CHECK_INT(ps_a->numDRBSetup, ps_b->numDRBSetup);
+    _E1_EQ_CHECK_INT(ps_a->numDRBFailed, ps_b->numDRBFailed);
+    // Check DRB Setup
+    for (int j = 0; j < ps_a->numDRBSetup; j++) {
+      const DRB_nGRAN_setup_t *drb_a = &ps_a->DRBnGRanList[j];
+      const DRB_nGRAN_setup_t *drb_b = &ps_b->DRBnGRanList[j];
+      _E1_EQ_CHECK_LONG(drb_a->id, drb_b->id);
+      _E1_EQ_CHECK_INT(drb_a->numUpParam, drb_b->numUpParam);
+      _E1_EQ_CHECK_INT(drb_a->numQosFlowSetup, drb_b->numQosFlowSetup);
+    }
+    // Check DRB Failed
+    for (int j = 0; j < ps_a->numDRBFailed; j++) {
+      const DRB_nGRAN_failed_t *drbf_a = &ps_a->DRBnGRanFailedList[j];
+      const DRB_nGRAN_failed_t *drbf_b = &ps_b->DRBnGRanFailedList[j];
+      _E1_EQ_CHECK_LONG(drbf_a->id, drbf_b->id);
+      _E1_EQ_CHECK_LONG(drbf_a->cause_type, drbf_b->cause_type);
+      _E1_EQ_CHECK_LONG(drbf_a->cause, drbf_b->cause);
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief E1AP Bearer Context Setup Response memory management
+ */
+void free_e1ap_context_setup_response(const e1ap_bearer_setup_resp_t *msg)
+{
+  // Do nothing (no dynamic allocation)
+}
diff --git a/openair2/E1AP/lib/e1ap_bearer_context_management.h b/openair2/E1AP/lib/e1ap_bearer_context_management.h
new file mode 100644
index 0000000000000000000000000000000000000000..95e4cb0e159c93c964dd261a40a86a5af64c4f34
--- /dev/null
+++ b/openair2/E1AP/lib/e1ap_bearer_context_management.h
@@ -0,0 +1,43 @@
+/*
+ * 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 E1AP_BEARER_CONTEXT_MANAGEMENT_H_
+#define E1AP_BEARER_CONTEXT_MANAGEMENT_H_
+
+#include <stdbool.h>
+#include "openair2/COMMON/e1ap_messages_types.h"
+#include "common/platform_types.h"
+
+struct E1AP_E1AP_PDU;
+
+struct E1AP_E1AP_PDU *encode_E1_bearer_context_setup_request(const e1ap_bearer_setup_req_t *msg);
+bool decode_E1_bearer_context_setup_request(const struct E1AP_E1AP_PDU *pdu, e1ap_bearer_setup_req_t *out);
+e1ap_bearer_setup_req_t cp_bearer_context_setup_request(const e1ap_bearer_setup_req_t *msg);
+void free_e1ap_context_setup_request(e1ap_bearer_setup_req_t *msg);
+bool eq_bearer_context_setup_request(const e1ap_bearer_setup_req_t *a, const e1ap_bearer_setup_req_t *b);
+
+struct E1AP_E1AP_PDU *encode_E1_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *msg);
+bool decode_E1_bearer_context_setup_response(const struct E1AP_E1AP_PDU *pdu, e1ap_bearer_setup_resp_t *out);
+void free_e1ap_context_setup_response(const e1ap_bearer_setup_resp_t *msg);
+e1ap_bearer_setup_resp_t cp_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *msg);
+bool eq_bearer_context_setup_response(const e1ap_bearer_setup_resp_t *a, const e1ap_bearer_setup_resp_t *b);
+
+#endif /* E1AP_BEARER_CONTEXT_MANAGEMENT_H_ */
diff --git a/openair2/E1AP/lib/e1ap_lib_common.h b/openair2/E1AP/lib/e1ap_lib_common.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3c6b24da24af5c23228d1a0169215c23e8465e5
--- /dev/null
+++ b/openair2/E1AP/lib/e1ap_lib_common.h
@@ -0,0 +1,69 @@
+/*
+ * 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 E1AP_LIB_COMMON_H_
+#define E1AP_LIB_COMMON_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "openair3/UTILS/conversions.h"
+
+#ifdef ENABLE_TESTS
+#define PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__);
+#else
+#define PRINT_ERROR(...) // Do nothing
+#endif
+
+#define _E1_EQ_CHECK_GENERIC(condition, fmt, ...)                                                  \
+  do {                                                                                             \
+    if (!(condition)) {                                                                            \
+      PRINT_ERROR("E1 Equality Check failure: %s:%d: Condition '%s' failed: " fmt " != " fmt "\n", \
+                  __FILE__,                                                                        \
+                  __LINE__,                                                                        \
+                  #condition,                                                                      \
+                  ##__VA_ARGS__);                                                                  \
+      return false;                                                                                \
+    }                                                                                              \
+  } while (0)
+
+#define _E1_EQ_CHECK_LONG(A, B) _E1_EQ_CHECK_GENERIC(A == B, "%ld", A, B);
+#define _E1_EQ_CHECK_INT(A, B) _E1_EQ_CHECK_GENERIC(A == B, "%d", A, B);
+#define _E1_EQ_CHECK_STR(A, B) _E1_EQ_CHECK_GENERIC(strcmp(A, B) == 0, "'%s'", A, B);
+
+// Macro to look up IE. If mandatory and not found, macro will log an error and return false.
+#define E1AP_LIB_FIND_IE(IE_TYPE, ie, container, IE_ID, mandatory)                                           \
+  do {                                                                                                       \
+    ie = NULL;                                                                                               \
+    for (int i = 0; i < (container)->protocolIEs.list.count; ++i) {                                          \
+      IE_TYPE *current_ie = (container)->protocolIEs.list.array[i];                                          \
+      if (current_ie->id == (IE_ID)) {                                                                       \
+        ie = current_ie;                                                                                     \
+        break;                                                                                               \
+      }                                                                                                      \
+    }                                                                                                        \
+    if (mandatory && ie == NULL) {                                                                           \
+      fprintf(stderr, "%s(): Mandatory element not found: ID" #IE_ID " with type " #IE_TYPE "\n", __func__); \
+      return false;                                                                                          \
+    }                                                                                                        \
+  } while (0)
+
+#endif /* E1AP_LIB_COMMON_H_ */
diff --git a/openair2/E1AP/lib/e1ap_lib_includes.h b/openair2/E1AP/lib/e1ap_lib_includes.h
new file mode 100644
index 0000000000000000000000000000000000000000..58da8f6c3001bc2e26824000dc98b9df5537e43a
--- /dev/null
+++ b/openair2/E1AP/lib/e1ap_lib_includes.h
@@ -0,0 +1,57 @@
+/*
+ * 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 E1AP_LIB_INCLUDES_H_
+#define E1AP_LIB_INCLUDES_H_
+
+#include "E1AP_E1AP-PDU.h"
+#include "E1AP_ProcedureCode.h"
+#include "E1AP_SuccessfulOutcome.h"
+#include "E1AP_InitiatingMessage.h"
+#include "E1AP_ProtocolIE-ID.h"
+#include "E1AP_ProtocolIE-Field.h"
+#include "E1AP_UP-TNL-Information.h"
+#include "E1AP_DefaultDRB.h"
+#include "E1AP_QoS-Characteristics.h"
+#include "E1AP_PDU-Session-Resource-To-Setup-Item.h"
+#include "E1AP_GTPTunnel.h"
+#include "E1AP_DRB-To-Setup-Item-NG-RAN.h"
+#include "E1AP_T-ReorderingTimer.h"
+#include "E1AP_QoS-Flow-QoS-Parameter-Item.h"
+#include "E1AP_Cell-Group-Information-Item.h"
+#include "E1AP_Dynamic5QIDescriptor.h"
+#include "E1AP_Non-Dynamic5QIDescriptor.h"
+// E1 Bearer Context Setup Request
+#include "E1AP_BearerContextSetupRequest.h"
+#include "E1AP_GNB-CU-CP-E1SetupRequest.h"
+#include "E1AP_GNB-CU-UP-E1SetupRequest.h"
+#include "E1AP_System-BearerContextSetupRequest.h"
+#include "E1AP_MaximumIPdatarate.h"
+#include "E1AP_PDU-Session-Type.h"
+// E1 Bearer Context Setup Response
+#include "E1AP_PDU-Session-Resource-Setup-Item.h"
+#include "E1AP_DRB-Setup-Item-NG-RAN.h"
+#include "E1AP_UP-Parameters-Item.h"
+#include "E1AP_QoS-Flow-Item.h"
+#include "E1AP_DRB-Failed-List-NG-RAN.h"
+#include "E1AP_DRB-Failed-Item-NG-RAN.h"
+
+#endif /* E1AP_LIB_INCLUDES_H_ */
diff --git a/openair2/E1AP/tests/CMakeLists.txt b/openair2/E1AP/tests/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fcec103f9c171af479954a1075965b80048cffb6
--- /dev/null
+++ b/openair2/E1AP/tests/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_executable(e1ap_lib_test e1ap_lib_test.c)
+add_dependencies(tests e1ap_lib_test)
+add_test(NAME e1ap_lib_test COMMAND e1ap_lib_test)
+target_link_libraries(e1ap_lib_test PRIVATE e1ap_lib)
+target_link_libraries(e1ap_lib_test PRIVATE asn1_e1ap)
+target_include_directories(e1ap_lib_test PRIVATE
+                           ${CMAKE_SOURCE_DIR}
+                           ${CMAKE_CURRENT_SOURCE_DIR}
+)
diff --git a/openair2/E1AP/tests/e1ap_lib_test.c b/openair2/E1AP/tests/e1ap_lib_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e3a1035d8227426ed65dc0d0790ba69d2a83019
--- /dev/null
+++ b/openair2/E1AP/tests/e1ap_lib_test.c
@@ -0,0 +1,225 @@
+/*
+ * 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 e1ap_lib_test.c
+ * \brief Unit tests for E1AP libraries
+ * \author Guido Casati
+ * \date 2024
+ * \version 0.1
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "E1AP/lib/e1ap_bearer_context_management.h"
+#include "E1AP/lib/e1ap_lib_includes.h"
+#include "common/utils/assertions.h"
+
+void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
+{
+  printf("detected error at %s:%d:%s: %s\n", file, line, function, s);
+  abort();
+}
+
+static E1AP_E1AP_PDU_t *e1ap_encode_decode(const E1AP_E1AP_PDU_t *enc_pdu)
+{
+  // xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, enc_pdu);
+
+  DevAssert(enc_pdu != NULL);
+  char errbuf[2048];
+  size_t errlen = sizeof(errbuf);
+  int ret = asn_check_constraints(&asn_DEF_E1AP_E1AP_PDU, enc_pdu, errbuf, &errlen);
+  AssertFatal(ret == 0, "asn_check_constraints() failed: %s\n", errbuf);
+
+  uint8_t msgbuf[16384];
+  asn_enc_rval_t enc = aper_encode_to_buffer(&asn_DEF_E1AP_E1AP_PDU, NULL, enc_pdu, msgbuf, sizeof(msgbuf));
+  AssertFatal(enc.encoded > 0, "aper_encode_to_buffer() failed\n");
+
+  E1AP_E1AP_PDU_t *dec_pdu = NULL;
+  asn_codec_ctx_t st = {.max_stack_size = 100 * 1000};
+  asn_dec_rval_t dec = aper_decode(&st, &asn_DEF_E1AP_E1AP_PDU, (void **)&dec_pdu, msgbuf, enc.encoded, 0, 0);
+  AssertFatal(dec.code == RC_OK, "aper_decode() failed\n");
+
+  // xer_fprint(stdout, &asn_DEF_E1AP_E1AP_PDU, dec_pdu);
+  return dec_pdu;
+}
+
+static void e1ap_msg_free(E1AP_E1AP_PDU_t *pdu)
+{
+  ASN_STRUCT_FREE(asn_DEF_E1AP_E1AP_PDU, pdu);
+}
+
+/**
+ * @brief Test E1AP Bearer Context Setup Request encoding/decoding
+ */
+static void test_bearer_context_setup_request(void)
+{
+  bearer_context_pdcp_config_t pdcp = {
+    .discardTimer = E1AP_DiscardTimer_ms10,
+    .pDCP_Reestablishment = E1AP_PDCP_Reestablishment_true,
+    .pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_12,
+    .pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_12,
+    .reorderingTimer = 10,
+    .rLC_Mode = E1AP_RLC_Mode_rlc_am,
+  };
+
+  bearer_context_sdap_config_t sdap = {
+    .defaultDRB = 1,
+    .sDAP_Header_DL = true,
+    .sDAP_Header_UL = true,
+  };
+
+  qos_flow_to_setup_t qos = {
+    .qfi = 1,
+    .qos_params.alloc_reten_priority.preemption_capability = E1AP_Pre_emptionCapability_shall_not_trigger_pre_emption,
+    .qos_params.alloc_reten_priority.preemption_vulnerability = E1AP_Pre_emptionVulnerability_not_pre_emptable,
+    .qos_params.alloc_reten_priority.priority_level = E1AP_PriorityLevel_highest,
+    .qos_params.qos_characteristics.non_dynamic.fiveqi = 9,
+  };
+
+  security_indication_t security = {
+    .confidentialityProtectionIndication = E1AP_ConfidentialityProtectionIndication_required,
+    .integrityProtectionIndication = E1AP_IntegrityProtectionIndication_required,
+    .maxIPrate = E1AP_MaxIPrate_max_UErate,
+  };
+
+  // Step 1: Initialize the E1AP Bearer Context Setup Request
+  e1ap_bearer_setup_req_t orig = {
+      .gNB_cu_cp_ue_id = 1234,
+      .cipheringAlgorithm = 0x01,
+      .integrityProtectionAlgorithm = 0x01,
+      .ueDlAggMaxBitRate = 1000000000,
+      .bearerContextStatus = 0,
+      .servingPLMNid.mcc = 001,
+      .servingPLMNid.mnc = 01,
+      .servingPLMNid.mnc_digit_length = 0x02,
+      .activityNotificationLevel = ANL_PDU_SESSION,
+      .numPDUSessions = 1,
+      .pduSession[0].sessionId = 1,
+      .pduSession[0].sessionType = E1AP_PDU_Session_Type_ipv4,
+      .pduSession[0].nssai.sd = 0x01,
+      .pduSession[0].nssai.sst = 0x01,
+      .pduSession[0].securityIndication = security,
+      .pduSession[0].numDRB2Setup = 1,
+      .pduSession[0].UP_TL_information.tlAddress = 167772161,
+      .pduSession[0].UP_TL_information.teId = 0x12345,
+      .pduSession[0].DRBnGRanList[0].id = 1,
+      .pduSession[0].DRBnGRanList[0].sdap_config = sdap,
+      .pduSession[0].DRBnGRanList[0].pdcp_config = pdcp,
+      .pduSession[0].DRBnGRanList[0].id = 1,
+      .pduSession[0].DRBnGRanList[0].numCellGroups = 1,
+      .pduSession[0].DRBnGRanList[0].cellGroupList[0] = MCG,
+      .pduSession[0].DRBnGRanList[0].numQosFlow2Setup = 1,
+      .pduSession[0].DRBnGRanList[0].qosFlows[0] = qos,
+  };
+  memset(orig.encryptionKey, 0xAB, sizeof(orig.encryptionKey));
+  memset(orig.integrityProtectionKey, 0xCD, sizeof(orig.integrityProtectionKey));
+  // E1AP encode the original message
+  E1AP_E1AP_PDU_t *enc = encode_E1_bearer_context_setup_request(&orig);
+  // E1AP decode the encoded message
+  E1AP_E1AP_PDU_t *dec = e1ap_encode_decode(enc);
+  // Free the E1AP encoded message
+  e1ap_msg_free(enc);
+  // E1 message decode
+  e1ap_bearer_setup_req_t decoded = {0};
+  bool ret = decode_E1_bearer_context_setup_request(dec, &decoded);
+  AssertFatal(ret, "decode_E1_bearer_context_setup_request(): could not decode message\n");
+  // Free the E1AP decoded message
+  e1ap_msg_free(dec);
+  // Equality check original/decoded
+  ret = eq_bearer_context_setup_request(&orig, &decoded);
+  AssertFatal(ret, "eq_bearer_context_setup_request(): decoded message doesn't match\n");
+  // Free the memory for the decoded message
+  free_e1ap_context_setup_request(&decoded);
+  // Deep copy and equality check of the original message
+  e1ap_bearer_setup_req_t cp = cp_bearer_context_setup_request(&orig);
+  ret = eq_bearer_context_setup_request(&orig, &cp);
+  AssertFatal(ret, "eq_bearer_context_setup_request(): copied message doesn't match\n");
+  // Free the copied message and original
+  free_e1ap_context_setup_request(&cp);
+  free_e1ap_context_setup_request(&orig);
+}
+
+/**
+ * @brief Test E1AP Bearer Context Setup Response encoding/decoding
+ */
+static void test_bearer_context_setup_response(void)
+{
+  // Step 1: Initialize the E1AP Bearer Context Setup Response
+  e1ap_bearer_setup_resp_t orig = {
+      .gNB_cu_cp_ue_id = 1234,
+      .gNB_cu_up_ue_id = 5678,
+      .numPDUSessions = 1,
+      .pduSession[0].id = 1,
+      .pduSession[0].tlAddress = 167772161,
+      .pduSession[0].teId = 0x12345,
+      .pduSession[0].numDRBSetup = 1,
+      .pduSession[0].numDRBFailed = 0,
+      .pduSession[0].DRBnGRanList[0].id = 1,
+      .pduSession[0].DRBnGRanList[0].numUpParam = 1,
+      .pduSession[0].DRBnGRanList[0].numQosFlowSetup = 1,
+      .pduSession[0].DRBnGRanList[0].qosFlows[0].qfi = 1,
+      .pduSession[0].DRBnGRanList[0].UpParamList[0].cell_group_id = MCG,
+      .pduSession[0].DRBnGRanList[0].UpParamList[0].teId = 0x34345,
+      .pduSession[0].DRBnGRanList[0].UpParamList[0].tlAddress = 167772161,
+  };
+  // E1AP encode the original message
+  E1AP_E1AP_PDU_t *enc = encode_E1_bearer_context_setup_response(&orig);
+
+  // E1AP decode the encoded message
+  E1AP_E1AP_PDU_t *dec = e1ap_encode_decode(enc);
+
+  // Free the E1AP encoded message
+  e1ap_msg_free(enc);
+
+  // E1 message decode
+  e1ap_bearer_setup_resp_t decoded = {0};
+  bool ret = decode_E1_bearer_context_setup_response(dec, &decoded);
+  AssertFatal(ret, "decode_E1_bearer_context_setup_response(): could not decode message\n");
+
+  // Free the E1AP decoded message
+  e1ap_msg_free(dec);
+
+  // Equality check original/decoded
+  ret = eq_bearer_context_setup_response(&orig, &decoded);
+  AssertFatal(ret, "eq_bearer_context_setup_response(): decoded message doesn't match\n");
+
+  // Free the memory for the decoded message
+  free_e1ap_context_setup_response(&decoded);
+
+  // Deep copy and equality check of the original message
+  e1ap_bearer_setup_resp_t cp = cp_bearer_context_setup_response(&orig);
+  ret = eq_bearer_context_setup_response(&orig, &cp);
+  AssertFatal(ret, "eq_bearer_context_setup_response(): copied message doesn't match\n");
+
+  // Free the copied message and original
+  free_e1ap_context_setup_response(&cp);
+  free_e1ap_context_setup_response(&orig);
+}
+
+int main()
+{
+  // E1 Bearer Context Setup
+  test_bearer_context_setup_request();
+  test_bearer_context_setup_response();
+  return 0;
+}
diff --git a/openair2/F1AP/lib/CMakeLists.txt b/openair2/F1AP/lib/CMakeLists.txt
index cb8d8b9712fea03ad2191a6353d9d2a979ba14c7..0c6137dc306d8898d5aa75df728a7e6aa678f170 100644
--- a/openair2/F1AP/lib/CMakeLists.txt
+++ b/openair2/F1AP/lib/CMakeLists.txt
@@ -8,3 +8,7 @@ target_include_directories(f1ap_lib PUBLIC
                            ${CMAKE_SOURCE_DIR}
                            ${CMAKE_CURRENT_SOURCE_DIR}
 )
+
+if(ENABLE_TESTS)
+  target_compile_definitions(f1ap_lib PRIVATE ENABLE_TESTS)
+endif()
diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c
index fe079faa4c730c459aea9f94785248389306bb74..f067985a2daa320f3d5688a45a4afbb752b6f614 100644
--- a/openair2/F1AP/lib/f1ap_interface_management.c
+++ b/openair2/F1AP/lib/f1ap_interface_management.c
@@ -72,7 +72,7 @@ static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai,
 /**
  * @brief F1AP Setup Request memory management
  */
-static void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_du_system_info_t *sys_info)
+void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_du_system_info_t *sys_info)
 {
   if (sys_info) {
     free(sys_info->mib);
@@ -83,72 +83,76 @@ static void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_d
   free(info->tac);
 }
 
+/**
+ * @brief Encode NR Frequency Info (9.3.1.17 of 3GPP TS 38.473)
+ */
+static F1AP_NRFreqInfo_t encode_frequency_info(const f1ap_nr_frequency_info_t *info)
+{
+  F1AP_NRFreqInfo_t nrFreqInfo = {0};
+  // NR ARFCN
+  nrFreqInfo.nRARFCN = info->arfcn;
+  int num_bands = 1;
+  // Frequency Band List
+  for (int j = 0; j < num_bands; j++) {
+    asn1cSequenceAdd(nrFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
+    // NR Frequency Band
+    nr_freqBandNrItem->freqBandIndicatorNr = info->band;
+  }
+  return nrFreqInfo;
+}
+
+/**
+ * @brief Encode Transmission Bandwidth (9.3.1.15 of 3GPP TS 38.473)
+ */
+static F1AP_Transmission_Bandwidth_t encode_tx_bandwidth(const f1ap_transmission_bandwidth_t *info)
+{
+  F1AP_Transmission_Bandwidth_t tb = {0};
+  tb.nRSCS = info->scs;
+  tb.nRNRB = to_NRNRB(info->nrb);
+  return tb;
+}
+
 /**
  * @brief Encoding of Served Cell Information (9.3.1.10 of 3GPP TS 38.473)
  */
 static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_cell_info_t *c)
 {
   F1AP_Served_Cell_Information_t scell_info = {0};
-  // NR CGI
+  // NR CGI (M)
   MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &(scell_info.nRCGI.pLMN_Identity));
   NR_CELL_ID_TO_BIT_STRING(c->nr_cellid, &(scell_info.nRCGI.nRCellIdentity));
-  // NR PCI
+  // NR PCI (M)
   scell_info.nRPCI = c->nr_pci; // int 0..1007
-  // 5GS TAC
+  // 5GS TAC (O)
   if (c->tac != NULL) {
     uint32_t tac = htonl(*c->tac);
     asn1cCalloc(scell_info.fiveGS_TAC, netOrder);
     OCTET_STRING_fromBuf(netOrder, ((char *)&tac) + 1, 3);
   }
-  // Served PLMNs
+  // Served PLMNs 1..<maxnoofBPLMNs>
   asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item);
+  // PLMN Identity (M)
   MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity);
-  // NR-Mode-Info
+  // NR-Mode-Info (M)
   F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info;
-  if (c->mode == F1AP_MODE_FDD) { // FDD
+  if (c->mode == F1AP_MODE_FDD) { // FDD Info
     const f1ap_fdd_info_t *fdd = &c->fdd;
     nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD;
     asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info);
-    /* FDD.1.1 UL NRFreqInfo ARFCN */
-    fDD_Info->uL_NRFreqInfo.nRARFCN = fdd->ul_freqinfo.arfcn;
-    /* FDD.1.3 freqBandListNr */
-    int ul_band = 1;
-    for (int j = 0; j < ul_band; j++) {
-      asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
-      /* FDD.1.3.1 freqBandIndicatorNr*/
-      nr_freqBandNrItem->freqBandIndicatorNr = fdd->ul_freqinfo.band;
-    }
-    /* FDD.2.1 DL NRFreqInfo ARFCN */
-    fDD_Info->dL_NRFreqInfo.nRARFCN = fdd->dl_freqinfo.arfcn;
-    /* FDD.2.3 freqBandListNr */
-    int dl_bands = 1;
-    for (int j = 0; j < dl_bands; j++) {
-      asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
-      /* FDD.2.3.1 freqBandIndicatorNr*/
-      nr_freqBandNrItem->freqBandIndicatorNr = fdd->dl_freqinfo.band;
-    } // for FDD : DL freq_Bands
-    /* FDD.3 UL Transmission Bandwidth */
-    fDD_Info->uL_Transmission_Bandwidth.nRSCS = fdd->ul_tbw.scs;
-    fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->ul_tbw.nrb);
-    /* FDD.4 DL Transmission Bandwidth */
-    fDD_Info->dL_Transmission_Bandwidth.nRSCS = fdd->dl_tbw.scs;
-    fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->dl_tbw.nrb);
-  } else if (c->mode == F1AP_MODE_TDD) {
+    // NR Frequency Info
+    fDD_Info->uL_NRFreqInfo = encode_frequency_info(&fdd->ul_freqinfo);
+    fDD_Info->dL_NRFreqInfo = encode_frequency_info(&fdd->dl_freqinfo);
+    // Transmission Bandwidth
+    fDD_Info->uL_Transmission_Bandwidth = encode_tx_bandwidth(&fdd->ul_tbw);
+    fDD_Info->dL_Transmission_Bandwidth = encode_tx_bandwidth(&fdd->dl_tbw);
+  } else if (c->mode == F1AP_MODE_TDD) { // TDD Info
     const f1ap_tdd_info_t *tdd = &c->tdd;
     nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD;
     asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info);
-    /* TDD.1.1 nRFreqInfo ARFCN */
-    tDD_Info->nRFreqInfo.nRARFCN = tdd->freqinfo.arfcn;
-    /* TDD.1.3 freqBandListNr */
-    int bands = 1;
-    for (int j = 0; j < bands; j++) {
-      asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem);
-      /* TDD.1.3.1 freqBandIndicatorNr*/
-      nr_freqBandNrItem->freqBandIndicatorNr = tdd->freqinfo.band;
-    }
-    /* TDD.2 transmission_Bandwidth */
-    tDD_Info->transmission_Bandwidth.nRSCS = tdd->tbw.scs;
-    tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(tdd->tbw.nrb);
+    // NR Frequency Info
+    tDD_Info->nRFreqInfo = encode_frequency_info(&tdd->freqinfo);
+    // Transmission Bandwidth
+    tDD_Info->transmission_Bandwidth = encode_tx_bandwidth(&tdd->tbw);
   } else {
     AssertFatal(false, "unknown duplex mode %d\n", c->mode);
   }
@@ -530,16 +534,16 @@ bool decode_f1ap_setup_request(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_req_t *out
   return true;
 }
 
-static void copy_f1ap_served_cell_info(f1ap_served_cell_info_t *dest, const f1ap_served_cell_info_t *src) {
+void copy_f1ap_served_cell_info(f1ap_served_cell_info_t *dest, const f1ap_served_cell_info_t *src)
+{
+  // shallow copy
   *dest = *src;
-  dest->mode = src->mode;
-  dest->tdd = src->tdd;
-  dest->fdd = src->fdd;
-  dest->plmn = src->plmn;
+  // tac
   if (src->tac) {
     dest->tac = malloc_or_fail(sizeof(*dest->tac));
     *dest->tac = *src->tac;
   }
+  // measurement timing config
   if (src->measurement_timing_config_len) {
     dest->measurement_timing_config = calloc_or_fail(src->measurement_timing_config_len, sizeof(*dest->measurement_timing_config));
     memcpy(dest->measurement_timing_config, src->measurement_timing_config, src->measurement_timing_config_len);
@@ -955,7 +959,7 @@ bool decode_f1ap_setup_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_failure_t
  */
 bool eq_f1ap_setup_failure(const f1ap_setup_failure_t *a, const f1ap_setup_failure_t *b)
 {
-  _F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id);
+  _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id);
   return true;
 }
 
diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h
index bdceee9a61845647a42be348dede126c250e8595..e483a743015447c59361121df9ebeaeeac1e1f68 100644
--- a/openair2/F1AP/lib/f1ap_interface_management.h
+++ b/openair2/F1AP/lib/f1ap_interface_management.h
@@ -32,6 +32,8 @@ bool decode_f1ap_setup_request(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_req_t
 f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg);
 bool eq_f1ap_setup_request(const f1ap_setup_req_t *a, const f1ap_setup_req_t *b);
 void free_f1ap_setup_request(const f1ap_setup_req_t *msg);
+void copy_f1ap_served_cell_info(f1ap_served_cell_info_t *a, const f1ap_served_cell_info_t *b);
+void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_du_system_info_t *sys_info);
 
 /* F1 Setup Response */
 struct F1AP_F1AP_PDU *encode_f1ap_setup_response(const f1ap_setup_resp_t *msg);
diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c
index 71d2bea95335f50eab418064e4db5107891d7814..4c75aa944e3353c94414a44062e79e0fc506a0c8 100644
--- a/openair2/F1AP/tests/f1ap_lib_test.c
+++ b/openair2/F1AP/tests/f1ap_lib_test.c
@@ -119,9 +119,8 @@ static void test_initial_ul_rrc_message_transfer(void)
  */
 static void test_dl_rrc_message_transfer(void)
 {
-  uint8_t *rrc = calloc(strlen("RRC Container") + 1, sizeof(uint8_t));
-  uint32_t *old_gNB_DU_ue_id = calloc(1, sizeof(uint32_t));
-  AssertFatal(rrc != NULL && old_gNB_DU_ue_id != NULL, "out of memory\n");
+  uint8_t *rrc = calloc_or_fail(strlen("RRC Container") + 1, sizeof(*rrc));
+  uint32_t *old_gNB_DU_ue_id = calloc_or_fail(1, sizeof(*old_gNB_DU_ue_id));
   memcpy((void *)rrc, "RRC Container", strlen("RRC Container") + 1);
 
   f1ap_dl_rrc_message_t orig = {
@@ -194,12 +193,11 @@ static void test_f1ap_setup_request(void)
 {
   /* allocate memory */
   /* gNB_DU_name */
-  uint8_t *gNB_DU_name = calloc(strlen("OAI DU") + 1, sizeof(uint8_t));
-  AssertFatal(gNB_DU_name != NULL, "out of memory\n");
+  uint8_t *gNB_DU_name = calloc_or_fail(strlen("OAI DU") + 1, sizeof(*gNB_DU_name));
   memcpy(gNB_DU_name, "OAI DU", strlen("OAI DU") + 1);
   /* sys_info */
-  uint8_t *mib = calloc(3, sizeof(uint8_t));
-  uint8_t *sib1 = calloc(3, sizeof(uint8_t));
+  uint8_t *mib = calloc_or_fail(3, sizeof(*mib));
+  uint8_t *sib1 = calloc_or_fail(3, sizeof(*sib1));
   f1ap_gnb_du_system_info_t sys_info = {
       .mib_length = 3,
       .mib = mib,
@@ -208,11 +206,10 @@ static void test_f1ap_setup_request(void)
   };
   /* measurement_timing_information */
   int measurement_timing_config_len = strlen("0") + 1;
-  uint8_t *measurement_timing_information = calloc(measurement_timing_config_len, sizeof(uint8_t));
-  AssertFatal(measurement_timing_information != NULL, "out of memory\n");
+  uint8_t *measurement_timing_information = calloc_or_fail(measurement_timing_config_len, sizeof(*measurement_timing_information));
   memcpy((void *)measurement_timing_information, "0", measurement_timing_config_len);
   /* TAC */
-  uint32_t *tac = calloc(1, sizeof(uint32_t));
+  uint32_t *tac = calloc_or_fail(1, sizeof(*tac));
   /*
    * TDD test
    */
@@ -245,7 +242,7 @@ static void test_f1ap_setup_request(void)
       .rrc_ver[2] = 56,
       .cell[0].info = info,
   };
-  orig.cell[0].sys_info = calloc(1, sizeof(*orig.cell[0].sys_info));
+  orig.cell[0].sys_info = calloc_or_fail(1, sizeof(*orig.cell[0].sys_info));
   *orig.cell[0].sys_info = sys_info;
   // encode
   F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_request(&orig);
@@ -311,8 +308,7 @@ static void test_f1ap_setup_response(void)
   /* gNB_CU_name */
   char *cu_name = "OAI-CU";
   int len = strlen(cu_name) + 1;
-  uint8_t *gNB_CU_name = calloc(len, sizeof(uint8_t));
-  AssertFatal(gNB_CU_name != NULL, "out of memory\n");
+  uint8_t *gNB_CU_name = calloc_or_fail(len, sizeof(*gNB_CU_name));
   memcpy((void *)gNB_CU_name, cu_name, len);
   /* create message */
   f1ap_setup_resp_t orig = {
@@ -393,8 +389,8 @@ static void test_f1ap_setup_failure(void)
 static void test_f1ap_du_configuration_update(void)
 {
   /* sys_info */
-  uint8_t *mib = calloc(3, sizeof(uint8_t));
-  uint8_t *sib1 = calloc(3, sizeof(uint8_t));
+  uint8_t *mib = calloc_or_fail(3, sizeof(*mib));
+  uint8_t *sib1 = calloc_or_fail(3, sizeof(*sib1));
   f1ap_gnb_du_system_info_t sys_info = {
       .mib_length = 3,
       .mib = mib,
@@ -404,12 +400,10 @@ static void test_f1ap_du_configuration_update(void)
   /* measurement_timing_information modify */
   char *s = "1";
   int measurement_timing_config_len = strlen(s) + 1;
-  uint8_t *measurement_timing_config_mod = calloc(measurement_timing_config_len, sizeof(uint8_t));
-  AssertFatal(measurement_timing_config_mod != NULL, "out of memory\n");
+  uint8_t *measurement_timing_config_mod = calloc_or_fail(measurement_timing_config_len, sizeof(*measurement_timing_config_mod));
   memcpy((void *)measurement_timing_config_mod, s, measurement_timing_config_len);
   /* TAC modify */
-  uint32_t *tac = calloc(1, sizeof(uint32_t));
-  AssertFatal(tac != NULL, "out of memory\n");
+  uint32_t *tac = calloc_or_fail(1, sizeof(*tac));
   *tac = 456;
   /* info modify */
   f1ap_served_cell_info_t info = {
@@ -437,8 +431,7 @@ static void test_f1ap_du_configuration_update(void)
       .cell_to_delete[0].plmn.mnc = 1,
       .cell_to_delete[0].plmn.mnc_digit_length = 3,
   };
-  orig.cell_to_modify[0].sys_info = calloc(1, sizeof(*orig.cell_to_modify[0].sys_info));
-  AssertFatal(orig.cell_to_modify[0].sys_info != NULL, "out of memory\n");
+  orig.cell_to_modify[0].sys_info = calloc_or_fail(1, sizeof(*orig.cell_to_modify[0].sys_info));
   *orig.cell_to_modify[0].sys_info = sys_info;
 
   F1AP_F1AP_PDU_t *f1enc = encode_f1ap_du_configuration_update(&orig);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 4e591b6a7ab99cfc0bcb2e106524fd49f55701e9..befe1ec3c785415caa59b733d2aa2728551ecf6e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -1006,18 +1006,11 @@ static bool get_feasible_msg3_tda(frame_type_t frame_type,
   return false;
 }
 
-static void nr_get_Msg3alloc(module_id_t module_id,
-                             int CC_id,
-                             NR_ServingCellConfigCommon_t *scc,
-                             sub_frame_t current_slot,
-                             frame_t current_frame,
-                             NR_RA_t *ra)
+static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, frame_t current_frame, NR_RA_t *ra)
 {
-  // msg3 is scheduled in mixed slot in the following TDD period
   DevAssert(ra->Msg3_tda_id >= 0 && ra->Msg3_tda_id < 16);
 
   uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes
-  gNB_MAC_INST *mac = RC.nrmac[module_id];
 
   NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP;
   NR_UE_ServingCell_Info_t *sc_info = &ra->sc_info;
@@ -1056,7 +1049,10 @@ static void nr_get_Msg3alloc(module_id_t module_id,
     rbSize = 0;
     while (rbStart < bwpSize && (vrb_map_UL[rbStart + bwpStart] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb)))
       rbStart++;
-    AssertFatal(rbStart < bwpSize - msg3_nb_rb, "no space to allocate Msg 3 for RA!\n");
+    if (rbStart + msg3_nb_rb > bwpSize) {
+      LOG_D(NR_MAC, "No space to allocate Msg 3\n");
+      return false;
+    }
     while (rbStart + rbSize < bwpSize
            && !(vrb_map_UL[rbStart + bwpStart + rbSize] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb)) && rbSize < msg3_nb_rb)
       rbSize++;
@@ -1064,6 +1060,7 @@ static void nr_get_Msg3alloc(module_id_t module_id,
   ra->msg3_nb_rb = msg3_nb_rb;
   ra->msg3_first_rb = rbStart;
   ra->msg3_bwp_start = bwpStart;
+  return true;
 }
 
 static void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu,
@@ -1493,6 +1490,13 @@ static void nr_generate_Msg2(module_id_t module_idP,
     return;
   }
 
+  bool msg3_ret = nr_get_Msg3alloc(nr_mac, CC_id, slotP, frameP, ra);
+  if (!msg3_ret) {
+    reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, ra->beam_id, n_slots_frame, ra->Msg3_beam.new_beam);
+    reset_beam_status(&nr_mac->beam_info, frameP, slotP, ra->beam_id, n_slots_frame, beam.new_beam);
+    return;
+  }
+
   LOG_D(NR_MAC, "Msg2 startSymbolIndex.nrOfSymbols %d.%d\n", tda_info.startSymbolIndex, tda_info.nrOfSymbols);
 
   // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially
@@ -1659,7 +1663,6 @@ static void nr_generate_Msg2(module_id_t module_idP,
   nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
 
   // Program UL processing for Msg3
-  nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra);
   nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *)&tx_req->TLVs[0].value.direct[0]);
 
   // Start RA contention resolution timer in Msg3 transmission slot (current slot + K2)
@@ -2426,7 +2429,8 @@ void nr_schedule_RA(module_id_t module_idP,
     NR_COMMON_channels_t *cc = &mac->common_channels[CC_id];
     for (int i = 0; i < NR_NB_RA_PROC_MAX; i++) {
       NR_RA_t *ra = &cc->ra[i];
-      LOG_D(NR_MAC, "RA[state:%d]\n", ra->ra_state);
+      if (ra->ra_state != nrRA_gNB_IDLE)
+        LOG_D(NR_MAC, "RA[%d] frame.slot %d.%d state: %d\n", i, frameP, slotP, ra->ra_state);
 
       // Check RA Contention Resolution timer
       if (ra->ra_type == RA_4_STEP && ra->ra_state >= nrRA_WAIT_Msg3) {
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 8a38c6e66d234ef359cdf7b621f708b9dda113c8..e161fa50ab32c2db42cb40a24f41929a0952877b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -585,38 +585,36 @@ void handle_nr_ul_harq(const int CC_idP,
                        const nfapi_nr_crc_t *crc_pdu)
 {
   gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
-  NR_SCHED_LOCK(&nrmac->sched_lock);
-
-  NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, crc_pdu->rnti);
-  bool UE_waiting_CFRA_msg3 = get_UE_waiting_CFRA_msg3(nrmac, CC_idP, frame, slot, crc_pdu->rnti);
+  if (nrmac->radio_config.disable_harq) {
+    LOG_D(NR_MAC, "skipping UL feedback handling as HARQ is disabled\n");
+    return;
+  }
 
-  if (!UE || UE_waiting_CFRA_msg3 == true) {
-    LOG_D(NR_MAC, "handle harq for rnti %04x, in RA process\n", crc_pdu->rnti);
-    for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
-      NR_RA_t *ra = &nrmac->common_channels[CC_idP].ra[i];
-      if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == crc_pdu->rnti) {
-        NR_SCHED_UNLOCK(&nrmac->sched_lock);
-        return;
-      }
+  NR_SCHED_LOCK(&nrmac->sched_lock);
+  for (int i = 0; i < NR_NB_RA_PROC_MAX; ++i) {
+    NR_RA_t *ra = &nrmac->common_channels[CC_idP].ra[i];
+    // if we find any ongoing RA that has already scheduled MSG3
+    // and it is expecting its reception in current frame and slot with matching RNTI
+    // we can exit the function (no HARQ involved)
+    if (ra->ra_state >= nrRA_WAIT_Msg3 && ra->rnti == crc_pdu->rnti && frame == ra->Msg3_frame && slot == ra->Msg3_slot) {
+      LOG_D(NR_MAC, "UL for rnti %04x in RA (MSG3), no need to process HARQ\n", crc_pdu->rnti);
+      NR_SCHED_UNLOCK(&nrmac->sched_lock);
+      return;
     }
-    NR_SCHED_UNLOCK(&nrmac->sched_lock);
-    LOG_D(NR_MAC, "no RA proc for RNTI 0x%04x in Msg3/MsgA-PUSCH\n", crc_pdu->rnti);
-    return;
   }
-  if (nrmac->radio_config.disable_harq) {
-    LOG_D(NR_MAC, "skipping UL feedback handling as HARQ is disabled\n");
+
+  NR_UE_info_t *UE = find_nr_UE(&nrmac->UE_info, crc_pdu->rnti);
+  if (!UE) {
     NR_SCHED_UNLOCK(&nrmac->sched_lock);
+    LOG_E(NR_MAC, "Couldn't identify UE connected with current UL HARQ process\n");
     return;
   }
+
   NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
   int8_t harq_pid = sched_ctrl->feedback_ul_harq.head;
   LOG_D(NR_MAC, "Comparing crc_pdu->harq_id vs feedback harq_pid = %d %d\n",crc_pdu->harq_id, harq_pid);
   while (crc_pdu->harq_id != harq_pid || harq_pid < 0) {
-    LOG_W(NR_MAC,
-          "Unexpected ULSCH HARQ PID %d (have %d) for RNTI 0x%04x (ignore this warning for RA)\n",
-          crc_pdu->harq_id,
-          harq_pid,
-          crc_pdu->rnti);
+    LOG_W(NR_MAC, "Unexpected ULSCH HARQ PID %d (have %d) for RNTI 0x%04x\n", crc_pdu->harq_id, harq_pid, crc_pdu->rnti);
     if (harq_pid < 0) {
       NR_SCHED_UNLOCK(&nrmac->sched_lock);
       return;
@@ -727,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) {
@@ -1403,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/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c
index ab2756c3cdbb4f0dbdf03bcefebf11f0aa861d67..1d3394e7888f5fbd0e0cbd1c3d2d669716a733f1 100644
--- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c
+++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c
@@ -88,11 +88,12 @@ static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, const
     pdcp_config->t_Reordering = calloc(1, sizeof(*pdcp_config->t_Reordering));
     *pdcp_config->t_Reordering = drb->pdcp_config.reorderingTimer;
     pdcp_config->ext1 = NULL;
-    if (pdu->integrityProtectionIndication == 0 || // Required
-        pdu->integrityProtectionIndication == 1) { // Preferred
-        asn1cCallocOne(drbCfg->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled);
+    const security_indication_t *sec = &pdu->securityIndication;
+    if (sec->integrityProtectionIndication == SECURITY_REQUIRED ||
+        sec->integrityProtectionIndication == SECURITY_PREFERRED) {
+      asn1cCallocOne(drbCfg->integrityProtection, NR_PDCP_Config__drb__integrityProtection_enabled);
     }
-    if (pdu->confidentialityProtectionIndication == 2) { // Not Needed
+    if (sec->confidentialityProtectionIndication == SECURITY_NOT_NEEDED) {
       asn1cCalloc(pdcp_config->ext1, ext1);
       asn1cCallocOne(ext1->cipheringDisabled, NR_PDCP_Config__ext1__cipheringDisabled_true);
     }
@@ -188,8 +189,8 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req)
                               req_drb->id,
                               req_pdu->sessionId,
                               qfi,
-                              req_pdu->tlAddress,
-                              req_pdu->teId,
+                              req_pdu->UP_TL_information.tlAddress,
+                              req_pdu->UP_TL_information.teId,
                               nr_pdcp_data_req_drb,
                               sdap_data_req,
                               &resp_n3);
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;
 }
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index 798ec5ce4e8851f49a3e95731fcb5031382288de..e70d7b66ebaa1a39dd2fb8da5d4a7ee36e111d6b 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -56,6 +56,7 @@
 #include "utils.h"
 #include "xer_encoder.h"
 
+#define PUCCH2_SIZE 8
 const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
 
 static NR_BWP_t clone_generic_parameters(const NR_BWP_t *gp)
@@ -187,6 +188,24 @@ static NR_PUSCH_Config_t *clone_pusch_config(const NR_PUSCH_Config_t *pc)
   return clone;
 }
 
+static int get_nb_pucch2_per_slot(const NR_ServingCellConfigCommon_t *scc, int bwp_size)
+{
+  const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
+  const int n_slots_frame = slotsperframe[*scc->ssbSubcarrierSpacing];
+  int ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0) : n_slots_frame;
+  int n_slots_period = tdd ? n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
+  int max_meas_report_period = 320; // slots
+  int max_csi_reports = MAX_MOBILES_PER_GNB << 1; // 2 reports per UE (RSRP and RI-PMI-CQI)
+  int available_report_occasions = max_meas_report_period * ul_slots_period / n_slots_period;
+  int nb_pucch2 = (max_csi_reports / (available_report_occasions + 1)) + 1;
+  // in current implementation we need (nb_pucch2 * PUCCH2_SIZE) prbs for PUCCH2
+  // and MAX_MOBILES_PER_GNB prbs for PUCCH1
+  AssertFatal((nb_pucch2 * PUCCH2_SIZE) + MAX_MOBILES_PER_GNB <= bwp_size,
+              "Cannot allocate all required PUCCH resources for max number of %d UEs in BWP with %d PRBs\n",
+              MAX_MOBILES_PER_GNB, bwp_size);
+  return nb_pucch2;
+}
+
 NR_SearchSpace_t *rrc_searchspace_config(bool is_common, int searchspaceid, int coresetid)
 {
 
@@ -295,7 +314,7 @@ static uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc)
 
 static int set_ideal_period(const int n_slots_period, const int n_ul_slots_period)
 {
-  return MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE
+  return MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE (RSRP and RI-PMI-CQI)
 }
 
 static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0,
@@ -307,7 +326,6 @@ static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0,
   nzpcsi0->periodicityAndOffset = calloc(1,sizeof(*nzpcsi0->periodicityAndOffset));
   // TODO ideal period to be set according to estimation by the gNB on how fast the channel changes
   const int offset = nb_slots_per_period * id;
-
   if (ideal_period < 5) {
     nzpcsi0->periodicityAndOffset->present = NR_CSI_ResourcePeriodicityAndOffset_PR_slots4;
     nzpcsi0->periodicityAndOffset->choice.slots4 = offset;
@@ -974,7 +992,11 @@ static void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedbac
 }
 
 // PUCCH resource set 0 for configuration with O_uci <= 2 bits and/or a positive or negative SR (section 9.2.1 of 38.213)
-static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, const NR_UE_NR_Capability_t *uecap)
+static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config,
+                                 int uid,
+                                 int curr_bwp,
+                                 int num_pucch2,
+                                 const NR_UE_NR_Capability_t *uecap)
 {
   NR_PUCCH_ResourceSet_t *pucchresset = calloc(1,sizeof(*pucchresset));
   pucchresset->pucch_ResourceSetId = 0;
@@ -990,7 +1012,7 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int c
 
   NR_PUCCH_Resource_t *pucchres0 = calloc(1,sizeof(*pucchres0));
   pucchres0->pucch_ResourceId = *pucchid;
-  pucchres0->startingPRB = 8 + uid;
+  pucchres0->startingPRB = (PUCCH2_SIZE * num_pucch2) + uid;
   AssertFatal(pucchres0->startingPRB < curr_bwp, "Not enough resources in current BWP (size %d) to allocate uid %d\n", curr_bwp, uid);
   pucchres0->intraSlotFrequencyHopping = NULL;
   pucchres0->secondHopPRB = NULL;
@@ -1006,7 +1028,10 @@ static void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int c
 
 
 // PUCCH resource set 1 for configuration with O_uci > 2 bits (currently format2)
-static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, const NR_UE_NR_Capability_t *uecap)
+static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config,
+                                 int uid,
+                                 int num_pucch2,
+                                 const NR_UE_NR_Capability_t *uecap)
 {
   NR_PUCCH_ResourceSet_t *pucchresset=calloc(1,sizeof(*pucchresset));
   pucchresset->pucch_ResourceSetId = 1;
@@ -1022,12 +1047,12 @@ static void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, const NR_UE_NR
 
   NR_PUCCH_Resource_t *pucchres2 = calloc(1,sizeof(*pucchres2));
   pucchres2->pucch_ResourceId = *pucchressetid;
-  pucchres2->startingPRB = 0;
+  pucchres2->startingPRB = PUCCH2_SIZE * (uid % num_pucch2);
   pucchres2->intraSlotFrequencyHopping = NULL;
   pucchres2->secondHopPRB = NULL;
   pucchres2->format.present = NR_PUCCH_Resource__format_PR_format2;
   pucchres2->format.choice.format2 = calloc(1,sizeof(*pucchres2->format.choice.format2));
-  pucchres2->format.choice.format2->nrofPRBs = 8;
+  pucchres2->format.choice.format2->nrofPRBs = PUCCH2_SIZE;
   pucchres2->format.choice.format2->nrofSymbols = 1;
   pucchres2->format.choice.format2->startingSymbolIndex = 13;
   asn1cSeqAdd(&pucch_Config->resourceToAddModList->list,pucchres2);
@@ -1501,8 +1526,9 @@ static void config_uplinkBWP(NR_BWP_Uplink_t *ubwp,
   pucch_Config->resourceSetToReleaseList = NULL;
   pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList));
   pucch_Config->resourceToReleaseList = NULL;
-  config_pucch_resset0(pucch_Config, uid, curr_bwp, uecap);
-  config_pucch_resset1(pucch_Config, uecap);
+  int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
+  config_pucch_resset0(pucch_Config, uid, curr_bwp, num_pucch2, uecap);
+  config_pucch_resset1(pucch_Config, uid, num_pucch2, uecap);
   set_pucch_power_config(pucch_Config, configuration->do_CSIRS);
   scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
   set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
@@ -1545,7 +1571,11 @@ static void set_phr_config(NR_MAC_CellGroupConfig_t *mac_CellGroupConfig)
   mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1;
 }
 
-static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR_CSI_ReportConfig_t *csirep, int uid, bool is_rsrp)
+static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc,
+                                     NR_CSI_ReportConfig_t *csirep,
+                                     int uid,
+                                     int curr_bwp,
+                                     bool is_rsrp)
 {
   const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   const int n_slots_frame = slotsperframe[*scc->ssbSubcarrierSpacing];
@@ -1553,7 +1583,8 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR
   const int n_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
   const int ideal_period = set_ideal_period(n_slots_period, n_ul_slots_period);
   const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
-  const int idx = (uid << 1) + is_rsrp;
+  const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
+  const int idx = (uid * 2 / num_pucch2) + is_rsrp;
   const int offset = first_ul_slot_period + idx % n_ul_slots_period + (idx / n_ul_slots_period) * n_slots_period;
   AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n");
 
@@ -1703,7 +1734,8 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
                                    const nr_pdsch_AntennaPorts_t *antennaports,
                                    const int max_layers,
                                    int rep_id,
-                                   int uid)
+                                   int uid,
+                                   int curr_bwp)
 {
   int resource_id = -1;
   int im_id = -1;
@@ -1732,7 +1764,7 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
   csirep->nzp_CSI_RS_ResourcesForInterference = NULL;
   csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
   csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic));
-  set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, false);
+  set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, false);
   asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires);
   csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI;
   csirep->reportQuantity.choice.cri_RI_PMI_CQI = (NULL_t)0;
@@ -1767,6 +1799,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
                                     int do_csi, // if rsrp is based on CSI or SSB
                                     int rep_id,
                                     int uid,
+                                    int curr_bwp,
                                     int num_antenna_ports)
 {
   int resource_id = -1;
@@ -1793,7 +1826,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
   csirep->nzp_CSI_RS_ResourcesForInterference = NULL;
   csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
   csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic));
-  set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, true);
+  set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, true);
   asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires);
   if (do_csi && num_antenna_ports < 4) {
     csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP;
@@ -2848,8 +2881,9 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
   pucch_Config->resourceSetToReleaseList = NULL;
   pucch_Config->resourceToAddModList = calloc(1, sizeof(*pucch_Config->resourceToAddModList));
   pucch_Config->resourceToReleaseList = NULL;
-  config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL);
-  config_pucch_resset1(pucch_Config, NULL);
+  int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp);
+  config_pucch_resset0(pucch_Config, uid, curr_bwp, num_pucch2, NULL);
+  config_pucch_resset1(pucch_Config, uid, num_pucch2, NULL);
   set_pucch_power_config(pucch_Config, configuration->do_CSIRS);
 
   initialUplinkBWP->pusch_Config = config_pusch(NULL, configuration->use_deltaMCS, scc, NULL);
@@ -3060,12 +3094,13 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
                              &configuration->pdsch_AntennaPorts,
                              *pdsch_servingcellconfig->ext1->maxMIMO_Layers,
                              bwp_id,
-                             uid);
+                             uid,
+                             curr_bwp);
     }
     NR_PUCCH_CSI_Resource_t *pucchrsrp = calloc(1, sizeof(*pucchrsrp));
     pucchrsrp->uplinkBandwidthPartId = bwp_id;
     pucchrsrp->pucch_Resource = pucch_Resource;
-    config_rsrp_meas_report(csi_MeasConfig, scc, pucchrsrp, configuration->do_CSIRS, bwp_id + 10, uid, pdsch_AntennaPorts);
+    config_rsrp_meas_report(csi_MeasConfig, scc, pucchrsrp, configuration->do_CSIRS, bwp_id + 10, uid, curr_bwp, pdsch_AntennaPorts);
   }
 
   fill_harq_IEs(SpCellConfig->spCellConfigDedicated, configuration->num_dlharq, configuration->num_ulharq);
@@ -3561,8 +3596,23 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
     pucchcsires1->uplinkBandwidthPartId = bwp->bwp_Id;
     pucchcsires1->pucch_Resource = 2;
 
-    config_csi_meas_report(csi_MeasConfig, servingcellconfigcommon, pucchcsires1, bwp->bwp_Dedicated->pdsch_Config, pdschap, *pdsch_servingcellconfig->ext1->maxMIMO_Layers, bwp->bwp_Id, uid);
-    config_rsrp_meas_report(csi_MeasConfig, servingcellconfigcommon, pucchcsires1, do_csirs, bwp->bwp_Id + 10, uid, dl_antenna_ports);
+    config_csi_meas_report(csi_MeasConfig,
+                           servingcellconfigcommon,
+                           pucchcsires1,
+                           bwp->bwp_Dedicated->pdsch_Config,
+                           pdschap,
+                           *pdsch_servingcellconfig->ext1->maxMIMO_Layers,
+                           bwp->bwp_Id,
+                           uid,
+                           curr_bwp);
+    config_rsrp_meas_report(csi_MeasConfig,
+                            servingcellconfigcommon,
+                            pucchcsires1,
+                            do_csirs,
+                            bwp->bwp_Id + 10,
+                            uid,
+                            curr_bwp,
+                            dl_antenna_ports);
   }
   secondaryCellGroup->spCellConfig->spCellConfigDedicated->sCellDeactivationTimer = NULL;
   secondaryCellGroup->spCellConfig->spCellConfigDedicated->crossCarrierSchedulingConfig = NULL;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index e94358f274f5a1e4c8745f7ae6d182e5b1094e9f..e8c7fcdc2cc2e9de4d4b8f13c405f87cbc4c635e 100644
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -94,6 +94,7 @@
 #include "utils.h"
 #include "x2ap_messages_types.h"
 #include "xer_encoder.h"
+#include "E1AP/lib/e1ap_bearer_context_management.h"
 
 #ifdef E2_AGENT
 #include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h"
@@ -2595,6 +2596,7 @@ void *rrc_gnb_task(void *args_p) {
 
       case E1AP_BEARER_CONTEXT_SETUP_RESP:
         rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance);
+        free_e1ap_context_setup_response(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p));
         break;
 
       case E1AP_BEARER_CONTEXT_MODIFICATION_RESP:
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index c2a641db3204e2f18ca05a6aecfbd2a58747f4a4..bf71357aeda5454d578c6e18451f08a38ac55f79 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -349,11 +349,13 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
     if (cuup_nssai.sst == 0)
       cuup_nssai = pdu->nssai; /* for CU-UP selection below */
 
-    pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed;
-
-    pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
-    pdu->teId = session->gtp_teid;
-    memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target
+    security_indication_t *sec = &pdu->securityIndication;
+    sec->integrityProtectionIndication = rrc->security.do_drb_integrity ? SECURITY_REQUIRED
+                                                                        : SECURITY_NOT_NEEDED;
+    sec->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? SECURITY_REQUIRED
+                                                                              : SECURITY_NOT_NEEDED;
+    pdu->UP_TL_information.teId = session->gtp_teid;
+    memcpy(&pdu->UP_TL_information.tlAddress, session->upf_addr.buffer, sizeof(in_addr_t));
 
     /* we assume for the moment one DRB per PDU session. Activate the bearer,
      * and configure in RRC. */
@@ -380,9 +382,10 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
 
       drb->numCellGroups = 1; // assume one cell group associated with a DRB
 
+      // Set all Cell Group IDs to MCG
       for (int k=0; k < drb->numCellGroups; k++) {
-        cell_group_t *cellGroup = drb->cellGroupList + k;
-        cellGroup->id = 0; // MCG
+        cell_group_id_t *cellGroup = drb->cellGroupList + k;
+        *cellGroup = MCG;
       }
 
       drb->numQosFlow2Setup = session->nb_qos;
diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c
index 639c279d4decf9084196b191bb933f954185ed33..bc3c564516a8edb9738aed38f77155cde38fb857 100644
--- a/openair2/RRC/NR/rrc_gNB_du.c
+++ b/openair2/RRC/NR/rrc_gNB_du.c
@@ -446,19 +446,9 @@ static void update_cell_info(nr_rrc_du_container_t *du, const f1ap_served_cell_i
 
   AssertFatal(du->setup_req->num_cells_available == 1, "expected 1 cell for DU, but has %d\n", du->setup_req->num_cells_available);
   f1ap_served_cell_info_t *ci = &du->setup_req->cell[0].info;
-
-  ci->nr_cellid = new_ci->nr_cellid;
-  ci->nr_pci = new_ci->nr_pci;
-  if (new_ci->tac != NULL)
-    *ci->tac = *new_ci->tac;
-  ci->num_ssi = new_ci->num_ssi;
-  for (int s = 0; s < new_ci->num_ssi; ++s)
-    ci->nssai[s] = new_ci->nssai[s];
-  ci->mode = new_ci->mode;
-  if (ci->mode == F1AP_MODE_TDD)
-    ci->tdd = new_ci->tdd;
-  else
-    ci->fdd = new_ci->fdd;
+  // make sure no memory is allocated
+  free_f1ap_cell(ci, NULL);
+  copy_f1ap_served_cell_info(ci, new_ci);
 
   NR_MeasurementTimingConfiguration_t *new_mtc =
       extract_mtc(new_ci->measurement_timing_config, new_ci->measurement_timing_config_len);
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index e9d1f20fb369c26dfbc94f96a4c9fb5c25efff81..b46da323740d789ef5fbef00f3262bbe9aea2edd 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -972,9 +972,12 @@ static void nr_rrc_process_reconfigurationWithSync(NR_UE_RRC_INST_t *rrc, NR_Rec
 
   NR_UE_Timers_Constants_t *tac = &rrc->timers_and_constants;
   nr_timer_stop(&tac->T310);
-  int t304_value = nr_rrc_get_T304(reconfigurationWithSync->t304);
-  nr_timer_setup(&tac->T304, t304_value, 10); // 10ms step
-  nr_timer_start(&tac->T304);
+  if (!get_softmodem_params()->phy_test) {
+    // T304 is stopped upon completion of RA procedure which is not done in phy-test mode
+    int t304_value = nr_rrc_get_T304(reconfigurationWithSync->t304);
+    nr_timer_setup(&tac->T304, t304_value, 10); // 10ms step
+    nr_timer_start(&tac->T304);
+  }
   rrc->rnti = reconfigurationWithSync->newUE_Identity;
   // reset the MAC entity of this cell group (done at MAC in handle_reconfiguration_with_sync)
 }
diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h
index 588edb1461fb77e3a98e36d8f2a831c4ed9392bf..31a479cab683af7244bfcd87357c2125788b3848 100644
--- a/openair3/UTILS/conversions.h
+++ b/openair3/UTILS/conversions.h
@@ -31,7 +31,7 @@
     ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24))
 
 # define hton_int16(x)   \
-    (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8)
+    ((((x) & 0x00FF) << 8) | (((x) & 0xFF00) >> 8))
 
 # define ntoh_int32_buf(bUF)        \
     ((*((uint8_t*)bUF)) << 24) | ((*((uint8_t*)bUF + 1)) << 16) | ((*((uint8_t*)bUF + 2)) << 8)   \
@@ -285,19 +285,6 @@ do {                                    \
     BUFFER_TO_UINT32((aSN)->buf, x);               \
   } while (0)
 
-#define BIT_STRING_TO_INT32(aSN, x)     \
-do {                                    \
-    DevCheck((aSN)->bits_unused == 0, (aSN)->bits_unused, 0, 0);    \
-    OCTET_STRING_TO_INT32(aSN, x);      \
-} while(0)
-
-#define BIT_STRING_TO_CELL_IDENTITY(aSN, vALUE)                     \
-do {                                                                \
-    DevCheck((aSN)->bits_unused == 4, (aSN)->bits_unused, 4, 0);    \
-    vALUE = ((aSN)->buf[0] << 20) | ((aSN)->buf[1] << 12) |         \
-        ((aSN)->buf[2] << 4) | (aSN)->buf[3];                       \
-} while(0)
-
 #define BIT_STRING_TO_NR_CELL_IDENTITY(aSN, vALUE)                     \
 do {                                                                   \
     DevCheck((aSN)->bits_unused == 4, (aSN)->bits_unused, 4, 0);       \
@@ -315,14 +302,6 @@ do {                                                                   \
 #define MCC_MNC_DIGIT(vALUE) \
     ((vALUE) % 10)
 
-#define MCC_TO_BUFFER(mCC, bUFFER)      \
-do {                                    \
-    DevAssert(bUFFER != NULL);          \
-    (bUFFER)[0] = MCC_HUNDREDS(mCC);    \
-    (bUFFER)[1] = MCC_MNC_DECIMAL(mCC); \
-    (bUFFER)[2] = MCC_MNC_DIGIT(mCC);   \
-} while(0)
-
 #define MCC_MNC_TO_PLMNID(mCC, mNC, mNCdIGITlENGTH, oCTETsTRING)               \
 do {                                                                           \
     (oCTETsTRING)->buf = calloc(3, sizeof(uint8_t));                           \
@@ -459,14 +438,6 @@ do {                                                    \
     (bITsTRING)->bits_unused = 4;                       \
 } while(0)
 
-/*
-#define INT16_TO_3_BYTE_BUFFER(x, buf) \
-do {                            \
-	(buf)[0] = 0x00; \
-    (buf)[1] = (x) >> 8;        \
-    (buf)[2] = (x);             \
-} while(0)
-*/
 
 #define NR_FIVEGS_TAC_ID_TO_BIT_STRING(x, aSN)      \
 do {                                                    \
@@ -497,20 +468,6 @@ do {                                                    \
     (bITsTRING)->bits_unused = 0;                       \
 } while(0)
 
-#define BIT_STRING_TO_MaskedIMEISV(bITsTRING, mACRO)    \
-do {                                                                    \
-    DevCheck((bITsTRING)->size == 8, (bITsTRING)->size, 8, 0);          \
-    DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \
-    mACRO = ((bITsTRING)->buf[0] << 56) +                               \
-            ((bITsTRING)->buf[1] << 48) +                               \
-            ((bITsTRING)->buf[2] << 40) +                               \
-            ((bITsTRING)->buf[3] << 32) +                               \
-            ((bITsTRING)->buf[4] << 24) +                               \
-            ((bITsTRING)->buf[5] << 16) +                               \
-            ((bITsTRING)->buf[6] << 8) +                                \
-            ((bITsTRING)->buf[7]);                                      \
-} while (0)
-
 /* TS 36.413 v10.9.0 section 9.2.1.37:
  * Macro eNB ID:
  * Equal to the 20 leftmost bits of the Cell