diff --git a/CMakeLists.txt b/CMakeLists.txt
index 631de36ea60cf85fe542bbf9ede87d0619f6ccf7..69c8eeaa242c2d563cfae91275b88b1fb4f3dad4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1774,6 +1774,7 @@ add_library (GTPV1U
   ${OPENAIR3_DIR}/ocp-gtpu/gtp_itf.cpp
   )
 target_link_libraries(GTPV1U PRIVATE asn1_nr_rrc asn1_lte_rrc)
+target_link_libraries(GTPV1U PRIVATE SIMU)
 include_directories(${OPENAIR3_DIR}/ocp-gtp)
 
 set (MME_APP_SRC
@@ -2120,13 +2121,6 @@ add_library(LIB_5GNAS_GNB
 target_link_libraries(LIB_5GNAS_GNB PRIVATE SECU_CN ${CRYPTO_LIBRARIES})
 target_link_libraries(LIB_5GNAS_GNB PRIVATE asn1_nr_rrc asn1_lte_rrc)
 
-add_library(SIMU_COMMON
-  ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
-  ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
-  ${OPENAIR1_DIR}/SIMULATION/TOOLS/phase_noise.c
-  )
-target_link_libraries(SIMU_COMMON PRIVATE asn1_nr_rrc asn1_lte_rrc)
-
 # Simulation library
 ##########################
 set (SIMUSRC
@@ -2135,15 +2129,15 @@ set (SIMUSRC
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/multipath_tv_channel.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/abstraction.c
   ${OPENAIR1_DIR}/SIMULATION/TOOLS/channel_sim.c
+  ${OPENAIR1_DIR}/SIMULATION/TOOLS/random_channel.c
+  ${OPENAIR1_DIR}/SIMULATION/TOOLS/rangen_double.c
+  ${OPENAIR1_DIR}/SIMULATION/TOOLS/phase_noise.c
   ${OPENAIR1_DIR}/SIMULATION/RF/rf.c
   ${OPENAIR1_DIR}/SIMULATION/RF/dac.c
   ${OPENAIR1_DIR}/SIMULATION/RF/adc.c
-  #${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
-  )
-
-# Simulation library
-##########################
-add_library(SIMU SHARED ${SIMUSRC} )
+)
+add_library(SIMU STATIC ${SIMUSRC} )
+target_include_directories(SIMU PUBLIC ${OPENAIR1_DIR}/SIMULATION/TOOLS ${OPENAIR1_DIR}/SIMULATION/RF)
 target_link_libraries(SIMU PRIVATE asn1_nr_rrc asn1_lte_rrc)
 
 add_library(SIMU_ETH
@@ -2201,7 +2195,7 @@ add_library(rfsimulator MODULE
   ${OPENAIR_DIR}/radio/rfsimulator/apply_channelmod.c
   ${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
 	)
-target_link_libraries(rfsimulator PRIVATE SIMU_COMMON ${ATLAS_LIBRARIES})
+target_link_libraries(rfsimulator PRIVATE SIMU ${ATLAS_LIBRARIES})
 target_link_libraries(rfsimulator PRIVATE asn1_nr_rrc asn1_lte_rrc)
 
 add_library(oai_iqplayer MODULE
@@ -2290,7 +2284,6 @@ add_executable(lte-softmodem
   ${OPENAIR_DIR}/executables/lte-softmodem.c
   ${OPENAIR_DIR}/executables/softmodem-common.c
   ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
-  ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_DIR}/executables/create_tasks.c
   ${OPENAIR_DIR}/executables/create_tasks_mbms.c
   ${OPENAIR_DIR}/radio/COMMON/common_lib.c
@@ -2315,7 +2308,7 @@ target_link_libraries(lte-softmodem PRIVATE
   -Wl,--start-group
   lte_rrc nr_rrc s1ap m2ap x2ap m3ap GTPV1U f1ap SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB
   PHY_COMMON PHY PHY_RU  L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
-  ${RAL_LIB} ${NAS_UE_LIB} ITTI
+  ${RAL_LIB} ${NAS_UE_LIB} ITTI SIMU
   -Wl,--end-group z dl)
 
 target_link_libraries(lte-softmodem PRIVATE ${LIBXML2_LIBRARIES})
@@ -2331,7 +2324,6 @@ add_executable(ocp-enb
   ${OPENAIR_DIR}/executables/main-fs6.c
   ${OPENAIR_DIR}/executables/transport_split.c
   ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
-  ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_DIR}/executables/create_tasks.c
   ${OPENAIR_DIR}/executables/create_tasks_mbms.c
   ${OPENAIR_DIR}/radio/COMMON/common_lib.c
@@ -2354,7 +2346,7 @@ add_dependencies(ocp-enb oai_iqplayer coding params_libconfig rfsimulator)
 target_link_libraries (ocp-enb
   -Wl,--start-group
   lte_rrc nr_rrc s1ap f1ap m2ap x2ap m3ap GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB SCHED_RU_LIB
-  PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU_COMMON
+  PHY_COMMON PHY PHY_RU L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU
   ${RAL_LIB} ${NAS_UE_LIB} ITTI
   -Wl,--end-group z dl)
 target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${CMAKE_DL_LIBS} ${LIB_LMS_LIBRARIES} ${T_LIB})
@@ -2415,7 +2407,7 @@ target_link_libraries(lte-uesoftmodem PRIVATE
   -Wl,--start-group
   lte_rrc nr_rrc s1ap x2ap m2ap m3ap
   SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
-  PHY_UE PHY_RU L2_UE L2_LTE SIMU_COMMON SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
+  PHY_UE PHY_RU L2_UE L2_LTE SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB MISC_NFAPI_LTE_LIB
   ${RAL_LIB} ${NAS_UE_LIB} ITTI ${ATLAS_LIBRARIES}
   -Wl,--end-group z dl)
 
@@ -2441,7 +2433,6 @@ add_executable(nr-softmodem
   ${OPENAIR_DIR}/executables/nr-ru.c
   ${OPENAIR_DIR}/executables/nr-softmodem.c
   ${OPENAIR_DIR}/executables/softmodem-common.c
-  ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_DIR}/radio/COMMON/common_lib.c
   ${OPENAIR_DIR}/radio/COMMON/record_player.c
   ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
@@ -2460,12 +2451,12 @@ target_link_libraries(nr-softmodem PRIVATE
   -Wl,--start-group
   UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA
   ITTI ${RAL_LIB} ${NAS_UE_LIB} lte_rrc nr_rrc
-  ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
+  ngap s1ap L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB SIMU
   x2ap f1ap m2ap m3ap
   -Wl,--end-group z dl)
 
 target_link_libraries(nr-softmodem PRIVATE ${LIBXML2_LIBRARIES})
-target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp  ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES})
+target_link_libraries(nr-softmodem PRIVATE pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${ATLAS_LIBRARIES})
 target_link_libraries(nr-softmodem PRIVATE ${LIB_LMS_LIBRARIES})
 target_link_libraries(nr-softmodem PRIVATE ${T_LIB})
 target_link_libraries(nr-softmodem PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2490,7 +2481,6 @@ add_executable(nr-uesoftmodem
   ${OPENAIR_DIR}/executables/nr-uesoftmodem.c
   ${OPENAIR_DIR}/executables/nr-ue.c
   ${OPENAIR_DIR}/executables/softmodem-common.c
-  ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
   ${OPENAIR_DIR}/radio/COMMON/common_lib.c
   ${OPENAIR_DIR}/radio/COMMON/record_player.c
   ${OPENAIR2_DIR}/RRC/NAS/nas_config.c
@@ -2509,7 +2499,7 @@ target_link_libraries(nr-uesoftmodem PRIVATE
   nr_rrc SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_NR_UE_LIB
   PHY_COMMON PHY_NR_COMMON PHY_NR_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
   NFAPI_USER_LIB MISC_NFAPI_NR_LIB
-  ${RAL_LIB} ITTI ${ATLAS_LIBRARIES} LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB}
+  ${RAL_LIB} ITTI ${ATLAS_LIBRARIES} LIB_5GNAS_GNB LIB_NAS_SIMUE ${NAS_SIM_LIB} SIMU
   -Wl,--end-group z dl)
 
 target_link_libraries(nr-uesoftmodem PRIVATE ${LIBXML2_LIBRARIES})
@@ -2543,7 +2533,7 @@ add_executable(dlsim_tm4
   ${T_SOURCE}
   )
 target_link_libraries (dlsim_tm4
-  -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY ITTI -Wl,--end-group
+  -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY ITTI -Wl,--end-group
   pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES} ${T_LIB}
   )
 
@@ -2563,7 +2553,7 @@ add_executable(polartest
   ${SHLIB_LOADER_SOURCES}
   )
 target_link_libraries(polartest PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON  SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR PHY_NR_COMMON PHY_NR_UE CONFIG_LIB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} dl
   )
 target_link_libraries(polartest PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2576,7 +2566,7 @@ add_executable(smallblocktest
 )
 
 target_link_libraries(smallblocktest PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} dl
 )
 target_link_libraries(smallblocktest PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2594,7 +2584,7 @@ if (CUDA_FOUND)
    add_dependencies( ldpctest ldpc_cuda)
 endif (CUDA_FOUND)
 target_link_libraries(ldpctest PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON  SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_NR PHY_COMMON PHY_NR_COMMON CONFIG_LIB -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} dl
   )
 target_link_libraries(ldpctest PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2607,7 +2597,7 @@ add_executable(nr_dlschsim
   ${SHLIB_LOADER_SOURCES}
   )
 target_link_libraries(nr_dlschsim PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
   )
 target_link_libraries(nr_dlschsim PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2619,7 +2609,7 @@ add_executable(nr_pbchsim
   ${SHLIB_LOADER_SOURCES}
   )
 target_link_libraries(nr_pbchsim PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
 )
 target_link_libraries(nr_pbchsim PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2634,7 +2624,7 @@ add_executable(nr_pucchsim
   ${SHLIB_LOADER_SOURCES}
   )
 target_link_libraries(nr_pucchsim PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
 )
 target_link_libraries(nr_pucchsim PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2652,7 +2642,7 @@ add_executable(nr_dlsim
   ${SHLIB_LOADER_SOURCES}
   )
 target_link_libraries(nr_dlsim PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl
   )
 target_link_libraries(nr_dlsim PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2670,7 +2660,7 @@ add_executable(nr_prachsim
   ${T_SOURCE}
   ${SHLIB_LOADER_SOURCES})
 target_link_libraries(nr_prachsim PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl)
 target_link_libraries(nr_prachsim PRIVATE asn1_nr_rrc asn1_lte_rrc)
 
@@ -2683,7 +2673,7 @@ add_executable(nr_ulschsim
   ${SHLIB_LOADER_SOURCES}
   )
 target_link_libraries(nr_ulschsim PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB CONFIG_LIB MAC_NR_COMMON -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI dl
 )
 target_link_libraries(nr_ulschsim PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2706,7 +2696,7 @@ add_dependencies( nr_ulsim ldpc_offload)
 endif ()
 
 target_link_libraries(nr_ulsim PRIVATE
-  -Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group
+  -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON lte_rrc nr_rrc CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE x2ap SECU_CN ngap NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB -lz -Wl,--end-group
   m pthread ${ATLAS_LIBRARIES} ${T_LIB} ITTI ${OPENSSL_LIBRARIES} dl
   )
 target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
@@ -2725,7 +2715,7 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
     ${NFAPI_USER_DIR}/nfapi.c
     )
   target_link_libraries (${myExe} PRIVATE
-    -Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU ITTI -Wl,--end-group
+    -Wl,--start-group SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU ITTI -Wl,--end-group
     pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES}  ${XFORMS_LIBRARIES} ${T_LIB} dl
     )
   target_link_libraries(${myExe} PRIVATE asn1_nr_rrc asn1_lte_rrc)
@@ -2773,7 +2763,7 @@ if (${T_TRACER})
         NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
         PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_COMMON PHY_NR_UE PHY_RU PHY_MEX
         L2 L2_LTE L2_NR L2_LTE_NR L2_UE NR_L2_UE L2_UE_LTE_NR MAC_NR_COMMON MAC_NR MAC_UE_NR ngap
-        CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU_COMMON SIMU SIMU_ETH OPENAIR0_LIB
+        CN_UTILS GTPV1U SCTP_CLIENT MME_APP LIB_NAS_UE NB_IoT SIMU SIMU_ETH OPENAIR0_LIB
         ldpc_orig ldpc_optim ldpc_optim8seg ldpc dfts)
     if (TARGET ${i})
       add_dependencies(${i} generate_T)
diff --git a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml
index 468005f54f677f8208ded94f278a67a7088e746e..8a6c67fa34b8aeaf4dd5adfeab7443f123641537 100644
--- a/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml
+++ b/ci-scripts/xml_files/fr1_sa_oaiue_n310.xml
@@ -54,7 +54,7 @@
 	<testCase id="040000">
 		<class>Initialize_eNB</class>
 		<desc>Initialize gNB</desc>
-		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf --sa --usrp-tx-thread-config 1 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
+		<Initialize_eNB_args>-O ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf --sa --usrp-tx-thread-config 1 --tune-offset 30000000 --thread-pool 1,3,5,7,9,11,13,15 --gNBs.[0].min_rxtxtime 5 --log_config.global_log_options level,nocolor,time</Initialize_eNB_args>
 		<eNB_instance>0</eNB_instance>
 		<eNB_serverId>0</eNB_serverId>
 		<air_interface>nr</air_interface>
diff --git a/cmake_targets/autotests/run_exec_autotests.bash b/cmake_targets/autotests/run_exec_autotests.bash
index 2bb42f3d4dda3749e2a86a3e2a36d4392f90ab8c..0b8c86795e0449dbff7d55c6f5ee334ba43418b4 100755
--- a/cmake_targets/autotests/run_exec_autotests.bash
+++ b/cmake_targets/autotests/run_exec_autotests.bash
@@ -114,6 +114,7 @@ function test_run() {
 
      for (( run_index=1; run_index <= $nruns; run_index++ ))
       do
+        temp_exec_log="$log_dir/test.$test_case_name.${tags_array[$tags_array_index]}.run_$run_index"
         echo "</EXECUTION LOG Test Case = $test_case_name.${tags_array[$tags_array_index]},  Run = $run_index >" >> $temp_exec_log  2>&1
         cat "$temp_exec_log" >> "$log_file"  2>&1
 
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index bce610b560129176653a6c306e05fb31d5e03258..48770b752621d095dfc72a0309cd7fb43c58152c 100755
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -440,30 +440,30 @@
                                  (Test23: 3GPP G-FR1-A5-14, PUSCH Type B, 100 MHz BW, 30 kHz SCS, 4 RX Antennas Requirements Test),
                                  (Test24: 3GPP G-FR1-A5-14, PUSCH Type B, 100 MHz BW, 30 kHz SCS, 8 RX Antennas Requirements Test)</desc>
       <main_exec>nr_ulsim</main_exec>
-      <main_exec_args>-n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z2 -s12.4 -S12.4
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z4 -s8.5 -S8.5
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z8 -s5.4 -S5.4
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z2 -s12.5 -S12.5
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z4 -s8.9 -S8.9
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z8 -s5.7 -S5.7
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z2 -s12.6 -S12.6
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z4 -s8.9 -S8.9
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z8 -s5.8 -S5.8
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.3 -S12.3
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.8 -S8.8
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.7 -S5.7
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z2 -s12.5 -S12.5
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z4 -s8.6 -S8.6
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z8 -s5.6 -S5.6
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z2 -s12.5 -S12.5
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z4 -s8.6 -S8.6
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z8 -s5.6 -S5.6
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.5 -S12.5
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.7 -S8.7
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.5 -S5.5
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z2 -s13.1 -S13.1
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z4 -s9.2 -S9.2
-                      -n100 -b14 -I15 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z8 -s5.9 -S5.9</main_exec_args>
+      <main_exec_args>-n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z2 -s12.4 -S12.4
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z4 -s8.5 -S8.5
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 0,1,1,2 -z8 -s5.4 -S5.4
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z2 -s12.5 -S12.5
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z4 -s8.9 -S8.9
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R25 -r25 -U 1,1,1,2 -z8 -s5.7 -S5.7
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z2 -s12.6 -S12.6
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z4 -s8.9 -S8.9
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R52 -r52 -U 1,1,1,2 -z8 -s5.8 -S5.8
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.3 -S12.3
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.8 -S8.8
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 0 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.7 -S5.7
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z2 -s12.5 -S12.5
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z4 -s8.6 -S8.6
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R24 -r24 -U 1,1,1,2 -z8 -s5.6 -S5.6
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z2 -s12.5 -S12.5
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z4 -s8.6 -S8.6
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R51 -r51 -U 1,1,1,2 -z8 -s5.6 -S5.6
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z2 -s12.5 -S12.5
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z4 -s8.7 -S8.7
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R106 -r106 -U 1,1,1,2 -z8 -s5.5 -S5.5
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z2 -s13.1 -S13.1
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z4 -s9.2 -S9.2
+                      -n100 -b14 -I7 -i 0,1 -g A,l,10 -t70 -u 1 -m20 -R273 -r273 -U 1,1,1,2 -z8 -s5.9 -S5.9</main_exec_args>
       <tags>test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 test22 test23 test24</tags>
       <search_expr_true>PUSCH test OK</search_expr_true>
       <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
diff --git a/common/openairinterface5g_limits.h b/common/openairinterface5g_limits.h
index f420722350f8163fd2bce6a23e696e04ce258c2e..2349941cf232324aaf7cdc951038d1dca167261a 100644
--- a/common/openairinterface5g_limits.h
+++ b/common/openairinterface5g_limits.h
@@ -27,7 +27,6 @@
 #        ifndef PHYSIM
 #            ifndef UE_EXPANSION
 #                    define NUMBER_OF_UE_MAX 40
-#                    define NUMBER_OF_NR_UE_MAX 4
 #                    define NUMBER_OF_CONNECTED_eNB_MAX 1
 #                    define NUMBER_OF_CONNECTED_gNB_MAX 1
 #            else
@@ -37,7 +36,6 @@
 #            endif
 #        else
 #                    define NUMBER_OF_UE_MAX 4
-#                    define NUMBER_OF_NR_UE_MAX 4
 #                    define NUMBER_OF_CONNECTED_eNB_MAX 1
 #                    define NUMBER_OF_CONNECTED_gNB_MAX 1
 #        endif
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index d8398def67b745a2131f4cdb48bed6d3a7172499..1dcafd47517e23629d552221da0849205cb3181b 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -227,7 +227,8 @@ void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset) {
   *n_rb = 6*count;
 }
 
-int get_nb_periods_per_frame(uint8_t tdd_period) {
+int get_nb_periods_per_frame(uint8_t tdd_period)
+{
 
   int nb_periods_per_frame;
   switch(tdd_period) {
@@ -270,7 +271,13 @@ int get_nb_periods_per_frame(uint8_t tdd_period) {
 }
 
 
-int get_dmrs_port(int nl, uint16_t dmrs_ports) {
+int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols)
+{
+  return (nrofDownlinkSlots + (nrofDownlinkSymbols != 0 && nrofUplinkSymbols == 0));
+}
+
+int get_dmrs_port(int nl, uint16_t dmrs_ports)
+{
 
   if (dmrs_ports == 0) return 0; // dci 1_0
   int p = -1;
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
index 893dcba7015c9e9494d9cade913ea0aa7ac03c49..8cd210dec8acdf36d6863e42b59e1280e1fbd500 100644
--- a/common/utils/nr/nr_common.h
+++ b/common/utils/nr/nr_common.h
@@ -63,6 +63,7 @@ static inline int get_num_dmrs(uint16_t dmrs_mask ) {
   return(num_dmrs);
 }
 
+int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols);
 int cce_to_reg_interleaving(const int R, int k, int n_shift, const int C, int L, const int N_regs);
 int get_SLIV(uint8_t S, uint8_t L);
 void get_coreset_rballoc(uint8_t *FreqDomainResource,int *n_rb,int *rb_offset);
diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md
index e69c8328bc11a629e93be003b772f358a028b442..3f7ffc9fdb24bba9dd800ab9876d4e7b4349b3a6 100644
--- a/doc/FEATURE_SET.md
+++ b/doc/FEATURE_SET.md
@@ -357,7 +357,8 @@ The following features are valid for the gNB and the 5G-NR UE.
   - RRCSetupRequest/RRCSetup/RRCSetupComplete
   - RRC Uplink/Downlink Information transfer carrying NAS messages transparently
   - RRC Reconfiguration/Reconfiguration complete
-  - Support for master cell group configuration 
+  - Paging
+  - Support for master cell group configuration
   - Interface with NGAP for the interactions with the AMF
   - Interface with F1AP for CU/DU split deployment option
   - Periodic RRC measurements of serving cell (no A/B events)
diff --git a/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md
index fccab23cf829463ec5a71b9ff85405f7ebd8d834..8d82b1964f464fc39eea5dd2ec66e2af4008db1c 100644
--- a/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md
+++ b/doc/NR_SA_CN5G_gNB_USRP_COTS_UE_Tutorial.md
@@ -17,7 +17,7 @@
 [[_TOC_]]
 
 #  1. Scenario
-In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB, OAI UE and COTS UE.
+In this tutorial we describe how to configure and run a 5G end-to-end setup with OAI CN5G, OAI gNB, OAI nrUE and COTS UE.
 
 Minimum hardware requirements:
 - Laptop/Desktop/Server for OAI CN5G and OAI gNB
@@ -233,13 +233,14 @@ iperf -s -u -i 1 -B 12.1.1.2
 docker exec -it oai-ext-dn iperf -u -t 86400 -i 1 -fk -B 192.168.70.135 -b 100M -c 12.1.1.2
 ```
 
-## 5.2 Testing with OAI UE
-### 5.2.1 Testing with OAI UE with USRP B210
+## 5.2 Testing with OAI nrUE
+### 5.2.1 Testing with OAI nrUE with USRP B210
 Important notes:
 - This should be run in a second Ubuntu 20.04 host, other than gNB
 - It only applies when running OAI gNB with USRP B210
+- OAI gNB must run with the following flag: `--gNBs.[0].min_rxtxtime 6`
 
-Run OAI UE
+Run OAI nrUE
 ```bash
 cd ~/openairinterface5g
 source oaienv
@@ -247,12 +248,12 @@ cd cmake_targets/ran_build/build
 sudo ./nr-uesoftmodem -r 106 --numerology 1 --band 78 -C 3619200000 --nokrnmod --ue-fo-compensation --sa -E --uicc0.imsi 001010000000001 --uicc0.nssai_sd 1
 ```
 
-### 5.2.2 Testing with OAI UE with RFsimulator
+### 5.2.2 Testing with OAI nrUE with RFsimulator
 Important notes:
 - This should be run on the same host as the OAI gNB
 - It only applies when running OAI gNB with RFsimulator
 
-Run OAI UE with RFsimulator
+Run OAI nrUE with RFsimulator
 ```bash
 cd ~/openairinterface5g
 source oaienv
@@ -291,6 +292,8 @@ sudo ethtool -G enp1s0f0 tx 4096 rx 4096
 ```
 
 ## 6.2 Real-time performance workarounds
+- Enable Performance Mode in Ubuntu 22:
+  - Settings/Power/Power Mode: Performance
 - If you get real-time problems on heavy UL traffic, reduce the maximum UL MCS using an additional command-line switch: `--MACRLCs.[0].ul_max_mcs 14`.
 
 ## 6.3 Uplink issues related with noise on the DC carriers
diff --git a/doc/nr-ue-design.md b/doc/nr-ue-design.md
new file mode 100644
index 0000000000000000000000000000000000000000..32abe6bd80f1b908c78f88d89d247653798cbab7
--- /dev/null
+++ b/doc/nr-ue-design.md
@@ -0,0 +1,34 @@
+# PHY and MAC Interface
+The PHY sends scheduling requests and data indication to MAC via `nr_ue_dl_indication` for DL path and `nr_ue_ul_indication()` for UL path and the MAC sends scheduling configuration to PHY via `nr_ue_scheduled_response()`. The following diagram shows the interaction for PDCCH and PDSCH reception.
+```mermaid
+sequenceDiagram
+    PHY->>+MAC: Requests for PDCCH config (via nr_ue_dl_indication)
+    MAC->>+PHY: Schedules PDCCH reception (via nr_ue_scheduled_response)
+    PHY->>+MAC: Indicates decoded DCI(s) (via nr_ue_dl_indication)
+    MAC->>+PHY: Schedules PDSCH reception (via nr_ue_scheduled_response)
+```
+
+# Multi-threading Design
+The `UE_thread` function in `nr-ue.c` is the main top level thread that interacts with the radio unit. Once the thread spawns, it starts the 'Initial Synchronization'. Once its complete, the regular processing of slots commences.
+
+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.
+
+## Initial Synchronization Block
+```mermaid
+graph TD
+    A(Start) -->|UE_thread| B["readFrame<br/>--Reads samples worth 2 frames"]
+    B --> |Tpool thread| C["UE_synch<br/>--PSS & SSS detection<br/>--PBCH decode"]
+    B --> |UE_thread| D["readFrame<br/>--trash samples to unblock radio"]
+    C --> |Tpool thread| E[syncInFrame<br/>--shift first sample to start of frame]
+    D --> |UE_thread| E
+```
+## Regular Slot Processing
+```mermaid
+graph TD
+    E[syncInFrame<br/>--shift first sample to start of frame] -->|UE_thread| F["trx_read_func (slot n)"]
+    F --> |Tpool thread| G["processSlotTX (slot n+4)<br/>--PUSCH encode<br/>--PUCCH encode<br/>--trx_write_func"]
+    F --> |UE_thread| H["UE_processing (slot n)<br/>--PDCCH decode<br/>--PDSCH decode"]
+    G --> |Tpool thread| I(Merge)
+    H --> |UE_thread| I(Merge)
+    I --> |Go to next slot<br/>UE_thread| F
+```
diff --git a/docker/Dockerfile.lteUE.rhel8.2 b/docker/Dockerfile.lteUE.rhel8.2
index 701e65c8caf6df6164f66761266598a31f1e9d7d..de4a315ce4b934c37dcc1375ec59698fdc130413 100644
--- a/docker/Dockerfile.lteUE.rhel8.2
+++ b/docker/Dockerfile.lteUE.rhel8.2
@@ -70,7 +70,6 @@ COPY --from=lte-ue-build \
     /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \
     /oai-ran/cmake_targets/ran_build/build/libcoding.so \
     /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
-    /oai-ran/cmake_targets/ran_build/build/libSIMU.so \
     /oai-ran/cmake_targets/ran_build/build/libdfts.so \
     /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
     /usr/local/lib/
diff --git a/docker/Dockerfile.lteUE.ubuntu18 b/docker/Dockerfile.lteUE.ubuntu18
index e070ba20aff222337519aa77f53478a353bce3bb..7f1b30c2c73c60de6951763d14e06a4d22666bee 100644
--- a/docker/Dockerfile.lteUE.ubuntu18
+++ b/docker/Dockerfile.lteUE.ubuntu18
@@ -76,7 +76,6 @@ COPY --from=lte-ue-build \
     /oai-ran/cmake_targets/ran_build/build/liboai_usrpdevif.so \
     /oai-ran/cmake_targets/ran_build/build/libcoding.so \
     /oai-ran/cmake_targets/ran_build/build/libparams_libconfig.so \
-    /oai-ran/cmake_targets/ran_build/build/libSIMU.so \
     /oai-ran/cmake_targets/ran_build/build/libdfts.so \
     /oai-ran/cmake_targets/ran_build/build/libtelnetsrv.so \
     /usr/local/lib/
diff --git a/docker/Dockerfile.phySim.rhel8.2 b/docker/Dockerfile.phySim.rhel8.2
index ba044d6203d305e63f79c30322496ba847e51662..c3f6d258b3df398a4753b2eb1af341f6294253e8 100644
--- a/docker/Dockerfile.phySim.rhel8.2
+++ b/docker/Dockerfile.phySim.rhel8.2
@@ -89,7 +89,6 @@ COPY --from=phy-sim-build \
     /lib64/libxslt.so.1 \
     /usr/lib64/libasan.so.5 \
     /oai-ran/cmake_targets/ran_build/build/libdfts.so \
-    /oai-ran/cmake_targets/ran_build/build/libSIMU.so \
     /oai-ran/cmake_targets/ran_build/build/libldpc.so \
     /oai-ran/cmake_targets/ran_build/build/libldpc_orig.so \
     /usr/local/lib/
diff --git a/executables/docs/nr-ue-design.md b/executables/docs/nr-ue-design.md
deleted file mode 100644
index 0b0b940d5fa2d4cca79e5204287a43a94df84150..0000000000000000000000000000000000000000
--- a/executables/docs/nr-ue-design.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Multi-threading Design
-The `UE_thread` function in `nr-ue.c` is the main top level thread that interacts with the radio unit. Once the thread spawns, it starts the 'Initial Syncronization'. Once its complete, the regular processing of slots commences.
-
-## Initial Syncronization Block
-```mermaid
-graph TD
-    A(Start) -->|UE_thread| B["readFrame<br/>--Reads samples worth 2 frames"]
-    B --> |Tpool thread| C["UE_synch<br/>--PSS & SSS detection<br/>--PBCH decode"]
-    B --> |UE_thread| D["readFrame<br/>--trash samples to unblock radio"]
-    C --> |Tpool thread| E[syncInFrame<br/>--shift first sample to start of frame]
-    D --> |UE_thread| E
-```
-## Regular Slot Processing
-```mermaid
-graph TD
-    E[syncInFrame<br/>--shift first sample to start of frame] -->|UE_thread| F["trx_read_func (slot n)"]
-    F --> |Tpool thread| G["processSlotTX (slot n+4)<br/>--PUSCH encode<br/>--PUCCH encode<br/>--trx_write_func"]
-    F --> |UE_thread| H["UE_processing (slot n)<br/>--PDCCH decode<br/>--PDSCH decode"]
-    G --> |Tpool thread| I(Merge)
-    H --> |UE_thread| I(Merge)
-    I --> |Go to next slot<br/>UE_thread| F
-```
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index 2e0dde6c675c2035a0a83d7fc5ad41d272a2dd39..cd64a6628734814888d98d3a6653869d8e2a667a 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -31,8 +31,6 @@
 #include "SCHED_NR_UE/defs.h"
 #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h"
 #include "executables/softmodem-common.h"
-#include "LAYER2/nr_pdcp/nr_pdcp_entity.h"
-#include "openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h"
 #include "PHY/NR_REFSIG/refsig_defs_ue.h"
 #include "radio/COMMON/common_lib.h"
 
@@ -103,8 +101,6 @@ typedef enum {
   si = 2
 } sync_mode_t;
 
-queue_t nr_rach_ind_queue;
-
 static void *NRUE_phy_stub_standalone_pnf_task(void *arg);
 
 static size_t dump_L1_UE_meas_stats(PHY_VARS_NR_UE *ue, char *output, size_t max_len)
@@ -154,17 +150,13 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
                      uint8_t abstraction_flag)
 {
 
-  int nb_connected_gNB = 1, gNB_id;
+  int nb_connected_gNB = 1;
 
   ue->Mod_id      = UE_id;
   ue->mac_enabled = 1;
   ue->if_inst     = nr_ue_if_module_init(0);
   ue->dci_thres   = 0;
 
-  // Setting UE mode to NOT_SYNCHED by default
-  for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++)
-    ue->UE_mode[gNB_id] = NOT_SYNCHED;
-
   // initialize all signal buffers
   init_nr_ue_signal(ue, nb_connected_gNB);
 
@@ -196,47 +188,6 @@ void init_nrUE_standalone_thread(int ue_idx)
   pthread_setname_np(phy_thread, "oai:nrue-stand-phy");
 }
 
-static void L1_nsa_prach_procedures(frame_t frame, int slot, fapi_nr_ul_config_prach_pdu *prach_pdu)
-{
-  NR_UE_MAC_INST_t *mac    = get_mac_inst(0);
-  nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind));
-  rach_ind->sfn = frame;
-  rach_ind->slot = slot;
-  rach_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION;
-
-  uint8_t pdu_index = 0;
-  rach_ind->pdu_list = CALLOC(1, sizeof(*rach_ind->pdu_list));
-  rach_ind->number_of_pdus  = 1;
-  rach_ind->pdu_list[pdu_index].phy_cell_id                         = prach_pdu->phys_cell_id;
-  rach_ind->pdu_list[pdu_index].symbol_index                        = prach_pdu->prach_start_symbol;
-  rach_ind->pdu_list[pdu_index].slot_index                          = prach_pdu->prach_slot;
-  rach_ind->pdu_list[pdu_index].freq_index                          = prach_pdu->num_ra;
-  rach_ind->pdu_list[pdu_index].avg_rssi                            = 128;
-  rach_ind->pdu_list[pdu_index].avg_snr                             = 0xff; // invalid for now
-
-  rach_ind->pdu_list[pdu_index].num_preamble                        = 1;
-  const int num_p = rach_ind->pdu_list[pdu_index].num_preamble;
-  rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t));
-  uint8_t preamble_index = get_softmodem_params()->nsa ?
-                           mac->ra.rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[0]->ra_PreambleIndex :
-                           mac->ra.ra_PreambleIndex;
-  rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index     = preamble_index;
-
-  rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance     = 0;
-  rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr       = 0xffffffff;
-
-  if (!put_queue(&nr_rach_ind_queue, rach_ind))
-  {
-    for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++)
-    {
-      free(rach_ind->pdu_list[pdu_index].preamble_list);
-    }
-    free(rach_ind->pdu_list);
-    free(rach_ind);
-  }
-  LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n");
-}
-
 static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
 {
   nfapi_nr_rach_indication_t *rach_ind = unqueue_matching(&nr_rach_ind_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
@@ -248,14 +199,12 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
             NFAPI_SFNSLOT2SFN(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot),
             NFAPI_SFNSLOT2SLOT(mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot), nr_ul_tti_req_queue.num_items);
     nfapi_nr_ul_tti_request_t *ul_tti_request_crc = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot);
-    if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0)
-    {
+    if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0) {
       check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc);
     }
   }
 
-  if (rach_ind && rach_ind->number_of_pdus > 0)
-  {
+  if (rach_ind && rach_ind->number_of_pdus > 0) {
       NR_UL_IND_t UL_INFO = {
         .rach_ind = *rach_ind,
       };
@@ -266,74 +215,32 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
       }
       free_and_zero(rach_ind->pdu_list);
       free_and_zero(rach_ind);
-      nr_Msg1_transmitted(0);
   }
-  if (dl_tti_request)
-  {
+  if (dl_tti_request) {
     int dl_tti_sfn_slot = NFAPI_SFNSLOT2HEX(dl_tti_request->SFN, dl_tti_request->Slot);
     nfapi_nr_tx_data_request_t *tx_data_request = unqueue_matching(&nr_tx_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &dl_tti_sfn_slot);
-    if (!tx_data_request)
-    {
+    if (!tx_data_request) {
       LOG_E(NR_MAC, "[%d %d] No corresponding tx_data_request for given dl_tti_request sfn/slot\n",
             NFAPI_SFNSLOT2SFN(dl_tti_sfn_slot), NFAPI_SFNSLOT2SLOT(dl_tti_sfn_slot));
       if (get_softmodem_params()->nsa)
         save_nr_measurement_info(dl_tti_request);
       free_and_zero(dl_tti_request);
     }
-    else if (dl_tti_request->dl_tti_request_body.nPDUs > 0 && tx_data_request->Number_of_PDUs > 0)
-    {
+    else if (dl_tti_request->dl_tti_request_body.nPDUs > 0 && tx_data_request->Number_of_PDUs > 0) {
       if (get_softmodem_params()->nsa)
         save_nr_measurement_info(dl_tti_request);
       check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL);
     }
-    else
-    {
+    else {
       AssertFatal(false, "We dont have PDUs in either dl_tti %d or tx_req %d\n",
                   dl_tti_request->dl_tti_request_body.nPDUs, tx_data_request->Number_of_PDUs);
     }
   }
-  if (ul_dci_request && ul_dci_request->numPdus > 0)
-  {
+  if (ul_dci_request && ul_dci_request->numPdus > 0) {
     check_and_process_dci(NULL, NULL, ul_dci_request, NULL);
   }
 }
 
-static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
-{
-  fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx);
-  if (!ul_config)
-  {
-    LOG_E(NR_MAC, "mac->ul_config is null! \n");
-    return;
-  }
-  if (mac->ra.ra_state != RA_SUCCEEDED)
-  {
-    AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
-                "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
-    fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
-    uint8_t nr_prach = nr_ue_get_rach(prach_pdu,
-                                      ul_info->module_id,
-                                      ul_info->cc_id,
-                                      ul_info->frame_tx,
-                                      ul_info->gNB_index,
-                                      ul_info->slot_tx);
-    if (nr_prach == 1)
-    {
-      L1_nsa_prach_procedures(ul_info->frame_tx, ul_info->slot_tx, prach_pdu);
-      ul_config->number_pdus = 0;
-      ul_info->ue_sched_mode = SCHED_PUSCH;
-    }
-    else if (nr_prach == 2)
-    {
-      LOG_I(NR_PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, ul_info->module_id);
-    }
-    else if(nr_prach == 3)
-    {
-      LOG_I(NR_PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, ul_info->module_id);
-    }
-  }
-}
-
 static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
 {
   LOG_I(MAC, "Clearing Queues\n");
@@ -358,17 +265,14 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
       mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn_slot = -1;
   }
 
-  while (!oai_exit)
-  {
-    if (sem_wait(&sfn_slot_semaphore) != 0)
-    {
+  while (!oai_exit) {
+    if (sem_wait(&sfn_slot_semaphore) != 0) {
       LOG_E(NR_MAC, "sem_wait() error\n");
       abort();
     }
     uint16_t *slot_ind = get_queue(&nr_sfn_slot_queue);
     nr_phy_channel_params_t *ch_info = get_queue(&nr_chan_param_queue);
-    if (!slot_ind && !ch_info)
-    {
+    if (!slot_ind && !ch_info) {
       LOG_D(MAC, "get nr_sfn_slot_queue and nr_chan_param_queue == NULL!\n");
       continue;
     }
@@ -383,8 +287,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
 
     frame_t frame = NFAPI_SFNSLOT2SFN(sfn_slot);
     int slot = NFAPI_SFNSLOT2SLOT(sfn_slot);
-    if (sfn_slot == last_sfn_slot)
-    {
+    if (sfn_slot == last_sfn_slot) {
       LOG_D(NR_MAC, "repeated sfn_sf = %d.%d\n",
             frame, slot);
       continue;
@@ -394,19 +297,16 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
     LOG_D(NR_MAC, "The received sfn/slot [%d %d] from proxy\n",
           frame, slot);
 
-    if (get_softmodem_params()->sa && mac->mib == NULL)
-    {
+    if (get_softmodem_params()->sa && mac->mib == NULL) {
       LOG_D(NR_MAC, "We haven't gotten MIB. Lets see if we received it\n");
       nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment);
       process_queued_nr_nfapi_msgs(mac, sfn_slot);
     }
-    if (mac->scc == NULL && mac->scc_SIB == NULL)
-    {
+    if (mac->scc == NULL && mac->scc_SIB == NULL) {
       LOG_D(MAC, "[NSA] mac->scc == NULL and [SA] mac->scc_SIB == NULL!\n");
       continue;
     }
 
-    mac->ra.generate_nr_prach = 0;
     int CC_id = 0;
     uint8_t gNB_id = 0;
     nr_uplink_indication_t ul_info;
@@ -419,7 +319,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
     ul_info.slot_rx = slot;
     ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame;
     ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx;
-    ul_info.ue_sched_mode = SCHED_PUSCH;
 
     if (pthread_mutex_lock(&mac->mutex_dl_info)) abort();
 
@@ -441,8 +340,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
     if (is_nr_DL_slot(get_softmodem_params()->nsa ?
                       mac->scc->tdd_UL_DL_ConfigurationCommon :
                       mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
-                      ul_info.slot_rx))
-    {
+                      ul_info.slot_rx)) {
       nr_ue_dl_indication(&mac->dl_info, &ul_time_alignment);
     }
 
@@ -451,13 +349,11 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
     if (is_nr_UL_slot(get_softmodem_params()->nsa ?
                       mac->scc->tdd_UL_DL_ConfigurationCommon :
                       mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
-                      ul_info.slot_tx, mac->frame_type))
-    {
+                      ul_info.slot_tx, mac->frame_type)) {
       LOG_D(NR_MAC, "Slot %d. calling nr_ue_ul_ind() and nr_ue_pucch_scheduler() from %s\n", ul_info.slot_tx, __FUNCTION__);
       nr_ue_scheduler(NULL, &ul_info);
       nr_ue_prach_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx);
       nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, NULL);
-      check_nr_prach(mac, &ul_info);
     }
     if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) {
       NR_UE_MAC_INST_t *mac = get_mac_inst(0);
@@ -682,14 +578,13 @@ void processSlotTX(void *arg) {
       ul_indication.slot_rx   = proc->nr_slot_rx;
       ul_indication.frame_tx  = proc->frame_tx;
       ul_indication.slot_tx   = proc->nr_slot_tx;
-      ul_indication.ue_sched_mode = rxtxD->ue_sched_mode;
       ul_indication.phy_data      = &phy_data;
 
       UE->if_inst->ul_indication(&ul_indication);
       stop_meas(&UE->ue_ul_indication_stats);
     }
 
-    phy_procedures_nrUE_TX(UE, proc, proc->gNB_id, &phy_data);
+    phy_procedures_nrUE_TX(UE, proc, &phy_data);
   }
 
   RU_write(rxtxD);
@@ -699,7 +594,6 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
 
   UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
   PHY_VARS_NR_UE    *UE   = rxtxD->UE;
-  uint8_t gNB_id = 0;
   nr_phy_data_t phy_data = {0};
 
   if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa) {
@@ -716,7 +610,7 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
 
     if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
       nr_downlink_indication_t dl_indication;
-      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, gNB_id, &phy_data);
+      nr_fill_dl_indication(&dl_indication, NULL, NULL, proc, UE, &phy_data);
       UE->if_inst->dl_indication(&dl_indication, NULL);
     }
 
@@ -725,7 +619,7 @@ void UE_processing(nr_rxtx_thread_data_t *rxtxD) {
     phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
 #else
     uint64_t a=rdtsc_oai();
-    phy_procedures_nrUE_RX(UE, proc, gNB_id, &phy_data);
+    phy_procedures_nrUE_RX(UE, proc, &phy_data);
     LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
 #endif
 
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 091fc813e912ed5c699c7fc72473f73289edb3c1..21710940d6c9cce797cbc9a03d32e0361258ccd8 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -189,8 +189,6 @@ typedef struct {
   uint8_t  restricted_set;
   /// see TS 38.211 (6.3.3.2).
   uint16_t freq_msg1;
-  // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble
-  uint8_t ssb_nb_in_ro;
   /// Preamble index for PRACH (0-63)
   uint8_t ra_PreambleIndex;
   /// PRACH TX power (TODO possibly modify to uint)
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index 08d47bad0bf32d7c637efc5fd35c0dd33fe97893..ac7d1ceed926585822dfe55a3615d0ce94d3d9ee 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -39,104 +39,6 @@
 
 extern uint16_t beta_cqi[16];
 
-/*! \brief Helper function to allocate memory for DLSCH data structures.
- * \param[out] pdsch Pointer to the LTE_UE_PDSCH structure to initialize.
- * \param[in] frame_parms LTE_DL_FRAME_PARMS structure.
- * \note This function is optimistic in that it expects malloc() to succeed.
- */
-void phy_init_nr_ue_PDSCH(NR_UE_PDSCH *const pdsch,
-                           const NR_DL_FRAME_PARMS *const fp) {
-
-  AssertFatal( pdsch, "pdsch==0" );
-
-  pdsch->llr128 = (int16_t **)malloc16_clear( sizeof(int16_t *) );
-  // FIXME! no further allocation for (int16_t*)pdsch->llr128 !!! expect SIGSEGV
-  // FK, 11-3-2015: this is only as a temporary pointer, no memory is stored there
-  pdsch->rxdataF_ext            = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->rxdataF_uespec_pilots  = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->rxdataF_comp0          = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->rho                    = (int32_t ***)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t **) );
-  pdsch->dl_ch_estimates        = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->dl_ch_estimates_ext    = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->dl_bf_ch_estimates     = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->dl_bf_ch_estimates_ext = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->dl_ch_mag0             = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->dl_ch_magb0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->dl_ch_magr0            = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->ptrs_phase_per_slot    = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
-  pdsch->ptrs_re_per_slot       = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
-  // the allocated memory size is fixed:
-  AssertFatal( fp->nb_antennas_rx <= 4, "nb_antennas_rx > 4" );//Extend the max number of UE Rx antennas to 4
-
-  const size_t num = 7*2*fp->N_RB_DL*12;
-  for (int i=0; i<fp->nb_antennas_rx; i++) {
-    pdsch->rxdataF_ext[i]              = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-    pdsch->rxdataF_uespec_pilots[i]    = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->N_RB_DL*12);
-    pdsch->ptrs_phase_per_slot[i]      = (int32_t *)malloc16_clear( sizeof(int32_t) * 14 );
-    pdsch->ptrs_re_per_slot[i]         = (int32_t *)malloc16_clear( sizeof(int32_t) * 14);
-    pdsch->rho[i]                      = (int32_t **)malloc16_clear( NR_MAX_NB_LAYERS*NR_MAX_NB_LAYERS*sizeof(int32_t *) );
-
-    for (int j=0; j<NR_MAX_NB_LAYERS; j++) {
-      const int idx = (j*fp->nb_antennas_rx)+i;
-      for (int k=0; k<NR_MAX_NB_LAYERS; k++) {
-        pdsch->rho[i][j*NR_MAX_NB_LAYERS+k] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      }
-      pdsch->rxdataF_comp0[idx]           = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_estimates[idx]         = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
-      pdsch->dl_ch_estimates_ext[idx]     = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_bf_ch_estimates[idx]      = (int32_t *)malloc16_clear( sizeof(int32_t) * fp->ofdm_symbol_size*7*2);
-      pdsch->dl_bf_ch_estimates_ext[idx]  = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_mag0[idx]              = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_magb0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-      pdsch->dl_ch_magr0[idx]             = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
-    }
-  }
-}
-
-void phy_term_nr_ue__PDSCH(NR_UE_PDSCH* pdsch, const NR_DL_FRAME_PARMS *const fp)
-{
-  for (int i = 0; i < fp->nb_antennas_rx; i++) {
-    for (int j = 0; j < NR_MAX_NB_LAYERS; j++) {
-      const int idx = j * fp->nb_antennas_rx + i;
-      for (int k = 0; k < NR_MAX_NB_LAYERS; k++)
-        free_and_zero(pdsch->rho[i][j*NR_MAX_NB_LAYERS+k]);
-      free_and_zero(pdsch->rxdataF_comp0[idx]);
-      free_and_zero(pdsch->dl_ch_estimates[idx]);
-      free_and_zero(pdsch->dl_ch_estimates_ext[idx]);
-      free_and_zero(pdsch->dl_bf_ch_estimates[idx]);
-      free_and_zero(pdsch->dl_bf_ch_estimates_ext[idx]);
-      free_and_zero(pdsch->dl_ch_mag0[idx]);
-      free_and_zero(pdsch->dl_ch_magb0[idx]);
-      free_and_zero(pdsch->dl_ch_magr0[idx]);
-    }
-    free_and_zero(pdsch->rxdataF_ext[i]);
-    free_and_zero(pdsch->rxdataF_uespec_pilots[i]);
-    free_and_zero(pdsch->ptrs_phase_per_slot[i]);
-    free_and_zero(pdsch->ptrs_re_per_slot[i]);
-    free_and_zero(pdsch->rho[i]);
-  }
-  free_and_zero(pdsch->pmi_ext);
-  int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-  for (int i=0; i<nb_codewords; i++)
-    free_and_zero(pdsch->llr[i]);
-  for (int i=0; i<NR_MAX_NB_LAYERS; i++)
-    free_and_zero(pdsch->layer_llr[i]);
-  free_and_zero(pdsch->llr128);
-  free_and_zero(pdsch->rxdataF_ext);
-  free_and_zero(pdsch->rxdataF_uespec_pilots);
-  free_and_zero(pdsch->rxdataF_comp0);
-  free_and_zero(pdsch->rho);
-  free_and_zero(pdsch->dl_ch_estimates);
-  free_and_zero(pdsch->dl_ch_estimates_ext);
-  free_and_zero(pdsch->dl_bf_ch_estimates);
-  free_and_zero(pdsch->dl_bf_ch_estimates_ext);
-  free_and_zero(pdsch->dl_ch_mag0);
-  free_and_zero(pdsch->dl_ch_magb0);
-  free_and_zero(pdsch->dl_ch_magr0);
-  free_and_zero(pdsch->ptrs_phase_per_slot);
-  free_and_zero(pdsch->ptrs_re_per_slot);
-}
-
 void RCconfig_nrUE_prs(void *cfg)
 {
   int j = 0, k = 0, gNB_id = 0;
@@ -406,11 +308,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   // init RX buffers
   common_vars->rxdata   = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
-  common_vars->rxdataF  = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) );
 
   for (i=0; i<fp->nb_antennas_rx; i++) {
     common_vars->rxdata[i] = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+fp->ofdm_symbol_size)*sizeof(int32_t) );
-    common_vars->rxdataF[i] = (int32_t *)malloc16_clear( sizeof(int32_t)*(fp->samples_per_slot_wCP) );
   }
 
   // ceil(((NB_RB<<1)*3)/32) // 3 RE *2(QPSK)
@@ -453,19 +353,6 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   }
 
   // DLSCH
-  for (gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) {
-    ue->pdsch_vars[gNB_id] = (NR_UE_PDSCH *)malloc16_clear(sizeof(NR_UE_PDSCH));
-    phy_init_nr_ue_PDSCH( ue->pdsch_vars[gNB_id], fp );
-
-    int nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
-    for (i=0; i<nb_codewords; i++) {
-      ue->pdsch_vars[gNB_id]->llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
-    }
-    for (i=0; i<NR_MAX_NB_LAYERS; i++) {
-      ue->pdsch_vars[gNB_id]->layer_llr[i] = (int16_t *)malloc16_clear( (8*(3*8*8448))*sizeof(int16_t) );//Q_m = 8 bits/Sym, Code_Rate=3, Number of Segments =8, Circular Buffer K_cb = 8448
-    }
-  }
-
   for (gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
     prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
     pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH));
@@ -539,9 +426,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
   for (int i = 0; i < fp->nb_antennas_rx; i++) {
     free_and_zero(common_vars->rxdata[i]);
-    free_and_zero(common_vars->rxdataF[i]);
   }
-  free_and_zero(common_vars->rxdataF);
   free_and_zero(common_vars->rxdata);
 
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
@@ -564,10 +449,6 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   for (int gNB_id = 0; gNB_id < ue->n_connected_gNB+1; gNB_id++) {
 
     // PDSCH
-    free_and_zero(ue->pdsch_vars[gNB_id]->llr_shifts);
-    free_and_zero(ue->pdsch_vars[gNB_id]->llr128_2ndstream);
-    phy_term_nr_ue__PDSCH(ue->pdsch_vars[gNB_id], fp);
-    free_and_zero(ue->pdsch_vars[gNB_id]);
   }
 
   for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) {
@@ -628,7 +509,7 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   }
 }
 
-void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb) {
+void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb) {
 
   uint16_t a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS;
   if (num_rb != 273) {
@@ -636,19 +517,21 @@ void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int
     a_segments = (a_segments/273)+1;
   }
 
-  for (int i=0; i<number_of_processes; i++) {
-    free_and_zero(harq_list[i].b);
+  for (int j=0; j < 2; j++) {
+    for (int i=0; i<number_of_processes; i++) {
+      free_and_zero(harq_list[j][i].b);
 
-    for (int r=0; r<a_segments; r++) {
-      free_and_zero(harq_list[i].c[r]);
-      free_and_zero(harq_list[i].d[r]);
+      for (int r=0; r<a_segments; r++) {
+        free_and_zero(harq_list[j][i].c[r]);
+        free_and_zero(harq_list[j][i].d[r]);
+      }
+      free_and_zero(harq_list[j][i].c);
+      free_and_zero(harq_list[j][i].d);
     }
-    free_and_zero(harq_list[i].c);
-    free_and_zero(harq_list[i].d);
   }
 }
 
-void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx) {
+void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx) {
 
   int max_layers = (num_ant_tx < NR_MAX_NB_LAYERS) ? num_ant_tx : NR_MAX_NB_LAYERS;
   uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*max_layers;  //number of segments to be allocated
@@ -676,14 +559,11 @@ void term_nr_ue_transport(PHY_VARS_NR_UE *ue)
 {
   const int N_RB_DL = ue->frame_parms.N_RB_DL;
   const int N_RB_UL = ue->frame_parms.N_RB_UL;
-  int num_cw = NR_MAX_NB_LAYERS > 4? 2:1;
-  for (int j = 0; j < num_cw; j++) {
-    free_nr_ue_dl_harq(ue->dl_harq_processes[j], NR_MAX_DLSCH_HARQ_PROCESSES, N_RB_DL);
-  }
+  free_nr_ue_dl_harq(ue->dl_harq_processes, NR_MAX_DLSCH_HARQ_PROCESSES, N_RB_DL);
   free_nr_ue_ul_harq(ue->ul_harq_processes, NR_MAX_ULSCH_HARQ_PROCESSES, N_RB_UL, ue->frame_parms.nb_antennas_tx);
 }
 
-void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb) {
+void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb) {
 
   int a_segments = MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER*NR_MAX_NB_LAYERS;  //number of segments to be allocated
   if (num_rb != 273) {
@@ -693,35 +573,39 @@ void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_process
 
   uint32_t dlsch_bytes = a_segments*1056;  // allocated bytes per segment
 
-  for (int i=0; i<number_of_processes; i++) {
-    memset(harq_list + i, 0, sizeof(NR_DL_UE_HARQ_t));
-    init_downlink_harq_status(harq_list + i);
-    harq_list[i].b = malloc16(dlsch_bytes);
+  for (int j=0; j<2; j++) {
+    for (int i=0; i<number_of_processes; i++) {
+      memset(harq_list[j] + i, 0, sizeof(NR_DL_UE_HARQ_t));
+      init_downlink_harq_status(harq_list[j] + i);
+      harq_list[j][i].b = malloc16(dlsch_bytes);
 
-    if (harq_list[i].b)
-      memset(harq_list[i].b, 0, dlsch_bytes);
-    else
-      AssertFatal(true, "Unable to reset harq memory \"b\"\n");
-
-    harq_list[i].c = malloc16(a_segments*sizeof(uint8_t *));
-    harq_list[i].d = malloc16(a_segments*sizeof(int16_t *));
-    for (int r=0; r<a_segments; r++) {
-      harq_list[i].c[r] = malloc16(1056);
-      harq_list[i].d[r] = malloc16(5*8448*sizeof(int16_t));
-      if (harq_list[i].c[r])
-        memset(harq_list[i].c[r],0,1056);
-      else
-        AssertFatal(true, "Unable to reset harq memory \"c\"\n");
-
-      if (harq_list[i].d[r])
-        memset(harq_list[i].d[r],0,5*8448);
+      if (harq_list[j][i].b)
+        memset(harq_list[j][i].b, 0, dlsch_bytes);
       else
-        AssertFatal(true, "Unable to reset harq memory \"d\"\n");
+        AssertFatal(true, "Unable to reset harq memory \"b\"\n");
+
+      harq_list[j][i].c = malloc16(a_segments*sizeof(uint8_t *));
+      harq_list[j][i].d = malloc16(a_segments*sizeof(int16_t *));
+      for (int r=0; r<a_segments; r++) {
+        harq_list[j][i].c[r] = malloc16(1056);
+        harq_list[j][i].d[r] = malloc16(5*8448*sizeof(int16_t));
+        if (harq_list[j][i].c[r])
+          memset(harq_list[j][i].c[r],0,1056);
+        else
+          AssertFatal(true, "Unable to reset harq memory \"c\"\n");
+
+        if (harq_list[j][i].d[r])
+          memset(harq_list[j][i].d[r],0,5*8448);
+        else
+          AssertFatal(true, "Unable to reset harq memory \"d\"\n");
+      }
+      harq_list[j][i].status  = 0;
+      harq_list[j][i].DLround = 0;
     }
   }
 }
 
-void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx) {
+void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx) {
 
   int max_layers = (num_ant_tx < NR_MAX_NB_LAYERS) ? num_ant_tx : NR_MAX_NB_LAYERS;
   uint16_t a_segments = MAX_NUM_NR_ULSCH_SEGMENTS_PER_LAYER*max_layers;  //number of segments to be allocated
@@ -772,11 +656,7 @@ void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t *harq_list, int number_of_process
 
 void init_nr_ue_transport(PHY_VARS_NR_UE *ue) {
 
-  int num_codeword = NR_MAX_NB_LAYERS > 4? 2:1;
-
-  for (int j=0; j<num_codeword; j++) {
-    nr_init_dl_harq_processes(ue->dl_harq_processes[j], NR_MAX_DLSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_DL);
-  }
+  nr_init_dl_harq_processes(ue->dl_harq_processes, NR_MAX_DLSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_DL);
   nr_init_ul_harq_processes(ue->ul_harq_processes, NR_MAX_ULSCH_HARQ_PROCESSES, ue->frame_parms.N_RB_UL, ue->frame_parms.nb_antennas_tx);
 
   for(int i=0; i<5; i++)
diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h
index ed4b83fa5db7bcea81001e6384639208ca908685..5ec47c1dae48f3d849bca1122ad10863a51aa0ff 100644
--- a/openair1/PHY/INIT/phy_init.h
+++ b/openair1/PHY/INIT/phy_init.h
@@ -418,10 +418,10 @@ void reset_DLSCH_struct(const PHY_VARS_gNB *gNB, processingData_L1tx_t *msg);
 
 void RCconfig_nrUE_prs(void *cfg);
 void init_nr_prs_ue_vars(PHY_VARS_NR_UE *ue);
-void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb);
-void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx);
-void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t* harq_list, int number_of_processes, int num_rb);
-void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t *harq_list, int number_of_processes, int num_rb, int num_ant_tx);
+void nr_init_dl_harq_processes(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb);
+void nr_init_ul_harq_processes(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx);
+void free_nr_ue_dl_harq(NR_DL_UE_HARQ_t harq_list[2][NR_MAX_DLSCH_HARQ_PROCESSES], int number_of_processes, int num_rb);
+void free_nr_ue_ul_harq(NR_UL_UE_HARQ_t harq_list[NR_MAX_ULSCH_HARQ_PROCESSES], int number_of_processes, int num_rb, int num_ant_tx);
 
 /** @} */
 #endif
diff --git a/openair1/PHY/MODULATION/modulation_UE.h b/openair1/PHY/MODULATION/modulation_UE.h
index 6ed10a8c77c3cf355235500d93ed10a175646f9b..031b444323b7f5699f1f3a0f827e749a625a9169 100644
--- a/openair1/PHY/MODULATION/modulation_UE.h
+++ b/openair1/PHY/MODULATION/modulation_UE.h
@@ -51,14 +51,14 @@ int slot_fep(PHY_VARS_UE *phy_vars_ue,
 int nr_slot_fep(PHY_VARS_NR_UE *phy_vars_ue,
                 UE_nr_rxtx_proc_t *proc,
                 unsigned char l,
-                unsigned char Ns);
+                c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP]);
 
 int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
                           UE_nr_rxtx_proc_t *proc,
                           unsigned char symbol,
-                          unsigned char Ns,
                           int sample_offset,
-                          bool pbch_decoded);
+                          bool pbch_decoded,
+                          c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 int slot_fep_mbsfn(PHY_VARS_UE *phy_vars_ue,
                    unsigned char l,
diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c
index a8bbe343551a3c9949b58c564a5495eed2363492..d902c2af479d8e92dda6a62592070725bbe0690a 100644
--- a/openair1/PHY/MODULATION/slot_fep_nr.c
+++ b/openair1/PHY/MODULATION/slot_fep_nr.c
@@ -37,10 +37,11 @@
 int nr_slot_fep(PHY_VARS_NR_UE *ue,
                 UE_nr_rxtx_proc_t *proc,
                 unsigned char symbol,
-                unsigned char Ns)
+                c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   NR_UE_COMMON *common_vars      = &ue->common_vars;
+  int Ns = proc->nr_slot_rx;
 
   AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
   AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
@@ -75,8 +76,6 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
   //#endif
 
   for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    memset(&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
-
     int16_t *rxdata_ptr = (int16_t *)&common_vars->rxdata[aa][rx_offset];
 
     // if input to dft is not 256-bit aligned
@@ -92,7 +91,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
 
     dft(dftsize,
         rxdata_ptr,
-        (int16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+        (int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
         1);
 
     stop_meas(&ue->rx_dft_stats);
@@ -108,7 +107,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
 #endif
 
     c16_t *shift_rot = frame_parms->timeshift_symbol_rotation;
-    c16_t *this_symbol = (c16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol];
+    c16_t *this_symbol = &rxdataF[aa][frame_parms->ofdm_symbol_size*symbol];
 
     if (frame_parms->N_RB_DL & 1) {
       rotate_cpx_vector(this_symbol, &rot2, this_symbol,
@@ -149,12 +148,13 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
 int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
                           UE_nr_rxtx_proc_t *proc,
                           unsigned char symbol,
-                          unsigned char Ns,
                           int sample_offset,
-                          bool pbch_decoded)
+                          bool pbch_decoded,
+                          c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   NR_UE_COMMON *common_vars   = &ue->common_vars;
+  int Ns = proc->nr_slot_rx;
 
   AssertFatal(symbol < frame_parms->symbols_per_slot, "slot_fep: symbol must be between 0 and %d\n", frame_parms->symbols_per_slot-1);
   AssertFatal(Ns < frame_parms->slots_per_frame, "slot_fep: Ns must be between 0 and %d\n", frame_parms->slots_per_frame-1);
@@ -189,7 +189,6 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
 #endif
 
   for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    memset(&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int32_t));
 
     int16_t *rxdata_ptr;
     rx_offset%=frame_length_samples*2;
@@ -225,7 +224,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
 
     dft(dftsize,
         rxdata_ptr,
-        (int16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
+        (int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
         1);
 
     stop_meas(&ue->rx_dft_stats);
@@ -240,7 +239,7 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue,
 	   symbol+symb_offset,rot2.r,rot2.i);
 #endif
 
-    c16_t *this_symbol = (c16_t *)&common_vars->rxdataF[aa][frame_parms->ofdm_symbol_size*symbol];
+    c16_t *this_symbol = &rxdataF[aa][frame_parms->ofdm_symbol_size*symbol];
     rotate_cpx_vector(this_symbol, &rot2, this_symbol, frame_parms->ofdm_symbol_size, 15);
   }
 
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c
index 1fd502a93e1369526ac012dd7905a24b6a94e3a8..179c5d9cbd320375480eca104814194cef7c9759 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.c
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c
@@ -341,7 +341,7 @@ int8_t get_valid_dmrs_idx_for_channel_est(uint16_t  dmrs_symb_pos, uint8_t count
 
 /* perform averaging of channel estimates and store result in first symbol buffer */
 void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
-                              int **ch_est,
+                              int32_t **ch_estimates,
                               uint8_t num_symbols,
                               uint8_t start_symbol,
                               uint16_t dmrs_bitmap,
@@ -356,9 +356,9 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
   AssertFatal(first_dmrs_symb > -1, "No DMRS symbol present in this slot\n");
   for (int aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
     for (int symb = first_dmrs_symb+1; symb < total_symbols; symb++) {
-      ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
+      ul_ch128_0 = (__m128i *)&ch_estimates[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
       if ((dmrs_bitmap >> symb) & 0x01) {
-        ul_ch128_1 = (__m128i *)&ch_est[aarx][symb*frame_parms->ofdm_symbol_size];
+        ul_ch128_1 = (__m128i *)&ch_estimates[aarx][symb*frame_parms->ofdm_symbol_size];
         for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) {
           ul_ch128_0[0] = _mm_adds_epi16(ul_ch128_0[0], ul_ch128_1[0]);
           ul_ch128_0[1] = _mm_adds_epi16(ul_ch128_0[1], ul_ch128_1[1]);
@@ -368,7 +368,7 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
         }
       }
     }
-    ul_ch128_0 = (__m128i *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
+    ul_ch128_0 = (__m128i *)&ch_estimates[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
     if (num_dmrs_symb == 2) {
       for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) {
         ul_ch128_0[0] = _mm_srai_epi16(ul_ch128_0[0], 1);
@@ -384,7 +384,7 @@ void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
         ul_ch128_0 += 3;
       }
     } else if (num_dmrs_symb == 3) {
-      ul_ch16_0 = (int16_t *)&ch_est[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
+      ul_ch16_0 = (int16_t *)&ch_estimates[aarx][first_dmrs_symb*frame_parms->ofdm_symbol_size];
       for (int rbIdx = 0; rbIdx < num_rbs; rbIdx++) {
         ul_ch16_0[0] /= 3;
         ul_ch16_0[1] /= 3;
diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.h b/openair1/PHY/NR_REFSIG/dmrs_nr.h
index 1297a0cc2ff7b2f95c65ccb2259fc77681094ed9..4611e363e57304b723db81e37138c6cc58a0a768 100644
--- a/openair1/PHY/NR_REFSIG/dmrs_nr.h
+++ b/openair1/PHY/NR_REFSIG/dmrs_nr.h
@@ -66,7 +66,7 @@ int8_t get_next_dmrs_symbol_in_slot(uint16_t  ul_dmrs_symb_pos, uint8_t counter,
 uint8_t get_dmrs_symbols_in_slot(uint16_t l_prime_mask,  uint16_t nb_symb);
 int8_t get_valid_dmrs_idx_for_channel_est(uint16_t  dmrs_symb_pos, uint8_t counter);
 void nr_chest_time_domain_avg(NR_DL_FRAME_PARMS *frame_parms,
-                              int **ch_est,
+                              int32_t **ch_estimates,
                               uint8_t num_symbols,
                               uint8_t start_symbol,
                               uint16_t dmrs_bitmap,
diff --git a/openair1/PHY/NR_REFSIG/sss_nr.h b/openair1/PHY/NR_REFSIG/sss_nr.h
index 03610ae30fb5adc597906d7f39e8ab8a27ad4b3c..212ee59c1d13e05a8429a1c9868c7abbc07c779c 100644
--- a/openair1/PHY/NR_REFSIG/sss_nr.h
+++ b/openair1/PHY/NR_REFSIG/sss_nr.h
@@ -96,7 +96,7 @@ int pss_ch_est_nr(PHY_VARS_NR_UE *ue,
                   int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
                   int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR]);
 
-int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss);
+int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 #undef INIT_VARIABLES_SSS_NR_H
 #undef EXTERN
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
index 983366e35e3eb13efc46a733bc4a33c4600c5d80..feed70b854c0a808c992f8d18eb7ff5b62299caf 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c
@@ -101,18 +101,9 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
       
   //printf("adjust sync count_max_pos_ok = %d\n",count_max_pos_ok);
 
-  if(count_max_pos_ok > 10 && first_time == 1)
-  {
+  if(count_max_pos_ok > 10 && first_time == 1) {
     first_time = 0;
     ue->time_sync_cell = 1;
-    if (get_softmodem_params()->do_ra || get_softmodem_params()->sa) {
-      LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
-      //mac_resynch();
-      //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
-      ue->UE_mode[0] = PRACH;
-    } else {
-      ue->UE_mode[0] = PUSCH;
-    }
   }
 
 #ifdef DEBUG_PHY
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 927734e538be53f3f9ccd60f3abb9540a56a0f95..0a0d92743d42e84e4de25236a18e7c46013152b8 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c
@@ -61,15 +61,15 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t
   *peak_idx = max_idx;
 }
 
-int nr_prs_channel_estimation(uint8_t gNB_id,
-                              uint8_t rsc_id,
+int nr_prs_channel_estimation(uint8_t rsc_id,
                               uint8_t rep_num,
                               PHY_VARS_NR_UE *ue,
                               UE_nr_rxtx_proc_t *proc,
-                              NR_DL_FRAME_PARMS *frame_params)
+                              NR_DL_FRAME_PARMS *frame_params,
+                              c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
+  int gNB_id = proc->gNB_id;
   uint8_t rxAnt = 0, idx = 0;
-  int32_t **rxdataF      = ue->common_vars.rxdataF;
   prs_config_t *prs_cfg  = &ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_cfg;
   prs_meas_t **prs_meas  = ue->prs_vars[gNB_id]->prs_resource[rsc_id].prs_meas;
   c16_t ch_tmp_buf[ ue->frame_parms.ofdm_symbol_size] __attribute__((aligned(32)));
@@ -567,11 +567,10 @@ int nr_prs_channel_estimation(uint8_t gNB_id,
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t gNB_id,
-                             unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
-                             NR_UE_SSB *current_ssb)
+                             NR_UE_SSB *current_ssb,
+                             c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
   int pilot[200] __attribute__((aligned(16)));
   unsigned short k;
@@ -583,7 +582,6 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
   uint8_t nushift;
   uint8_t ssb_index=current_ssb->i_ssb;
   uint8_t n_hf=current_ssb->n_hf;
-  int **rxdataF=ue->common_vars.rxdataF;
 
   nushift =  ue->frame_parms.Nid_cell%4;
   ue->frame_parms.nushift = nushift;
@@ -600,7 +598,7 @@ int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_PBCH
-  printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
+  printf("PBCH DMRS Correlation : gNB_id %d , OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
 #endif
 
   // generate pilot
@@ -730,13 +728,13 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                struct complex16 dl_ch_estimates [][estimateSz],
                                struct complex16 dl_ch_estimates_time [][ue->frame_parms.ofdm_symbol_size],
                                UE_nr_rxtx_proc_t *proc,
-                               uint8_t gNB_id,
-                               unsigned char Ns,
                                unsigned char symbol,
                                int dmrss,
                                uint8_t ssb_index,
-                               uint8_t n_hf)
+                               uint8_t n_hf,
+                               c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
+  int Ns = proc->nr_slot_rx;
   int pilot[200] __attribute__((aligned(16)));
   unsigned short k;
   unsigned int pilot_cnt;
@@ -745,8 +743,6 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   //int slot_pbch;
 
   uint8_t nushift;
-   int **rxdataF=ue->common_vars.rxdataF;
-
   nushift =  ue->frame_parms.Nid_cell%4;
   ue->frame_parms.nushift = nushift;
   unsigned int  ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
@@ -764,7 +760,7 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
   k = nushift;
 
 #ifdef DEBUG_PBCH
-  printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
+  printf("PBCH Channel Estimation : gNB_id %d ch_offset %d, OFDM size %d, Ncp=%d, Ns=%d, k=%d symbol %d\n", proc->gNB_id, ch_offset, ue->frame_parms.ofdm_symbol_size, ue->frame_parms.Ncp, Ns, k, symbol);
 #endif
 
   switch (k) {
@@ -994,24 +990,23 @@ int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                  UE_nr_rxtx_proc_t *proc,
-                                 uint8_t gNB_id,
-                                 unsigned char Ns,
                                  unsigned char symbol,
                                  fapi_nr_coreset_t *coreset,
                                  uint16_t first_carrier_offset,
                                  uint16_t BWPStart,
                                  int32_t pdcch_est_size,
-                                 int32_t pdcch_dl_ch_estimates[][pdcch_est_size])
+                                 int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                                 c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
 
+  int Ns = proc->nr_slot_rx;
+  int gNB_id = proc->gNB_id;
   unsigned char aarx;
   unsigned short k;
   unsigned int pilot_cnt;
   int16_t ch[2],*pil,*rxF,*dl_ch;
   int ch_offset,symbol_offset;
 
-  int **rxdataF=ue->common_vars.rxdataF;
-
   ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
 
   symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
@@ -1239,9 +1234,7 @@ void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t gNB_id,
                                 bool is_SI,
-                                unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
                                 unsigned char nscid,
@@ -1249,8 +1242,13 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned short BWPStart,
                                 uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
-                                unsigned short nb_rb_pdsch)
+                                unsigned short nb_rb_pdsch,
+                                uint32_t pdsch_est_size,
+                                int32_t dl_ch_estimates[][pdsch_est_size],
+                                c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
+  int gNB_id = proc->gNB_id;
+  int Ns = proc->nr_slot_rx;
   int pilot[3280] __attribute__((aligned(16)));
   unsigned char aarx;
   unsigned short k;
@@ -1260,9 +1258,6 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
   int ch_offset,symbol_offset;
 
   uint8_t nushift;
-  int **dl_ch_estimates = ue->pdsch_vars[gNB_id]->dl_ch_estimates;
-  int **rxdataF=ue->common_vars.rxdataF;
-
   ch_offset     = ue->frame_parms.ofdm_symbol_size*symbol;
 
   symbol_offset = ue->frame_parms.ofdm_symbol_size*symbol;
@@ -2030,7 +2025,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
  * NAME :         nr_pdsch_ptrs_processing
  *
  * PARAMETERS :   PHY_VARS_NR_UE    : ue data structure
- *                NR_UE_PDSCH       : pdsch_vars pointer
+ *                c16_t             : ptrs_phase_per_slot array
+ *                int32_t           : ptrs_re_per_slot array
+ *                uint32_t          : rx_size,
+ *                int32_t           : rxdataF_comp, array
  *                NR_DL_FRAME_PARMS : frame_parms pointer
  *                NR_DL_UE_HARQ_t   : dlsch0_harq pointer
  *                NR_DL_UE_HARQ_t   : dlsch1_harq pointer
@@ -2049,7 +2047,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
  *  3) Compensate signal with PTRS estimation for slot
  *********************************************************************/
 void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
-                              NR_UE_PDSCH **pdsch_vars,
+                              c16_t ptrs_phase_per_slot[][14],
+                              int32_t ptrs_re_per_slot[][14],
+                              uint32_t rx_size,
+                              int32_t rxdataF_comp[][rx_size],
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
@@ -2104,8 +2105,8 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
   }
   /* loop over antennas */
   for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-    c16_t *phase_per_symbol = (c16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx];
-    ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx];
+    c16_t *phase_per_symbol = (c16_t*)ptrs_phase_per_slot[aarx];
+    ptrs_re_symbol = (int32_t*)ptrs_re_per_slot[aarx];
     ptrs_re_symbol[symbol] = 0;
     phase_per_symbol[symbol].i = 0; // Imag
     /* set DMRS estimates to 0 angle with magnitude 1 */
@@ -2141,7 +2142,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
                                rnti,
                                nr_slot_rx,
                                symbol,frame_parms->ofdm_symbol_size,
-                               (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)],
+                               (int16_t*)&rxdataF_comp[aarx][(symbol * nb_re_pdsch)],
                                ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0],
                                (int16_t*)&phase_per_symbol[symbol],
                                &ptrs_re_symbol[symbol]);
@@ -2161,9 +2162,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
         }
       }
 #ifdef DEBUG_DL_PTRS
-      LOG_M("ptrsEst.m","est",pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
+      LOG_M("ptrsEst.m","est",ptrs_phase_per_slot[aarx],frame_parms->symbols_per_slot,1,1 );
       LOG_M("rxdataF_bf_ptrs_comp.m","bf_ptrs_cmp",
-            &pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
+            &rxdataF_comp[aarx][(*startSymbIndex) * NR_NB_SC_PER_RB * (*nb_rb) ],
             (*nb_rb) * NR_NB_SC_PER_RB * (*nbSymb),1,1);
 #endif
       /*------------------------------------------------------------------------------------------------------- */
@@ -2176,9 +2177,9 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
 #ifdef DEBUG_DL_PTRS
           printf("[PHY][DL][PTRS]: Rotate Symbol %2d with  %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i);
 #endif
-          rotate_cpx_vector((c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+          rotate_cpx_vector((c16_t*)&rxdataF_comp[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             &phase_per_symbol[i],
-                            (c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
+                            (c16_t*)&rxdataF_comp[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)],
                             ((*nb_rb) * NR_NB_SC_PER_RB), 15);
         }// if not DMRS Symbol
       }// symbol loop
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index c8ae045e1b1e313434795175f4662cea526f4ea8..cf4917369a1ebe8b0c26c56877d8a203401d95a5 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -33,12 +33,12 @@
 #define SYNCH_HYST 2
 
 /* A function to perform the channel estimation of DL PRS signal */
-int nr_prs_channel_estimation(uint8_t gNB_id,
-                              uint8_t rsc_id,
+int nr_prs_channel_estimation(uint8_t rsc_id,
                               uint8_t rep_num,
                               PHY_VARS_NR_UE *ue,
                               UE_nr_rxtx_proc_t *proc,
-                              NR_DL_FRAME_PARMS *frame_params);
+                              NR_DL_FRAME_PARMS *frame_params,
+                              c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 /* Generic function to find the peak of channel estimation buffer */
 void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t *peak_val);
@@ -52,40 +52,35 @@ void peak_estimator(int32_t *buffer, int32_t buf_len, int32_t *peak_idx, int32_t
 */
 void nr_pdcch_channel_estimation(PHY_VARS_NR_UE *ue,
                                  UE_nr_rxtx_proc_t *proc,
-                                 uint8_t gNB_id,
-                                 unsigned char Ns,
                                  unsigned char symbol,
                                  fapi_nr_coreset_t *coreset,
                                  uint16_t first_carrier_offset,
                                  uint16_t BWPStart,
                                  int32_t pdcch_est_size,
-                                 int32_t pdcch_dl_ch_estimates[][pdcch_est_size]);
+                                 int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
+                                 c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 int nr_pbch_dmrs_correlation(PHY_VARS_NR_UE *ue,
                              UE_nr_rxtx_proc_t *proc,
-                             uint8_t gNB_id,
-                             unsigned char Ns,
                              unsigned char symbol,
                              int dmrss,
-                             NR_UE_SSB *current_ssb);
+                             NR_UE_SSB *current_ssb,
+                             c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 int nr_pbch_channel_estimation(PHY_VARS_NR_UE *ue,
                                int estimateSz,
-			       struct complex16 dl_ch_estimates [][estimateSz],
-			       struct complex16 dl_ch_estimates_time [][estimateSz],
-			       UE_nr_rxtx_proc_t *proc,
-                               uint8_t gNB_id,
-                               unsigned char Ns,
+                               struct complex16 dl_ch_estimates [][estimateSz],
+                               struct complex16 dl_ch_estimates_time [][estimateSz],
+                               UE_nr_rxtx_proc_t *proc,
                                unsigned char symbol,
                                int dmrss,
                                uint8_t ssb_index,
-                               uint8_t n_hf);
+                               uint8_t n_hf,
+                               c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 UE_nr_rxtx_proc_t *proc,
-                                uint8_t gNB_id,
                                 bool is_SI,
-                                unsigned char Ns,
                                 unsigned short p,
                                 unsigned char symbol,
                                 unsigned char nscid,
@@ -93,7 +88,10 @@ int nr_pdsch_channel_estimation(PHY_VARS_NR_UE *ue,
                                 unsigned short BWPStart,
                                 uint8_t config_type,
                                 unsigned short bwp_start_subcarrier,
-                                unsigned short nb_rb_pdsch);
+                                unsigned short nb_rb_pdsch,
+                                uint32_t pdsch_est_size,
+                                int32_t pdsch_dl_ch_estimates[][pdsch_est_size],
+                                c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
                         PHY_VARS_NR_UE *ue,
@@ -107,24 +105,28 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
                       
 void nr_ue_measurements(PHY_VARS_NR_UE *ue,
                         UE_nr_rxtx_proc_t *proc,
-                        uint8_t slot,
-                        NR_UE_DLSCH_t *dlsch);
+                        NR_UE_DLSCH_t *dlsch,
+                        uint32_t pdsch_est_size,
+                        int32_t dl_ch_estimates[][pdsch_est_size]);
 
 void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
                                  uint8_t gNB_index,
                                  UE_nr_rxtx_proc_t *proc,
-                                 uint8_t slot);
+                                 c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
-                            uint8_t slot);
+                            c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
                         uint32_t rx_power_fil_dB,
                         uint8_t gNB_id);
 
 void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
-                              NR_UE_PDSCH **pdsch_vars,
+                              c16_t ptrs_phase_per_slot[][14],
+                              int32_t ptrs_re_per_slot[][14],
+                              uint32_t rx_size,
+                              int32_t rxdataF_comp[][rx_size],
                               NR_DL_FRAME_PARMS *frame_parms,
                               NR_DL_UE_HARQ_t *dlsch0_harq,
                               NR_DL_UE_HARQ_t *dlsch1_harq,
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
index 1b5689f33523ef0e7b3aa5e4224694d5aa166df8..5545f5c4bd4edf62af2e227cb840ecd21c27653b 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c
@@ -76,9 +76,11 @@ float_t get_nr_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t gNB_index)
 
 void nr_ue_measurements(PHY_VARS_NR_UE *ue,
                         UE_nr_rxtx_proc_t *proc,
-                        uint8_t slot,
-                        NR_UE_DLSCH_t *dlsch)
+                        NR_UE_DLSCH_t *dlsch,
+                        uint32_t pdsch_est_size,
+                        int32_t dl_ch_estimates[][pdsch_est_size])
 {
+  int slot = proc->nr_slot_rx;
   int aarx, aatx, gNB_id = 0;
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int ch_offset = frame_parms->ofdm_symbol_size*2;
@@ -97,7 +99,7 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
 
       for (aatx = 0; aatx < frame_parms->nb_antenna_ports_gNB; aatx++){
 
-        ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = (signal_energy_nodc(&ue->pdsch_vars[0]->dl_ch_estimates[gNB_id][ch_offset], N_RB_DL*NR_NB_SC_PER_RB));
+        ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = (signal_energy_nodc(&dl_ch_estimates[gNB_id][ch_offset], N_RB_DL*NR_NB_SC_PER_RB));
 
         if (ue->measurements.rx_spatial_power[gNB_id][aatx][aarx]<0)
           ue->measurements.rx_spatial_power[gNB_id][aatx][aarx] = 0;
@@ -170,10 +172,11 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
 void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
                                  int ssb_index,
                                  UE_nr_rxtx_proc_t *proc,
-                                 uint8_t slot) {
+                                 c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
   int k_start = 56;
   int k_end   = 183;
+  int slot = proc->nr_slot_rx;
   unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
   int symbol_offset = nr_get_ssb_start_symbol(&ue->frame_parms,ssb_index);
 
@@ -192,7 +195,7 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
 
   for (int aarx = 0; aarx < ue->frame_parms.nb_antennas_rx; aarx++) {
 
-    int16_t *rxF_sss = (int16_t *)&ue->common_vars.rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset];
+    int16_t *rxF_sss = (int16_t *)&rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset];
 
     for(int k = k_start; k < k_end; k++){
 
@@ -225,9 +228,10 @@ void nr_ue_ssb_rsrp_measurements(PHY_VARS_NR_UE *ue,
 // - psd_awgn (AWGN power spectral density):     dBm/Hz
 void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
-                            uint8_t slot){
+                            c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]){
 
   uint8_t k;
+  int slot = proc->nr_slot_rx;
   int aarx, nb_nulls;
   int16_t *rxF_sss;
   uint8_t k_left = 48;
@@ -246,7 +250,7 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
 
     nb_nulls = 0;
     ue->measurements.n0_power[aarx] = 0;
-    rxF_sss = (int16_t *)&ue->common_vars.rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset];
+    rxF_sss = (int16_t *)&rxdataF[aarx][(l_sss*ue->frame_parms.ofdm_symbol_size) + ssb_offset];
 
     //-ve spectrum from SSS
     for(k = k_left; k < k_left + k_length; k++){
diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c
index 64222cab9a34dd7e71b473a7c7987f48a23e765e..6768c8bc37005d94573451fa2a45d27bb9348c11 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c
@@ -190,9 +190,9 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
                          const uint8_t *l_overline,
                          int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP],
                          uint32_t *rsrp,
-                         int *rsrp_dBm) {
+                         int *rsrp_dBm,
+                         c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
-  int32_t **rxdataF  =  ue->common_vars.rxdataF;
   const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   uint16_t meas_count = 0;
   uint32_t rsrp_sum = 0;
@@ -218,7 +218,7 @@ int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue,
             for (int lp = 0; lp <= l_prime; lp++) {
               uint16_t symb = lp + l_overline[cdm_id];
               uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
-              c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset];
+              c16_t *rx_signal = &rxdataF[ant_rx][symbol_offset];
               c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
               rx_csi_rs_signal[k].r = rx_signal[k].r;
               rx_csi_rs_signal[k].i = rx_signal[k].i;
@@ -729,9 +729,9 @@ int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr,
 int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue,
                                const UE_nr_rxtx_proc_t *proc,
                                const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu,
-                               uint32_t *interference_plus_noise_power) {
+                               uint32_t *interference_plus_noise_power,
+                               c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
-  int32_t **rxdataF = ue->common_vars.rxdataF;
   const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
 
   const uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ?
@@ -764,7 +764,7 @@ int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue,
 
     for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
 
-      c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset];
+      c16_t *rx_signal = &rxdataF[ant_rx][symbol_offset];
 
       for (int rb = csiim_config_pdu->start_rb; rb < end_rb; rb++) {
 
@@ -800,8 +800,9 @@ int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue,
   return 0;
 }
 
-int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
+int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
+  int gNB_id = proc->gNB_id;
   if(!ue->csiim_vars[gNB_id]->active) {
     return -1;
   }
@@ -818,14 +819,15 @@ int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
   LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]);
 #endif
 
-  nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power);
+  nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power, rxdataF);
   ue->nr_csi_info->csi_im_meas_computed = true;
 
   return 0;
 }
 
-int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
+int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
+  int gNB_id = proc->gNB_id;
   if(!ue->csirs_vars[gNB_id]->active) {
     return -1;
   }
@@ -901,7 +903,8 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
                        l_overline,
                        csi_rs_received_signal,
                        &rsrp,
-                       &rsrp_dBm);
+                       &rsrp_dBm,
+                       rxdataF);
 
   nr_csi_rs_channel_estimation(ue,
                                proc,
@@ -958,8 +961,8 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
   csirs_measurements.cqi = cqi;
   nr_downlink_indication_t dl_indication;
   fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind),1);
-  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
-  nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, gNB_id, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements);
+  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, NULL);
+  nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements);
   if (ue->if_inst && ue->if_inst->dl_indication) {
     ue->if_inst->dl_indication(&dl_indication, NULL);
   } else {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
index 315519bf993960a6fd39d396238309a75516ad5a..423140fc7a3bddb7e02c428eb44e9cf83af03ea7 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
@@ -340,7 +340,8 @@ void nr_pdcch_channel_level(int32_t rx_size,
 
 
 // This function will extract the mapped DM-RS PDCCH REs as per 38.211 Section 7.4.1.3.2 (Mapping to physical resources)
-void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
+void nr_pdcch_extract_rbs_single(uint32_t rxdataF_sz,
+                                 c16_t rxdataF[][rxdataF_sz],
                                  int32_t est_size,
                                  int32_t dl_ch_estimates[][est_size],
                                  int32_t rx_size,
@@ -415,7 +416,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
       // first we set initial conditions for pointer to rxdataF depending on the situation of the first RB within the CORESET (c_rb = n_BWP_start)
       if (((c_rb + n_BWP_start) < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
         //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): even case
-        rxF = &rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
+        rxF = (int32_t *)&rxdataF[aarx][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size)))+n_BWP_start*12];
         LOG_DDD("in even case c_rb (%d) is lower than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))) = (%d)]\n",
                c_rb,aarx,(frame_parms->first_carrier_offset + 12 * c_rb + (symbol * (frame_parms->ofdm_symbol_size))));
       }
@@ -423,14 +424,14 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
       if (((c_rb + n_BWP_start) >= (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) == 0)) {
         // number of RBs is even  and c_rb is higher than half system bandwidth (we don't skip DC)
         // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF
-        rxF = &rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol
+        rxF = (int32_t *)&rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol
         LOG_DDD("in even case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size = (%d)]\n",
                c_rb,aarx,(12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) + symbol * frame_parms->ofdm_symbol_size));
       }
 
       if (((c_rb + n_BWP_start) < (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) {
         //if RB to be treated is lower than middle system bandwidth then rxdataF pointed at (offset + c_br + symbol * ofdm_symbol_size): odd case
-        rxF = &rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size];
+        rxF = (int32_t *)&rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size];
         LOG_DDD("in odd case c_rb (%d) is lower or equal than half N_RB_DL -> rxF = &rxdataF[aarx = (%d)][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size = (%d)]\n",
                c_rb,aarx,(frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size));
       }
@@ -438,7 +439,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
       if (((c_rb + n_BWP_start) > (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) {
         // number of RBs is odd  and   c_rb is higher than half system bandwidth + 1
         // if these conditions are true the pointer has to be situated at the 1st part of the rxdataF just after the first IQ symbols of the RB containing DC
-        rxF = &rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol
+        rxF = (int32_t *)&rxdataF[aarx][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol
         LOG_DDD("in odd case c_rb (%d) is higher than half N_RB_DL (not DC) -> rxF = &rxdataF[aarx = (%d)][12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size = (%d)]\n",
                c_rb,aarx,(12*(c_rb + n_BWP_start - (frame_parms->N_RB_DL>>1)) - 6 + symbol * frame_parms->ofdm_symbol_size));
       }
@@ -446,7 +447,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
       if (((c_rb + n_BWP_start) == (frame_parms->N_RB_DL >> 1)) && ((frame_parms->N_RB_DL & 1) != 0)) { // treatment of RB containing the DC
         // if odd number RBs in system bandwidth and first RB to be treated is higher than middle system bandwidth (around DC)
         // we have to treat the RB in two parts: first part from i=0 to 5, the data is at the end of rxdataF (pointing at the end of the table)
-        rxF = &rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size];
+        rxF = (int32_t *)&rxdataF[aarx][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size];
         LOG_DDD("in odd case c_rb (%d) is half N_RB_DL + 1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size = (%d)]\n",
                c_rb,aarx,(frame_parms->first_carrier_offset + 12 * (c_rb + n_BWP_start) + symbol * frame_parms->ofdm_symbol_size));
         j = 0;
@@ -467,7 +468,7 @@ void nr_pdcch_extract_rbs_single(int32_t **rxdataF,
         }
 
         // then we point at the begining of the symbol part of rxdataF do process second part of RB
-        rxF = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol
+        rxF = (int32_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; // we point at the 1st part of the rxdataF in symbol
         LOG_DDD("in odd case c_rb (%d) is half N_RB_DL +1 we treat DC case -> rxF = &rxdataF[aarx = (%d)][symbol * frame_parms->ofdm_symbol_size = (%d)]\n",
                c_rb,aarx,(symbol * frame_parms->ofdm_symbol_size));
         for (; i < 12; i++) {
@@ -671,11 +672,11 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
                     int32_t pdcch_est_size,
                     int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
                     int16_t *pdcch_e_rx,
-                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) {
+                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
+                    c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
   uint32_t frame = proc->frame_rx;
   uint32_t slot  = proc->nr_slot_rx;
-  NR_UE_COMMON *common_vars      = &ue->common_vars;
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
 
   uint8_t log2_maxh, aarx;
@@ -703,7 +704,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
   for (int s=rel15->coreset.StartSymbolIndex; s<(rel15->coreset.StartSymbolIndex+rel15->coreset.duration); s++) {
     LOG_D(PHY,"in nr_pdcch_extract_rbs_single(rxdataF -> rxdataF_ext || dl_ch_estimates -> dl_ch_estimates_ext)\n");
 
-    nr_pdcch_extract_rbs_single(common_vars->rxdataF,
+    nr_pdcch_extract_rbs_single(ue->frame_parms.samples_per_slot_wCP,
+                                rxdataF,
                                 pdcch_est_size,
                                 pdcch_dl_ch_estimates,
                                 rx_size,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
index 2a3de5a9bc879ae796176acb0bfe8cee6123e995..39d45a82d85ca61298f9d75a402909a5ee146f33 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
@@ -81,38 +81,40 @@ unsigned char offset_mumimo_llr_drange[29][3]={{8,8,8},{7,7,7},{7,7,7},{7,7,7},{
 #define print_shorts(s,x) printf("%s = [%d+j*%d, %d+j*%d, %d+j*%d, %d+j*%d]\n",s,(x)[0],(x)[1],(x)[2],(x)[3],(x)[4],(x)[5],(x)[6],(x)[7])
 
 /* compute H_h_H matrix inversion up to 4x4 matrices */
-uint8_t nr_zero_forcing_rx(int **rxdataF_comp,
-                                   int **dl_ch_mag,
-                                   int **dl_ch_magb,
-                                   int **dl_ch_magr,
-                                   int **dl_ch_estimates_ext,
-                                   unsigned short nb_rb,
-                                   unsigned char n_rx,
-                                   unsigned char n_tx,//number of layer
-                                   unsigned char mod_order,
-                                   int shift,
-                                   unsigned char symbol,
-                                   int length);
+uint8_t nr_zero_forcing_rx(uint32_t rx_size,
+                           int32_t rxdataF_comp[][rx_size],
+                           int32_t dl_ch_mag[][rx_size],
+                           int32_t dl_ch_magb[][rx_size],
+                           int32_t dl_ch_magr[][rx_size],
+                           int32_t dl_ch_estimates_ext[][rx_size],
+                           unsigned short nb_rb,
+                           unsigned char n_rx,
+                           unsigned char n_tx,//number of layer
+                           unsigned char mod_order,
+                           int shift,
+                           unsigned char symbol,
+                           int length);
 
 /* Apply layer demapping */
-static void nr_dlsch_layer_demapping(int16_t **llr_cw,
+static void nr_dlsch_layer_demapping(int16_t *llr_cw[2],
                                      uint8_t Nl,
                                      uint8_t mod_order,
                                      uint32_t length,
                                      int32_t codeword_TB0,
                                      int32_t codeword_TB1,
-                                     int16_t **llr_layers);
+                                     int16_t *llr_layers[NR_MAX_NB_LAYERS]);
 
 /* compute LLR */
-static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
+static int nr_dlsch_llr(uint32_t rx_size,
+                        int16_t *layer_llr[NR_MAX_NB_LAYERS],
                         NR_DL_FRAME_PARMS *frame_parms,
-                        int32_t **rxdataF_comp_ptr,
-                        int32_t **dl_ch_mag_ptr,
+                        int32_t rxdataF_comp[][rx_size],
+                        int32_t dl_ch_mag[][rx_size],
+                        int32_t dl_ch_magb[][rx_size],
+                        int32_t dl_ch_magr[][rx_size],
                         NR_DL_UE_HARQ_t *dlsch0_harq,
                         NR_DL_UE_HARQ_t *dlsch1_harq,
                         unsigned char harq_pid,
-                        unsigned char gNB_id,
-                        unsigned char gNB_id_i,
                         unsigned char first_symbol_flag,
                         unsigned char symbol,
                         unsigned short nb_rb,
@@ -120,26 +122,40 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         int32_t codeword_TB1,
                         uint32_t len,
                         uint8_t nr_slot_rx,
-                        NR_UE_DLSCH_t *dlsch);
-
+                        NR_UE_DLSCH_t dlsch[2],
+                        uint32_t llr_offset[NR_SYMBOLS_PER_SLOT]);
 
 /* Main Function */
 int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                 UE_nr_rxtx_proc_t *proc,
-                NR_UE_DLSCH_t *dlsch,
-                unsigned char gNB_id,
-                unsigned char gNB_id_i,
-                uint32_t frame,
-                uint8_t nr_slot_rx,
+                NR_UE_DLSCH_t dlsch[2],
                 unsigned char symbol,
                 unsigned char first_symbol_flag,
-                unsigned char harq_pid)
+                unsigned char harq_pid,
+                uint32_t pdsch_est_size,
+                int32_t dl_ch_estimates[][pdsch_est_size],
+                int16_t *llr[2],
+                c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
+                int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
+                uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
+                uint32_t rx_size,
+                int32_t dl_ch_estimates_ext[][rx_size],
+                int32_t rxdataF_ext[][rx_size],
+                int32_t rxdataF_comp[][rx_size],
+                int32_t dl_ch_mag[][rx_size],
+                int32_t dl_ch_magb[][rx_size],
+                int32_t dl_ch_magr[][rx_size],
+                c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
+                uint32_t llr_offset[NR_SYMBOLS_PER_SLOT],
+                int32_t *log2_maxh)
 {
 
   NR_UE_COMMON *common_vars  = &ue->common_vars;
-  NR_UE_PDSCH **pdsch_vars;
   NR_DL_FRAME_PARMS *frame_parms    = &ue->frame_parms;
   PHY_NR_MEASUREMENTS *measurements = &ue->measurements;
+  int frame = proc->frame_rx;
+  int nr_slot_rx = proc->nr_slot_rx;
+  int gNB_id = proc->gNB_id;
 
   int avg[16];
 //  int avg_0[2];
@@ -152,8 +168,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   int avgs = 0;// rb;
   NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL;
 
-  int32_t **rxdataF_comp_ptr;
-  int32_t **dl_ch_mag_ptr;
   int32_t codeword_TB0 = -1;
   int32_t codeword_TB1 = -1;
 
@@ -169,7 +183,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   uint16_t nbSymb=0;
   uint16_t pduBitmap=0x0;
 
-  pdsch_vars = ue->pdsch_vars;
   dlsch0_harq = &ue->dl_harq_processes[0][harq_pid];
   if (NR_MAX_NB_LAYERS>4)
     dlsch1_harq = &ue->dl_harq_processes[1][harq_pid];
@@ -251,11 +264,6 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
     return(-1);
   }
 
-  if (!pdsch_vars) {
-    LOG_W(PHY,"dlsch_demodulation.c: Null pdsch_vars pointer\n");
-    return(-1);
-  }
-
   if (!frame_parms) {
     LOG_W(PHY,"dlsch_demodulation.c: Null frame_parms\n");
     return(-1);
@@ -272,10 +280,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //--------------------- RBs extraction ---------------------
   //----------------------------------------------------------
   start_meas(&ue->generic_stat_bis[slot]);
-  nr_dlsch_extract_rbs(common_vars->rxdataF,
-                       pdsch_vars[gNB_id]->dl_ch_estimates,
-                       pdsch_vars[gNB_id]->rxdataF_ext,
-                       pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+  nr_dlsch_extract_rbs(ue->frame_parms.samples_per_slot_wCP,
+                       rxdataF,
+                       rx_size,
+                       dl_ch_estimates,
+                       rxdataF_ext,
+                       dl_ch_estimates_ext,
                        symbol,
                        pilots,
                        config_type,
@@ -298,7 +308,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //--------------------- Channel Scaling --------------------
   //----------------------------------------------------------
   start_meas(&ue->generic_stat_bis[slot]);
-  nr_dlsch_scale_channel(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+  nr_dlsch_scale_channel(rx_size,
+                         dl_ch_estimates_ext,
                          frame_parms,
                          nl,
                          n_rx,
@@ -317,7 +328,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //----------------------------------------------------------
   start_meas(&ue->generic_stat_bis[slot]);
   if (first_symbol_flag==1) {
-    nr_dlsch_channel_level(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+    nr_dlsch_channel_level(rx_size,
+                           dl_ch_estimates_ext,
                            frame_parms,
                            nl,
                            avg,
@@ -333,7 +345,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
         median[(aatx*n_rx)+aarx] = avg[(aatx*n_rx)+aarx];
       }
     if (dlsch[0].Nl > 1) {
-      nr_dlsch_channel_level_median(pdsch_vars[gNB_id]->dl_ch_estimates_ext,
+      nr_dlsch_channel_level_median(rx_size,
+                                    dl_ch_estimates_ext,
                                     median,
                                     nl,
                                     n_rx,
@@ -345,14 +358,12 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
         }
       }
     }
-    pdsch_vars[gNB_id]->log2_maxh = (log2_approx(avgs)/2) + 1;
-    //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  pdsch_vars[gNB_id]->log2_maxh);
-    LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
+    *log2_maxh = (log2_approx(avgs)/2) + 1;
+    //LOG_I(PHY, "avgs Power per SC is %d lg2_maxh %d\n", avgs,  log2_maxh);
+    LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d (%d,%d)\n",
           frame%1024,
           nr_slot_rx,
-          pdsch_vars[gNB_id]->log2_maxh,
-          pdsch_vars[gNB_id]->log2_maxh0,
-          pdsch_vars[gNB_id]->log2_maxh1,
+          *log2_maxh,
           avg[0],
           avgs);
   }
@@ -373,13 +384,14 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
   //----------------------------------------------------------
   // Disable correlation measurement for optimizing UE
   start_meas(&ue->generic_stat_bis[slot]);
-  nr_dlsch_channel_compensation(pdsch_vars[gNB_id]->rxdataF_ext,
-                                pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                pdsch_vars[gNB_id]->dl_ch_mag0,
-                                pdsch_vars[gNB_id]->dl_ch_magb0,
-                                pdsch_vars[gNB_id]->dl_ch_magr0,
-                                pdsch_vars[gNB_id]->rxdataF_comp0,
-                                NULL,//NULL:disable meas. pdsch_vars[gNB_id]->rho:enable meas.
+  nr_dlsch_channel_compensation(rx_size,
+                                rxdataF_ext,
+                                dl_ch_estimates_ext,
+                                dl_ch_mag,
+                                dl_ch_magb,
+                                dl_ch_magr,
+                                rxdataF_comp,
+                                NULL,
                                 frame_parms,
                                 nl,
                                 symbol,
@@ -387,67 +399,63 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                                 first_symbol_flag,
                                 dlsch[0].dlsch_config.qamModOrder,
                                 nb_rb_pdsch,
-                                pdsch_vars[gNB_id]->log2_maxh,
+                                *log2_maxh,
                                 measurements); // log2_maxh+I0_shift
     stop_meas(&ue->generic_stat_bis[slot]);
     if (cpumeas(CPUMEAS_GETSTATE))
-      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp  %5.2f \n", frame, nr_slot_rx, slot, symbol, pdsch_vars[gNB_id]->log2_maxh, proc->channel_level, ue->generic_stat_bis[slot].p_time/(cpuf*1000.0));
+      LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp  %5.2f \n", frame, nr_slot_rx, slot, symbol, *log2_maxh, proc->channel_level, ue->generic_stat_bis[slot].p_time/(cpuf*1000.0));
 
     start_meas(&ue->generic_stat_bis[slot]);
 
   if (n_rx > 1) {
-    nr_dlsch_detection_mrc(pdsch_vars[gNB_id]->rxdataF_comp0,
-                           (nl>1)? pdsch_vars[gNB_id]->rho : NULL,
-                           pdsch_vars[gNB_id]->dl_ch_mag0,
-                           pdsch_vars[gNB_id]->dl_ch_magb0,
-                           pdsch_vars[gNB_id]->dl_ch_magr0,
+    nr_dlsch_detection_mrc(rx_size,
+                           rxdataF_comp,
+                           NULL,
+                           dl_ch_mag,
+                           dl_ch_magb,
+                           dl_ch_magr,
                            nl,
                            n_rx,
                            symbol,
                            nb_rb_pdsch,
                            nb_re_pdsch);
     if (nl >= 2)//Apply zero forcing for 2, 3, and 4 Tx layers
-      nr_zero_forcing_rx(pdsch_vars[gNB_id]->rxdataF_comp0,
-                                 pdsch_vars[gNB_id]->dl_ch_mag0,
-                                 pdsch_vars[gNB_id]->dl_ch_magb0,
-                                 pdsch_vars[gNB_id]->dl_ch_magr0,
-                                 pdsch_vars[gNB_id]->dl_ch_estimates_ext,
-                                 nb_rb_pdsch,
-                                 n_rx,
-                                 nl,
-                                 dlsch[0].dlsch_config.qamModOrder,
-                                 pdsch_vars[gNB_id]->log2_maxh,
-                                 symbol,
-                                 nb_re_pdsch);
+      nr_zero_forcing_rx(rx_size,
+                         rxdataF_comp,
+                         dl_ch_mag,
+                         dl_ch_magb,
+                         dl_ch_magr,
+                         dl_ch_estimates_ext,
+                         nb_rb_pdsch,
+                         n_rx,
+                         nl,
+                         dlsch[0].dlsch_config.qamModOrder,
+                         *log2_maxh,
+                         symbol,
+                         nb_re_pdsch);
   }
   stop_meas(&ue->generic_stat_bis[slot]);
 
-  //printf("start compute LLR\n");
-  rxdataF_comp_ptr = pdsch_vars[gNB_id_i]->rxdataF_comp0;
-  dl_ch_mag_ptr = pdsch_vars[gNB_id_i]->dl_ch_mag0;
-
   if (cpumeas(CPUMEAS_GETSTATE))
     LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
 
   start_meas(&ue->generic_stat_bis[slot]);
   /* Store the valid DL RE's */
-  pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch;
+  dl_valid_re[symbol-1] = nb_re_pdsch;
 
   if(dlsch0_harq->status == ACTIVE) {
     startSymbIdx = dlsch[0].dlsch_config.start_symbol;
     nbSymb = dlsch[0].dlsch_config.number_symbols;
     pduBitmap = dlsch[0].dlsch_config.pduBitmap;
   }
-  if(dlsch1_harq) {
-    startSymbIdx = dlsch[1].dlsch_config.start_symbol;
-    nbSymb = dlsch[1].dlsch_config.number_symbols;
-    pduBitmap = dlsch[1].dlsch_config.pduBitmap;
-  }
-  
+
   /* Check for PTRS bitmap and process it respectively */
   if((pduBitmap & 0x1) && (dlsch[0].rnti_type == _C_RNTI_)) {
     nr_pdsch_ptrs_processing(ue,
-                             pdsch_vars,
+                             ptrs_phase_per_slot,
+                             ptrs_re_per_slot,
+                             rx_size,
+                             rxdataF_comp,
                              frame_parms,
                              dlsch0_harq,
                              dlsch1_harq,
@@ -456,11 +464,31 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                              symbol,
                              (nb_rb_pdsch*12),
                              dlsch[0].rnti,dlsch);
-    pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol];
+    dl_valid_re[symbol-1] -= ptrs_re_per_slot[0][symbol];
   }
   
   /* at last symbol in a slot calculate LLR's for whole slot */
   if(symbol == (startSymbIdx + nbSymb -1)) {
+    uint8_t nb_re_dmrs;
+    if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
+      nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
+    }
+    else {
+      nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
+    }
+    uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos);
+
+    const uint32_t rx_llr_size = nr_get_G(dlsch[0].dlsch_config.number_rbs,
+                                          dlsch[0].dlsch_config.number_symbols,
+                                          nb_re_dmrs,
+                                          dmrs_len,
+                                          dlsch[0].dlsch_config.qamModOrder,
+                                          dlsch[0].Nl);
+    const uint32_t rx_llr_layer_size = (rx_llr_size + dlsch[0].Nl - 1) / dlsch[0].Nl;
+
+    int16_t* layer_llr[NR_MAX_NB_LAYERS];
+    for (int i=0; i<NR_MAX_NB_LAYERS; i++)
+      layer_llr[i] = (int16_t *)malloc16_clear(rx_llr_layer_size*sizeof(int16_t));
     for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) {
       /* re evaluating the first symbol flag as LLR's are done in symbol loop  */
       if(i == startSymbIdx && i < 3) {
@@ -470,27 +498,27 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
         first_symbol_flag=0;
       }
       /* Calculate LLR's for each symbol */
-      nr_dlsch_llr(pdsch_vars, frame_parms,
-                   rxdataF_comp_ptr, dl_ch_mag_ptr,
-                   dlsch0_harq, dlsch1_harq,
+      nr_dlsch_llr(rx_size,
+                   layer_llr,
+                   frame_parms,
+                   rxdataF_comp,
+                   dl_ch_mag,
+                   dl_ch_magb,
+                   dl_ch_magr,
+                   dlsch0_harq,
+                   dlsch1_harq,
                    harq_pid,
-                   gNB_id, gNB_id_i,
                    first_symbol_flag,
-                   i, nb_rb_pdsch,
-                   codeword_TB0, codeword_TB1,
-                   pdsch_vars[gNB_id]->dl_valid_re[i-1],
-                   nr_slot_rx, dlsch);
+                   i,
+                   nb_rb_pdsch,
+                   codeword_TB0,
+                   codeword_TB1,
+                   dl_valid_re[i-1],
+                   nr_slot_rx,
+                   dlsch,
+                   llr_offset);
     }
     
-    int dmrs_type = dlsch[0].dlsch_config.dmrsConfigType;
-    uint8_t nb_re_dmrs;
-    uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos);
-    if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
-      nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
-    } else {
-      nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
-    }
-
     dlsch0_harq->G = nr_get_G(dlsch[0].dlsch_config.number_rbs,
                               dlsch[0].dlsch_config.number_symbols,
                               nb_re_dmrs,
@@ -498,51 +526,53 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                               dlsch[0].dlsch_config.qamModOrder,
                               dlsch[0].Nl);
 
-    nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr,
+    nr_dlsch_layer_demapping(llr,
                              dlsch[0].Nl,
                              dlsch[0].dlsch_config.qamModOrder,
                              dlsch0_harq->G,
                              codeword_TB0,
                              codeword_TB1,
-                             pdsch_vars[gNB_id]->layer_llr);    
-  }
-  
-  stop_meas(&ue->generic_stat_bis[slot]);
-  if (cpumeas(CPUMEAS_GETSTATE))
-    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation  %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
+                             layer_llr);
 
+    for (int i=0; i<NR_MAX_NB_LAYERS; i++)
+      free(layer_llr[i]);
   // Please keep it: useful for debugging
 #ifdef DEBUG_PDSCH_RX
-  char filename[50];
-  uint8_t aa = 0;
-  
-  snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
-  write_output(filename, "rxdataF0", &common_vars->rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
+    char filename[50];
+    uint8_t aa = 0;
 
-  snprintf(filename, 50, "dl_ch_estimates0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
-  write_output(filename, "dl_ch_estimates", &pdsch_vars[gNB_id]->dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
+    snprintf(filename, 50, "rxdataF0_symb_%d_nr_slot_rx_%d.m", symbol, nr_slot_rx);
+    write_output(filename, "rxdataF0", &rxdataF[0][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
 
-  snprintf(filename, 50, "rxdataF_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
-  write_output(filename, "rxdataF_ext", &pdsch_vars[gNB_id]->rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
+    snprintf(filename, 50, "dl_ch_estimates0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
+    write_output(filename, "dl_ch_estimates", &dl_ch_estimates[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->ofdm_symbol_size, 1, 1);
 
-  snprintf(filename, 50, "dl_ch_estimates_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
-  write_output(filename, "dl_ch_estimates_ext00", &pdsch_vars[gNB_id]->dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
+    snprintf(filename, 50, "rxdataF_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
+    write_output(filename, "rxdataF_ext", &rxdataF_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
 
-  snprintf(filename, 50, "rxdataF_comp0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
-  write_output(filename, "rxdataF_comp00", &pdsch_vars[gNB_id]->rxdataF_comp0[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
-/*
-  for (int i=0; i < 2; i++){
-    snprintf(filename, 50,  "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx);
-    write_output(filename,"llr",  &pdsch_vars[gNB_id]->llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
-  }
-*/
+    snprintf(filename, 50, "dl_ch_estimates_ext0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
+    write_output(filename, "dl_ch_estimates_ext00", &dl_ch_estimates_ext[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
+
+    snprintf(filename, 50, "rxdataF_comp0%d_symb_%d_nr_slot_rx_%d.m", aa, symbol, nr_slot_rx);
+    write_output(filename, "rxdataF_comp00", &rxdataF_comp[aa][0], NR_SYMBOLS_PER_SLOT*frame_parms->N_RB_DL*NR_NB_SC_PER_RB, 1, 1);
+  /*
+    for (int i=0; i < 2; i++){
+      snprintf(filename, 50,  "llr%d_symb_%d_nr_slot_rx_%d.m", i, symbol, nr_slot_rx);
+      write_output(filename,"llr",  &llr[i][0], (NR_SYMBOLS_PER_SLOT*nb_rb_pdsch*NR_NB_SC_PER_RB*dlsch1_harq->Qm) - 4*(nb_rb_pdsch*4*dlsch1_harq->Qm), 1, 0);
+    }
+  */
 #endif
+  }
+
+  stop_meas(&ue->generic_stat_bis[slot]);
+  if (cpumeas(CPUMEAS_GETSTATE))
+    LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation  %5.2f \n", frame, nr_slot_rx, slot, symbol, ue->generic_stat_bis[slot].p_time / (cpuf * 1000.0));
 
 #if T_TRACER
   T(T_UE_PHY_PDSCH_IQ, T_INT(gNB_id), T_INT(ue->Mod_id), T_INT(frame%1024),
     T_INT(nr_slot_rx), T_INT(nb_rb_pdsch),
     T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_slot),
-    T_BUFFER(&pdsch_vars[gNB_id]->rxdataF_comp0[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2));
+    T_BUFFER(&rxdataF_comp[gNB_id][0], 2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_slot*2));
 #endif
   return(0);
 
@@ -599,12 +629,13 @@ void nr_dlsch_deinterleaving(uint8_t symbol,
 // Pre-processing for LLR computation
 //==============================================================================================
 
-void nr_dlsch_channel_compensation(int **rxdataF_ext,
-                                   int **dl_ch_estimates_ext,
-                                   int **dl_ch_mag,
-                                   int **dl_ch_magb,
-                                   int **dl_ch_magr,
-                                   int **rxdataF_comp,
+void nr_dlsch_channel_compensation(uint32_t rx_size,
+                                   int32_t rxdataF_ext[][rx_size],
+                                   int32_t dl_ch_estimates_ext[][rx_size],
+                                   int32_t dl_ch_mag[][rx_size],
+                                   int32_t dl_ch_magb[][rx_size],
+                                   int32_t dl_ch_magr[][rx_size],
+                                   int32_t rxdataF_comp[][rx_size],
                                    int ***rho,
                                    NR_DL_FRAME_PARMS *frame_parms,
                                    uint8_t nb_aatx,
@@ -1304,14 +1335,15 @@ void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
 }
 
 
-void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
-			    NR_DL_FRAME_PARMS *frame_parms,
-			    uint8_t n_tx,
-			    uint8_t n_rx,
-			    uint8_t symbol,
-			    uint8_t pilots,
-			    uint32_t len,
-			    unsigned short nb_rb)
+void nr_dlsch_scale_channel(uint32_t rx_size,
+                            int32_t dl_ch_estimates_ext[][rx_size],
+			                      NR_DL_FRAME_PARMS *frame_parms,
+			                      uint8_t n_tx,
+			                      uint8_t n_rx,
+			                      uint8_t symbol,
+			                      uint8_t pilots,
+			                      uint32_t len,
+			                      unsigned short nb_rb)
 {
 
 #if defined(__x86_64__)||defined(__i386__)
@@ -1359,13 +1391,14 @@ void nr_dlsch_scale_channel(int **dl_ch_estimates_ext,
 
 
 //compute average channel_level on each (TX,RX) antenna pair
-void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
-			    NR_DL_FRAME_PARMS *frame_parms,
-			    uint8_t n_tx,
-			    int32_t *avg,
-			    uint8_t symbol,
-			    uint32_t len,
-			    unsigned short nb_rb)
+void nr_dlsch_channel_level(uint32_t rx_size,
+                            int32_t dl_ch_estimates_ext[][rx_size],
+			                      NR_DL_FRAME_PARMS *frame_parms,
+			                      uint8_t n_tx,
+			                      int32_t *avg,
+			                      uint8_t symbol,
+			                      uint32_t len,
+			                      unsigned short nb_rb)
 {
 
 #if defined(__x86_64__)||defined(__i386__)
@@ -1466,12 +1499,13 @@ void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
 #endif
 }
 
-void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
-                                int32_t *median,
-                                int n_tx,
-                                int n_rx,
-                                int length,
-                                int start_point)
+void nr_dlsch_channel_level_median(uint32_t rx_size,
+                                   int32_t dl_ch_estimates_ext[][rx_size],
+                                   int32_t *median,
+                                   int n_tx,
+                                   int n_rx,
+                                   int length,
+                                   int start_point)
 {
 
 #if defined(__x86_64__)||defined(__i386__)
@@ -1563,10 +1597,12 @@ void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
 // Extraction functions
 //==============================================================================================
 
-void nr_dlsch_extract_rbs(int **rxdataF,
-                          int **dl_ch_estimates,
-                          int **rxdataF_ext,
-                          int **dl_ch_estimates_ext,
+void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
+                          c16_t rxdataF[][rxdataF_sz],
+                          uint32_t rx_size,
+                          int32_t dl_ch_estimates[][rx_size],
+                          int32_t rxdataF_ext[][rx_size],
+                          int32_t dl_ch_estimates_ext[][rx_size],
                           unsigned char symbol,
                           uint8_t pilots,
                           uint8_t config_type,
@@ -1597,7 +1633,7 @@ void nr_dlsch_extract_rbs(int **rxdataF,
   for (unsigned char aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
 
     int32_t *rxF_ext = &rxdataF_ext[aarx][symbol * nb_rb_pdsch * NR_NB_SC_PER_RB];
-    int32_t *rxF     = &rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
+    int32_t *rxF     = (int32_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size];
 
     for (unsigned char aatx = 0; aatx < Nl; aatx++) {
 
@@ -1682,11 +1718,12 @@ void nr_dlsch_extract_rbs(int **rxdataF,
   }
 }
 
-void nr_dlsch_detection_mrc(int **rxdataF_comp,
+void nr_dlsch_detection_mrc(uint32_t rx_size,
+                            int32_t rxdataF_comp[][rx_size],
                             int ***rho,
-                            int **dl_ch_mag,
-                            int **dl_ch_magb,
-                            int **dl_ch_magr,
+                            int32_t dl_ch_mag[][rx_size],
+                            int32_t dl_ch_magb[][rx_size],
+                            int32_t dl_ch_magr[][rx_size],
                             short n_tx,
                             short n_rx,
                             unsigned char symbol,
@@ -2144,11 +2181,12 @@ void nr_conjch0_mult_ch1(int *ch0,
  *
  *
  * */
-uint8_t nr_zero_forcing_rx(int **rxdataF_comp,
-                           int **dl_ch_mag,
-                           int **dl_ch_magb,
-                           int **dl_ch_magr,
-                           int **dl_ch_estimates_ext,
+uint8_t nr_zero_forcing_rx(uint32_t rx_size,
+                           int32_t rxdataF_comp[][rx_size],
+                           int32_t dl_ch_mag[][rx_size],
+                           int32_t dl_ch_magb[][rx_size],
+                           int32_t dl_ch_magr[][rx_size],
+                           int32_t dl_ch_estimates_ext[][rx_size],
                            unsigned short nb_rb,
                            unsigned char n_rx,
                            unsigned char n_tx,//number of layer
@@ -2305,13 +2343,13 @@ uint8_t nr_zero_forcing_rx(int **rxdataF_comp,
   return(0);
 }
 
-static void nr_dlsch_layer_demapping(int16_t **llr_cw,
-				     uint8_t Nl,
-				     uint8_t mod_order,
-				     uint32_t length,
-				     int32_t codeword_TB0,
-				     int32_t codeword_TB1,
-				     int16_t **llr_layers) {
+static void nr_dlsch_layer_demapping(int16_t *llr_cw[2],
+                                     uint8_t Nl,
+                                     uint8_t mod_order,
+                                     uint32_t length,
+                                     int32_t codeword_TB0,
+                                     int32_t codeword_TB1,
+                                     int16_t *llr_layers[NR_MAX_NB_LAYERS]) {
 
   switch (Nl) {
     case 1:
@@ -2343,15 +2381,16 @@ static void nr_dlsch_layer_demapping(int16_t **llr_cw,
   }
 }
 
-static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
+static int nr_dlsch_llr(uint32_t rx_size,
+                        int16_t *layer_llr[NR_MAX_NB_LAYERS],
                         NR_DL_FRAME_PARMS *frame_parms,
-                        int32_t **rxdataF_comp_ptr,
-                        int32_t **dl_ch_mag_ptr,
+                        int32_t rxdataF_comp[][rx_size],
+                        int32_t dl_ch_mag[][rx_size],
+                        int32_t dl_ch_magb[][rx_size],
+                        int32_t dl_ch_magr[][rx_size],
                         NR_DL_UE_HARQ_t *dlsch0_harq,
                         NR_DL_UE_HARQ_t *dlsch1_harq,
                         unsigned char harq_pid,
-                        unsigned char gNB_id,
-                        unsigned char gNB_id_i,
                         unsigned char first_symbol_flag,
                         unsigned char symbol,
                         unsigned short nb_rb,
@@ -2359,22 +2398,23 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
                         int32_t codeword_TB1,
                         uint32_t len,
                         uint8_t nr_slot_rx,
-                        NR_UE_DLSCH_t *dlsch)
+                        NR_UE_DLSCH_t dlsch[2],
+                        uint32_t llr_offset[14])
 {
   uint32_t llr_offset_symbol;
   
   if (first_symbol_flag==1)
-    pdsch_vars[gNB_id]->llr_offset[symbol-1] = 0;
-  llr_offset_symbol = pdsch_vars[gNB_id]->llr_offset[symbol-1];
+    llr_offset[symbol-1] = 0;
+  llr_offset_symbol = llr_offset[symbol-1];
 
-  pdsch_vars[gNB_id]->llr_offset[symbol] = len*dlsch->dlsch_config.qamModOrder + llr_offset_symbol;
+  llr_offset[symbol] = len*dlsch[0].dlsch_config.qamModOrder + llr_offset_symbol;
  
   switch (dlsch[0].dlsch_config.qamModOrder) {
     case 2 :
       for(int l=0; l < dlsch[0].Nl; l++)
         nr_dlsch_qpsk_llr(frame_parms,
-                          pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
-                          pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
+                          rxdataF_comp[l*frame_parms->nb_antennas_rx],
+                          layer_llr[l]+llr_offset_symbol,
                           symbol,
                           len,
                           first_symbol_flag,
@@ -2384,9 +2424,9 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     case 4 :
       for(int l=0; l < dlsch[0].Nl; l++)
         nr_dlsch_16qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
-                           pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
-                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           rxdataF_comp[l*frame_parms->nb_antennas_rx],
+                           layer_llr[l]+llr_offset_symbol,
+                           dl_ch_mag[0],
                            symbol,
                            len,
                            first_symbol_flag,
@@ -2396,10 +2436,10 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     case 6 :
       for(int l=0; l < dlsch[0].Nl; l++)
         nr_dlsch_64qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
-                           pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
-                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
-                           pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                           rxdataF_comp[l*frame_parms->nb_antennas_rx],
+                           layer_llr[l]+llr_offset_symbol,
+                           dl_ch_mag[0],
+                           dl_ch_magb[0],
                            symbol,
                            len,
                            first_symbol_flag,
@@ -2409,11 +2449,11 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
     case 8:
       for(int l=0; l < dlsch[0].Nl; l++)
         nr_dlsch_256qam_llr(frame_parms,
-                            pdsch_vars[gNB_id]->rxdataF_comp0[l*frame_parms->nb_antennas_rx],
-                            pdsch_vars[gNB_id]->layer_llr[l]+llr_offset_symbol,
-                            pdsch_vars[gNB_id]->dl_ch_mag0[0],
-                            pdsch_vars[gNB_id]->dl_ch_magb0[0],
-                            pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                            rxdataF_comp[l*frame_parms->nb_antennas_rx],
+                            layer_llr[l]+llr_offset_symbol,
+                            dl_ch_mag[0],
+                            dl_ch_magb[0],
+                            dl_ch_magr[0],
                             symbol,
                             len,
                             first_symbol_flag,
@@ -2426,12 +2466,13 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
       break;
   }
 
+  //TODO: Revisited for Nl>4
   if (dlsch1_harq) {
     switch (dlsch[1].dlsch_config.qamModOrder) {
       case 2 :
         nr_dlsch_qpsk_llr(frame_parms,
-                          pdsch_vars[gNB_id]->rxdataF_comp0[0],
-                          pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
+                          rxdataF_comp[0],
+                          layer_llr[0]+llr_offset_symbol,
                           symbol,
                           len,
                           first_symbol_flag,
@@ -2440,9 +2481,9 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
 
       case 4:
         nr_dlsch_16qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
-                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
-                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
+                           rxdataF_comp[0],
+                           layer_llr[0]+llr_offset_symbol,
+                           dl_ch_mag[0],
                            symbol,
                            len,
                            first_symbol_flag,
@@ -2451,10 +2492,10 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
 
       case 6 :
         nr_dlsch_64qam_llr(frame_parms,
-                           pdsch_vars[gNB_id]->rxdataF_comp0[0],
-                           pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
-                           pdsch_vars[gNB_id]->dl_ch_mag0[0],
-                           pdsch_vars[gNB_id]->dl_ch_magb0[0],
+                           rxdataF_comp[0],
+                           layer_llr[0]+llr_offset_symbol,
+                           dl_ch_mag[0],
+                           dl_ch_magb[0],
                            symbol,
                            len,
                            first_symbol_flag,
@@ -2463,11 +2504,11 @@ static int nr_dlsch_llr(NR_UE_PDSCH **pdsch_vars,
 
       case 8 :
         nr_dlsch_256qam_llr(frame_parms,
-                            pdsch_vars[gNB_id]->rxdataF_comp0[0],
-                            pdsch_vars[gNB_id]->layer_llr[0]+llr_offset_symbol,
-                            pdsch_vars[gNB_id]->dl_ch_mag0[0],
-                            pdsch_vars[gNB_id]->dl_ch_magb0[0],
-                            pdsch_vars[gNB_id]->dl_ch_magr0[0],
+                            rxdataF_comp[0],
+                            layer_llr[0]+llr_offset_symbol,
+                            dl_ch_mag[0],
+                            dl_ch_magb[0],
+                            dl_ch_magr[0],
                             symbol,
                             len,
                             first_symbol_flag,
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index e87062de55d815bde44861d0b7de7aa16e8194b0..1904bed4570fb86b10e6f23abf6e13a95fae5934 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -101,7 +101,7 @@ void free_list(NR_UE_SSB *node) {
 }
 
 
-int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, nr_phy_data_t *phy_data)
+int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_initial_symbol, nr_phy_data_t *phy_data, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   int ret =-1;
@@ -127,7 +127,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
       start_meas(&ue->dlsch_channel_estimation_stats);
       // computing correlation between received DMRS symbols and transmitted sequence for current i_ssb and n_hf
       for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
-          nr_pbch_dmrs_correlation(ue,proc,0,0,i,i-pbch_initial_symbol,current_ssb);
+          nr_pbch_dmrs_correlation(ue,proc,i,i-pbch_initial_symbol,current_ssb,rxdataF);
       stop_meas(&ue->dlsch_channel_estimation_stats);
       
       current_ssb->metric = current_ssb->c_re*current_ssb->c_re + current_ssb->c_im*current_ssb->c_im;
@@ -152,7 +152,7 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
 
     for(int i=pbch_initial_symbol; i<pbch_initial_symbol+3;i++)
       nr_pbch_channel_estimation(ue,estimateSz, dl_ch_estimates, dl_ch_estimates_time, 
-                                 proc,0,0,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf);
+                                 proc,i,i-pbch_initial_symbol,temp_ptr->i_ssb,temp_ptr->n_hf,rxdataF);
 
     stop_meas(&ue->dlsch_channel_estimation_stats);
     fapiPbch_t result;
@@ -162,11 +162,11 @@ int nr_pbch_detection(UE_nr_rxtx_proc_t * proc, PHY_VARS_NR_UE *ue, int pbch_ini
                      dl_ch_estimates,
                      ue->pbch_vars[0],
                      frame_parms,
-                     0,
                      temp_ptr->i_ssb,
                      SISO,
                      phy_data,
-                     &result);
+                     &result,
+                     rxdataF);
 
     if (DUMP_PBCH_CH_ESTIMATES && (ret == 0)) {
       write_output("pbch_ch_estimates.m", "pbch_ch_estimates", dl_ch_estimates, frame_parms->nb_antennas_rx*estimateSz, 1, 1);
@@ -242,6 +242,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
   *          sync_pos            SS/PBCH block
   */
 
+  const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
+  __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
   cnt++;
   if (1){ // (cnt>100)
    cnt =0;
@@ -302,16 +304,16 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
         nr_slot_fep_init_sync(ue,
                               proc,
                               i,
-                              0,
                               is*fp->samples_per_frame+ue->ssb_offset,
-                              false);
+                              false,
+                              rxdataF);
 
 #ifdef DEBUG_INITIAL_SYNCH
       LOG_I(PHY,"Calling sss detection (normal CP)\n");
 #endif
 
       int freq_offset_sss = 0;
-      ret = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss);
+      ret = rx_sss_nr(ue, proc, &metric_tdd_ncp, &phase_tdd_ncp, &freq_offset_sss, rxdataF);
 
       // digital compensation of FFO for SSB symbols
       if (ue->UE_fo_compensation){
@@ -341,7 +343,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
 
       if (ret==0) { //we got sss channel
         nr_gold_pbch(ue);
-        ret = nr_pbch_detection(proc, ue, 1, &phy_data);  // start pbch detection at first symbol after pss
+        ret = nr_pbch_detection(proc, ue, 1, &phy_data, rxdataF);  // start pbch detection at first symbol after pss
       }
 
       if (ret == 0) {
@@ -464,7 +466,6 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
           frame_parms->Nid_cell,frame_parms->frame_type);
 #endif
 
-    ue->UE_mode[0] = NOT_SYNCHED;
     ue->pbch_vars[0]->pdu_errors_last=ue->pbch_vars[0]->pdu_errors;
     ue->pbch_vars[0]->pdu_errors++;
     ue->pbch_vars[0]->pdu_errors_conseq++;
@@ -525,7 +526,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
   if (sa==1 && ret==0) {
     nr_ue_dlsch_init(phy_data.dlsch, 1, ue->max_ldpc_iterations);
     bool dec = false;
-    int gnb_id = 0; //FIXME
+    proc->gNB_id = 0; //FIXME
 
     // Hold the channel estimates in frequency domain.
     int32_t pdcch_est_size = ((((fp->symbols_per_slot*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH))+15)/16)*16);
@@ -539,23 +540,22 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
         nr_slot_fep_init_sync(ue,
                               proc,
                               l, // the UE PHY has no notion of the symbols to be monitored in the search space
-                              phy_pdcch_config->slot,
                               is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset,
-                              true);
+                              true,
+                              rxdataF);
 
         nr_pdcch_channel_estimation(ue,
                                     proc,
-                                    0,
-                                    phy_pdcch_config->slot,
                                     l,
                                     &phy_pdcch_config->pdcch_config[n_ss].coreset,
                                     fp->first_carrier_offset,
                                     phy_pdcch_config->pdcch_config[n_ss].BWPStart,
                                     pdcch_est_size,
-                                    pdcch_dl_ch_estimates);
+                                    pdcch_dl_ch_estimates,
+                                    rxdataF);
 
       }
-      int  dci_cnt = nr_ue_pdcch_procedures(gnb_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_data, n_ss);
+      int  dci_cnt = nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, &phy_data, n_ss, rxdataF);
       if (dci_cnt>0){
         NR_UE_DLSCH_t *dlsch = phy_data.dlsch;
         if (dlsch[0].active == 1) {
@@ -566,24 +566,46 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
             nr_slot_fep_init_sync(ue,
                                   proc,
                                   m,
-                                  phy_pdcch_config->slot,  // same slot and offset as pdcch
                                   is*fp->samples_per_frame+phy_pdcch_config->sfn*fp->samples_per_frame+ue->rx_offset,
-                                  true);
+                                  true,
+                                  rxdataF);
           }
 
+          uint8_t nb_re_dmrs;
+          if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
+            nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
+          }
+          else {
+            nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
+          }
+          uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos);
+
+          const uint32_t rx_llr_size = nr_get_G(dlsch[0].dlsch_config.number_rbs,
+                                                dlsch[0].dlsch_config.number_symbols,
+                                                nb_re_dmrs,
+                                                dmrs_len,
+                                                dlsch[0].dlsch_config.qamModOrder,
+                                                dlsch[0].Nl);
+          int16_t* llr[2];
+          int16_t* layer_llr[NR_MAX_NB_LAYERS];
+          llr[0] = (int16_t *)malloc16_clear(rx_llr_size*sizeof(int16_t));
+
           int ret = nr_ue_pdsch_procedures(ue,
                                            proc,
-                                           gnb_id,
-                                           dlsch);
+                                           phy_data.dlsch,
+                                           llr,
+                                           rxdataF);
           if (ret >= 0)
             dec = nr_ue_dlsch_procedures(ue,
                                          proc,
-                                         gnb_id,
-                                         dlsch,
-                                         NULL);
+                                         phy_data.dlsch,
+                                         llr);
 
           // deactivate dlsch once dlsch proc is done
-          dlsch->active = 0;
+          dlsch[0].active = 0;
+          free(llr[0]);
+          for (int i=0; i<NR_MAX_NB_LAYERS; i++)
+            free(layer_llr[i]);
         }
       }
     }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
index 2a037d1e70bab81162ace66835709fba28236e94..1d9d30ec33d151064936a3568217f8193481c49a 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
@@ -49,7 +49,8 @@
 #define PBCH_MAX_RE (PBCH_MAX_RE_PER_SYMBOL*4)
 #define print_shorts(s,x) printf("%s : %d,%d,%d,%d,%d,%d,%d,%d\n",s,((int16_t*)x)[0],((int16_t*)x)[1],((int16_t*)x)[2],((int16_t*)x)[3],((int16_t*)x)[4],((int16_t*)x)[5],((int16_t*)x)[6],((int16_t*)x)[7])
 
-static uint16_t nr_pbch_extract(int **rxdataF,
+static uint16_t nr_pbch_extract(uint32_t rxdataF_sz,
+                                c16_t rxdataF[][rxdataF_sz],
                                 const int estimateSz,
                                 struct complex16 dl_ch_estimates[][estimateSz],
                                 struct complex16 rxdataF_ext[][PBCH_MAX_RE_PER_SYMBOL],
@@ -67,7 +68,7 @@ static uint16_t nr_pbch_extract(int **rxdataF,
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
     unsigned int rx_offset = frame_parms->first_carrier_offset + frame_parms->ssb_start_subcarrier;
     rx_offset = (rx_offset)%(frame_parms->ofdm_symbol_size);
-    struct complex16 *rxF        = (struct complex16 *)&rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
+    struct complex16 *rxF        = &rxdataF[aarx][(symbol+s_offset)*frame_parms->ofdm_symbol_size];
     struct complex16 *rxF_ext    = rxdataF_ext[aarx];
 #ifdef DEBUG_PBCH
     printf("extract_rbs (nushift %d): rx_offset=%d, symbol %u\n",frame_parms->nushift,
@@ -388,13 +389,12 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
                 int estimateSz, struct complex16 dl_ch_estimates [][estimateSz],
                 NR_UE_PBCH *nr_ue_pbch_vars,
                 NR_DL_FRAME_PARMS *frame_parms,
-                uint8_t gNB_id,
                 uint8_t i_ssb,
                 MIMO_mode_t mimo_mode,
                 nr_phy_data_t *phy_data,
-                fapiPbch_t *result) {
+                fapiPbch_t *result,
+                c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
-  NR_UE_COMMON *nr_ue_common_vars = &ue->common_vars;
   int max_h=0;
   int symbol;
   //uint8_t pbch_a[64];
@@ -424,7 +424,7 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
 #ifdef DEBUG_PBCH
   //printf("address dataf %p",nr_ue_common_vars->rxdataF);
   write_output("rxdataF0_pbch.m","rxF0pbch",
-               &nr_ue_common_vars->rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
+               &rxdataF[0][(symbol_offset+1)*frame_parms->ofdm_symbol_size],frame_parms->ofdm_symbol_size*3,1,1);
 #endif
   // symbol refers to symbol within SSB. symbol_offset is the offset of the SSB wrt start of slot
   double log2_maxh = 0;
@@ -434,7 +434,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
     __attribute__ ((aligned(32))) struct complex16 rxdataF_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
     __attribute__ ((aligned(32))) struct complex16 dl_ch_estimates_ext[frame_parms->nb_antennas_rx][PBCH_MAX_RE_PER_SYMBOL];
     memset(dl_ch_estimates_ext,0, sizeof  dl_ch_estimates_ext);
-    nr_pbch_extract(nr_ue_common_vars->rxdataF,
+    nr_pbch_extract(ue->frame_parms.samples_per_slot_wCP,
+                    rxdataF,
                     estimateSz,
                     dl_ch_estimates,
                     rxdataF_ext,
@@ -580,8 +581,8 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
   fapi_nr_rx_indication_t *rx_ind=calloc(sizeof(*rx_ind),1);
   uint16_t number_pdus = 1;
 
-  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, phy_data);
-  nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, gNB_id, ue, NULL, NULL, number_pdus, proc,(void *)result);
+  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, phy_data);
+  nr_fill_rx_indication(rx_ind, FAPI_NR_RX_PDU_TYPE_SSB, ue, NULL, NULL, number_pdus, proc,(void *)result);
 
   if (ue->if_inst && ue->if_inst->dl_indication)
     ue->if_inst->dl_indication(&dl_indication, NULL);
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
index efdcd51e64706bdd9be3852ca72f7e6bd1946fc6..921be8500245bac72024ca98b00696d33baed20c 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h
@@ -543,10 +543,12 @@ void nr_dlsch_256qam_llr(NR_DL_FRAME_PARMS *frame_parms,
     @param n_dmrs_cdm_groups
     @param frame_parms Pointer to frame descriptor
 */
-void nr_dlsch_extract_rbs(int **rxdataF,
-                          int **dl_ch_estimates,
-                          int **rxdataF_ext,
-                          int **dl_ch_estimates_ext,
+void nr_dlsch_extract_rbs(uint32_t rxdataF_sz,
+                          c16_t rxdataF[][rxdataF_sz],
+                          uint32_t rx_size,
+                          int32_t dl_ch_estimates[][rx_size],
+                          int32_t rxdataF_ext[][rx_size],
+                          int32_t dl_ch_estimates_ext[][rx_size],
                           unsigned char symbol,
                           uint8_t pilots,
                           uint8_t config_type,
@@ -558,7 +560,6 @@ void nr_dlsch_extract_rbs(int **rxdataF,
                           uint16_t dlDmrsSymbPos,
                           int chest_time_type);
 
-
 /** \brief This function performs channel compensation (matched filtering) on the received RBs for this allocation.  In addition, it computes the squared-magnitude of the channel with weightings for 16QAM/64QAM detection as well as dual-stream detection (cross-correlation)
     @param rxdataF_ext Frequency-domain received signal in RBs to be demodulated
     @param dl_ch_estimates_ext Frequency-domain channel estimates in RBs to be demodulated
@@ -574,22 +575,23 @@ void nr_dlsch_extract_rbs(int **rxdataF,
     @param output_shift Rescaling for compensated output (should be energy-normalizing)
     @param phy_measurements Pointer to UE PHY measurements
 */
-void nr_dlsch_channel_compensation(int32_t **rxdataF_ext,
-                                int32_t **dl_ch_estimates_ext,
-                                int32_t **dl_ch_mag,
-                                int32_t **dl_ch_magb,
-                                int32_t **dl_ch_magr,
-                                int32_t **rxdataF_comp,
-                                int32_t ***rho,
-                                NR_DL_FRAME_PARMS *frame_parms,
-                                uint8_t nb_aatx,
-                                uint8_t symbol,
-                                int length,
-                                uint8_t first_symbol_flag,
-                                uint8_t mod_order,
-                                uint16_t nb_rb,
-                                uint8_t output_shift,
-                                PHY_NR_MEASUREMENTS *phy_measurements);
+void nr_dlsch_channel_compensation(uint32_t rx_size,
+                                   int32_t rxdataF_ext[][rx_size],
+                                   int32_t dl_ch_estimates_ext[][rx_size],
+                                   int32_t dl_ch_mag[][rx_size],
+                                   int32_t dl_ch_magb[][rx_size],
+                                   int32_t dl_ch_magr[][rx_size],
+                                   int32_t rxdataF_comp[][rx_size],
+                                   int ***rho,
+                                   NR_DL_FRAME_PARMS *frame_parms,
+                                   uint8_t nb_aatx,
+                                   unsigned char symbol,
+                                   int length,
+                                   uint8_t first_symbol_flag,
+                                   unsigned char mod_order,
+                                   unsigned short nb_rb,
+                                   unsigned char output_shift,
+                                   PHY_NR_MEASUREMENTS *measurements);
 
 void nr_dlsch_channel_compensation_core(int **rxdataF_ext,
                                      int **dl_ch_estimates_ext,
@@ -611,18 +613,20 @@ void nr_dlsch_deinterleaving(uint8_t symbol,
                              uint16_t *llr_deint,
                              uint16_t nb_rb_pdsch);
 
-void nr_dlsch_channel_level_median(int **dl_ch_estimates_ext,
-                                int32_t *median,
-                                int n_tx,
-                                int n_rx,
-                                int length,
-                                int start_point);
+void nr_dlsch_channel_level_median(uint32_t rx_size,
+                                   int32_t dl_ch_estimates[][rx_size],
+                                   int32_t *median,
+                                   int n_tx,
+                                   int n_rx,
+                                   int length,
+                                   int start_point);
 
-void nr_dlsch_detection_mrc(int **rxdataF_comp,
+void nr_dlsch_detection_mrc(uint32_t rx_size,
+                            int32_t rxdataF_comp[][rx_size],
                             int ***rho,
-                            int **dl_ch_mag,
-                            int **dl_ch_magb,
-                            int **dl_ch_magr,
+                            int32_t dl_ch_mag[][rx_size],
+                            int32_t dl_ch_magb[][rx_size],
+                            int32_t dl_ch_magr[][rx_size],
                             short n_tx,
                             short n_rx,
                             unsigned char symbol,
@@ -647,23 +651,24 @@ void nr_a_sum_b(__m128i *input_x,
     @param pilots_flag Flag to indicate pilots in symbol
     @param nb_rb Number of allocated RBs
 */
-void nr_dlsch_channel_level(int **dl_ch_estimates_ext,
-                         NR_DL_FRAME_PARMS *frame_parms,
-                         uint8_t n_tx,
-                         int32_t *avg,
-                         uint8_t symbol,
-                         uint32_t len,
-                         unsigned short nb_rb);
-
-
-void nr_dlsch_scale_channel(int32_t **dl_ch_estimates_ext,
-                         NR_DL_FRAME_PARMS *frame_parms,
-                         uint8_t n_tx,
-                         uint8_t n_rx,
-                         uint8_t symbol,
-                         uint8_t start_symbol,
-                         uint32_t len,
-                         uint16_t nb_rb);
+void nr_dlsch_channel_level(uint32_t rx_size,
+                            int32_t dl_ch_estimates[][rx_size],
+			                      NR_DL_FRAME_PARMS *frame_parms,
+			                      uint8_t n_tx,
+			                      int32_t *avg,
+			                      uint8_t symbol,
+			                      uint32_t len,
+			                      unsigned short nb_rb);
+
+void nr_dlsch_scale_channel(uint32_t rx_size,
+                            int32_t dl_ch_estimates[][rx_size],
+			                      NR_DL_FRAME_PARMS *frame_parms,
+			                      uint8_t n_tx,
+			                      uint8_t n_rx,
+			                      uint8_t symbol,
+			                      uint8_t pilots,
+			                      uint32_t len,
+			                      unsigned short nb_rb);
 
 /** \brief This is the top-level entry point for DLSCH decoding in UE.  It should be replicated on several
     threads (on multi-core machines) corresponding to different HARQ processes. The routine first
@@ -751,7 +756,8 @@ int32_t nr_rx_pdcch(PHY_VARS_NR_UE *ue,
                     int32_t pdcch_est_size,
                     int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
                     int16_t *pdcch_e_rx,
-                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15);
+                    fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15,
+                    c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 
 /*! \brief Performs detection of SSS to find cell ID and other framing parameters (FDD/TDD, normal/extended prefix)
@@ -773,16 +779,17 @@ int nr_rx_pbch(PHY_VARS_NR_UE *ue,
                struct complex16 dl_ch_estimates[][estimateSz],
                NR_UE_PBCH *nr_ue_pbch_vars,
                NR_DL_FRAME_PARMS *frame_parms,
-               uint8_t eNB_id,
                uint8_t i_ssb,
                MIMO_mode_t mimo_mode,
                nr_phy_data_t *phy_data,
-               fapiPbch_t* result);
+               fapiPbch_t* result,
+               c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 int nr_pbch_detection(UE_nr_rxtx_proc_t *proc,
                       PHY_VARS_NR_UE *ue,
                       int pbch_initial_symbol,
-                      nr_phy_data_t *phy_data);
+                      nr_phy_data_t *phy_data,
+                      c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 
 #ifndef modOrder
@@ -862,14 +869,26 @@ uint8_t nr_dci_decoding_procedure(PHY_VARS_NR_UE *ue,
 */
 int nr_rx_pdsch(PHY_VARS_NR_UE *ue,
                 UE_nr_rxtx_proc_t *proc,
-                NR_UE_DLSCH_t *dlsch,
-                unsigned char gNB_id,
-                unsigned char gNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
-                uint32_t frame,
-                uint8_t nr_slot_rx,
+                NR_UE_DLSCH_t dlsch[2],
                 unsigned char symbol,
                 unsigned char first_symbol_flag,
-                unsigned char harq_pid);
+                unsigned char harq_pid,
+                uint32_t pdsch_est_size,
+                int32_t dl_ch_estimates[][pdsch_est_size],
+                int16_t *llr[2],
+                c16_t ptrs_phase_per_slot[][NR_SYMBOLS_PER_SLOT],
+                int32_t ptrs_re_per_slot[][NR_SYMBOLS_PER_SLOT],
+                uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT],
+                uint32_t rx_size,
+                int32_t dl_ch_estimates_ext[][rx_size],
+                int32_t rxdataF_ext[][rx_size],
+                int32_t rxdataF_comp[][rx_size],
+                int32_t dl_ch_mag[][rx_size],
+                int32_t dl_ch_magb[][rx_size],
+                int32_t dl_ch_magr[][rx_size],
+                c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP],
+                uint32_t llr_offset[NR_SYMBOLS_PER_SLOT],
+                int32_t *log2_maxh);
 
 int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t slot);
 
diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
index 55669ba3229e6c99372565870886ac4941e9aed3..5e60ae29407502b266dfcb8f7aff69f588e07642 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
@@ -432,9 +432,8 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu,
 *                send srs according to current configuration
 *
 *********************************************************************/
-int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id)
+int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc)
 {
-
   if(!ue->srs_vars[0]->active) {
     return -1;
   }
diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h
index 2c3d6d266cf486366e09fe5e0c8f04ba1b2ac6ce..5feea8d9ce3ca072c8f54ddf8193f3ecd2414dc4 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h
@@ -175,7 +175,7 @@ int is_srs_period_nr(SRS_Resource_t *p_SRS_Resource,
     @param current gNB_id identifier
     @returns 0 if srs is transmitted -1 otherwise */
 
-int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
+int ue_srs_procedures_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc);
 
 #undef EXTERN
 #undef INIT_VARIABLES_SRS_MODULATION_NR_H
diff --git a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
index 53191f09462d46d5d411f09a0409e60516ab685c..41829b68f2dbc3e5e2b9fafa80e840d270a5d5c0 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/sss_nr.c
@@ -318,13 +318,13 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
                           int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
                           int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
                           uint8_t doPss, uint8_t doSss,
-                          uint8_t subframe) // add flag to indicate extracting only PSS, only SSS, or both
+                          uint8_t subframe,
+                          c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) // add flag to indicate extracting only PSS, only SSS, or both
 {
   uint8_t aarx;
   int32_t *pss_rxF,*pss_rxF_ext;
   int32_t *sss_rxF,*sss_rxF_ext;
   uint8_t pss_symbol, sss_symbol;
-  int32_t **rxdataF;
   NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
 
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -332,12 +332,10 @@ int do_pss_sss_extract_nr(PHY_VARS_NR_UE *ue,
     pss_symbol = 0;
     sss_symbol = SSS_SYMBOL_NB-PSS_SYMBOL_NB;
 
-    rxdataF  =  ue->common_vars.rxdataF;
-
     unsigned int ofdm_symbol_size = frame_parms->ofdm_symbol_size;
 
-    pss_rxF  =  &rxdataF[aarx][pss_symbol*ofdm_symbol_size];
-    sss_rxF  =  &rxdataF[aarx][sss_symbol*ofdm_symbol_size];
+    pss_rxF  =  (int32_t *)&rxdataF[aarx][pss_symbol*ofdm_symbol_size];
+    sss_rxF  =  (int32_t *)&rxdataF[aarx][sss_symbol*ofdm_symbol_size];
 
     pss_rxF_ext = &pss_ext[aarx][0];
     sss_rxF_ext = &sss_ext[aarx][0];
@@ -402,9 +400,10 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
                        UE_nr_rxtx_proc_t *proc,
                        int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR],
                        int32_t sss_ext[NB_ANTENNAS_RX][LENGTH_SSS_NR],
-                       uint8_t subframe)
+                       uint8_t subframe,
+                       c16_t rxdataF[][phy_vars_ue->frame_parms.samples_per_slot_wCP])
 {
-  return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe);
+  return do_pss_sss_extract_nr(phy_vars_ue, proc, pss_ext, sss_ext, 1 /* doPss */, 1 /* doSss */, subframe, rxdataF);
 }
 
 /*******************************************************************
@@ -420,7 +419,7 @@ int pss_sss_extract_nr(PHY_VARS_NR_UE *phy_vars_ue,
 *
 *********************************************************************/
 
-int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss)
+int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric, uint8_t *phase_max, int *freq_offset_sss, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
   uint8_t i;
   int32_t pss_ext[NB_ANTENNAS_RX][LENGTH_PSS_NR];
@@ -439,7 +438,8 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
                      proc,
                      pss_ext,
                      sss_ext,
-                     0);          /* subframe */
+                     0,
+                     rxdataF);          /* subframe */
 
 #ifdef DEBUG_PLOT_SSS
 
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c
index 8d963281c43d771c58e6d8293008540be6334f0e..23f6f761818690700f51111a350b5981e2d3dfea 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.c
+++ b/openair1/PHY/TOOLS/nr_phy_scope.c
@@ -788,13 +788,19 @@ static void ueChannelResponse  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_
 }
 
 static void ueFreqWaterFall (scopeGraphData_t **data, OAIgraph_t *graph,PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id ) {
-  NR_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->frame_parms;
   //use 1st antenna
+  if (!data[commonRxdataF])
+    return;
+
+  const int sz = data[commonRxdataF]->lineSz;
+
+  scopeSample_t *rxdataF = (scopeSample_t *)(data[commonRxdataF]+1);
+
   genericWaterFall(graph,
-                   (scopeSample_t *)phy_vars_ue->common_vars.rxdataF[0],
-                   frame_parms->samples_per_slot_wCP,
-                   phy_vars_ue->frame_parms.slots_per_frame,
-                   "X axis: one frame frequency" );
+                   rxdataF,
+                   sz,
+                   1,
+                   "X axis: one slot frequency" );
 }
 /*
 static void uePbchFrequencyResp  (OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
@@ -925,70 +931,48 @@ static void uePcchIQ  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_U
 }
 static void uePdschLLR  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDSCH LLRs
-  if (!phy_vars_ue->pdsch_vars[eNB_id]->llr[0])
+  if (!data[pdschLlr])
     return;
 
-  int num_re = 4500;
-  int Qm = 2;
-  int coded_bits_per_codeword = num_re*Qm;
-  int newsz = 0;
+  const int sz = data[pdschLlr]->lineSz;
   float *llr, *bit;
+  int nx = sz;
+  int16_t *pdsch_llr = (int16_t *)(data[pdschLlr]+1);
 
-#ifndef WEBSRVSCOPE
-  oai_xygraph_getbuff(graph, &bit, &llr, coded_bits_per_codeword*RX_NB_TH_MAX, 0);
-#endif
-  int base=0;
-
-  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
-    int16_t *pdsch_llr = (int16_t *) phy_vars_ue->pdsch_vars[eNB_id]->llr[0]; // stream 0
 #ifdef WEBSRVSCOPE
-    newsz += websrv_cpllrbuff_tomsg(graph, pdsch_llr, coded_bits_per_codeword, 0, thr, RX_NB_TH_MAX);
+  nx = websrv_cpllrbuff_tomsg(graph, pdsch_llr, sz, UE_id, 0, 0);
 #else
-    for (int i=0; i<coded_bits_per_codeword; i++) {
-      llr[base+i] = (float) pdsch_llr[i];
-      bit[base+i] = (float) base+i;
-    }
-    newsz += coded_bits_per_codeword;
-#endif
-    base+=coded_bits_per_codeword;
+  oai_xygraph_getbuff(graph, &bit, &llr, sz, 0);
+
+  for (int i=0; i<sz; i++) {
+    llr[i] = (float) pdsch_llr[i];
   }
+#endif
 
-  AssertFatal(base <= coded_bits_per_codeword*RX_NB_TH_MAX, "");
   //fl_set_xyplot_xbounds(form->pdsch_llr,0,coded_bits_per_codeword);
-  oai_xygraph(graph, bit, llr, newsz, 0, 10);
+  oai_xygraph(graph, bit, llr, nx, 0, 10);
 }
 static void uePdschIQ  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   // PDSCH I/Q of MF Output
-  if (!phy_vars_ue->pdsch_vars[eNB_id]->rxdataF_comp0[0])
+  if (!data[pdschRxdataF_comp])
     return;
 
-  NR_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
-  int sz=7*2*frame_parms->N_RB_DL*12; // size of the malloced buffer
-  int newsz = 0;
+  const int sz=data[pdschRxdataF_comp]->lineSz;
+  int nz = sz;
   float *I, *Q;
-  int base=0;
-
-#ifndef WEBSRVSCOPE
-  oai_xygraph_getbuff(graph, &I, &Q, sz * RX_NB_TH_MAX, 0);
-  memset(I+base, 0, sz*RX_NB_TH_MAX * sizeof(*I));
-  memset(Q+base, 0, sz*RX_NB_TH_MAX * sizeof(*Q));
-#endif
-  for (int thr=0 ; thr < RX_NB_TH_MAX ; thr ++ ) {
-    scopeSample_t *pdsch_comp = (scopeSample_t *) phy_vars_ue->pdsch_vars[eNB_id]->rxdataF_comp0[0];
+  scopeSample_t *pdsch_comp = (scopeSample_t *) (data[pdschRxdataF_comp]+1);
 #ifdef WEBSRVSCOPE
-    newsz += websrv_cpiqbuff_tomsg(graph, pdsch_comp, sz, 0, base);
+  nz += websrv_cpiqbuff_tomsg(graph, pdsch_comp, sz, 0, 0);
 #else
-    for (int s=0; s<sz; s++) {
-      I[s+base] += pdsch_comp[s].r;
-      Q[s+base] += pdsch_comp[s].i;
-    }
-    newsz += sz;
-#endif
-    base+=sz;
+  oai_xygraph_getbuff(graph, &I, &Q, sz, 0);
+
+  for (int s=0; s<sz; s++) {
+    I[s] = pdsch_comp[s].r;
+    Q[s] = pdsch_comp[s].i;
   }
+#endif
 
-  AssertFatal(base <= sz*RX_NB_TH_MAX, "");
-  oai_xygraph(graph, I, Q, newsz, 0, 10);
+  oai_xygraph(graph, I, Q, nz, 0, 10);
 }
 static void uePdschThroughput  (scopeGraphData_t **data, OAIgraph_t *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id) {
   /*
@@ -1153,19 +1137,23 @@ static void *nrUEscopeThread(void *arg) {
 }
 #endif
 
+pthread_mutex_t UEcopyDataMutex;
+
 void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) {
   // Local static copy of the scope data bufs
   // The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input)
   // Index of "2" could be set to the number of Rx threads + 1
-  static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][2] = {0};
+  static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][3] = {0};
   static int  copyDataBufsIdx[UEdataTypeNumberOfItems] = {0};
 
   scopeData_t *tmp=(scopeData_t *)ue->scopeData;
 
   if (tmp) {
-    // Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex
-    int newCopyDataIdx = (copyDataBufsIdx[type]==0)?1:0;
+    // Begin of critical zone between UE Rx threads that might copy new data at the same time:
+    pthread_mutex_lock(&UEcopyDataMutex);
+    int newCopyDataIdx = (copyDataBufsIdx[type]<2)?copyDataBufsIdx[type]+1:0;
     copyDataBufsIdx[type] = newCopyDataIdx;
+    pthread_mutex_unlock(&UEcopyDataMutex);
     // End of critical zone between UE Rx threads
 
     // New data will be copied in a different buffer than the live one
@@ -1204,6 +1192,7 @@ STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue)
   pthread_t forms_thread;
   threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW);
 #endif
+  pthread_mutex_init(&UEcopyDataMutex, NULL);
 }
 
 void nrscope_autoinit(void *dataptr) {
diff --git a/openair1/PHY/TOOLS/phy_scope_interface.h b/openair1/PHY/TOOLS/phy_scope_interface.h
index 6162e1eee58023622c0aaccc5e2de962aa62bb67..00efbdff245c2958e15db6cf98cfb4c69e63d133 100644
--- a/openair1/PHY/TOOLS/phy_scope_interface.h
+++ b/openair1/PHY/TOOLS/phy_scope_interface.h
@@ -47,6 +47,9 @@ enum UEdataType {
   pbchRxdataF_comp,
   pdcchLlr,
   pdcchRxdataF_comp,
+  pdschLlr,
+  pdschRxdataF_comp,
+  commonRxdataF,
   UEdataTypeNumberOfItems
 };
 
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 2b96f1582cce8f20dd61b2d5374ac606b1419723..a75529b1d315c74eacc46fc713722b53e2b4ac4a 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -232,11 +232,6 @@ typedef struct {
   /// - second index: sample [0..2*FRAME_LENGTH_COMPLEX_SAMPLES+2048[
   int32_t **rxdata;
 
-  /// \brief Holds the received data in the frequency domain.
-  /// - first index: rx antenna [0..nb_antennas_rx[
-  /// - second index: symbol [0..28*ofdm_symbol_size[
-  int32_t **rxdataF;
-
   /// holds output of the sync correlator
   int32_t *sync_corr;
   /// estimated frequency offset (in radians) for all subcarriers
@@ -245,97 +240,6 @@ typedef struct {
   int32_t eNb_id;
 } NR_UE_COMMON;
 
-typedef struct {
-  /// \brief Received frequency-domain signal after extraction.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_ext;
-  /// \brief Received frequency-domain ue specific pilots.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..12*N_RB_DL[
-  int32_t **rxdataF_uespec_pilots;
-  /// \brief Received frequency-domain signal after extraction and channel compensation.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **rxdataF_comp0;
-  /// \brief Hold the channel estimates in frequency domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
-  int32_t **dl_ch_estimates;
-  /// \brief Downlink channel estimates extracted in PRBS.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_estimates_ext;
-  /// \brief Downlink beamforming channel estimates in frequency domain.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: samples? [0..symbols_per_tti*(ofdm_symbol_size+LTE_CE_FILTER_LENGTH)[
-  int32_t **dl_bf_ch_estimates;
-  /// \brief Downlink beamforming channel estimates.
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_bf_ch_estimates_ext;
-  /// \brief Downlink PMIs extracted in PRBS and grouped in subbands.
-  /// - first index: ressource block [0..N_RB_DL[
-  uint8_t *pmi_ext;
-  /// \brief Magnitude of Downlink Channel first layer (16QAM level/First 64QAM level).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_mag0;
-  /// \brief Magnitude of Downlink Channel, first layer (2nd 64QAM level).
-  /// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
-  /// - second index: ? [0..168*N_RB_DL[
-  int32_t **dl_ch_magb0;
-  /// \brief Magnitude of Downlink Channel, first layer (256QAM level).
-  int32_t **dl_ch_magr0;
-  /// \brief Cross-correlation Matrix of the gNB Tx channel signals.
-  /// - first index: aatx*n_rx+aarx for all aatx=[0..n_tx[ and aarx=[0..nb_rx[
-  /// - second index: symbol [0..]
-  int32_t ***rho;
-  /// \brief Pointers to llr vectors (2 TBs).
-  /// - first index: ? [0..1] (hard coded)
-  /// - second index: ? [0..1179743] (hard coded)
-  int16_t *llr[2];
-  /// Pointers to layer llr vectors (4 layers).
-  int16_t *layer_llr[4];
-  /// \f$\log_2(\max|H_i|^2)\f$
-  int16_t log2_maxh;
-  /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer1 channel compensation
-  int16_t log2_maxh0;
-  /// \f$\log_2(\max|H_i|^2)\f$ //this is for TM3-4 layer2 channel commpensation
-  int16_t log2_maxh1;
-  /// \brief LLR shifts for subband scaling.
-  /// - first index: ? [0..168*N_RB_DL[
-  uint8_t *llr_shifts;
-  /// \brief Pointer to LLR shifts.
-  /// - first index: ? [0..168*N_RB_DL[
-  uint8_t *llr_shifts_p;
-  /// \brief Pointers to llr vectors (128-bit alignment).
-  /// - first index: ? [0..0] (hard coded)
-  /// - second index: ? [0..]
-  int16_t **llr128;
-  /// \brief Pointers to llr vectors (128-bit alignment).
-  /// - first index: ? [0..0] (hard coded)
-  /// - second index: ? [0..]
-  int16_t **llr128_2ndstream;
-  //uint32_t *rb_alloc;
-  //uint8_t Qm[2];
-  //MIMO_mode_t mimo_mode;
-  // llr offset per ofdm symbol
-  uint32_t llr_offset[14];
-  // llr length per ofdm symbol
-  uint32_t llr_length[14];
-  // llr offset per ofdm symbol
-  uint32_t dl_valid_re[14];
-  /// \brief Estimated phase error based upon PTRS on each symbol .
-  /// - first index: ? [0..7] Number of Antenna
-  /// - second index: ? [0...14] smybol per slot
-  int32_t **ptrs_phase_per_slot;
-  /// \brief Estimated phase error based upon PTRS on each symbol .
-  /// - first index: ? [0..7] Number of Antenna
-  /// - second index: ? [0...14] smybol per slot
-  int32_t **ptrs_re_per_slot;
-} NR_UE_PDSCH;
-
 #define NR_PRS_IDFT_OVERSAMP_FACTOR 1  // IDFT oversampling factor for NR PRS channel estimates in time domain, ALLOWED value 16x, and 1x is default(ie. IDFT size is frame_params->ofdm_symbol_size)
 typedef struct {
   prs_config_t prs_cfg;
@@ -421,6 +325,7 @@ typedef struct {
 
 typedef struct {
   int16_t amp;
+  bool active;
   fapi_nr_ul_config_prach_pdu prach_pdu;
 } NR_UE_PRACH;
 
@@ -532,7 +437,6 @@ typedef struct {
 
   fapi_nr_config_request_t nrUE_config;
 
-  NR_UE_PDSCH     *pdsch_vars[NUMBER_OF_CONNECTED_gNB_MAX+1];
   NR_UE_PBCH      *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PRACH     *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_CSI_IM    *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX];
@@ -540,7 +444,7 @@ typedef struct {
   NR_UE_SRS       *srs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PRS       *prs_vars[NR_MAX_PRS_COMB_SIZE];
   uint8_t          prs_active_gNBs;
-  NR_DL_UE_HARQ_t  dl_harq_processes[NR_MAX_NB_LAYERS>4 ? 2:1][NR_MAX_DLSCH_HARQ_PROCESSES];
+  NR_DL_UE_HARQ_t  dl_harq_processes[2][NR_MAX_DLSCH_HARQ_PROCESSES];
   NR_UL_UE_HARQ_t  ul_harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES];
   
   //Paging parameters
@@ -548,10 +452,6 @@ typedef struct {
   uint32_t              PF;
   uint32_t              PO;
 
-  UE_MODE_t           UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
-  /// cell-specific reference symbols
-  //uint32_t lte_gold_table[7][20][2][14];
-
 #if defined(UPGRADE_RAT_NR)
 
   /// demodulation reference signal for NR PBCH
@@ -750,6 +650,13 @@ typedef struct {
   int dl_errors;
   int dl_stats[8];
   void* scopeData;
+  // Pointers to hold PDSCH data only for phy simulators
+  void *phy_sim_rxdataF;
+  void *phy_sim_pdsch_llr;
+  void *phy_sim_pdsch_rxdataF_ext;
+  void *phy_sim_pdsch_rxdataF_comp;
+  void *phy_sim_pdsch_dl_ch_estimates;
+  void *phy_sim_pdsch_dl_ch_estimates_ext;
 } PHY_VARS_NR_UE;
 
 typedef struct nr_phy_data_tx_s {
@@ -759,7 +666,7 @@ typedef struct nr_phy_data_tx_s {
 
 typedef struct nr_phy_data_s {
   NR_UE_PDCCH_CONFIG phy_pdcch_config;
-  NR_UE_DLSCH_t dlsch[NR_MAX_NB_LAYERS>4 ? 2:1];
+  NR_UE_DLSCH_t dlsch[2];
 } nr_phy_data_t;
 /* this structure is used to pass both UE phy vars and
  * proc to the function UE_thread_rxn_txnp4
@@ -767,7 +674,6 @@ typedef struct nr_phy_data_s {
 typedef struct nr_rxtx_thread_data_s {
   UE_nr_rxtx_proc_t proc;
   PHY_VARS_NR_UE    *UE;
-  NR_UE_SCHED_MODE_t ue_sched_mode;
   int writeBlockSize;
 } nr_rxtx_thread_data_t;
 
diff --git a/openair1/PHY/impl_defs_nr.h b/openair1/PHY/impl_defs_nr.h
index 742f77186dd8a9987515a4423036645b2e6ad634..6db54684e65927e62ef05cd782491b157e89e154 100644
--- a/openair1/PHY/impl_defs_nr.h
+++ b/openair1/PHY/impl_defs_nr.h
@@ -518,102 +518,6 @@ typedef struct {
 } initial_pucch_resource_t;
 
 
-/* structure with all possible fields for pucch format from 0 to 4  */
-typedef struct {
-  pucch_format_nr_t      format;              /* format   0    1    2    3    4    */
-  uint8_t                initialCyclicShift;  /*          x    x                   */
-  uint8_t                nrofSymbols;         /*          x    x    x    x    x    */
-  uint8_t                startingSymbolIndex; /*          x    x    x    x    x    */
-  uint8_t                timeDomainOCC;       /*               x                   */
-  uint8_t                nrofPRBs;            /*                    x    x         */
-  uint8_t                occ_length;          /*                              x    */
-  uint8_t                occ_Index;           /*                              x    */
-} PUCCH_format_t;
-
-typedef struct {
-  uint8_t                pucch_ResourceId;           /*  maxNrofPUCCH-Resources = 128 */
-  uint16_t               startingPRB;                /* maxNrofPhysicalResourceBlocks  = 275 */
-  feature_status_t       intraSlotFrequencyHopping;
-  uint16_t               secondHopPRB;
-  PUCCH_format_t         format_parameters;
-} PUCCH_Resource_t;
-
-typedef struct {
-  uint8_t                pucch_ResourceSetId; /* maxNrofPUCCH-ResourceSets = 4 */
-/*
-  -- PUCCH resources of format0 and format1 are only allowed in the first PUCCH reosurce set,
-  -- i.e., in a PUCCH-ResourceSet with pucch-ResourceSetId = 0. This set may contain between 8 and 32 resources.
-  -- PUCCH resources of format2, format3 and format4 are only allowed  in a PUCCH-ReosurceSet with pucch-ResourceSetId > 0. If present, these sets must contain 8 resources each.
-  -- The UE chooses a PUCCH-Resource from this list based on the 3-bit PUCCH resource indicator field in DCI as
-  -- speciied in 38.213, FFS_section.
-  -- Note that this list contains only a list of resource IDs. The actual resources are configured in PUCCH-Config.
-*/
-  uint8_t                pucch_resource_id[MAX_NB_OF_PUCCH_RESOURCES_PER_SET];  /* pucch resources belonging to current set is a 32 bit map to address maxNrofPUCCH-ResourcesPerSet = 32 resources */
-
-  uint8_t                first_resources_set_R_PUCCH;  /* size of first resource set which can be higher than 8 */
-/*
-  -- Maximum number of payload bits minus 1 that the UE may transmit using this PUCCH resource set. In a PUCCH occurrence, the UE
-  -- chooses the first of its PUCCH-ResourceSet which supports the number of bits that the UE wants to transmit.
-  -- The field is not present in the first set (Set0) since the maximum Size of Set0 is specified to be 3 bit.
-  -- The field is not present in the last configured set since the UE derives its maximum payload size as specified in 38.213.
-  -- This field can take integer values that are multiples of 4. Corresponds to L1 parameter 'N_2' or 'N_3' (see 38.213, section 9.2)
-*/
-  uint16_t               maxPayloadMinus1;  /* INTEGER (4..256) */
-} PUCCH_ResourceSet_t;
-
-typedef struct {
-/*
-  -- Enabling inter-slot frequency hopping when PUCCH Format 1, 3 or 4 is repeated over multiple slots.
-  -- The field is not applicable for format 2.
- */
-  feature_status_t       interslotFrequencyHopping;
-/*
-  -- Enabling 2 DMRS symbols per hop of a PUCCH Format 3 or 4 if both hops are more than X symbols when FH is enabled (X=4).
-  -- Enabling 4 DMRS sybmols for a PUCCH Format 3 or 4 with more than 2X+1 symbols when FH is disabled (X=4).
-  -- Corresponds to L1 parameter 'PUCCH-F3-F4-additional-DMRS' (see 38.213, section 9.2.1)
-  -- The field is not applicable for format 1 and 2.
-*/
-  enable_feature_t       additionalDMRS;
-/*
-  -- Max coding rate to determine how to feedback UCI on PUCCH for format 2, 3 or 4
-  -- Corresponds to L1 parameter 'PUCCH-F2-maximum-coderate', 'PUCCH-F3-maximum-coderate' and 'PUCCH-F4-maximum-coderate'
-  -- (see 38.213, section 9.2.5)
-  -- The field is not applicable for format 1.
-*/
-  PUCCH_MaxCodeRate_t    maxCodeRate;
-/*
-  -- Number of slots with the same PUCCH F1, F3 or F4. When the field is absent the UE applies the value n1.
-  -- Corresponds to L1 parameter 'PUCCH-F1-number-of-slots', 'PUCCH-F3-number-of-slots' and 'PUCCH-F4-number-of-slots'
-  -- (see 38.213, section 9.2.6)
-  -- The field is not applicable for format 2.
-*/
-  uint8_t                nrofSlots;
-/*
-  -- Enabling pi/2 BPSK for UCI symbols instead of QPSK for PUCCH.
-  -- Corresponds to L1 parameter 'PUCCH-PF3-PF4-pi/2PBSK' (see 38.213, section 9.2.5)
-  -- The field is not applicable for format 1 and 2.
-*/
-  feature_status_t       pi2PBSK;
-/*
-  -- Enabling simultaneous transmission of CSI and HARQ-ACK feedback with or without SR with PUCCH Format 2, 3 or 4
-  -- Corresponds to L1 parameter 'PUCCH-F2-Simultaneous-HARQ-ACK-CSI', 'PUCCH-F3-Simultaneous-HARQ-ACK-CSI' and
-  -- 'PUCCH-F4-Simultaneous-HARQ-ACK-CSI' (see 38.213, section 9.2.5)
-  -- When the field is absent the UE applies the value OFF
-  -- The field is not applicable for format 1.
-*/
-  enable_feature_t       simultaneousHARQ_ACK_CSI;
-} PUCCH_FormatConfig_t;
-
-typedef struct {
-  PUCCH_Resource_t       *PUCCH_Resource[MAX_NB_OF_PUCCH_RESOURCES];
-  PUCCH_ResourceSet_t    *PUCCH_ResourceSet[MAX_NB_OF_PUCCH_RESOURCE_SETS];
-  PUCCH_FormatConfig_t   *formatConfig[NUMBER_PUCCH_FORMAT_NR-1];   /* format 0 is not there */
-  uint8_t                dl_DataToUL_ACK[NB_DL_DATA_TO_UL_ACK];     /* table TS 38.213 Table 9.2.3-1: Mapping of PSDCH-to-HARQ_feedback timing indicator field values to numbers of slots */
-  void                   *spatial_Relation_Info[MAX_NR_OF_SPATIAL_RELATION_INFOS];
-} PUCCH_Config_t;
-
-
-
 /***********************************************************************
 *
 * FUNCTIONALITY    :  Scheduling Request Configuration (SR)
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index 89e5d7501c9c2807d034b56a9a7623dfe5f1c6d5..1439c9fd010dcd98f631c95fa24ef4a886e8e48c 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -96,22 +96,20 @@ typedef struct {
   @param proc Pointer to RXn-TXnp4 proc information
   @param eNB_id Local id of eNB on which to act
 */
-void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, nr_phy_data_tx_t *phy_data);
+void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, nr_phy_data_tx_t *phy_data);
 
 /*! \brief Scheduling for UE RX procedures in normal subframes.
   @param ue                     Pointer to UE variables on which to act
   @param proc                   Pointer to proc information
-  @param gNB_id                 Local id of eNB on which to act
   @param dlsch_parallel         use multithreaded dlsch processing
   @param phy_pdcch_config       PDCCH Config for this slot
   @param txFifo                 Result fifo if PDSCH is run in parallel
 */
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
-                           uint8_t gNB_id,
                            nr_phy_data_t *phy_data);
 
-int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
+int phy_procedures_slot_parallelization_nrUE_RX(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag, uint8_t do_pdcch_flag, relaying_type_t r_type);
 
 void processSlotTX(void *arg);
 
@@ -120,7 +118,7 @@ void processSlotTX(void *arg);
     @param
     @param
  */
-void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc);
 
 int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
 
@@ -151,7 +149,6 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id,
                            void *phy_data);
 
 /*@}*/
@@ -164,7 +161,6 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
  */
 void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t pdu_type,
-                           uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0,
                            NR_UE_DLSCH_t *dlsch1,
@@ -174,26 +170,26 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
 
 bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
-                            int gNB_id,
-                            NR_UE_DLSCH_t *dlsch0,
-                            NR_UE_DLSCH_t *dlsch1);
+                            NR_UE_DLSCH_t dlsch[2],
+                            int16_t* llr[2]);
 
 int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
-                           int gNB_id,
-                           NR_UE_DLSCH_t *dlsch);
+                           NR_UE_DLSCH_t dlsch[2],
+                           int16_t *llr[2],
+                           c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
-int nr_ue_pdcch_procedures(uint8_t gNB_id,
-                           PHY_VARS_NR_UE *ue,
+int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            int32_t pdcch_est_size,
                            int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
                            nr_phy_data_t *phy_data,
-                           int n_ss);
+                           int n_ss,
+                           c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
-int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
+int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
-int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
+int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]);
 
 #endif
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 9c9e7a249b5da6f776ba2f9199afbc75e17fa716..e7fc09e4a26ffde59339042e7fa8729aaa5fd538 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -49,6 +49,7 @@ const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"};
 queue_t nr_rx_ind_queue;
 queue_t nr_crc_ind_queue;
 queue_t nr_uci_ind_queue;
+queue_t nr_rach_ind_queue;
 
 static void fill_uci_2_3_4(nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4,
                            fapi_nr_ul_config_pucch_pdu *pucch_pdu)
@@ -108,29 +109,56 @@ static void free_uci_inds(nfapi_nr_uci_indication_t *uci_ind)
 }
 
 int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response) {
+
   NR_UE_MAC_INST_t *mac = get_mac_inst(0);
-  if(scheduled_response != NULL)
-  {
-    if (scheduled_response->ul_config != NULL)
-    {
+
+  if(scheduled_response != NULL) {
+    if (scheduled_response->ul_config != NULL) {
       fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config;
       AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
                   "Too many ul_config pdus %d", ul_config->number_pdus);
-      for (int i = 0; i < ul_config->number_pdus; ++i)
-      {
+      for (int i = 0; i < ul_config->number_pdus; ++i) {
         LOG_D(NR_PHY, "In %s: processing type %d PDU of %d total UL PDUs (ul_config %p) \n",
               __FUNCTION__, ul_config->ul_config_list[i].pdu_type, ul_config->number_pdus, ul_config);
 
         uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type;
-        switch (pdu_type)
-        {
-          case (FAPI_NR_UL_CONFIG_TYPE_PUSCH):
-          {
+        switch (pdu_type) {
+          case FAPI_NR_UL_CONFIG_TYPE_PRACH: {
+            fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
+            nfapi_nr_rach_indication_t *rach_ind = CALLOC(1, sizeof(*rach_ind));
+            rach_ind->sfn = scheduled_response->frame;
+            rach_ind->slot = scheduled_response->slot;
+            rach_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION;
+            uint8_t pdu_index = 0;
+            rach_ind->pdu_list = CALLOC(1, sizeof(*rach_ind->pdu_list));
+            rach_ind->number_of_pdus  = 1;
+            rach_ind->pdu_list[pdu_index].phy_cell_id = prach_pdu->phys_cell_id;
+            rach_ind->pdu_list[pdu_index].symbol_index = prach_pdu->prach_start_symbol;
+            rach_ind->pdu_list[pdu_index].slot_index = prach_pdu->prach_slot;
+            rach_ind->pdu_list[pdu_index].freq_index = prach_pdu->num_ra;
+            rach_ind->pdu_list[pdu_index].avg_rssi = 128;
+            rach_ind->pdu_list[pdu_index].avg_snr = 0xff; // invalid for now
+            rach_ind->pdu_list[pdu_index].num_preamble  = 1;
+            const int num_p = rach_ind->pdu_list[pdu_index].num_preamble;
+            rach_ind->pdu_list[pdu_index].preamble_list = calloc(num_p, sizeof(nfapi_nr_prach_indication_preamble_t));
+            rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_index = prach_pdu->ra_PreambleIndex;
+            rach_ind->pdu_list[pdu_index].preamble_list[0].timing_advance = 0;
+            rach_ind->pdu_list[pdu_index].preamble_list[0].preamble_pwr = 0xffffffff;
+
+            if (!put_queue(&nr_rach_ind_queue, rach_ind)) {
+              for (int pdu_index = 0; pdu_index < rach_ind->number_of_pdus; pdu_index++)
+                free(rach_ind->pdu_list[pdu_index].preamble_list);
+              free(rach_ind->pdu_list);
+              free(rach_ind);
+            }
+            LOG_D(NR_MAC, "We have successfully filled the rach_ind queue with the recently filled rach ind\n");
+            break;
+          }
+          case (FAPI_NR_UL_CONFIG_TYPE_PUSCH): {
             nfapi_nr_rx_data_indication_t *rx_ind = CALLOC(1, sizeof(*rx_ind));
             nfapi_nr_crc_indication_t *crc_ind = CALLOC(1, sizeof(*crc_ind));
             nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu;
-            if (scheduled_response->tx_request)
-            {
+            if (scheduled_response->tx_request) {
               AssertFatal(scheduled_response->tx_request->number_of_pdus <
                           sizeof(scheduled_response->tx_request->tx_request_body) / sizeof(scheduled_response->tx_request->tx_request_body[0]),
                           "Too many tx_req pdus %d", scheduled_response->tx_request->number_of_pdus);
@@ -139,8 +167,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
               rx_ind->slot = scheduled_response->ul_config->slot;
               rx_ind->number_of_pdus = scheduled_response->tx_request->number_of_pdus;
               rx_ind->pdu_list = CALLOC(rx_ind->number_of_pdus, sizeof(*rx_ind->pdu_list));
-              for (int j = 0; j < rx_ind->number_of_pdus; j++)
-              {
+              for (int j = 0; j < rx_ind->number_of_pdus; j++) {
                 fapi_nr_tx_request_body_t *tx_req_body = &scheduled_response->tx_request->tx_request_body[j];
                 rx_ind->pdu_list[j].handle = pusch_config_pdu->handle;
                 rx_ind->pdu_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id;
@@ -160,8 +187,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
               crc_ind->sfn = scheduled_response->ul_config->sfn;
               crc_ind->slot = scheduled_response->ul_config->slot;
               crc_ind->crc_list = CALLOC(crc_ind->number_crcs, sizeof(*crc_ind->crc_list));
-              for (int j = 0; j < crc_ind->number_crcs; j++)
-              {
+              for (int j = 0; j < crc_ind->number_crcs; j++) {
                 crc_ind->crc_list[j].handle = pusch_config_pdu->handle;
                 crc_ind->crc_list[j].harq_id = pusch_config_pdu->pusch_data.harq_process_id;
                 LOG_D(NR_MAC, "This is the harq pid %d for crc_list[%d]\n", crc_ind->crc_list[j].harq_id, j);
@@ -179,11 +205,9 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
                       scheduled_response->frame, scheduled_response->slot, crc_ind->sfn, crc_ind->slot,pusch_config_pdu->mcs_index);
               }
 
-              if (!put_queue(&nr_rx_ind_queue, rx_ind))
-              {
+              if (!put_queue(&nr_rx_ind_queue, rx_ind)) {
                 LOG_E(NR_MAC, "Put_queue failed for rx_ind\n");
-                for (int i = 0; i < rx_ind->number_of_pdus; i++)
-                {
+                for (int i = 0; i < rx_ind->number_of_pdus; i++) {
                   free(rx_ind->pdu_list[i].pdu);
                   rx_ind->pdu_list[i].pdu = NULL;
                 }
@@ -193,8 +217,7 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
                 free(rx_ind);
                 rx_ind = NULL;
               }
-              if (!put_queue(&nr_crc_ind_queue, crc_ind))
-              {
+              if (!put_queue(&nr_crc_ind_queue, crc_ind)) {
                 LOG_E(NR_MAC, "Put_queue failed for crc_ind\n");
                 free(crc_ind->crc_list);
                 crc_ind->crc_list = NULL;
@@ -203,32 +226,26 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
               }
 
               LOG_D(PHY, "In %s: Filled queue rx/crc_ind which was filled by ulconfig. \n", __FUNCTION__);
-
               scheduled_response->tx_request->number_of_pdus = 0;
             }
             break;
           }
-
-          case FAPI_NR_UL_CONFIG_TYPE_PUCCH:
-          {
+          case FAPI_NR_UL_CONFIG_TYPE_PUCCH: {
             nfapi_nr_uci_indication_t *uci_ind = CALLOC(1, sizeof(*uci_ind));
             uci_ind->header.message_id = NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION;
             uci_ind->sfn = scheduled_response->frame;
             uci_ind->slot = scheduled_response->slot;
             uci_ind->num_ucis = 1;
             uci_ind->uci_list = CALLOC(uci_ind->num_ucis, sizeof(*uci_ind->uci_list));
-            for (int j = 0; j < uci_ind->num_ucis; j++)
-            {
+            for (int j = 0; j < uci_ind->num_ucis; j++) {
               LOG_D(NR_MAC, "ul_config->ul_config_list[%d].pucch_config_pdu.n_bit = %d\n", i, ul_config->ul_config_list[i].pucch_config_pdu.n_bit);
-              if (ul_config->ul_config_list[i].pucch_config_pdu.n_bit > 3 && mac->nr_ue_emul_l1.num_csi_reports > 0)
-              {
+              if (ul_config->ul_config_list[i].pucch_config_pdu.n_bit > 3 && mac->nr_ue_emul_l1.num_csi_reports > 0) {
                 uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_2_3_4_PDU_TYPE;
                 uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_2_3_4_t);
                 nfapi_nr_uci_pucch_pdu_format_2_3_4_t *pdu_2_3_4 = &uci_ind->uci_list[j].pucch_pdu_format_2_3_4;
                 fill_uci_2_3_4(pdu_2_3_4, &ul_config->ul_config_list[i].pucch_config_pdu);
               }
-              else
-              {
+              else {
                 nfapi_nr_uci_pucch_pdu_format_0_1_t *pdu_0_1 = &uci_ind->uci_list[j].pucch_pdu_format_0_1;
                 uci_ind->uci_list[j].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE;
                 uci_ind->uci_list[j].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t);
@@ -248,12 +265,10 @@ int8_t nr_ue_scheduled_response_stub(nr_scheduled_response_t *scheduled_response
                   pdu_0_1->harq->harq_confidence_level = 0;
                   pdu_0_1->harq->harq_list = CALLOC(pdu_0_1->harq->num_harq, sizeof(*pdu_0_1->harq->harq_list));
                   int harq_pid = -1;
-                  for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++)
-                  {
+                  for (int k = 0; k < NR_MAX_HARQ_PROCESSES; k++) {
                     if (mac->nr_ue_emul_l1.harq[k].active &&
                         mac->nr_ue_emul_l1.harq[k].active_dl_harq_sfn == uci_ind->sfn &&
-                        mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot)
-                    {
+                        mac->nr_ue_emul_l1.harq[k].active_dl_harq_slot == uci_ind->slot) {
                       mac->nr_ue_emul_l1.harq[k].active = false;
                       harq_pid = k;
                       AssertFatal(harq_index < pdu_0_1->harq->num_harq, "Invalid harq_index %d\n", harq_index);
@@ -481,6 +496,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
           // prach config pdu
           prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu;
           memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu));
+          PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->active = true;
           ul_config->ul_config_list[i].pdu_type = FAPI_NR_UL_CONFIG_TYPE_DONE; // not handle it any more
           pdu_done++;
           LOG_D(PHY, "%d.%d ul A ul_config %p t %d pdu_done %d number_pdus %d\n", scheduled_response->frame, slot, ul_config, pdu_type, pdu_done, ul_config->number_pdus);
@@ -533,11 +549,9 @@ int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){
 
   fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config;
 
-  if(phy_config != NULL) {
-      memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
-      if (PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] == NOT_SYNCHED)
-	      PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->UE_mode[0] = PRACH;
-  }
+  if(phy_config != NULL)
+    memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t));
+
   return 0;
 }
 
diff --git a/openair1/SCHED_NR_UE/harq_nr.h b/openair1/SCHED_NR_UE/harq_nr.h
index e511e6f1c651bd4b8ef6354a8b0baa531d34d9f2..f640d0f7be96e69c428ac0932030f3f202cb8842 100644
--- a/openair1/SCHED_NR_UE/harq_nr.h
+++ b/openair1/SCHED_NR_UE/harq_nr.h
@@ -65,6 +65,11 @@
 
 /*************** FUNCTIONS ****************************************/
 
+/** \brief This function update uplink harq context and return transmission type (new transmission or retransmission)
+    @param ulsch uplink harq context
+    @param harq process identifier harq_pid
+    @returns retransmission or new transmission */
+
 harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, NR_UL_UE_HARQ_t harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES], int ndi, uint8_t rnti_type);
 
 /** \brief This function initialises downlink HARQ status
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 305cf3922501f18c4acac979b8be033e724dfd8a..5d624bfd63b03174e44124a322814c6d509352d2 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -52,7 +52,8 @@
 #include "executables/softmodem-common.h"
 #include "executables/nr-uesoftmodem.h"
 #include "LAYER2/NR_MAC_UE/mac_proto.h"
-#include "openair1/SCHED_NR_UE/pucch_uci_ue_nr.h"
+#include "SCHED_NR_UE/pucch_uci_ue_nr.h"
+#include <openair1/PHY/TOOLS/phy_scope_interface.h>
 
 //#define DEBUG_PHY_PROC
 #define NR_PDCCH_SCHED
@@ -76,8 +77,6 @@ fifo_dump_emos_UE emos_dump_UE;
 #include "intertask_interface.h"
 #include "T.h"
 
-char nr_mode_string[NUM_UE_MODE][20] = {"NOT SYNCHED","PRACH","RAR","RA_WAIT_CR", "PUSCH", "RESYNCH"};
-
 #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
 extern uint64_t downlink_frequency[MAX_NUM_CCs][4];
 #endif
@@ -89,12 +88,11 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id,
                            void *phy_data){
 
   memset((void*)dl_ind, 0, sizeof(nr_downlink_indication_t));
 
-  dl_ind->gNB_index = gNB_id;
+  dl_ind->gNB_index = proc->gNB_id;
   dl_ind->module_id = ue->Mod_id;
   dl_ind->cc_id     = ue->CC_id;
   dl_ind->frame     = proc->frame_rx;
@@ -116,7 +114,6 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
 
 void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t pdu_type,
-                           uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0,
                            NR_UE_DLSCH_t *dlsch1,
@@ -270,11 +267,11 @@ void ue_ta_procedures(PHY_VARS_NR_UE *ue, int slot_tx, int frame_tx){
 
 void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
-                            uint8_t gNB_id,
                             nr_phy_data_tx_t *phy_data) {
 
   int slot_tx = proc->nr_slot_tx;
   int frame_tx = proc->frame_tx;
+  int gNB_id = proc->gNB_id;
 
   AssertFatal(ue->CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
 
@@ -287,22 +284,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
 
   start_meas(&ue->phy_proc_tx);
 
-  if (ue->UE_mode[gNB_id] <= PUSCH){
-
-    for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
-      if (ue->ul_harq_processes[harq_pid].status == ACTIVE)
-        nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data);
-    }
+  for (uint8_t harq_pid = 0; harq_pid < NR_MAX_ULSCH_HARQ_PROCESSES; harq_pid++) {
+    if (ue->ul_harq_processes[harq_pid].status == ACTIVE)
+      nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, gNB_id, phy_data);
   }
 
-  ue_srs_procedures_nr(ue, proc, gNB_id);
+  ue_srs_procedures_nr(ue, proc);
 
-  if (ue->UE_mode[gNB_id] <= PUSCH) {
-    pucch_procedures_ue_nr(ue,
-                           gNB_id,
-                           proc,
-                           phy_data);
-  }
+  pucch_procedures_ue_nr(ue, proc, phy_data);
 
   LOG_D(PHY, "Sending Uplink data \n");
   nr_ue_pusch_common_procedures(ue,
@@ -310,8 +299,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
                                 &ue->frame_parms,
                                 ue->frame_parms.nb_antennas_tx);
 
-  if (ue->UE_mode[gNB_id] > NOT_SYNCHED && ue->UE_mode[gNB_id] < PUSCH)
-    nr_ue_prach_procedures(ue, proc, proc->gNB_id);
+  nr_ue_prach_procedures(ue, proc);
 
   LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", proc->frame_tx, proc->nr_slot_tx);
 
@@ -322,13 +310,14 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
 void nr_ue_measurement_procedures(uint16_t l,
                                   PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
-                                  uint8_t gNB_id,
-                                  uint16_t slot,
-                                  NR_UE_DLSCH_t *dlsch){
+                                  NR_UE_DLSCH_t *dlsch,
+                                  uint32_t pdsch_est_size,
+                                  int32_t dl_ch_estimates[][pdsch_est_size]) {
 
   NR_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   int frame_rx   = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
+  int gNB_id = proc->gNB_id;
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
 
   if (l==2) {
@@ -339,10 +328,10 @@ void nr_ue_measurement_procedures(uint16_t l,
       nr_slot_rx,
       ue->common_vars.rxdata);
 
-    nr_ue_measurements(ue, proc, nr_slot_rx, dlsch);
+    nr_ue_measurements(ue, proc, dlsch, pdsch_est_size, dl_ch_estimates);
 
 #if T_TRACER
-    if(slot == 0)
+    if(nr_slot_rx == 0)
       T(T_UE_PHY_MEAS, T_INT(gNB_id),  T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(nr_slot_rx),
 	T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
 	T_INT((int)ue->measurements.rx_rssi_dBm[0]),
@@ -355,7 +344,7 @@ void nr_ue_measurement_procedures(uint16_t l,
   }
 
   // accumulate and filter timing offset estimation every subframe (instead of every frame)
-  if (( slot == 2) && (l==(2-frame_parms->Ncp))) {
+  if (( nr_slot_rx == 2) && (l==(2-frame_parms->Ncp))) {
 
     // AGC
 
@@ -372,46 +361,40 @@ void nr_ue_measurement_procedures(uint16_t l,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
 }
 
-static void nr_ue_pbch_procedures(uint8_t gNB_id,
-                                  PHY_VARS_NR_UE *ue,
+static void nr_ue_pbch_procedures(PHY_VARS_NR_UE *ue,
                                   UE_nr_rxtx_proc_t *proc,
                                   int estimateSz,
                                   struct complex16 dl_ch_estimates[][estimateSz],
-                                  nr_phy_data_t *phy_data) {
+                                  nr_phy_data_t *phy_data,
+                                  c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
   int ret = 0;
   DevAssert(ue);
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
+  int gNB_id = proc->gNB_id;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
 
   LOG_D(PHY,"[UE  %d] Frame %d Slot %d, Trying PBCH (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,nr_slot_rx,ue->frame_parms.Nid_cell,gNB_id);
   fapiPbch_t result;
-  ret = nr_rx_pbch(ue, proc,
-		   estimateSz, dl_ch_estimates,
+  ret = nr_rx_pbch(ue,
+                   proc,
+                   estimateSz,
+                   dl_ch_estimates,
                    ue->pbch_vars[gNB_id],
                    &ue->frame_parms,
-                   gNB_id,
                    (ue->frame_parms.ssb_index)&7,
                    SISO,
                    phy_data,
-                   &result);
+                   &result,
+                   rxdataF);
 
   if (ret==0) {
 
     ue->pbch_vars[gNB_id]->pdu_errors_conseq = 0;
 
-    // Switch to PRACH state if it is first PBCH after initial synch and no timing correction is performed
-    if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){
-      if (get_softmodem_params()->do_ra) {
-        ue->UE_mode[gNB_id] = PRACH;
-      } else {
-        ue->UE_mode[gNB_id] = PUSCH;
-      }
-    }
-
 #ifdef DEBUG_PHY_PROC
     uint16_t frame_tx;
     LOG_D(PHY,"[UE %d] frame %d, nr_slot_rx %d, Received PBCH (MIB): frame_tx %d. N_RB_DL %d\n",
@@ -498,13 +481,13 @@ unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb
 
 #ifdef NR_PDCCH_SCHED
 
-int nr_ue_pdcch_procedures(uint8_t gNB_id,
-                           PHY_VARS_NR_UE *ue,
+int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            int32_t pdcch_est_size,
                            int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
                            nr_phy_data_t *phy_data,
-                           int n_ss)
+                           int n_ss,
+                           c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP])
 {
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
@@ -522,7 +505,7 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   int16_t pdcch_e_rx[pdcch_e_rx_size];
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
-  nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15);
+  nr_rx_pdcch(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, pdcch_e_rx, rel15, rxdataF);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
   
 
@@ -543,18 +526,18 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
   //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d nr_slot_rx %d PHICH RX\n",ue->Mod_id,frame_rx,nr_slot_rx);
 
   for (int i=0; i<dci_cnt; i++) {
-    LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
-      ue->Mod_id,frame_rx%1024,nr_slot_rx,nr_mode_string[ue->UE_mode[gNB_id]],
-      i + 1,
-      dci_cnt,
-      dci_ind.dci_list[i].rnti,
-      dci_ind.dci_list[i].dci_format);
+    LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d: DCI %i of %d total DCIs found --> rnti %x : format %d\n",
+          ue->Mod_id,frame_rx%1024,nr_slot_rx,
+          i + 1,
+          dci_cnt,
+          dci_ind.dci_list[i].rnti,
+          dci_ind.dci_list[i].dci_format);
   }
 
   dci_ind.number_of_dcis = dci_cnt;
 
   // fill dl_indication message
-  nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, gNB_id, phy_data);
+  nr_fill_dl_indication(&dl_indication, &dci_ind, NULL, proc, ue, phy_data);
   //  send to mac
   ue->if_inst->dl_indication(&dl_indication, NULL);
 
@@ -566,23 +549,22 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
 }
 #endif // NR_PDCCH_SCHED
 
-int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_id, NR_UE_DLSCH_t *dlsch) {
+int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
+                           UE_nr_rxtx_proc_t *proc,
+                           NR_UE_DLSCH_t dlsch[2],
+                           int16_t *llr[2],
+                           c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   int m;
-  int gNB_id_i;
   int first_symbol_flag=0;
 
   if (!dlsch[0].active)
     return 0;
 
-  NR_UE_DLSCH_t *dlsch1 = NULL;
-
-  if (NR_MAX_NB_LAYERS > 4)
-    dlsch1 = &dlsch[1];
-
-  if (!dlsch1) {
+  // We handle only one CW now
+  if (!(NR_MAX_NB_LAYERS>4)) {
     NR_UE_DLSCH_t *dlsch0 = &dlsch[0];
     int harq_pid = dlsch0->dlsch_config.harq_process_nbr;
     NR_DL_UE_HARQ_t *dlsch0_harq = ue->dl_harq_processes[harq_pid];
@@ -596,15 +578,17 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
     LOG_D(PHY,"[UE %d] nr_slot_rx %d, harq_pid %d (%d), rb_start %d, nb_rb %d, symbol_start %d, nb_symbols %d, DMRS mask %x, Nl %d\n",
           ue->Mod_id,nr_slot_rx,harq_pid,dlsch0_harq->status,pdsch_start_rb,pdsch_nb_rb,s0,s1,dlsch0->dlsch_config.dlDmrsSymbPos, dlsch0->Nl);
 
+    const uint32_t pdsch_est_size = ((ue->frame_parms.symbols_per_slot*ue->frame_parms.ofdm_symbol_size+15)/16)*16;
+    __attribute__ ((aligned(32))) int32_t pdsch_dl_ch_estimates[ue->frame_parms.nb_antennas_rx][pdsch_est_size];
+    memset(pdsch_dl_ch_estimates, 0, sizeof(int32_t)*ue->frame_parms.nb_antennas_rx*pdsch_est_size);
+
     for (m = s0; m < (s0 +s1); m++) {
       if (dlsch0->dlsch_config.dlDmrsSymbPos & (1 << m)) {
         for (uint8_t aatx=0; aatx<dlsch0->Nl; aatx++) {//for MIMO Config: it shall loop over no_layers
           LOG_D(PHY,"PDSCH Channel estimation gNB id %d, PDSCH antenna port %d, slot %d, symbol %d\n",0,aatx,nr_slot_rx,m);
           nr_pdsch_channel_estimation(ue,
                                       proc,
-                                      gNB_id,
                                       is_SI,
-                                      nr_slot_rx,
                                       get_dmrs_port(aatx,dlsch0->dlsch_config.dmrs_ports),
                                       m,
                                       dlsch0->dlsch_config.nscid,
@@ -612,7 +596,10 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
                                       BWPStart,
                                       dlsch0->dlsch_config.dmrsConfigType,
                                       ue->frame_parms.first_carrier_offset+(BWPStart + pdsch_start_rb)*12,
-                                      pdsch_nb_rb);
+                                      pdsch_nb_rb,
+                                      pdsch_est_size,
+                                      pdsch_dl_ch_estimates,
+                                      rxdataF);
 #if 0
           ///LOG_M: the channel estimation
           int nr_frame_rx = proc->frame_rx;
@@ -626,10 +613,11 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
         }
       }
     }
+    nr_ue_measurement_procedures(2, ue, proc, &dlsch[0], pdsch_est_size, pdsch_dl_ch_estimates);
 
     if (ue->chest_time == 1) { // averaging time domain channel estimates
       nr_chest_time_domain_avg(&ue->frame_parms,
-                               ue->pdsch_vars[gNB_id]->dl_ch_estimates,
+                               (int32_t **) pdsch_dl_ch_estimates,
                                dlsch0->dlsch_config.number_symbols,
                                dlsch0->dlsch_config.start_symbol,
                                dlsch0->dlsch_config.dlDmrsSymbPos,
@@ -648,10 +636,40 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
       first_symbol_with_data++;
     }
 
+    c16_t ptrs_phase_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT];
+    memset(ptrs_phase_per_slot, 0, ue->frame_parms.nb_antennas_rx*NR_SYMBOLS_PER_SLOT*sizeof(c16_t));
+
+    int32_t ptrs_re_per_slot[ue->frame_parms.nb_antennas_rx][NR_SYMBOLS_PER_SLOT];
+    memset(ptrs_re_per_slot, 0, ue->frame_parms.nb_antennas_rx*NR_SYMBOLS_PER_SLOT*sizeof(c16_t));
+
+    uint32_t dl_valid_re[NR_SYMBOLS_PER_SLOT] = {0};
+    uint32_t llr_offset[NR_SYMBOLS_PER_SLOT] = {0};
+
+    const uint32_t rx_size = NR_SYMBOLS_PER_SLOT*
+                             dlsch[0].dlsch_config.number_rbs*
+                             NR_NB_SC_PER_RB;
+    __attribute__ ((aligned(32))) int32_t dl_ch_estimates_ext[ue->frame_parms.nb_antennas_rx][rx_size];
+    memset(dl_ch_estimates_ext, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t));
+
+    __attribute__ ((aligned(32))) int32_t rxdataF_ext[ue->frame_parms.nb_antennas_rx][rx_size];
+    memset(rxdataF_ext, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t));
+
+    __attribute__ ((aligned(32))) int32_t rxdataF_comp[ue->frame_parms.nb_antennas_rx][rx_size];
+    memset(rxdataF_comp, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t));
+
+    __attribute__ ((aligned(32))) int32_t dl_ch_mag[ue->frame_parms.nb_antennas_rx][rx_size];
+    memset(dl_ch_mag, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t));
+
+    __attribute__ ((aligned(32))) int32_t dl_ch_magb[ue->frame_parms.nb_antennas_rx][rx_size];
+    memset(dl_ch_magb, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t));
+
+    __attribute__ ((aligned(32))) int32_t dl_ch_magr[ue->frame_parms.nb_antennas_rx][rx_size];
+    memset(dl_ch_magr, 0, ue->frame_parms.nb_antennas_rx*rx_size*sizeof(int32_t));
+
+    int32_t log2_maxh = 0;
     start_meas(&ue->rx_pdsch_stats);
     for (m = s0; m < (s1 + s0); m++) {
  
-      gNB_id_i = gNB_id+1;
       if (m==first_symbol_with_data)
         first_symbol_flag = 1;
       else
@@ -666,13 +684,25 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
       if (nr_rx_pdsch(ue,
                       proc,
                       dlsch,
-                      gNB_id,
-                      gNB_id_i,
-                      frame_rx,
-                      nr_slot_rx,
                       m,
                       first_symbol_flag,
-                      harq_pid) < 0)
+                      harq_pid,
+                      pdsch_est_size,
+                      pdsch_dl_ch_estimates,
+                      llr,
+                      ptrs_phase_per_slot,
+                      ptrs_re_per_slot,
+                      dl_valid_re,
+                      rx_size,
+                      dl_ch_estimates_ext,
+                      rxdataF_ext,
+                      rxdataF_comp,
+                      dl_ch_mag,
+                      dl_ch_magb,
+                      dl_ch_magr,
+                      rxdataF,
+                      llr_offset,
+                      &log2_maxh) < 0)
         return -1;
 
       stop_meas(&ue->dlsch_llr_stats_parallelization[slot]);
@@ -683,27 +713,40 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int gNB_
       }
     } // CRNTI active
     stop_meas(&ue->rx_pdsch_stats);
+
+    UEscopeCopy(ue, pdschRxdataF_comp, rxdataF_comp, sizeof(struct complex16), ue->frame_parms.nb_antennas_rx, rx_size);
+
+    if (ue->phy_sim_pdsch_rxdataF_comp)
+      memcpy(ue->phy_sim_pdsch_rxdataF_comp, rxdataF_comp, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx);
+    if (ue->phy_sim_pdsch_rxdataF_ext)
+      memcpy(ue->phy_sim_pdsch_rxdataF_ext, rxdataF_ext, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx);
+    if (ue->phy_sim_pdsch_dl_ch_estimates_ext)
+      memcpy(ue->phy_sim_pdsch_dl_ch_estimates_ext, dl_ch_estimates_ext, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx);
+    if (ue->phy_sim_pdsch_dl_ch_estimates)
+      memcpy(ue->phy_sim_pdsch_dl_ch_estimates, dl_ch_estimates_ext, sizeof(int32_t)*rx_size*ue->frame_parms.nb_antennas_rx);
   }
   return 0;
 }
 
 bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
-                            int gNB_id,
-                            NR_UE_DLSCH_t *dlsch0,
-                            NR_UE_DLSCH_t *dlsch1) {
+                            NR_UE_DLSCH_t dlsch[2],
+                            int16_t* llr[2]) {
 
-  if (dlsch0==NULL)
-    AssertFatal(0,"dlsch0 should be defined at this level \n");
+  if (dlsch[0].active == false) {
+    LOG_E(PHY, "DLSCH should be active when calling this function\n");
+    return 1;
+  }
+
+  int gNB_id = proc->gNB_id;
   bool dec = false;
-  int harq_pid = dlsch0->dlsch_config.harq_process_nbr;
+  int harq_pid = dlsch[0].dlsch_config.harq_process_nbr;
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
   uint32_t ret = UINT32_MAX, ret1 = UINT32_MAX;
-  NR_UE_PDSCH *pdsch_vars;
   NR_DL_UE_HARQ_t *dl_harq0 = &ue->dl_harq_processes[0][harq_pid];
-  NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[NR_MAX_NB_LAYERS>4 ? 1:0][harq_pid];
-  uint16_t dmrs_len = get_num_dmrs(dlsch0->dlsch_config.dlDmrsSymbPos);
+  NR_DL_UE_HARQ_t *dl_harq1 = &ue->dl_harq_processes[1][harq_pid];
+  uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos);
   nr_downlink_indication_t dl_indication;
   fapi_nr_rx_indication_t *rx_ind = calloc(1, sizeof(*rx_ind));
   uint16_t number_pdus = 1;
@@ -711,45 +754,40 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
   NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[gNB_id];
 
   uint8_t is_cw0_active = dl_harq0->status;
-  uint16_t nb_symb_sch = dlsch0->dlsch_config.number_symbols;
-  uint16_t start_symbol = dlsch0->dlsch_config.start_symbol;
-  uint8_t dmrs_type = dlsch0->dlsch_config.dmrsConfigType;
+  uint8_t is_cw1_active = dl_harq1->status;
+  uint16_t nb_symb_sch = dlsch[0].dlsch_config.number_symbols;
+  uint16_t start_symbol = dlsch[0].dlsch_config.start_symbol;
+  uint8_t dmrs_type = dlsch[0].dlsch_config.dmrsConfigType;
 
   uint8_t nb_re_dmrs;
   if (dmrs_type==NFAPI_NR_DMRS_TYPE1) {
-    nb_re_dmrs = 6*dlsch0->dlsch_config.n_dmrs_cdm_groups;
+    nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
   }
   else {
-    nb_re_dmrs = 4*dlsch0->dlsch_config.n_dmrs_cdm_groups;
+    nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
   }
 
-  uint8_t is_cw1_active = 0;
-  if(dlsch1)
-    is_cw1_active = dl_harq1->status;
-
   LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw0_active);
   LOG_D(PHY,"AbsSubframe %d.%d Start LDPC Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, nr_slot_rx, harq_pid, is_cw1_active);
 
-  pdsch_vars = ue->pdsch_vars[gNB_id];
-
   // exit dlsch procedures as there are no active dlsch
   if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE)
     return false;
 
   // start ldpc decode for CW 0
-  dl_harq0->G = nr_get_G(dlsch0->dlsch_config.number_rbs,
+  dl_harq0->G = nr_get_G(dlsch[0].dlsch_config.number_rbs,
                          nb_symb_sch,
                          nb_re_dmrs,
                          dmrs_len,
-                         dlsch0->dlsch_config.qamModOrder,
-                         dlsch0->Nl);
+                         dlsch[0].dlsch_config.qamModOrder,
+                         dlsch[0].Nl);
 
   start_meas(&ue->dlsch_unscrambling_stats);
-  nr_dlsch_unscrambling(pdsch_vars->llr[0],
+  nr_dlsch_unscrambling(llr[0],
                         dl_harq0->G,
                         0,
                         ue->frame_parms.Nid_cell,
-                        dlsch0->rnti);
+                        dlsch[0].rnti);
     
 
   stop_meas(&ue->dlsch_unscrambling_stats);
@@ -759,9 +797,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
   ret = nr_dlsch_decoding(ue,
                           proc,
                           gNB_id,
-                          pdsch_vars->llr[0],
+                          llr[0],
                           &ue->frame_parms,
-                          dlsch0,
+                          &dlsch[0],
                           dl_harq0,
                           frame_rx,
                           nb_symb_sch,
@@ -775,7 +813,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     dec = true;
 
   int ind_type = -1;
-  switch(dlsch0->rnti_type) {
+  switch(dlsch[0].rnti_type) {
     case _RA_RNTI_:
       ind_type = FAPI_NR_RX_PDU_TYPE_RAR;
       break;
@@ -789,14 +827,14 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       break;
 
     default:
-      AssertFatal(true, "Invalid DLSCH type %d\n", dlsch0->rnti_type);
+      AssertFatal(true, "Invalid DLSCH type %d\n", dlsch[0].rnti_type);
       break;
   }
 
-  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL);
-  nr_fill_rx_indication(rx_ind, ind_type, gNB_id, ue, dlsch0, NULL, number_pdus, proc, NULL);
+  nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, NULL);
+  nr_fill_rx_indication(rx_ind, ind_type, ue, &dlsch[0], NULL, number_pdus, proc, NULL);
 
-  LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch0->dlsch_config.TBS, dlsch0->dlsch_config.TBS / 8);
+  LOG_D(PHY, "In %s DL PDU length in bits: %d, in bytes: %d \n", __FUNCTION__, dlsch[0].dlsch_config.TBS, dlsch[0].dlsch_config.TBS / 8);
 
   stop_meas(&ue->dlsch_decoding_stats);
   if (cpumeas(CPUMEAS_GETSTATE))  {
@@ -808,18 +846,18 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
   if(is_cw1_active) {
     // start ldpc decode for CW 1
-    dl_harq1->G = nr_get_G(dlsch1->dlsch_config.number_rbs,
+    dl_harq1->G = nr_get_G(dlsch[1].dlsch_config.number_rbs,
                            nb_symb_sch,
                            nb_re_dmrs,
                            dmrs_len,
-                           dlsch1->dlsch_config.qamModOrder,
-                           dlsch1->Nl);
+                           dlsch[1].dlsch_config.qamModOrder,
+                           dlsch[1].Nl);
     start_meas(&ue->dlsch_unscrambling_stats);
-    nr_dlsch_unscrambling(pdsch_vars->llr[1],
+    nr_dlsch_unscrambling(llr[1],
                           dl_harq1->G,
                           0,
                           ue->frame_parms.Nid_cell,
-                          dlsch1->rnti);
+                          dlsch[1].rnti);
     stop_meas(&ue->dlsch_unscrambling_stats);
 
     start_meas(&ue->dlsch_decoding_stats);
@@ -827,9 +865,9 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     ret1 = nr_dlsch_decoding(ue,
                              proc,
                              gNB_id,
-                             pdsch_vars->llr[1],
+                             llr[1],
                              &ue->frame_parms,
-                             dlsch1,
+                             &dlsch[1],
                              dl_harq1,
                              frame_rx,
                              nb_symb_sch,
@@ -844,7 +882,7 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       LOG_D(PHY, "AbsSubframe %d.%d --> ldpc Decoding for CW1 %5.3f\n",
             frame_rx%1024, nr_slot_rx,(ue->dlsch_decoding_stats.p_time)/(cpuf*1000.0));
       }
-  LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch0->dlsch_config.TBS);
+  LOG_D(PHY, "harq_pid: %d, TBS expected dlsch1: %d \n", harq_pid, dlsch[1].dlsch_config.TBS);
   }
   //  send to mac
   if (ue->if_inst && ue->if_inst->dl_indication) {
@@ -996,11 +1034,11 @@ bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
 
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
-                           uint8_t gNB_id,
                            nr_phy_data_t *phy_data) {
 
   int frame_rx = proc->frame_rx;
   int nr_slot_rx = proc->nr_slot_rx;
+  int gNB_id = proc->gNB_id;
   fapi_nr_config_request_t *cfg = &ue->nrUE_config;
   NR_DL_FRAME_PARMS *fp = &ue->frame_parms;
   NR_UE_PDCCH_CONFIG *phy_pdcch_config = &phy_data->phy_pdcch_config;
@@ -1012,6 +1050,8 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   LOG_D(PHY," ****** start RX-Chain for Frame.Slot %d.%d ******  \n",
         frame_rx%1024, nr_slot_rx);
 
+  const uint32_t rxdataF_sz = ue->frame_parms.samples_per_slot_wCP;
+  __attribute__ ((aligned(32))) c16_t rxdataF[ue->frame_parms.nb_antennas_rx][rxdataF_sz];
   // checking if current frame is compatible with SSB periodicity
   if (cfg->ssb_table.ssb_period == 0 ||
       !(frame_rx%(1<<(cfg->ssb_table.ssb_period-1)))){
@@ -1039,17 +1079,23 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
             nr_slot_fep(ue,
                         proc,
                         (ssb_start_symbol+i)%(fp->symbols_per_slot),
-                        nr_slot_rx);
+                        rxdataF);
 
             start_meas(&ue->dlsch_channel_estimation_stats);
-            nr_pbch_channel_estimation(ue, estimateSz, dl_ch_estimates,
-                                       dl_ch_estimates_time, proc, gNB_id,
-                                       nr_slot_rx, (ssb_start_symbol+i)%(fp->symbols_per_slot),
-                                       i-1, ssb_index&7, ssb_slot_2 == nr_slot_rx);
+            nr_pbch_channel_estimation(ue,
+                                       estimateSz,
+                                       dl_ch_estimates,
+                                       dl_ch_estimates_time,
+                                       proc,
+                                       (ssb_start_symbol+i)%(fp->symbols_per_slot),
+                                       i-1,
+                                       ssb_index&7,
+                                       ssb_slot_2 == nr_slot_rx,
+                                       rxdataF);
             stop_meas(&ue->dlsch_channel_estimation_stats);
           }
 
-          nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, nr_slot_rx);
+          nr_ue_ssb_rsrp_measurements(ue, ssb_index, proc, rxdataF);
 
           // resetting ssb index for PBCH detection if there is a stronger SSB index
           if(ue->measurements.ssb_rsrp_dBm[ssb_index] > ue->measurements.ssb_rsrp_dBm[fp->ssb_index])
@@ -1058,23 +1104,23 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
           if(ssb_index == fp->ssb_index) {
 
             LOG_D(PHY," ------  Decode MIB: frame.slot %d.%d ------  \n", frame_rx%1024, nr_slot_rx);
-            nr_ue_pbch_procedures(gNB_id, ue, proc, estimateSz, dl_ch_estimates, phy_data);
+            nr_ue_pbch_procedures(ue, proc, estimateSz, dl_ch_estimates, phy_data, rxdataF);
 
             if (ue->no_timing_correction==0) {
-             LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
-             nr_adjust_synch_ue(fp,
-                                ue,
-                                gNB_id,
-                                fp->ofdm_symbol_size,
-                                dl_ch_estimates_time,
-                                frame_rx,
-                                nr_slot_rx,
-                                0,
-                                16384);
+              LOG_D(PHY,"start adjust sync slot = %d no timing %d\n", nr_slot_rx, ue->no_timing_correction);
+              nr_adjust_synch_ue(fp,
+                                 ue,
+                                 gNB_id,
+                                 fp->ofdm_symbol_size,
+                                 dl_ch_estimates_time,
+                                 frame_rx,
+                                 nr_slot_rx,
+                                 0,
+                                 16384);
             }
           }
           LOG_D(PHY, "Doing N0 measurements in %s\n", __FUNCTION__);
-          nr_ue_rrc_measurements(ue, proc, nr_slot_rx);
+          nr_ue_rrc_measurements(ue, proc, rxdataF);
           VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PBCH, VCD_FUNCTION_OUT);
         }
       }
@@ -1096,9 +1142,14 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
             nr_slot_fep(ue,
                         proc,
                         (j%fp->symbols_per_slot),
-                        nr_slot_rx);
+                        rxdataF);
           }
-          nr_prs_channel_estimation(gNB_id,rsc_id,i,ue,proc,fp);
+          nr_prs_channel_estimation(rsc_id,
+                                    i,
+                                    ue,
+                                    proc,
+                                    fp,
+                                    rxdataF);
         }
       } // for i
     } // for rsc_id
@@ -1132,7 +1183,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     nr_slot_fep(ue,
                 proc,
                 l,
-                nr_slot_rx);
+                rxdataF);
   }
 
     // Hold the channel estimates in frequency domain.
@@ -1147,19 +1198,18 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 
       nr_pdcch_channel_estimation(ue,
                                   proc,
-                                  gNB_id,
-                                  nr_slot_rx,
                                   l,
                                   &phy_pdcch_config->pdcch_config[n_ss].coreset,
                                   fp->first_carrier_offset,
                                   phy_pdcch_config->pdcch_config[n_ss].BWPStart,
                                   pdcch_est_size,
-                                  pdcch_dl_ch_estimates);
+                                  pdcch_dl_ch_estimates,
+                                  rxdataF);
 
       stop_meas(&ue->ofdm_demod_stats);
 
     }
-    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(gNB_id, ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss);
+    dci_cnt = dci_cnt + nr_ue_pdcch_procedures(ue, proc, pdcch_est_size, pdcch_dl_ch_estimates, phy_data, n_ss, rxdataF);
   }
   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);
@@ -1181,7 +1231,7 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
         nr_slot_fep(ue,
                     proc,
                     m,  //to be updated from higher layer
-                    nr_slot_rx);
+                    rxdataF);
       }
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP_PDSCH, VCD_FUNCTION_OUT);
     }
@@ -1194,27 +1244,47 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   start_meas(&ue->generic_stat);
   // do procedures for C-RNTI
   int ret_pdsch = 0;
-  if (dlsch->active) {
+  if (dlsch[0].active) {
+
+    uint8_t nb_re_dmrs;
+    if (dlsch[0].dlsch_config.dmrsConfigType == NFAPI_NR_DMRS_TYPE1) {
+      nb_re_dmrs = 6*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
+    }
+    else {
+      nb_re_dmrs = 4*dlsch[0].dlsch_config.n_dmrs_cdm_groups;
+    }
+    uint16_t dmrs_len = get_num_dmrs(dlsch[0].dlsch_config.dlDmrsSymbPos);
+
+    const uint32_t rx_llr_size = nr_get_G(dlsch[0].dlsch_config.number_rbs,
+                                          dlsch[0].dlsch_config.number_symbols,
+                                          nb_re_dmrs,
+                                          dmrs_len,
+                                          dlsch[0].dlsch_config.qamModOrder,
+                                          dlsch[0].Nl);
+    const uint32_t rx_llr_buf_sz = ((rx_llr_size+15)/16)*16;
+    const uint32_t nb_codewords = NR_MAX_NB_LAYERS > 4 ? 2 : 1;
+    int16_t* llr[2];
+    for (int i=0; i<nb_codewords; i++)
+      llr[i] = (int16_t *)malloc16_clear(rx_llr_buf_sz*sizeof(int16_t));
+
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_IN);
     ret_pdsch = nr_ue_pdsch_procedures(ue,
                                        proc,
-                                       gNB_id,
-                                       dlsch);
+                                       dlsch,
+                                       llr,
+                                       rxdataF);
 
-    nr_ue_measurement_procedures(2, ue, proc, gNB_id, nr_slot_rx, dlsch);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_C, VCD_FUNCTION_OUT);
 
+    UEscopeCopy(ue, pdschLlr, llr[0], sizeof(int16_t), 1, rx_llr_size);
+
     LOG_D(PHY, "DLSCH data reception at nr_slot_rx: %d\n", nr_slot_rx);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
 
     start_meas(&ue->dlsch_procedures_stat);
 
-    NR_UE_DLSCH_t *dlsch1 = NULL;
-    if (NR_MAX_NB_LAYERS>4)
-      dlsch1 = &phy_data->dlsch[1];
-
     if (ret_pdsch >= 0)
-      nr_ue_dlsch_procedures(ue, proc, gNB_id, dlsch, dlsch1);
+      nr_ue_dlsch_procedures(ue, proc, dlsch, llr);
 
     stop_meas(&ue->dlsch_procedures_stat);
     if (cpumeas(CPUMEAS_GETSTATE)) {
@@ -1222,8 +1292,14 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
       LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",nr_slot_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
     }
 
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    if (ue->phy_sim_rxdataF)
+      memcpy(ue->phy_sim_rxdataF, rxdataF, sizeof(int32_t)*rxdataF_sz*ue->frame_parms.nb_antennas_rx);
+    if (ue->phy_sim_pdsch_llr)
+      memcpy(ue->phy_sim_pdsch_llr, llr[0], sizeof(int16_t)*rx_llr_buf_sz);
 
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    for (int i=0; i<nb_codewords; i++)
+      free(llr[i]);
   }
 
   // do procedures for CSI-IM
@@ -1238,10 +1314,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
       }
       l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx];
       if(nr_slot_fep_done == false) {
-        nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], nr_slot_rx);
+        nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], rxdataF);
       }
     }
-    nr_ue_csi_im_procedures(ue, proc, gNB_id);
+    nr_ue_csi_im_procedures(ue, proc, rxdataF);
     ue->csiim_vars[gNB_id]->active = 0;
   }
 
@@ -1249,10 +1325,10 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) {
     for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
       if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu,symb)) {
-        nr_slot_fep(ue, proc, symb, nr_slot_rx);
+        nr_slot_fep(ue, proc, symb, rxdataF);
       }
     }
-    nr_ue_csi_rs_procedures(ue, proc, gNB_id);
+    nr_ue_csi_rs_procedures(ue, proc, rxdataF);
     ue->csirs_vars[gNB_id]->active = 0;
   }
 
@@ -1298,24 +1374,22 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
     LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",nr_slot_rx,ue->phy_proc_rx.p_time/(cpuf*1000.0));
 
   LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, nr_slot_rx);
+  UEscopeCopy(ue, commonRxdataF, rxdataF, sizeof(int32_t), ue->frame_parms.nb_antennas_rx, rxdataF_sz);
   return (0);
 }
 
 
 // todo:
 // - power control as per 38.213 ch 7.4
-void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc) {
 
+  int gNB_id = proc->gNB_id;
   int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp
   uint8_t mod_id = ue->Mod_id;
-  uint8_t nr_prach = 0;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
 
-  nr_prach = nr_ue_get_rach(&ue->prach_vars[gNB_id]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx);
-  LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources : %d\n", __FUNCTION__, frame_tx, nr_slot_tx,nr_prach);
-
-  if (nr_prach == GENERATE_PREAMBLE) {
+  if (ue->prach_vars[gNB_id]->active) {
 
     fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
     ue->tx_power_dBm[nr_slot_tx] = prach_pdu->prach_tx_power;
@@ -1345,15 +1419,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
       dB_fixed(prach_power),
       ue->prach_vars[gNB_id]->amp);
 
-  } else if (nr_prach == WAIT_CONTENTION_RESOLUTION) {
-    LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id);
-    ue->UE_mode[gNB_id] = RA_WAIT_CR;
-  } else if (nr_prach == RA_SUCCEEDED) {
-    LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id);
-    ue->UE_mode[gNB_id] = PUSCH;
-  } else if(nr_prach == RA_FAILED){
-    LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id);
-    ue->UE_mode[gNB_id] = PRACH;
+    ue->prach_vars[gNB_id]->active = false;
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index a10e6a29b47903c41e0c8f589658b6391d1d3b89..5e53b3e17b7f4fb721262a90499694a1f9d1cdcf 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -199,11 +199,10 @@ void nr_generate_pucch3_4(int32_t **txdataF,
 *********************************************************************/
 
 void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, 
-                            uint8_t gNB_id,
                             UE_nr_rxtx_proc_t *proc,
                             nr_phy_data_tx_t *phy_data) {
 
-  int       nr_slot_tx = proc->nr_slot_tx;
+  int nr_slot_tx = proc->nr_slot_tx;
   fapi_nr_ul_config_pucch_pdu *pucch_pdu;
   NR_UE_PUCCH *pucch_vars = &phy_data->pucch_vars;
 
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
index 7f8bf13da3d7efe9c7f93420ca39f0031f89006a..26404427ce5c5c2156b620ce47f30112b5694fe3 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.h
@@ -60,7 +60,6 @@
 /*************** FUNCTIONS ****************************************/
 
 void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, 
-                            uint8_t gNB_id,
                             UE_nr_rxtx_proc_t *proc,
                             nr_phy_data_tx_t *phy_data);
 
diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c
index e7c8f92cab788619f3070bb32ac2d87db0d50a2f..585f77ac71aa150987caca4382564b152ad84caa 100644
--- a/openair1/SIMULATION/NR_PHY/dlschsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlschsim.c
@@ -433,7 +433,7 @@ int main(int argc, char **argv)
   nr_ue_dlsch_init(dlsch_ue, num_codeword, 5);
   for (int i=0; i < num_codeword; i++)
     dlsch_ue[0].rnti = n_rnti;
-  nr_init_dl_harq_processes(UE->dl_harq_processes[0], 8, nb_rb);
+  nr_init_dl_harq_processes(UE->dl_harq_processes, 8, nb_rb);
 
 	unsigned char harq_pid = 0; //dlsch->harq_ids[subframe];
   processingData_L1tx_t msgDataTx;
@@ -639,9 +639,7 @@ int main(int argc, char **argv)
   free(RC.gNB[0]);
   free(RC.gNB);
 
-  int num_cw = NR_MAX_NB_LAYERS > 4? 2:1;
-  for (int i = 0; i < num_cw; i++)
-    free_nr_ue_dl_harq(UE->dl_harq_processes[i], 8, nb_rb);
+  free_nr_ue_dl_harq(UE->dl_harq_processes, 8, nb_rb);
   term_nr_ue_signal(UE, 1);
   free(UE);
 
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 40125fb2c31ae50a378f3013835ce129f24c4668..dd49f1d01097c4a3fb3be8836ee3cd0e7da059eb 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -893,8 +893,10 @@ int main(int argc, char **argv)
   UE->frame_parms.nb_antennas_rx = n_rx;
   UE->max_ldpc_iterations = max_ldpc_iterations;
 
-  if (run_initial_sync==1)  UE->is_synchronized = 0;
-  else                      {UE->is_synchronized = 1; UE->UE_mode[0]=PUSCH;}
+  if (run_initial_sync==1)
+    UE->is_synchronized = 0;
+  else
+    UE->is_synchronized = 1;
 
   if (init_nr_ue_signal(UE, 1) != 0)
   {
@@ -984,6 +986,14 @@ int main(int argc, char **argv)
   msgDataTx->frame = frame;
   memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
 
+  // Buffers to store internal memory of slot process
+  UE->phy_sim_rxdataF = calloc(frame_parms->samples_per_slot_wCP*sizeof(int32_t), frame_parms->nb_antennas_rx);
+  UE->phy_sim_pdsch_llr = calloc((8*(3*8*8448))*sizeof(int16_t), 1); //Max length
+  UE->phy_sim_pdsch_rxdataF_ext = calloc(14*frame_parms->N_RB_DL*12*sizeof(int32_t), frame_parms->nb_antennas_rx);
+  UE->phy_sim_pdsch_rxdataF_comp = calloc(14*frame_parms->N_RB_DL*12*sizeof(int32_t), frame_parms->nb_antennas_rx);
+  UE->phy_sim_pdsch_dl_ch_estimates = calloc(14*frame_parms->ofdm_symbol_size*sizeof(int32_t), frame_parms->nb_antennas_rx);
+  UE->phy_sim_pdsch_dl_ch_estimates_ext = calloc(14*frame_parms->N_RB_DL*12*sizeof(int32_t), frame_parms->nb_antennas_rx);
+
   for (SNR = snr0; SNR < snr1; SNR += .2) {
 
     varArray_t *table_tx=initVarArray(1000,sizeof(double));
@@ -1022,6 +1032,7 @@ int main(int argc, char **argv)
       UE->rx_offset=0;
       UE_proc.frame_rx   = frame;
       UE_proc.nr_slot_rx = slot;
+      UE_proc.gNB_id     = 0;
       
       dcireq.frame     = frame;
       dcireq.slot      = slot;
@@ -1203,7 +1214,6 @@ int main(int argc, char **argv)
 
         phy_procedures_nrUE_RX(UE,
                                &UE_proc,
-                               0,
                                &phy_data);
         
         //----------------------------------------------------------
@@ -1213,8 +1223,7 @@ int main(int argc, char **argv)
         if (dlsch0->last_iteration_cnt >= dlsch0->max_ldpc_iterations+1)
           n_errors[round]++;
 
-        NR_UE_PDSCH **pdsch_vars = UE->pdsch_vars;
-        int16_t *UE_llr = pdsch_vars[0]->llr[0];
+        int16_t *UE_llr = (int16_t*)UE->phy_sim_pdsch_llr;
 
         TBS                  = dlsch0->dlsch_config.TBS;//rel15->TBSize[0];
         uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos);
@@ -1352,11 +1361,11 @@ int main(int argc, char **argv)
       LOG_M("rxsig0.m","rxs0", UE->common_vars.rxdata[0], frame_length_complex_samples, 1, 1);
       if (UE->frame_parms.nb_antennas_rx>1)
 	LOG_M("rxsig1.m","rxs1", UE->common_vars.rxdata[1], frame_length_complex_samples, 1, 1);
-      LOG_M("rxF0.m","rxF0", UE->common_vars.rxdataF[0], frame_parms->samples_per_slot_wCP, 1, 1);
-      LOG_M("rxF_ext.m","rxFe",&UE->pdsch_vars[0]->rxdataF_ext[0][0],g_rbSize*12*14,1,1);
-      LOG_M("chestF0.m","chF0",&UE->pdsch_vars[0]->dl_ch_estimates_ext[0][0],g_rbSize*12*14,1,1);
-      write_output("rxF_comp.m","rxFc",&UE->pdsch_vars[0]->rxdataF_comp0[0][0],N_RB_DL*12*14,1,1);
-      LOG_M("rxF_llr.m","rxFllr",UE->pdsch_vars[0]->llr[0],available_bits,1,0);
+      LOG_M("rxF0.m","rxF0", UE->phy_sim_rxdataF, frame_parms->samples_per_slot_wCP, 1, 1);
+      LOG_M("rxF_ext.m","rxFe",UE->phy_sim_pdsch_rxdataF_ext,g_rbSize*12*14,1,1);
+      LOG_M("chestF0.m","chF0",UE->phy_sim_pdsch_dl_ch_estimates_ext,g_rbSize*12*14,1,1);
+      write_output("rxF_comp.m","rxFc",UE->phy_sim_pdsch_rxdataF_comp,N_RB_DL*12*14,1,1);
+      LOG_M("rxF_llr.m","rxFllr",UE->phy_sim_pdsch_llr,available_bits,1,0);
       break;
     }
 
@@ -1387,6 +1396,12 @@ int main(int argc, char **argv)
   free(txdata);
   free(test_input_bit);
   free(estimated_output_bit);
+  free(UE->phy_sim_rxdataF);
+  free(UE->phy_sim_pdsch_llr);
+  free(UE->phy_sim_pdsch_rxdataF_ext);
+  free(UE->phy_sim_pdsch_rxdataF_comp);
+  free(UE->phy_sim_pdsch_dl_ch_estimates);
+  free(UE->phy_sim_pdsch_dl_ch_estimates_ext);
   
   if (output_fd)
     fclose(output_fd);
diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c
index 1ca43dfa30cbd58c68d50b802f9950e74d080a40..6e7398858b39c7feb2265a57818a4d50db480d7e 100644
--- a/openair1/SIMULATION/NR_PHY/pbchsim.c
+++ b/openair1/SIMULATION/NR_PHY/pbchsim.c
@@ -108,11 +108,9 @@ void nr_fill_dl_indication(nr_downlink_indication_t *dl_ind,
                            fapi_nr_rx_indication_t *rx_ind,
                            UE_nr_rxtx_proc_t *proc,
                            PHY_VARS_NR_UE *ue,
-                           uint8_t gNB_id,
                            void *phy_data) {}
 void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
                            uint8_t pdu_type,
-                           uint8_t gNB_id,
                            PHY_VARS_NR_UE *ue,
                            NR_UE_DLSCH_t *dlsch0,
                            NR_UE_DLSCH_t *dlsch1,
@@ -122,28 +120,28 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind,
 
 void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {}
 
-int nr_ue_pdcch_procedures(uint8_t gNB_id,
-			   PHY_VARS_NR_UE *ue,
+int nr_ue_pdcch_procedures(PHY_VARS_NR_UE *ue,
 			   UE_nr_rxtx_proc_t *proc,
          int32_t pdcch_est_size,
          int32_t pdcch_dl_ch_estimates[][pdcch_est_size],
          nr_phy_data_t *phy_data,
-         int n_ss) {
+         int n_ss,
+         c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
   return 0;
 }
 
 int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
-                           int eNB_id,
-                           NR_UE_DLSCH_t *dlsch) {
+                           NR_UE_DLSCH_t dlsch[2],
+                           int16_t *llr[2],
+                           c16_t rxdataF[][ue->frame_parms.samples_per_slot_wCP]) {
   return 0;
 }
 
 bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
-                            int gNB_id,
-                            NR_UE_DLSCH_t *dlsch0,
-                            NR_UE_DLSCH_t *dlsch1) {
+                            NR_UE_DLSCH_t dlsch[2],
+                            int16_t *llr[2]) {
   return false;
 }
 
@@ -633,6 +631,8 @@ int main(int argc, char **argv)
 
   processingData_L1tx_t msgDataTx;
   // generate signal
+  const uint32_t rxdataF_sz = UE->frame_parms.samples_per_slot_wCP;
+  __attribute__ ((aligned(32))) c16_t rxdataF[UE->frame_parms.nb_antennas_rx][rxdataF_sz];
   if (input_fd==NULL) {
 
     for (i=0; i<frame_parms->Lmax; i++) {
@@ -797,14 +797,16 @@ int main(int argc, char **argv)
 	UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
 
         int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
+        proc.nr_slot_rx = ssb_slot;
+        proc.gNB_id = 0;
 	for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
           nr_slot_fep(UE,
                       &proc,
                       i%frame_parms->symbols_per_slot,
-                      ssb_slot);
+                      rxdataF);
 
           nr_pbch_channel_estimation(UE,estimateSz, dl_ch_estimates, dl_ch_estimates_time, &proc, 
-				     0,ssb_slot,i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf);
+				     i%frame_parms->symbols_per_slot,i-(UE->symbol_offset+1),ssb_index%8,n_hf,rxdataF);
 
         }
 	fapiPbch_t result;
@@ -813,11 +815,11 @@ int main(int argc, char **argv)
 			 estimateSz, dl_ch_estimates,
 			 UE->pbch_vars[0],
                          frame_parms,
-                         0,
                          ssb_index%8,
                          SISO,
                          &phy_data,
-                         &result);
+                         &result,
+                         rxdataF);
 
 	if (ret==0) {
 	  //UE->rx_ind.rx_indication_body->mib_pdu.ssb_index;  //not yet detected automatically
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index dd71aecacdb697117fd3067a39676143bf9d4475..f18a36d2991360d7955b307d8b97d0ae41bc7fe4 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -241,11 +241,10 @@ int main(int argc, char **argv)
   uint16_t nb_rb = 50;
   int Imcs = 9;
   uint8_t precod_nbr_layers = 1;
-  int gNB_id = 0;
   int tx_offset;
   int32_t txlev_sum = 0, atxlev[4];
   int start_rb = 0;
-  int UE_id =0; // [hna] only works for UE_id = 0 because NUMBER_OF_NR_UE_MAX is set to 1 (phy_init_nr_gNB causes segmentation fault)
+  int UE_id = 0;
   int print_perf = 0;
   cpuf = get_cpu_freq_GHz();
   int msg3_flag = 0;
@@ -1038,6 +1037,7 @@ int main(int argc, char **argv)
 
         UE_proc.nr_slot_tx = slot;
         UE_proc.frame_tx = frame;
+        UE_proc.gNB_id   = 0;
 
         UL_tti_req->SFN = frame;
         UL_tti_req->Slot = slot;
@@ -1181,7 +1181,7 @@ int main(int argc, char **argv)
           /////////////////////////phy_procedures_nr_ue_TX///////////////////////
           ///////////
 
-          phy_procedures_nrUE_TX(UE, &UE_proc, gNB_id, &phy_data);
+          phy_procedures_nrUE_TX(UE, &UE_proc, &phy_data);
 
           if (n_trials == 1) {
             LOG_M("txsig0.m", "txs0", &UE->common_vars.txdata[0][slot_offset], slot_length, 1, 1);
diff --git a/openair1/SIMULATION/RF/rf.c b/openair1/SIMULATION/RF/rf.c
index bff3453de0c30ae3df4696a756b0202dbe80be62..081a102bbb21dcb3cd823f805b8897086b845683 100644
--- a/openair1/SIMULATION/RF/rf.c
+++ b/openair1/SIMULATION/RF/rf.c
@@ -26,21 +26,7 @@
 //#include "PHY/defs.h"
 #include "SIMULATION/TOOLS/sim.h"
 #include "rf.h"
-/*
-extern void randominit(void);
-extern double gaussdouble(double,double);
-  //free(input_data);
-
-//extern int LOG_M(const char *,const char *,void *,int,int,char);
-//flag change
-extern int LOG_M(const char *,const char *,void *,int,int,char);
-*/
-
-//double pn[1024];
-
-//#define DEBUG_RF 1
 
-//free(input_data);
 void rf_rx(double **r_re,
            double **r_im,
            double **r_re_i1,
diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c
index 863012f69a97142ff95cd799059383ac1cdc2c65..df45199006470953884ab9136f4b8868c7dafa46 100644
--- a/openair1/SIMULATION/TOOLS/rangen_double.c
+++ b/openair1/SIMULATION/TOOLS/rangen_double.c
@@ -26,57 +26,67 @@
 
 #include  "sim.h"
 
-static unsigned int seed, iy, ir[98];
-/*
-@defgroup _uniformdouble
-@ingroup numerical Uniform linear congruential random number generator.
-*/
-
-/*!\brief Initialization routine for Uniform/Gaussian random number generators. */
-
-#define a 1664525lu
-#define mod 4294967296.0                /* is 2**32 */
+static unsigned int urseed, iy, ir[98]; /// uniformrandom
+static bool tableNordDone = false; /// gaussZiggurat
 
-#if 1
-void randominit(unsigned seed_init)
+/*!\brief Generate a random number form `/dev/urandom`. */
+void fill_random(void *buf, size_t sz)
 {
-  int i;
-  // this need to be integrated with the existing rng, like taus: navid
-
-  if (seed_init == 0) {
-    srand((unsigned)time(NULL));
-
-    seed = (unsigned int) rand();
-  } else {
-    seed = seed_init;
+  const char* fn = "/dev/urandom";
+  FILE* f = fopen(fn, "rb");
+  if (f == NULL) {
+    fprintf(stderr, "could not open %s for seed generation: %d %s\n", fn, errno, strerror(errno));
+    abort();
   }
-  printf("Initializing random number generator, seed %x\n",seed);
+  int rc = fread(buf, sz, 1, f);
+  if (rc < 0) {
+    fprintf(stderr, "could not read %s for seed generation: %d %s\n", fn, errno, strerror(errno));
+    abort();
+  }
+  fclose(f);
+}
+
 
-  if (seed % 2 == 0) seed += 1; /* seed and mod are relative prime */
+static const unsigned int a = 1664525lu;
 
-  for (i=1; i<=97; i++) {
-    seed = a*seed;                 /* mod 2**32  */
-    ir[i]= seed;                   /* initialize the shuffle table    */
+/*!\brief Initialization routine for Uniform/Gaussian random number generators. */
+void randominit(unsigned long seed_init)
+{
+  unsigned long seed = seed_init;
+  if (seed_init == 0)
+    fill_random(&seed, sizeof(seed));
+  printf("Initializing random number generator, seed %ld\n", seed);
+
+  // initialize uniformrandom RNG
+  urseed = (unsigned int) seed;
+  if (urseed % 2 == 0)
+    urseed += 1; /* urseed and mod are relative prime */
+  for (int i = 1; i <= 97; i++) {
+    urseed = a * urseed; /* mod 2**32  */
+    ir[i] = urseed; /* initialize the shuffle table    */
   }
+  iy = 1;
 
- iy=1;
+  // initialize gaussZiggurat RNG
+  tableNor(seed);
+  tableNordDone = true;
 }
-#endif
+
+/*
+@defgroup _uniformdouble
+@ingroup numerical Uniform linear congruential random number generator.
+*/
 
 /*!\brief Uniform linear congruential random number generator on \f$[0,1)\f$.  Returns a double-precision floating-point number.*/
 
 double uniformrandom(void)
 {
-#define a 1664525lu
-#define mod 4294967296.0                /* is 2**32 */
-
-  int j;
-
-  j=1 + 97.0*iy/mod;
-  iy=ir[j];
-  seed = a*seed;                          /* mod 2**32 */
-  ir[j] = seed;
-  return( (double) iy/mod );
+  const double mod = 4294967296.0; /* is 2**32 */
+  int j = 1 + 97.0 * iy / mod;
+  iy = ir[j];
+  urseed = a * urseed; /* mod 2**32 */
+  ir[j] = urseed;
+  return (double)iy / mod;
 }
 
 /*
@@ -109,8 +119,12 @@ double __attribute__ ((no_sanitize_address)) gaussdouble(double mean, double var
   }
 }
 
+
+/*
+@defgroup _gaussZiggurat
+@ingroup numerical ziggurat random number generator for exponentially distributed numbers
+*/
 // Ziggurat
-static bool tableNordDone=false;
 static double wn[128], fn[128];
 static uint32_t iz, jz, jsr = 123456789, kn[128];
 static int32_t hz;
@@ -180,9 +194,9 @@ double __attribute__ ((no_sanitize_address)) gaussZiggurat(double mean, double v
 {
   if (!tableNordDone) {
     // let's make reasonnable constant tables
-    struct timespec t;
-    clock_gettime(CLOCK_MONOTONIC, &t);
-    tableNor((long)(t.tv_nsec%INT_MAX));
+    unsigned long seed;
+    fill_random(&seed, sizeof(seed));
+    tableNor(seed);
   }
   hz = SHR3;
   iz = hz & 127;
diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h
index 92c11c8da5695b822a8465059f503c8bcf587d6d..b23aaac4b5e84dfe7737bbeb56a69daf0d33c6da 100644
--- a/openair1/SIMULATION/TOOLS/sim.h
+++ b/openair1/SIMULATION/TOOLS/sim.h
@@ -523,8 +523,9 @@ the value \f$\mathrm{sgn}(u)i\f$.  The search requires at most \f$Nbits-1\f$ com
 */
 int gauss(unsigned int *gauss_LUT,unsigned char Nbits);
 
+void fill_random(void *buf, size_t sz);
 double gaussdouble(double,double);
-void randominit(unsigned int seed_init);
+void randominit(unsigned long seed_init);
 double uniformrandom(void);
 double gaussZiggurat(double mean, double variance);
 void tableNor(unsigned long seed);
diff --git a/openair1/SIMULATION/TOOLS/taus.c b/openair1/SIMULATION/TOOLS/taus.c
index a9d2750c06374d80d4b0575176c7bd65e56feccf..5280cceafb6edbeeabde8388c5b83a0e548cac76 100644
--- a/openair1/SIMULATION/TOOLS/taus.c
+++ b/openair1/SIMULATION/TOOLS/taus.c
@@ -23,7 +23,7 @@
 #include <stdlib.h>
 #include <fcntl.h>
 #include <unistd.h>
-//#include "SIMULATION/TOOLS/sim.h"
+#include "sim.h"
 
 
 static unsigned int s0, s1, s2;
@@ -52,20 +52,9 @@ void set_taus_seed(unsigned int seed_init)
   unsigned long result = 0;
 
   if (seed_init == 0) {
-    unsigned int data[3];
-    int fd = open("/dev/urandom", O_RDONLY);
-    if (fd == -1)
-    {
-      abort();
-    }
-    if (read(fd, data, sizeof(data)) != sizeof(data))
-    {
-      abort();
-    }
-    close(fd);
-    s0 = data[0];
-    s1 = data[1];
-    s2 = data[2];
+    fill_random(&s0, sizeof(s0));
+    fill_random(&s1, sizeof(s1));
+    fill_random(&s2, sizeof(s2));
   } else {
     /* Use reentrant version of rand48 to ensure that no conflicts with other generators occur */
     srand48_r((long int)seed_init, &buffer);
diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h
index f28e0e5ddfc1989db3329a74feef9e487e94f279..5db598409fe0a0ce8c0853f1e06997b7c5123f34 100644
--- a/openair2/COMMON/f1ap_messages_def.h
+++ b/openair2/COMMON/f1ap_messages_def.h
@@ -40,7 +40,6 @@ MESSAGE_DEF(F1AP_UL_RRC_MESSAGE                , MESSAGE_PRIORITY_MED, f1ap_ul_r
 MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_req_t, f1ap_ue_context_release_req)
 MESSAGE_DEF(F1AP_UE_CONTEXT_RELEASE_CMD, MESSAGE_PRIORITY_MED, f1ap_ue_context_release_cmd_t, f1ap_ue_context_release_cmd)
 
-
 /* RRC -> F1AP  messages */
 MESSAGE_DEF(F1AP_DL_RRC_MESSAGE              , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t              , f1ap_dl_rrc_message )
 //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req )
@@ -49,6 +48,5 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_se
 MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ,  MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req)
 MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp)
 
-
-
-
+/* CU -> DU*/
+MESSAGE_DEF(F1AP_PAGING_IND, MESSAGE_PRIORITY_MED, f1ap_paging_ind_t, f1ap_paging_ind)
diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h
index cbc4d1c6f2dedc169e7c7fd64e97d6a90a09d833..e615005991926fa2d89fe76596a42885a89a401f 100644
--- a/openair2/COMMON/f1ap_messages_types.h
+++ b/openair2/COMMON/f1ap_messages_types.h
@@ -50,6 +50,8 @@
 #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR)        (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
 #define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR)        (mSGpTR)->ittiMsg.f1ap_ue_context_release_req
 
+#define F1AP_PAGING_IND(mSGpTR)                    (mSGpTR)->ittiMsg.f1ap_paging_ind
+
 /* Length of the transport layer address string
  * 160 bits / 8 bits by char.
  */
@@ -424,4 +426,15 @@ typedef struct f1ap_ue_context_release_s {
 } f1ap_ue_context_release_req_t, f1ap_ue_context_release_cmd_t,
   f1ap_ue_context_release_cplt_t;
 
+typedef struct f1ap_paging_ind_s {
+  uint16_t ueidentityindexvalue;
+  uint64_t fiveg_s_tmsi;
+  uint8_t  fiveg_s_tmsi_length;
+  uint16_t mcc;
+  uint16_t mnc;
+  uint8_t  mnc_digit_length;
+  uint64_t nr_cellid;
+  uint8_t  paging_drx;
+} f1ap_paging_ind_t;
+
 #endif /* F1AP_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h
index f053fe7f1e5f69eed557cc92bb54b636be123653..47dac57832a97134c6b48a6d7ceeeadf8c21eace 100644
--- a/openair2/COMMON/platform_constants.h
+++ b/openair2/COMMON/platform_constants.h
@@ -119,6 +119,10 @@
 #define CH_OFFSET      0x0004
 #define CH_SHIFT       2
 
+// RLC Entity
+#define RLC_TX_MAXSIZE       10000000
+#define RLC_RX_MAXSIZE       10000000
+
 // RLC_AM_SEND_MRW
 #        define SEND_MRW_OFF    15
 #        define SEND_MRW_ON     240
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
deleted file mode 100644
index 7825d7faea2082cfb788670465173777f486a22b..0000000000000000000000000000000000000000
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ /dev/null
@@ -1,3797 +0,0 @@
-/*
- * 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 flexran_agent_ran_api.c
- * \brief FlexRAN RAN API abstraction
- * \author N. Nikaein, X. Foukas, S. SHARIAT BAGHERI and R. Schmidt
- * \date 2017
- * \version 0.1
- */
-
-#include <dlfcn.h>
-#include "flexran_agent_ran_api.h"
-#include "s1ap_eNB_ue_context.h"
-#include "s1ap_eNB_management_procedures.h"
-#include "openair2/LAYER2/MAC/slicing/slicing.h"
-
-#include "common/ran_context.h"
-extern RAN_CONTEXT_t RC;
-
-static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) {
-  return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id];
-}
-
-static inline int mac_is_present(mid_t mod_id) {
-  return RC.mac && RC.mac[mod_id];
-}
-
-static inline int rrc_is_present(mid_t mod_id) {
-  return RC.rrc && RC.rrc[mod_id];
-}
-
-uint32_t flexran_get_current_time_ms(mid_t mod_id, int subframe_flag) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  if (subframe_flag == 1)
-    return RC.mac[mod_id]->frame*10 + RC.mac[mod_id]->subframe;
-  else
-    return RC.mac[mod_id]->frame*10;
-}
-
-frame_t flexran_get_current_frame(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  //  #warning "SFN will not be in [0-1023] when oaisim is used"
-  return RC.mac[mod_id]->frame;
-}
-
-frame_t flexran_get_current_system_frame_num(mid_t mod_id) {
-  return flexran_get_current_frame(mod_id) % 1024;
-}
-
-sub_frame_t flexran_get_current_subframe(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->subframe;
-}
-
-uint32_t flexran_get_sfn_sf(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return flexran_get_current_frame(mod_id) * 10 + flexran_get_current_subframe(mod_id);
-}
-
-uint16_t flexran_get_future_sfn_sf(mid_t mod_id, int ahead_of_time) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  frame_t frame = flexran_get_current_system_frame_num(mod_id);
-  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
-  uint16_t sfn_sf, frame_mask, sf_mask;
-  int additional_frames;
-  subframe = (subframe + ahead_of_time) % 10;
-
-  if (subframe < flexran_get_current_subframe(mod_id))
-    frame = (frame + 1) % 1024;
-
-  additional_frames = ahead_of_time / 10;
-  frame = (frame + additional_frames) % 1024;
-  frame_mask = (1 << 12) - 1;
-  sf_mask = (1 << 4) - 1;
-  sfn_sf = (subframe & sf_mask) | ((frame & frame_mask) << 4);
-  return sfn_sf;
-}
-
-int flexran_get_mac_num_ues(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.num_UEs;
-}
-
-int flexran_get_num_ue_lcs(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  // Not sure whether this is needed: if (!rrc_is_present(mod_id)) return 0;
-  const rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
-  const int s = mac_eNB_get_rrc_status(mod_id, rnti);
-
-  if (s < RRC_CONNECTED)
-    return 0;
-  else if (s == RRC_CONNECTED)
-    return 1;
-  else
-    return 3;
-}
-
-int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti) {
-  int n;
-
-  if (!mac_is_present(mod_id)) return 0;
-
-  /* get the (active) UE with RNTI i */
-  for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
-    if (RC.mac[mod_id]->UE_info.active[n] == true
-        && rnti == UE_RNTI(mod_id, n)) {
-      return n;
-    }
-  }
-
-  return 0;
-}
-
-int flexran_get_mac_ue_id(mid_t mod_id, int i) {
-  int n;
-
-  if (!mac_is_present(mod_id)) return 0;
-
-  /* get the (i+1)'th active UE */
-  for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) {
-    if (RC.mac[mod_id]->UE_info.active[n] == true) {
-      if (i == 0)
-        return n;
-
-      --i;
-    }
-  }
-
-  return 0;
-}
-
-rnti_t flexran_get_mac_ue_crnti(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return UE_RNTI(mod_id, ue_id);
-}
-
-int flexran_get_ue_bsr_ul_buffer_info(mid_t mod_id, mid_t ue_id, lcid_t lcid) {
-  if (!mac_is_present(mod_id)) return -1;
-
-  return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].ul_buffer_info[lcid];
-}
-
-int8_t flexran_get_ue_phr(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].phr_info;
-}
-
-uint8_t flexran_get_ue_wcqi(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].dl_cqi[0];
-}
-
-rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id, ue_id);
-  frame_t frame = flexran_get_current_frame(mod_id);
-  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
-  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0, 0
-                                                       );
-  return rlc_status.bytes_in_buffer;
-}
-
-rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
-  frame_t frame = flexran_get_current_frame(mod_id);
-  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
-  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0, 0
-                                                       );
-  return rlc_status.pdus_in_buffer;
-}
-
-frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  rnti_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
-  frame_t frame = flexran_get_current_frame(mod_id);
-  sub_frame_t subframe = flexran_get_current_subframe(mod_id);
-  mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0, 0
-                                                       );
-  return rlc_status.head_sdu_creation_time;
-}
-
-int32_t flexran_get_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  int32_t tau = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].timing_advance_update;
-
-  switch (flexran_get_N_RB_DL(mod_id, cc_id)) {
-    case 6:
-      return tau;
-
-    case 15:
-      return tau / 2;
-
-    case 25:
-      return tau / 4;
-
-    case 50:
-      return tau / 8;
-
-    case 75:
-      return tau / 12;
-
-    case 100:
-      if (flexran_get_threequarter_fs(mod_id, cc_id) == 0)
-        return tau / 16;
-      else
-        return tau / 12;
-
-    default:
-      return 0;
-  }
-}
-
-uint32_t flexran_get_total_size_dl_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_sdu_bytes;
-}
-
-uint32_t flexran_get_total_size_ul_mac_sdus(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  uint64_t bytes = 0;
-
-  for (int i = 0; i < NB_RB_MAX; ++i) {
-    bytes += RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].num_bytes_rx[i];
-  }
-
-  return bytes;
-}
-
-uint32_t flexran_get_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].TBS;
-}
-
-uint32_t flexran_get_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].ulsch_TBS;
-}
-
-uint16_t flexran_get_num_prb_retx_dl_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used_retx;
-}
-
-uint32_t flexran_get_num_prb_retx_ul_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used_retx_rx;
-}
-
-uint16_t flexran_get_num_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used;
-}
-
-uint16_t flexran_get_num_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].rbs_used_rx;
-}
-
-uint8_t flexran_get_ue_wpmi(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].periodic_wideband_pmi[cc_id];
-}
-
-uint8_t flexran_get_mcs1_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].dlsch_mcs1;
-}
-
-uint8_t flexran_get_mcs2_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].dlsch_mcs2;
-}
-
-uint8_t flexran_get_mcs1_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].ulsch_mcs1;
-}
-
-uint8_t flexran_get_mcs2_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].ulsch_mcs2;
-}
-
-uint32_t flexran_get_total_prb_dl_tx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_rbs_used;
-}
-
-uint32_t flexran_get_total_prb_ul_rx_per_ue(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_rbs_used_rx;
-}
-
-uint32_t flexran_get_total_num_pdu_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_num_pdus;
-}
-
-uint32_t flexran_get_total_num_pdu_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_num_pdus_rx;
-}
-
-uint64_t flexran_get_total_TBS_dl(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_pdu_bytes;
-}
-
-uint64_t flexran_get_total_TBS_ul(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].total_ulsch_TBS;
-}
-
-int flexran_get_harq_round(mid_t mod_id, uint8_t cc_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].harq_round;
-}
-
-uint32_t flexran_get_num_mac_sdu_tx(mid_t mod_id, mid_t ue_id, int cc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].num_mac_sdu_tx;
-}
-
-unsigned char flexran_get_mac_sdu_lcid_index(mid_t mod_id, mid_t ue_id, int cc_id, int index) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].lcid_sdu[index];
-}
-
-uint32_t flexran_get_mac_sdu_size(mid_t mod_id, mid_t ue_id, int cc_id, int lcid) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.eNB_UE_stats[cc_id][ue_id].sdu_length_tx[lcid];
-}
-
-
-/* TODO needs to be revised */
-void flexran_update_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  /*
-    UE_info_t *UE_info=&eNB_mac_inst[mod_id].UE_info;
-    UE_sched_ctrl *ue_sched_ctl = &UE_info->UE_sched_ctrl[ue_id];
-
-    if (ue_sched_ctl->ta_timer == 0) {
-
-      // WE SHOULD PROTECT the eNB_UE_stats with a mutex here ...
-      //    LTE_eNB_UE_stats    *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id, CC_id, rnti);
-      //ue_sched_ctl->ta_timer          = 20; // wait 20 subframes before taking TA measurement from PHY
-      ue_sched_ctl->ta_update = flexran_get_TA(mod_id, ue_id, CC_id);
-
-      // clear the update in case PHY does not have a new measurement after timer expiry
-      //    eNB_UE_stats->timing_advance_update       = 0;
-    } else {
-      ue_sched_ctl->ta_timer--;
-      ue_sched_ctl->ta_update         = 0;  // don't trigger a timing advance command
-    }
-  #warning "Implement flexran_update_TA() in RAN API"
-  */
-}
-
-/* TODO needs to be revised, looks suspicious: why do we need UE stats? */
-int flexran_get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  /*
-  #warning "Implement flexran_get_MAC_CE_bitmap_TA() in RAN API"
-  */
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  /* UE_stats can not be null, they are an array in RC
-  LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(mod_id,CC_id,rnti);
-
-  if (eNB_UE_stats == NULL) {
-    return 0;
-  }
-  */
-
-  if (flexran_get_TA(mod_id, ue_id, cc_id) != 0) {
-    return PROTOCOL__FLEX_CE_TYPE__FLPCET_TA;
-  } else {
-    return 0;
-  }
-}
-
-int flexran_get_active_CC(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.numactiveCCs[ue_id];
-}
-
-uint8_t flexran_get_current_RI(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].rank;
-}
-
-int flexran_get_tpc(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  /* before: tested that UL_rssi != NULL and set parameter ([0]), but it is a
-   * static array -> target_rx_power is useless in old ifs?! */
-  int pCCid = UE_PCCID(mod_id,ue_id);
-  int32_t target_rx_power = RC.eNB[mod_id][pCCid]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
-  int32_t normalized_rx_power = RC.eNB[mod_id][cc_id]->UE_stats[ue_id].UL_rssi[0];
-  int tpc;
-
-  if (normalized_rx_power > target_rx_power + 1)
-    tpc = 0;  //-1
-  else if (normalized_rx_power < target_rx_power - 1)
-    tpc = 2;  //+1
-  else
-    tpc = 1;  //0
-
-  return tpc;
-}
-
-int flexran_get_harq(mid_t       mod_id,
-                     uint8_t     cc_id,
-                     mid_t       ue_id,
-                     frame_t     frame,
-                     sub_frame_t subframe,
-                     uint8_t    *pid,
-                     uint8_t    *round,
-                     uint8_t     harq_flag) {
-  /* TODO: Add int TB in function parameters to get the status of the second
-   * TB. This can be done to by editing in get_ue_active_harq_pid function in
-   * line 272 file: phy_procedures_lte_eNB.c to add DLSCH_ptr =
-   * PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][1];*/
-  /* TODO IMPLEMENT */
-  /*
-  uint8_t harq_pid;
-  uint8_t harq_round;
-
-  if (mac_xface_not_ready()) return 0 ;
-
-  uint16_t rnti = flexran_get_mac_ue_crnti(mod_id,ue_id);
-  if (harq_flag == openair_harq_DL){
-
-      mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,&harq_round,openair_harq_DL);
-
-   } else if (harq_flag == openair_harq_UL){
-
-     mac_xface->get_ue_active_harq_pid(mod_id,CC_id,rnti,frame,subframe,&harq_pid,round,openair_harq_UL);
-   }
-   else {
-
-      LOG_W(FLEXRAN_AGENT,"harq_flag is not recongnized");
-   }
-
-
-  *pid = harq_pid;
-  *round = harq_round;*/
-  /* if (round > 0) { */
-  /*   *status = 1; */
-  /* } else { */
-  /*   *status = 0; */
-  /* } */
-  /*return *round;*/
-  /*
-  #warning "Implement flexran_get_harq() in RAN API"
-  */
-  return 0;
-}
-
-int32_t flexran_get_p0_pucch_dbm(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_dBm;
-}
-
-int8_t flexran_get_p0_nominal_pucch(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
-}
-
-int32_t flexran_get_p0_pucch_status(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update;
-}
-
-int flexran_update_p0_pucch(mid_t mod_id, mid_t ue_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  RC.eNB[mod_id][cc_id]->UE_stats[ue_id].Po_PUCCH_update = 0;
-  return 0;
-}
-
-
-/*
- * ************************************
- * Get Messages for eNB Configuration Reply
- * ************************************
- */
-uint8_t flexran_get_threequarter_fs(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.threequarter_fs;
-}
-
-
-uint8_t flexran_get_hopping_offset(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.pusch_HoppingOffset;
-}
-
-Protocol__FlexHoppingMode flexran_get_hopping_mode(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return -1;
-
-  switch (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.hoppingMode) {
-    case interSubFrame:
-      return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTER;
-
-    case intraAndInterSubFrame:
-      return PROTOCOL__FLEX_HOPPING_MODE__FLHM_INTERINTRA;
-  }
-
-  return -1;
-}
-
-uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.n_SB;
-}
-
-Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == true)
-    return PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM;
-  else
-    return PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM;
-}
-
-Protocol__FlexPhichDuration flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return -1;
-
-  switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_duration) {
-    case normal:
-      return PROTOCOL__FLEX_PHICH_DURATION__FLPD_NORMAL;
-
-    case extended:
-      return PROTOCOL__FLEX_PHICH_DURATION__FLPD_EXTENDED;
-  }
-
-  return -1;
-}
-
-Protocol__FlexPhichResource flexran_get_phich_resource(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return -1;
-
-  switch (RC.eNB[mod_id][cc_id]->frame_parms.phich_config_common.phich_resource) {
-    case oneSixth:
-      return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE_SIXTH;
-
-    case half:
-      return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_HALF;
-
-    case one:
-      return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_ONE;
-
-    case two:
-      return PROTOCOL__FLEX_PHICH_RESOURCE__FLPR_TWO;
-  }
-
-  return -1;
-}
-
-uint16_t flexran_get_n1pucch_an(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.n1PUCCH_AN;
-}
-
-uint8_t flexran_get_nRB_CQI(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.nRB_CQI;
-}
-
-uint8_t flexran_get_deltaPUCCH_Shift(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.pucch_config_common.deltaPUCCH_Shift;
-}
-
-uint8_t flexran_get_prach_ConfigIndex(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
-}
-
-uint8_t flexran_get_prach_FreqOffset(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
-}
-
-uint8_t flexran_get_maxHARQ_Msg3Tx(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.maxHARQ_Msg3Tx;
-}
-
-Protocol__FlexUlCyclicPrefixLength flexran_get_ul_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return -1;
-
-  switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp_UL) {
-    case EXTENDED:
-      return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_EXTENDED;
-
-    case NORMAL:
-      return PROTOCOL__FLEX_UL_CYCLIC_PREFIX_LENGTH__FLUCPL_NORMAL;
-  }
-
-  return -1;
-}
-
-Protocol__FlexDlCyclicPrefixLength flexran_get_dl_cyclic_prefix_length(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return -1;
-
-  switch (RC.eNB[mod_id][cc_id]->frame_parms.Ncp) {
-    case EXTENDED:
-      return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_EXTENDED;
-
-    case NORMAL:
-      return PROTOCOL__FLEX_DL_CYCLIC_PREFIX_LENGTH__FLDCPL_NORMAL;
-  }
-
-  return -1;
-}
-
-uint16_t flexran_get_cell_id(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.Nid_cell;
-}
-
-uint8_t flexran_get_srs_BandwidthConfig(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_BandwidthConfig;
-}
-
-uint8_t flexran_get_srs_SubframeConfig(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_SubframeConfig;
-}
-
-uint8_t flexran_get_srs_MaxUpPts(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.soundingrs_ul_config_common.srs_MaxUpPts;
-}
-
-uint8_t flexran_get_N_RB_DL(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL;
-}
-
-uint8_t flexran_get_N_RB_UL(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL;
-}
-
-uint8_t flexran_get_N_RBG(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.N_RBG;
-}
-
-uint8_t flexran_get_subframe_assignment(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config;
-}
-
-uint8_t flexran_get_special_subframe_assignment(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.tdd_config_S;
-}
-
-long flexran_get_ra_ResponseWindowSize(mid_t mod_id, uint8_t cc_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].rach_raResponseWindowSize;
-}
-
-long flexran_get_mac_ContentionResolutionTimer(mid_t mod_id, uint8_t cc_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].rach_macContentionResolutionTimer;
-}
-
-Protocol__FlexDuplexMode flexran_get_duplex_mode(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  switch (RC.eNB[mod_id][cc_id]->frame_parms.frame_type) {
-    case TDD:
-      return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_TDD;
-
-    case FDD:
-      return PROTOCOL__FLEX_DUPLEX_MODE__FLDM_FDD;
-
-    default:
-      return -1;
-  }
-}
-
-long flexran_get_si_window_length(mid_t mod_id, uint8_t cc_id) {
-  if (!rrc_is_present(mod_id) || !RC.rrc[mod_id]->carrier[cc_id].sib1) return 0;
-
-  return RC.rrc[mod_id]->carrier[cc_id].sib1->si_WindowLength;
-}
-
-uint8_t flexran_get_sib1_length(mid_t mod_id, uint8_t cc_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->carrier[cc_id].sizeof_SIB1;
-}
-
-uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->pdcch_vars[0].num_pdcch_symbols;
-}
-
-
-
-/*
- * ************************************
- * Get Messages for UE Configuration Reply
- * ************************************
- */
-int flexran_get_rrc_num_ues(mid_t mod_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->Nb_ue;
-}
-
-rnti_t flexran_get_rrc_rnti_nth_ue(mid_t mod_id, int index) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = NULL;
-  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) {
-    if (index == 0) return ue_context_p->ue_context.rnti;
-
-    --index;
-  }
-  return 0;
-}
-
-int flexran_get_rrc_rnti_list(mid_t mod_id, rnti_t *list, int max_list) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  int n = 0;
-  struct rrc_eNB_ue_context_s *ue_context_p = NULL;
-  RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[mod_id]->rrc_ue_head) {
-    if (n >= max_list) break;
-
-    list[n] = ue_context_p->ue_context.rnti;
-    ++n;
-  }
-  return n;
-}
-
-LTE_TimeAlignmentTimer_t  flexran_get_time_alignment_timer(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
-
-  return ue_context_p->ue_context.mac_MainConfig->timeAlignmentTimerDedicated;
-}
-
-Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measGapConfig) return -1;
-
-  if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1;
-
-  switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) {
-    case LTE_MeasGapConfig__setup__gapOffset_PR_gp0:
-      return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1;
-
-    case LTE_MeasGapConfig__setup__gapOffset_PR_gp1:
-      return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2;
-
-    default:
-      return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF;
-  }
-}
-
-
-long flexran_get_meas_gap_config_offset(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measGapConfig) return -1;
-
-  if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1;
-
-  switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) {
-    case LTE_MeasGapConfig__setup__gapOffset_PR_gp0:
-      return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0;
-
-    case LTE_MeasGapConfig__setup__gapOffset_PR_gp1:
-      return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp1;
-
-    default:
-      return -1;
-  }
-}
-
-uint8_t flexran_get_rrc_status(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return RRC_INACTIVE;
-
-  return ue_context_p->ue_context.StatusRrc;
-}
-
-uint64_t flexran_get_ue_aggregated_max_bitrate_dl(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return 0; //RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateDL;
-}
-
-uint64_t flexran_get_ue_aggregated_max_bitrate_ul(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return 0; //RC.mac[mod_id]->UE_info.UE_sched_ctrl[ue_id].ue_AggregatedMaximumBitrateUL;
-}
-
-int flexran_get_half_duplex(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability) return -1;
-
-  LTE_SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA;
-
-  for (int i = 0; i < bands->list.count; i++) {
-    if (bands->list.array[i]->halfDuplex > 0) return 1;
-  }
-
-  return 0;
-}
-
-int flexran_get_intra_sf_hopping(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
-
-  /* According to TS 36.331 Annex B.1, Intra SF Hopping is bit 1 (leftmost bit)
-   * in this bitmap, i.e. the eighth bit (from right) in the first bye (from
-   * left) */
-  BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators;
-  uint8_t buf = fgi->buf[0];
-  return (buf >> 7) & 1;
-}
-
-int flexran_get_type2_sb_1(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
-
-  /* According to TS 36.331 Annex B.1, Predefined intra- and inter-sf or
-   * predfined inter-sf frequency hopping for PUSCH with N_sb>1 is bit 21 (bit
-   * 1 is leftmost bit) in this bitmap, i.e. the fourth bit (from right) in the
-   * third byte (from left) */
-  BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators;
-  uint8_t buf = fgi->buf[2];
-  return (buf >> 3) & 1;
-}
-
-long flexran_get_ue_category(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability) return -1;
-
-  return ue_context_p->ue_context.UE_Capability->ue_Category;
-}
-
-int flexran_get_res_alloc_type1(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability) return -1;
-
-  if (!ue_context_p->ue_context.UE_Capability->featureGroupIndicators) return -1;
-
-  /* According to TS 36.331 Annex B.1, Resource allocation type 1 for PDSCH is
-   * bit 2 (bit 1 is leftmost bit) in this bitmap, i.e. the seventh bit (from
-   * right) in the first byte (from left) */
-  BIT_STRING_t *fgi = ue_context_p->ue_context.UE_Capability->featureGroupIndicators;
-  uint8_t buf = fgi->buf[0];
-  return (buf >> 6) & 1;
-}
-
-long flexran_get_ue_transmission_mode(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1;
-
-  return ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode;
-}
-
-BOOLEAN_t flexran_get_tti_bundling(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1;
-
-  return ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->ttiBundling;
-}
-
-long flexran_get_maxHARQ_TX(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config) return -1;
-
-  return *(ue_context_p->ue_context.mac_MainConfig->ul_SCH_Config->maxHARQ_Tx);
-}
-
-long flexran_get_beta_offset_ack_index(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
-
-  return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_ACK_Index;
-}
-
-long flexran_get_beta_offset_ri_index(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
-
-  return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;
-}
-
-long flexran_get_beta_offset_cqi_index(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated) return -1;
-
-  return ue_context_p->ue_context.physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index;
-}
-
-BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) return -1;
-
-  return ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI;
-}
-
-BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, uint8_t cc_id) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  if (!RC.rrc[mod_id]->carrier[cc_id].sib2) return -1;
-
-  return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission;
-}
-
-Protocol__FlexAperiodicCqiReportMode flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig) return -1;
-
-  switch (*ue_context_p->ue_context.physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic) {
-    case LTE_CQI_ReportModeAperiodic_rm12:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM12;
-
-    case LTE_CQI_ReportModeAperiodic_rm20:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM20;
-
-    case LTE_CQI_ReportModeAperiodic_rm22:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM22;
-
-    case LTE_CQI_ReportModeAperiodic_rm30:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM30;
-
-    case LTE_CQI_ReportModeAperiodic_rm31:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM31;
-
-    case LTE_CQI_ReportModeAperiodic_rm32_v1250:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM32_v1250;
-
-    case LTE_CQI_ReportModeAperiodic_rm10_v1310:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM10_v1310;
-
-    case LTE_CQI_ReportModeAperiodic_rm11_v1310:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_RM11_v1310;
-
-    default:
-      return PROTOCOL__FLEX_APERIODIC_CQI_REPORT_MODE__FLACRM_NONE;
-  }
-}
-
-long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) return -1;
-
-  return *(ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode);
-}
-
-long flexran_get_ack_nack_repetition_factor(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated) return -1;
-
-  return ue_context_p->ue_context.physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.choice.setup.repetitionFactor;
-}
-
-long flexran_get_extended_bsr_size(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig->ext2) return -1;
-
-  if (!ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020) return -1;
-
-  return *(ue_context_p->ue_context.mac_MainConfig->ext2->mac_MainConfig_v1020->extendedBSR_Sizes_r10);
-}
-
-int flexran_get_ue_transmission_antenna(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated) return -1;
-
-  if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1;
-
-  switch (ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup) {
-    case LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop:
-      return 2;
-
-    case LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop:
-      return 1;
-
-    default:
-      return 0;
-  }
-}
-
-uint64_t flexran_get_ue_imsi(mid_t mod_id, rnti_t rnti) {
-  uint64_t imsi;
-
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return 0;
-
-  imsi  = ue_context_p->ue_context.imsi.digit15;
-  imsi += ue_context_p->ue_context.imsi.digit14 * 10;              // pow(10, 1)
-  imsi += ue_context_p->ue_context.imsi.digit13 * 100;             // pow(10, 2)
-  imsi += ue_context_p->ue_context.imsi.digit12 * 1000;            // pow(10, 3)
-  imsi += ue_context_p->ue_context.imsi.digit11 * 10000;           // pow(10, 4)
-  imsi += ue_context_p->ue_context.imsi.digit10 * 100000;          // pow(10, 5)
-  imsi += ue_context_p->ue_context.imsi.digit9  * 1000000;         // pow(10, 6)
-  imsi += ue_context_p->ue_context.imsi.digit8  * 10000000;        // pow(10, 7)
-  imsi += ue_context_p->ue_context.imsi.digit7  * 100000000;       // pow(10, 8)
-  imsi += ue_context_p->ue_context.imsi.digit6  * 1000000000;      // pow(10, 9)
-  imsi += ue_context_p->ue_context.imsi.digit5  * 10000000000;     // pow(10, 10)
-  imsi += ue_context_p->ue_context.imsi.digit4  * 100000000000;    // pow(10, 11)
-  imsi += ue_context_p->ue_context.imsi.digit3  * 1000000000000;   // pow(10, 12)
-  imsi += ue_context_p->ue_context.imsi.digit2  * 10000000000000;  // pow(10, 13)
-  imsi += ue_context_p->ue_context.imsi.digit1  * 100000000000000; // pow(10, 14)
-  return imsi;
-}
-
-long flexran_get_lcg(mid_t mod_id, mid_t ue_id, mid_t lc_id) {
-  if (!mac_is_present(mod_id)) return 0;
-
-  return RC.mac[mod_id]->UE_info.UE_template[UE_PCCID(mod_id, ue_id)][ue_id].lcgidmap[lc_id];
-}
-
-/* TODO Navid: needs to be revised */
-int flexran_get_direction(mid_t ue_id, mid_t lc_id) {
-  switch (lc_id) {
-    case DCCH:
-    case DCCH1:
-      return 2;
-
-    case DTCH:
-      return 1;
-
-    default:
-      return -1;
-  }
-}
-
-uint8_t flexran_get_antenna_ports(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.nb_antenna_ports_eNB;
-}
-
-uint32_t flexran_agent_get_operating_dl_freq(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq / 1000000;
-}
-
-uint32_t flexran_agent_get_operating_ul_freq(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq / 1000000;
-}
-
-uint8_t flexran_agent_get_operating_eutra_band(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.eutra_band;
-}
-
-int8_t flexran_agent_get_operating_pdsch_refpower(mid_t mod_id, uint8_t cc_id) {
-  if (!phy_is_present(mod_id, cc_id)) return 0;
-
-  return RC.eNB[mod_id][cc_id]->frame_parms.pdsch_config_common.referenceSignalPower;
-}
-
-long flexran_agent_get_operating_pusch_p0(mid_t mod_id, uint8_t cc_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->configuration.radioresourceconfig[cc_id].pusch_p0_Nominal;
-}
-
-void flexran_agent_set_operating_dl_freq(mid_t mod_id, uint8_t cc_id, uint32_t dl_freq_mhz) {
-  if (phy_is_present(mod_id, cc_id)) {
-    RC.eNB[mod_id][cc_id]->frame_parms.dl_CarrierFreq = dl_freq_mhz * 1000000;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set dl_CarrierFreq to %d MHz in PHY: PHY is not present\n", dl_freq_mhz);
-  }
-
-  if (rrc_is_present(mod_id)) {
-    RC.rrc[mod_id]->configuration.downlink_frequency[cc_id] = dl_freq_mhz * 1000000;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set downlink_frequency to %d MHz in RRC: RRC is not present\n", dl_freq_mhz);
-  }
-}
-
-void flexran_agent_set_operating_ul_freq(mid_t mod_id, uint8_t cc_id, int32_t ul_freq_mhz_offset) {
-  if (phy_is_present(mod_id, cc_id)) {
-    uint32_t new_ul_freq_mhz = flexran_agent_get_operating_dl_freq(mod_id, cc_id) + ul_freq_mhz_offset;
-    RC.eNB[mod_id][cc_id]->frame_parms.ul_CarrierFreq = new_ul_freq_mhz * 1000000;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set ul_CarrierFreq using offset %d MHz in PHY: PHY is not present\n", ul_freq_mhz_offset);
-  }
-
-  if (rrc_is_present(mod_id)) {
-    RC.rrc[mod_id]->configuration.uplink_frequency_offset[cc_id] = ul_freq_mhz_offset;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set uplink_frequency_offset to %d MHz in RRC: RRC is not present\n", ul_freq_mhz_offset);
-  }
-}
-
-void flexran_agent_set_operating_eutra_band(mid_t mod_id, uint8_t cc_id, uint8_t eutra_band) {
-  if (phy_is_present(mod_id, cc_id)) {
-    RC.eNB[mod_id][cc_id]->frame_parms.eutra_band = eutra_band;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in PHY: PHY is not present\n", eutra_band);
-  }
-
-  if (rrc_is_present(mod_id)) {
-    RC.rrc[mod_id]->configuration.eutra_band[cc_id] = eutra_band;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set eutra_band to %d in RRC: RRC is not present\n", eutra_band);
-  }
-}
-
-/* Sets both DL/UL */
-void flexran_agent_set_operating_bandwidth(mid_t mod_id, uint8_t cc_id, uint8_t N_RB) {
-  if (phy_is_present(mod_id, cc_id)) {
-    RC.eNB[mod_id][cc_id]->frame_parms.N_RB_DL = N_RB;
-    RC.eNB[mod_id][cc_id]->frame_parms.N_RB_UL = N_RB;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL and N_RB_UL to %d in PHY: PHY is not present\n", N_RB);
-  }
-
-  if (rrc_is_present(mod_id)) {
-    RC.rrc[mod_id]->configuration.N_RB_DL[cc_id] = N_RB;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set N_RB_DL to %d in RRC: RRC is not present\n", N_RB);
-  }
-}
-
-void flexran_agent_set_operating_frame_type(mid_t mod_id, uint8_t cc_id, frame_type_t frame_type) {
-  if (phy_is_present(mod_id, cc_id)) {
-    RC.eNB[mod_id][cc_id]->frame_parms.frame_type = frame_type;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in PHY: PHY is not present\n", frame_type);
-  }
-
-  if (rrc_is_present(mod_id)) {
-    RC.rrc[mod_id]->configuration.frame_type[cc_id] = frame_type;
-  } else {
-    LOG_E(FLEXRAN_AGENT, "can not set frame_type to %d in RRC: RRC is not present\n", frame_type);
-  }
-}
-
-/*********** PDCP  *************/
-
-uint16_t flexran_get_pdcp_uid_from_rnti(mid_t mod_id, rnti_t rnti) {
-  if (rnti == NOT_A_RNTI) return 0;
-
-  if (mod_id < 0 || mod_id >= RC.nb_inst)
-    return 0;
-
-  for (uint16_t pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) {
-    if (pdcp_enb[mod_id].rnti[pdcp_uid] == rnti)
-      return pdcp_uid;
-  }
-
-  return 0;
-}
-
-/*PDCP super frame counter flexRAN*/
-uint32_t flexran_get_pdcp_sfn(mid_t mod_id) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst)
-    return 0;
-
-  return pdcp_enb[mod_id].sfn;
-}
-
-/*PDCP super frame counter flexRAN*/
-void flexran_set_pdcp_tx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB)
-    return;
-
-  Pdcp_stats_tx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000;
-}
-
-/*PDCP super frame counter flexRAN*/
-void flexran_set_pdcp_rx_stat_window(mid_t mod_id, uint16_t uid, uint16_t obs_window) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB)
-    return;
-
-  Pdcp_stats_rx_window_ms[mod_id][uid] = obs_window > 0 ? obs_window : 1000;
-}
-
-/*PDCP num tx pdu status flexRAN*/
-uint32_t flexran_get_pdcp_tx(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_tx[mod_id][uid][lcid];
-}
-
-/*PDCP num tx bytes status flexRAN*/
-uint32_t flexran_get_pdcp_tx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_tx_bytes[mod_id][uid][lcid];
-}
-
-/*PDCP number of transmit packet / second status flexRAN*/
-uint32_t flexran_get_pdcp_tx_w(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_tx_w[mod_id][uid][lcid];
-}
-
-/*PDCP throughput (bit/s) status flexRAN*/
-uint32_t flexran_get_pdcp_tx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_tx_bytes_w[mod_id][uid][lcid];
-}
-
-/*PDCP tx sequence number flexRAN*/
-uint32_t flexran_get_pdcp_tx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_tx_sn[mod_id][uid][lcid];
-}
-
-/*PDCP tx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_tx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_tx_aiat[mod_id][uid][lcid];
-}
-
-/*PDCP tx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_tx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_tx_aiat_w[mod_id][uid][lcid];
-}
-
-/*PDCP num rx pdu status flexRAN*/
-uint32_t flexran_get_pdcp_rx(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx[mod_id][uid][lcid];
-}
-
-/*PDCP num rx bytes status flexRAN*/
-uint32_t flexran_get_pdcp_rx_bytes(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx_bytes[mod_id][uid][lcid];
-}
-
-/*PDCP number of received packet / second  flexRAN*/
-uint32_t flexran_get_pdcp_rx_w(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx_w[mod_id][uid][lcid];
-}
-
-/*PDCP gootput (bit/s) status flexRAN*/
-uint32_t flexran_get_pdcp_rx_bytes_w(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx_bytes_w[mod_id][uid][lcid];
-}
-
-/*PDCP rx sequence number flexRAN*/
-uint32_t flexran_get_pdcp_rx_sn(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx_sn[mod_id][uid][lcid];
-}
-
-/*PDCP rx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_rx_aiat(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx_aiat[mod_id][uid][lcid];
-}
-
-/*PDCP rx aggregated packet arrival  flexRAN*/
-uint32_t flexran_get_pdcp_rx_aiat_w(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx_aiat_w[mod_id][uid][lcid];
-}
-
-/*PDCP num of received outoforder pdu status flexRAN*/
-uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, uint16_t uid, lcid_t lcid) {
-  if (mod_id < 0 || mod_id >= RC.nb_inst || uid < 0
-      || uid >= MAX_MOBILES_PER_ENB || lcid < 0 || lcid >= NB_RB_MAX)
-    return 0;
-
-  return Pdcp_stats_rx_outoforder[mod_id][uid][lcid];
-}
-
-/******************** RRC *****************************/
-/* RRC Wrappers */
-int flexran_call_rrc_reconfiguration (mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  protocol_ctxt_t  ctxt;
-  memset(&ctxt, 0, sizeof(ctxt));
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id);
-  flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, ue_context_p, 0);
-  return 0;
-}
-
-int flexran_call_rrc_trigger_handover (mid_t mod_id, rnti_t rnti, int target_cell_id) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  protocol_ctxt_t  ctxt;
-  memset(&ctxt, 0, sizeof(ctxt));
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, ue_context_p->ue_context.rnti, flexran_get_current_frame(mod_id), flexran_get_current_subframe (mod_id), mod_id);
-  return flexran_rrc_eNB_trigger_handover(mod_id, &ctxt, ue_context_p, target_cell_id);
-}
-
-/* RRC Getters */
-
-LTE_MeasId_t  flexran_get_rrc_pcell_measid(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measResults) return -1;
-
-  return ue_context_p->ue_context.measResults->measId;
-}
-
-float flexran_get_rrc_pcell_rsrp(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measResults) return -1;
-
-  return RSRP_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrpResult];
-}
-
-float flexran_get_rrc_pcell_rsrq(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measResults) return -1;
-
-  return RSRQ_meas_mapping[ue_context_p->ue_context.measResults->measResultPCell.rsrqResult];
-}
-
-/*Number of neighbouring cells for specific UE*/
-int flexran_get_rrc_num_ncell(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return 0;
-
-  if (!ue_context_p->ue_context.measResults) return 0;
-
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
-
-  //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
-  return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count;
-}
-
-long flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measResults) return -1;
-
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
-
-  //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
-
-  return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId;
-}
-
-int flexran_get_rrc_neigh_cgi(mid_t mod_id, rnti_t rnti, long cell_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return 0;
-
-  if (!ue_context_p->ue_context.measResults) return 0;
-
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0;
-
-  //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0;
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return 0;
-
-  return (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info)?0:1;
-}
-
-uint32_t flexran_get_rrc_neigh_cgi_cell_id(mid_t mod_id, rnti_t rnti, long cell_id) {
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-  uint8_t *cId = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.cellIdentity.buf;
-  return ((cId[0] << 20) + (cId[1] << 12) + (cId[2] << 4) + (cId[3] >> 4));
-}
-
-uint32_t flexran_get_rrc_neigh_cgi_tac(mid_t mod_id, rnti_t rnti, long cell_id) {
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-  uint8_t *tac = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->trackingAreaCode.buf;
-  return (tac[0] << 8) + (tac[1]);
-}
-
-int flexran_get_rrc_neigh_cgi_num_mnc(mid_t mod_id, rnti_t rnti, long cell_id) {
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-  return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count;
-}
-
-int flexran_get_rrc_neigh_cgi_num_mcc(mid_t mod_id, rnti_t rnti, long cell_id) {
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-  return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count;
-}
-
-uint32_t flexran_get_rrc_neigh_cgi_mnc(mid_t mod_id, rnti_t rnti, long cell_id, int mnc_id) {
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-  int num_mnc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.count;
-  return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mnc.list.array[mnc_id]) *
-         ((uint32_t) pow(10, num_mnc - mnc_id - 1));
-}
-
-uint32_t flexran_get_rrc_neigh_cgi_mcc(mid_t mod_id, rnti_t rnti, long cell_id, int mcc_id) {
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-  int num_mcc = ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.count;
-  return *(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->cgi_Info->cellGlobalId.plmn_Identity.mcc->list.array[mcc_id]) *
-         ((uint32_t) pow(10, num_mcc - mcc_id - 1));
-}
-
-float flexran_get_rrc_neigh_rsrp(mid_t mod_id, rnti_t rnti, long cell_id) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measResults) return -1;
-
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
-
-  //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1;
-
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return -1;
-
-  return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)];
-}
-
-float flexran_get_rrc_neigh_rsrq(mid_t mod_id, rnti_t rnti, long cell_id) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measResults) return -1;
-
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1;
-
-  //if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1;
-  if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return -1;
-
-  return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)];
-}
-
-/* Measurement offsets */
-
-long flexran_get_rrc_ofp(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  return ue_context_p->ue_context.measurement_info->offsetFreq;
-}
-
-long flexran_get_rrc_ofn(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  return ue_context_p->ue_context.measurement_info->offsetFreq;
-}
-
-long flexran_get_rrc_ocp(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[0]) {
-    case LTE_Q_OffsetRange_dB_24:
-      return -24;
-
-    case LTE_Q_OffsetRange_dB_22:
-      return -22;
-
-    case LTE_Q_OffsetRange_dB_20:
-      return -20;
-
-    case LTE_Q_OffsetRange_dB_18:
-      return -18;
-
-    case LTE_Q_OffsetRange_dB_16:
-      return -16;
-
-    case LTE_Q_OffsetRange_dB_14:
-      return -14;
-
-    case LTE_Q_OffsetRange_dB_12:
-      return -12;
-
-    case LTE_Q_OffsetRange_dB_10:
-      return -10;
-
-    case LTE_Q_OffsetRange_dB_8:
-      return -8;
-
-    case LTE_Q_OffsetRange_dB_6:
-      return -6;
-
-    case LTE_Q_OffsetRange_dB_5:
-      return -5;
-
-    case LTE_Q_OffsetRange_dB_4:
-      return -4;
-
-    case LTE_Q_OffsetRange_dB_3:
-      return -3;
-
-    case LTE_Q_OffsetRange_dB_2:
-      return -2;
-
-    case LTE_Q_OffsetRange_dB_1:
-      return -1;
-
-    case LTE_Q_OffsetRange_dB0:
-      return  0;
-
-    case LTE_Q_OffsetRange_dB1:
-      return  1;
-
-    case LTE_Q_OffsetRange_dB2:
-      return  2;
-
-    case LTE_Q_OffsetRange_dB3:
-      return  3;
-
-    case LTE_Q_OffsetRange_dB4:
-      return  4;
-
-    case LTE_Q_OffsetRange_dB5:
-      return  5;
-
-    case LTE_Q_OffsetRange_dB6:
-      return  6;
-
-    case LTE_Q_OffsetRange_dB8:
-      return  8;
-
-    case LTE_Q_OffsetRange_dB10:
-      return 10;
-
-    case LTE_Q_OffsetRange_dB12:
-      return 12;
-
-    case LTE_Q_OffsetRange_dB14:
-      return 14;
-
-    case LTE_Q_OffsetRange_dB16:
-      return 16;
-
-    case LTE_Q_OffsetRange_dB18:
-      return 18;
-
-    case LTE_Q_OffsetRange_dB20:
-      return 20;
-
-    case LTE_Q_OffsetRange_dB22:
-      return 22;
-
-    case LTE_Q_OffsetRange_dB24:
-      return 24;
-
-    default:
-      return -99;
-  }
-}
-
-long flexran_get_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  switch (ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1]) {
-    case LTE_Q_OffsetRange_dB_24:
-      return -24;
-
-    case LTE_Q_OffsetRange_dB_22:
-      return -22;
-
-    case LTE_Q_OffsetRange_dB_20:
-      return -20;
-
-    case LTE_Q_OffsetRange_dB_18:
-      return -18;
-
-    case LTE_Q_OffsetRange_dB_16:
-      return -16;
-
-    case LTE_Q_OffsetRange_dB_14:
-      return -14;
-
-    case LTE_Q_OffsetRange_dB_12:
-      return -12;
-
-    case LTE_Q_OffsetRange_dB_10:
-      return -10;
-
-    case LTE_Q_OffsetRange_dB_8:
-      return -8;
-
-    case LTE_Q_OffsetRange_dB_6:
-      return -6;
-
-    case LTE_Q_OffsetRange_dB_5:
-      return -5;
-
-    case LTE_Q_OffsetRange_dB_4:
-      return -4;
-
-    case LTE_Q_OffsetRange_dB_3:
-      return -3;
-
-    case LTE_Q_OffsetRange_dB_2:
-      return -2;
-
-    case LTE_Q_OffsetRange_dB_1:
-      return -1;
-
-    case LTE_Q_OffsetRange_dB0:
-      return  0;
-
-    case LTE_Q_OffsetRange_dB1:
-      return  1;
-
-    case LTE_Q_OffsetRange_dB2:
-      return  2;
-
-    case LTE_Q_OffsetRange_dB3:
-      return  3;
-
-    case LTE_Q_OffsetRange_dB4:
-      return  4;
-
-    case LTE_Q_OffsetRange_dB5:
-      return  5;
-
-    case LTE_Q_OffsetRange_dB6:
-      return  6;
-
-    case LTE_Q_OffsetRange_dB8:
-      return  8;
-
-    case LTE_Q_OffsetRange_dB10:
-      return 10;
-
-    case LTE_Q_OffsetRange_dB12:
-      return 12;
-
-    case LTE_Q_OffsetRange_dB14:
-      return 14;
-
-    case LTE_Q_OffsetRange_dB16:
-      return 16;
-
-    case LTE_Q_OffsetRange_dB18:
-      return 18;
-
-    case LTE_Q_OffsetRange_dB20:
-      return 20;
-
-    case LTE_Q_OffsetRange_dB22:
-      return 22;
-
-    case LTE_Q_OffsetRange_dB24:
-      return 24;
-
-    default:
-      return -99;
-  }
-}
-
-long flexran_get_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRP) {
-    case LTE_FilterCoefficient_fc0:
-      return 0;
-
-    case LTE_FilterCoefficient_fc1:
-      return 1;
-
-    case LTE_FilterCoefficient_fc2:
-      return 2;
-
-    case LTE_FilterCoefficient_fc3:
-      return 3;
-
-    case LTE_FilterCoefficient_fc4:
-      return 4;
-
-    case LTE_FilterCoefficient_fc5:
-      return 5;
-
-    case LTE_FilterCoefficient_fc6:
-      return 6;
-
-    case LTE_FilterCoefficient_fc7:
-      return 7;
-
-    case LTE_FilterCoefficient_fc8:
-      return 8;
-
-    case LTE_FilterCoefficient_fc9:
-      return 9;
-
-    case LTE_FilterCoefficient_fc11:
-      return 11;
-
-    case LTE_FilterCoefficient_fc13:
-      return 13;
-
-    case LTE_FilterCoefficient_fc15:
-      return 15;
-
-    case LTE_FilterCoefficient_fc17:
-      return 17;
-
-    case LTE_FilterCoefficient_fc19:
-      return 19;
-
-    case LTE_FilterCoefficient_spare1:
-      return -1; /* spare means no coefficient */
-
-    default:
-      return -1;
-  }
-}
-
-long flexran_get_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  switch (ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ) {
-    case LTE_FilterCoefficient_fc0:
-      return 0;
-
-    case LTE_FilterCoefficient_fc1:
-      return 1;
-
-    case LTE_FilterCoefficient_fc2:
-      return 2;
-
-    case LTE_FilterCoefficient_fc3:
-      return 3;
-
-    case LTE_FilterCoefficient_fc4:
-      return 4;
-
-    case LTE_FilterCoefficient_fc5:
-      return 5;
-
-    case LTE_FilterCoefficient_fc6:
-      return 6;
-
-    case LTE_FilterCoefficient_fc7:
-      return 7;
-
-    case LTE_FilterCoefficient_fc8:
-      return 8;
-
-    case LTE_FilterCoefficient_fc9:
-      return 9;
-
-    case LTE_FilterCoefficient_fc11:
-      return 11;
-
-    case LTE_FilterCoefficient_fc13:
-      return 13;
-
-    case LTE_FilterCoefficient_fc15:
-      return 15;
-
-    case LTE_FilterCoefficient_fc17:
-      return 17;
-
-    case LTE_FilterCoefficient_fc19:
-      return 19;
-
-    case LTE_FilterCoefficient_spare1:
-      return -1; /* spare means no coefficient */
-
-    default:
-      return -1;
-  }
-}
-
-/* Periodic event */
-
-long flexran_get_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1;
-
-  return ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells;
-}
-
-/* A3 event */
-
-long flexran_get_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  return ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis;
-}
-
-long flexran_get_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  switch (ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger) {
-    case LTE_TimeToTrigger_ms0:
-      return 0;
-
-    case LTE_TimeToTrigger_ms40:
-      return 40;
-
-    case LTE_TimeToTrigger_ms64:
-      return 64;
-
-    case LTE_TimeToTrigger_ms80:
-      return 80;
-
-    case LTE_TimeToTrigger_ms100:
-      return 100;
-
-    case LTE_TimeToTrigger_ms128:
-      return 128;
-
-    case LTE_TimeToTrigger_ms160:
-      return 160;
-
-    case LTE_TimeToTrigger_ms256:
-      return 256;
-
-    case LTE_TimeToTrigger_ms320:
-      return 320;
-
-    case LTE_TimeToTrigger_ms480:
-      return 480;
-
-    case LTE_TimeToTrigger_ms512:
-      return 512;
-
-    case LTE_TimeToTrigger_ms640:
-      return 640;
-
-    case LTE_TimeToTrigger_ms1024:
-      return 1024;
-
-    case LTE_TimeToTrigger_ms1280:
-      return 1280;
-
-    case LTE_TimeToTrigger_ms2560:
-      return 2560;
-
-    case LTE_TimeToTrigger_ms5120:
-      return 5120;
-
-    default:
-      return -1;
-  }
-}
-
-long flexran_get_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  return ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells;
-}
-
-long flexran_get_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  return ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset;
-}
-
-int flexran_get_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  return ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave;
-}
-
-/* RRC Setters */
-
-/* Measurement offsets */
-
-int flexran_set_rrc_ofp(mid_t mod_id, rnti_t rnti, long offsetFreq) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1;
-
-  ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq;
-  return 0;
-}
-
-int flexran_set_rrc_ofn(mid_t mod_id, rnti_t rnti, long offsetFreq) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!((offsetFreq >= -15) && (offsetFreq <= 15))) return -1;
-
-  ue_context_p->ue_context.measurement_info->offsetFreq = offsetFreq;
-  return 0;
-}
-
-int flexran_set_rrc_ocp(mid_t mod_id, rnti_t rnti, long cellIndividualOffset) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[0];
-
-  switch (cellIndividualOffset) {
-    case -24:
-      *cio = LTE_Q_OffsetRange_dB_24;
-      break;
-
-    case -22:
-      *cio = LTE_Q_OffsetRange_dB_22;
-      break;
-
-    case -20:
-      *cio = LTE_Q_OffsetRange_dB_20;
-      break;
-
-    case -18:
-      *cio = LTE_Q_OffsetRange_dB_18;
-      break;
-
-    case -16:
-      *cio = LTE_Q_OffsetRange_dB_16;
-      break;
-
-    case -14:
-      *cio = LTE_Q_OffsetRange_dB_14;
-      break;
-
-    case -12:
-      *cio = LTE_Q_OffsetRange_dB_12;
-      break;
-
-    case -10:
-      *cio = LTE_Q_OffsetRange_dB_10;
-      break;
-
-    case -8:
-      *cio = LTE_Q_OffsetRange_dB_8;
-      break;
-
-    case -6:
-      *cio = LTE_Q_OffsetRange_dB_6;
-      break;
-
-    case -5:
-      *cio = LTE_Q_OffsetRange_dB_5;
-      break;
-
-    case -4:
-      *cio = LTE_Q_OffsetRange_dB_4;
-      break;
-
-    case -3:
-      *cio = LTE_Q_OffsetRange_dB_3;
-      break;
-
-    case -2:
-      *cio = LTE_Q_OffsetRange_dB_2;
-      break;
-
-    case -1:
-      *cio = LTE_Q_OffsetRange_dB_1;
-      break;
-
-    case 0:
-      *cio = LTE_Q_OffsetRange_dB0;
-      break;
-
-    case 1:
-      *cio = LTE_Q_OffsetRange_dB1;
-      break;
-
-    case 2:
-      *cio = LTE_Q_OffsetRange_dB2;
-      break;
-
-    case 3:
-      *cio = LTE_Q_OffsetRange_dB3;
-      break;
-
-    case 4:
-      *cio = LTE_Q_OffsetRange_dB4;
-      break;
-
-    case 5:
-      *cio = LTE_Q_OffsetRange_dB5;
-      break;
-
-    case 6:
-      *cio = LTE_Q_OffsetRange_dB6;
-      break;
-
-    case 8:
-      *cio = LTE_Q_OffsetRange_dB8;
-      break;
-
-    case 10:
-      *cio = LTE_Q_OffsetRange_dB10;
-      break;
-
-    case 12:
-      *cio = LTE_Q_OffsetRange_dB12;
-      break;
-
-    case 14:
-      *cio = LTE_Q_OffsetRange_dB14;
-      break;
-
-    case 16:
-      *cio = LTE_Q_OffsetRange_dB16;
-      break;
-
-    case 18:
-      *cio = LTE_Q_OffsetRange_dB18;
-      break;
-
-    case 20:
-      *cio = LTE_Q_OffsetRange_dB20;
-      break;
-
-    case 22:
-      *cio = LTE_Q_OffsetRange_dB22;
-      break;
-
-    case 24:
-      *cio = LTE_Q_OffsetRange_dB24;
-      break;
-
-    default:
-      return -1;
-  }
-
-  return 0;
-}
-
-int flexran_set_rrc_ocn(mid_t mod_id, rnti_t rnti, long cell_id, long cellIndividualOffset) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  LTE_Q_OffsetRange_t *cio = &ue_context_p->ue_context.measurement_info->cellIndividualOffset[cell_id+1];
-
-  switch (cellIndividualOffset) {
-    case -24:
-      *cio = LTE_Q_OffsetRange_dB_24;
-      break;
-
-    case -22:
-      *cio = LTE_Q_OffsetRange_dB_22;
-      break;
-
-    case -20:
-      *cio = LTE_Q_OffsetRange_dB_20;
-      break;
-
-    case -18:
-      *cio = LTE_Q_OffsetRange_dB_18;
-      break;
-
-    case -16:
-      *cio = LTE_Q_OffsetRange_dB_16;
-      break;
-
-    case -14:
-      *cio = LTE_Q_OffsetRange_dB_14;
-      break;
-
-    case -12:
-      *cio = LTE_Q_OffsetRange_dB_12;
-      break;
-
-    case -10:
-      *cio = LTE_Q_OffsetRange_dB_10;
-      break;
-
-    case -8:
-      *cio = LTE_Q_OffsetRange_dB_8;
-      break;
-
-    case -6:
-      *cio = LTE_Q_OffsetRange_dB_6;
-      break;
-
-    case -5:
-      *cio = LTE_Q_OffsetRange_dB_5;
-      break;
-
-    case -4:
-      *cio = LTE_Q_OffsetRange_dB_4;
-      break;
-
-    case -3:
-      *cio = LTE_Q_OffsetRange_dB_3;
-      break;
-
-    case -2:
-      *cio = LTE_Q_OffsetRange_dB_2;
-      break;
-
-    case -1:
-      *cio = LTE_Q_OffsetRange_dB_1;
-      break;
-
-    case 0:
-      *cio = LTE_Q_OffsetRange_dB0;
-      break;
-
-    case 1:
-      *cio = LTE_Q_OffsetRange_dB1;
-      break;
-
-    case 2:
-      *cio = LTE_Q_OffsetRange_dB2;
-      break;
-
-    case 3:
-      *cio = LTE_Q_OffsetRange_dB3;
-      break;
-
-    case 4:
-      *cio = LTE_Q_OffsetRange_dB4;
-      break;
-
-    case 5:
-      *cio = LTE_Q_OffsetRange_dB5;
-      break;
-
-    case 6:
-      *cio = LTE_Q_OffsetRange_dB6;
-      break;
-
-    case 8:
-      *cio = LTE_Q_OffsetRange_dB8;
-      break;
-
-    case 10:
-      *cio = LTE_Q_OffsetRange_dB10;
-      break;
-
-    case 12:
-      *cio = LTE_Q_OffsetRange_dB12;
-      break;
-
-    case 14:
-      *cio = LTE_Q_OffsetRange_dB14;
-      break;
-
-    case 16:
-      *cio = LTE_Q_OffsetRange_dB16;
-      break;
-
-    case 18:
-      *cio = LTE_Q_OffsetRange_dB18;
-      break;
-
-    case 20:
-      *cio = LTE_Q_OffsetRange_dB20;
-      break;
-
-    case 22:
-      *cio = LTE_Q_OffsetRange_dB22;
-      break;
-
-    case 24:
-      *cio = LTE_Q_OffsetRange_dB24;
-      break;
-
-    default:
-      return -1;
-  }
-
-  return 0;
-}
-
-int flexran_set_filter_coeff_rsrp(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRP) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRP;
-
-  switch (filterCoefficientRSRP) {
-    case 0:
-      *fc = LTE_FilterCoefficient_fc0;
-      break;
-
-    case 1:
-      *fc = LTE_FilterCoefficient_fc1;
-      break;
-
-    case 2:
-      *fc = LTE_FilterCoefficient_fc2;
-      break;
-
-    case 3:
-      *fc = LTE_FilterCoefficient_fc3;
-      break;
-
-    case 4:
-      *fc = LTE_FilterCoefficient_fc4;
-      break;
-
-    case 5:
-      *fc = LTE_FilterCoefficient_fc5;
-      break;
-
-    case 6:
-      *fc = LTE_FilterCoefficient_fc6;
-      break;
-
-    case 7:
-      *fc = LTE_FilterCoefficient_fc7;
-      break;
-
-    case 8:
-      *fc = LTE_FilterCoefficient_fc8;
-      break;
-
-    case 9:
-      *fc = LTE_FilterCoefficient_fc9;
-      break;
-
-    case 11:
-      *fc = LTE_FilterCoefficient_fc11;
-      break;
-
-    case 13:
-      *fc = LTE_FilterCoefficient_fc13;
-      break;
-
-    case 15:
-      *fc = LTE_FilterCoefficient_fc15;
-      break;
-
-    case 17:
-      *fc = LTE_FilterCoefficient_fc17;
-      break;
-
-    case 19:
-      *fc = LTE_FilterCoefficient_fc19;
-      break;
-
-    case -1:
-      *fc = LTE_FilterCoefficient_spare1;
-      break;
-
-    default:
-      return -1;
-  }
-
-  return 0;
-}
-
-int flexran_set_filter_coeff_rsrq(mid_t mod_id, rnti_t rnti, long filterCoefficientRSRQ) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  LTE_FilterCoefficient_t *fc = &ue_context_p->ue_context.measurement_info->filterCoefficientRSRQ;
-
-  switch (filterCoefficientRSRQ) {
-    case 0:
-      *fc = LTE_FilterCoefficient_fc0;
-      break;
-
-    case 1:
-      *fc = LTE_FilterCoefficient_fc1;
-      break;
-
-    case 2:
-      *fc = LTE_FilterCoefficient_fc2;
-      break;
-
-    case 3:
-      *fc = LTE_FilterCoefficient_fc3;
-      break;
-
-    case 4:
-      *fc = LTE_FilterCoefficient_fc4;
-      break;
-
-    case 5:
-      *fc = LTE_FilterCoefficient_fc5;
-      break;
-
-    case 6:
-      *fc = LTE_FilterCoefficient_fc6;
-      break;
-
-    case 7:
-      *fc = LTE_FilterCoefficient_fc7;
-      break;
-
-    case 8:
-      *fc = LTE_FilterCoefficient_fc8;
-      break;
-
-    case 9:
-      *fc = LTE_FilterCoefficient_fc9;
-      break;
-
-    case 11:
-      *fc = LTE_FilterCoefficient_fc11;
-      break;
-
-    case 13:
-      *fc = LTE_FilterCoefficient_fc13;
-      break;
-
-    case 15:
-      *fc = LTE_FilterCoefficient_fc15;
-      break;
-
-    case 17:
-      *fc = LTE_FilterCoefficient_fc17;
-      break;
-
-    case 19:
-      *fc = LTE_FilterCoefficient_fc19;
-      break;
-
-    case -1:
-      *fc = LTE_FilterCoefficient_spare1;
-      break;
-
-    default:
-      return -1;
-  }
-
-  return 0;
-}
-
-/* Periodic event */
-
-int flexran_set_rrc_per_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->per_event) return -1;
-
-  if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1;
-
-  ue_context_p->ue_context.measurement_info->events->per_event->maxReportCells = maxReportCells;
-  return 0;
-}
-
-/* A3 event */
-
-int flexran_set_rrc_a3_event_hysteresis(mid_t mod_id, rnti_t rnti, long hysteresis) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  if (!((hysteresis >=0) && (hysteresis <= 30))) return -1;
-
-  ue_context_p->ue_context.measurement_info->events->a3_event->hysteresis = hysteresis;
-  return 0;
-}
-
-int flexran_set_rrc_a3_event_timeToTrigger(mid_t mod_id, rnti_t rnti, long timeToTrigger) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  LTE_TimeToTrigger_t *ttt = &ue_context_p->ue_context.measurement_info->events->a3_event->timeToTrigger;
-
-  switch (timeToTrigger) {
-    case 0:
-      *ttt = LTE_TimeToTrigger_ms0;
-      break;
-
-    case 40:
-      *ttt = LTE_TimeToTrigger_ms40;
-      break;
-
-    case 64:
-      *ttt = LTE_TimeToTrigger_ms64;
-      break;
-
-    case 80:
-      *ttt = LTE_TimeToTrigger_ms80;
-      break;
-
-    case 100:
-      *ttt = LTE_TimeToTrigger_ms100;
-      break;
-
-    case 128:
-      *ttt = LTE_TimeToTrigger_ms128;
-      break;
-
-    case 160:
-      *ttt = LTE_TimeToTrigger_ms160;
-      break;
-
-    case 256:
-      *ttt = LTE_TimeToTrigger_ms256;
-      break;
-
-    case 320:
-      *ttt = LTE_TimeToTrigger_ms320;
-      break;
-
-    case 480:
-      *ttt = LTE_TimeToTrigger_ms480;
-      break;
-
-    case 512:
-      *ttt = LTE_TimeToTrigger_ms512;
-      break;
-
-    case 640:
-      *ttt = LTE_TimeToTrigger_ms640;
-      break;
-
-    case 1024:
-      *ttt = LTE_TimeToTrigger_ms1024;
-      break;
-
-    case 1280:
-      *ttt = LTE_TimeToTrigger_ms1280;
-      break;
-
-    case 2560:
-      *ttt = LTE_TimeToTrigger_ms2560;
-      break;
-
-    case 5120:
-      *ttt = LTE_TimeToTrigger_ms5120;
-      break;
-
-    default:
-      return -1;
-  }
-
-  return 0;
-}
-
-int flexran_set_rrc_a3_event_maxReportCells(mid_t mod_id, rnti_t rnti, long maxReportCells) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  if (!((maxReportCells >= 1) && (maxReportCells <= 8))) return -1;
-
-  ue_context_p->ue_context.measurement_info->events->a3_event->maxReportCells = maxReportCells;
-  return 0;
-}
-
-int flexran_set_rrc_a3_event_a3_offset(mid_t mod_id, rnti_t rnti, long a3_offset) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  if (!((a3_offset >= -30) && (a3_offset <= 30))) return -1;
-
-  ue_context_p->ue_context.measurement_info->events->a3_event->a3_offset = a3_offset;
-  return 0;
-}
-
-int flexran_set_rrc_a3_event_reportOnLeave(mid_t mod_id, rnti_t rnti, int reportOnLeave) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events) return -1;
-
-  if (!ue_context_p->ue_context.measurement_info->events->a3_event) return -1;
-
-  if (!((reportOnLeave == 0) || (reportOnLeave == 1))) return -1;
-
-  ue_context_p->ue_context.measurement_info->events->a3_event->reportOnLeave = reportOnLeave;
-  return 0;
-}
-
-int flexran_set_x2_ho_net_control(mid_t mod_id, int x2_ho_net_control) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  if (!((x2_ho_net_control == 0) || (x2_ho_net_control == 1))) return -1;
-
-  RC.rrc[mod_id]->x2_ho_net_control = x2_ho_net_control;
-  return 0;
-}
-
-int flexran_get_x2_ho_net_control(mid_t mod_id) {
-  if (!rrc_is_present(mod_id)) return -1;
-
-  return RC.rrc[mod_id]->x2_ho_net_control;
-}
-
-uint8_t flexran_get_rrc_num_plmn_ids(mid_t mod_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->configuration.num_plmn;
-}
-
-uint16_t flexran_get_rrc_mcc(mid_t mod_id, uint8_t index) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->configuration.mcc[index];
-}
-
-uint16_t flexran_get_rrc_mnc(mid_t mod_id, uint8_t index) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->configuration.mnc[index];
-}
-
-uint8_t flexran_get_rrc_mnc_digit_length(mid_t mod_id, uint8_t index) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->configuration.mnc_digit_length[index];
-}
-
-int flexran_get_rrc_num_adj_cells(mid_t mod_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->num_neigh_cells;
-}
-
-int flexran_agent_rrc_gtp_num_e_rab(mid_t mod_id, rnti_t rnti) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return 0;
-
-  return ue_context_p->ue_context.setup_e_rabs;
-}
-
-int flexran_agent_rrc_gtp_get_e_rab_id(mid_t mod_id, rnti_t rnti, int index) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return 0;
-
-  return ue_context_p->ue_context.e_rab[index].param.e_rab_id;
-}
-
-int flexran_agent_rrc_gtp_get_teid_enb(mid_t mod_id, rnti_t rnti, int index) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return 0;
-
-  return ue_context_p->ue_context.enb_gtp_teid[index];
-}
-
-int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-
-  if (!ue_context_p) return 0;
-
-  return ue_context_p->ue_context.e_rab[index].param.gtp_teid;
-}
-
-uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti)
-{
-  if (!rrc_is_present(mod_id)) return 0;
-  struct rrc_eNB_ue_context_s* ue_context_p = rrc_eNB_get_ue_context(RC.rrc[mod_id], rnti);
-  if (!ue_context_p) return -1;
-  return ue_context_p->ue_context.eNB_ue_s1ap_id;
-}
-
-/**************************** SLICING ****************************/
-Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
-
-  switch (RC.mac[mod_id]->pre_processor_dl.algorithm) {
-    case STATIC_SLICING:
-      return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
-    default:
-      return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
-  }
-}
-
-int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
-  if (!mac_is_present(mod_id)) return 0;
-  eNB_MAC_INST *mac = RC.mac[mod_id];
-  const int cc_id = 0;
-
-  pp_impl_param_t dl = mac->pre_processor_dl;
-  switch (algo) {
-    case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
-      mac->pre_processor_dl = static_dl_init(mod_id, cc_id);
-      break;
-    default:
-      mac->pre_processor_dl.algorithm = 0;
-      mac->pre_processor_dl.dl = dlsch_scheduler_pre_processor;
-      mac->pre_processor_dl.dl_algo.data = mac->pre_processor_dl.dl_algo.setup();
-      mac->pre_processor_dl.slices = NULL;
-      break;
-  }
-  if (dl.slices)
-    dl.destroy(&dl.slices);
-  if (dl.dl_algo.data)
-    dl.dl_algo.unset(&dl.dl_algo.data);
-  return 1;
-}
-
-Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
-
-  switch (RC.mac[mod_id]->pre_processor_ul.algorithm) {
-    case STATIC_SLICING:
-      return PROTOCOL__FLEX_SLICE_ALGORITHM__Static;
-    default:
-      return PROTOCOL__FLEX_SLICE_ALGORITHM__None;
-  }
-}
-
-int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) {
-  if (!mac_is_present(mod_id)) return 0;
-  eNB_MAC_INST *mac = RC.mac[mod_id];
-  const int cc_id = 0;
-
-  pp_impl_param_t ul = mac->pre_processor_ul;
-  switch (algo) {
-    case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
-      mac->pre_processor_ul = static_ul_init(mod_id, cc_id);
-      break;
-    default:
-      mac->pre_processor_ul.algorithm = 0;
-      mac->pre_processor_ul.ul = ulsch_scheduler_pre_processor;
-      mac->pre_processor_ul.ul_algo.data = mac->pre_processor_ul.ul_algo.setup();
-      mac->pre_processor_ul.slices = NULL;
-      break;
-  }
-  if (ul.slices)
-    ul.destroy(&ul.slices);
-  if (ul.ul_algo.data)
-    ul.ul_algo.unset(&ul.ul_algo.data);
-  return 1;
-}
-
-int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return -1;
-  slice_info_t *slices = RC.mac[mod_id]->pre_processor_dl.slices;
-  if (!slices) return -1;
-  const int idx = slices->UE_assoc_slice[ue_id];
-  return slices->s[idx]->id;
-}
-
-int flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
-  if (!mac_is_present(mod_id)) return 0;
-  int idx = flexran_find_dl_slice(mod_id, slice_id);
-  if (idx < 0) return 0;
-  pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
-  dl->move_UE(dl->slices, ue_id, idx);
-  return 1;
-}
-
-int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) {
-  if (!mac_is_present(mod_id)) return -1;
-  slice_info_t *slices = RC.mac[mod_id]->pre_processor_ul.slices;
-  if (!slices) return -1;
-  const int idx = slices->UE_assoc_slice[ue_id];
-  return slices->s[idx]->id;
-}
-
-int flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) {
-  if (!mac_is_present(mod_id)) return 0;
-  int idx = flexran_find_ul_slice(mod_id, slice_id);
-  if (idx < 0) return 0;
-  pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
-  ul->move_UE(ul->slices, ue_id, idx);
-  return 1;
-}
-
-int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) {
-  if (!mac_is_present(mod_id)) return 0;
-  void *params = NULL;
-  switch (s->params_case) {
-    case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
-      params = malloc(sizeof(static_slice_param_t));
-      if (!params) return 0;
-      ((static_slice_param_t *)params)->posLow = s->static_->poslow;
-      ((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
-      break;
-    default:
-      break;
-  }
-  pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
-  char *l = s->label ? strdup(s->label) : NULL;
-  void *algo = &dl->dl_algo; // default scheduler
-  if (s->scheduler) {
-    algo = dlsym(object, s->scheduler);
-    if (!algo) {
-      free(params);
-      LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
-      return -15;
-    }
-  }
-  return dl->addmod_slice(dl->slices, s->id, l, algo, params);
-}
-
-int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
-  if (!mac_is_present(mod_id)) return 0;
-  const int idx = flexran_find_dl_slice(mod_id, s->id);
-  if (idx < 0) return 0;
-  pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl;
-  return dl->remove_slice(dl->slices, idx);
-}
-
-int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) {
-  if (!mac_is_present(mod_id)) return -1;
-  slice_info_t *si = RC.mac[mod_id]->pre_processor_dl.slices;
-  for (int i = 0; i < si->num; ++i)
-    if (si->s[i]->id == slice_id)
-      return i;
-  return -1;
-}
-
-void flexran_get_dl_slice(mid_t mod_id,
-                          int slice_idx,
-                          Protocol__FlexSlice *slice,
-                          Protocol__FlexSliceAlgorithm algo) {
-  if (!mac_is_present(mod_id)) return;
-  slice_t *s_ = RC.mac[mod_id]->pre_processor_dl.slices->s[slice_idx];
-  slice->has_id = 1;
-  slice->id = s_->id;
-  slice->label = s_->label;
-  slice->scheduler = s_->dl_algo.name;
-  slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
-  switch (algo) {
-    case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
-      slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
-      if (!slice->static_) return;
-      protocol__flex_slice_static__init(slice->static_);
-      slice->static_->has_poslow = 1;
-      slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
-      slice->static_->has_poshigh = 1;
-      slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
-      slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
-      break;
-    default:
-      break;
-  }
-}
-
-int flexran_get_num_dl_slices(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return 0;
-  if (!RC.mac[mod_id]->pre_processor_dl.slices) return 0;
-  return RC.mac[mod_id]->pre_processor_dl.slices->num;
-}
-
-int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s, void *object) {
-  if (!mac_is_present(mod_id)) return -1;
-  void *params = NULL;
-  switch (s->params_case) {
-    case PROTOCOL__FLEX_SLICE__PARAMS_STATIC:
-      params = malloc(sizeof(static_slice_param_t));
-      if (!params) return 0;
-      ((static_slice_param_t *)params)->posLow = s->static_->poslow;
-      ((static_slice_param_t *)params)->posHigh = s->static_->poshigh;
-      break;
-    default:
-      break;
-  }
-  pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
-  char *l = s->label ? strdup(s->label) : NULL;
-  void *algo = &ul->ul_algo; // default scheduler
-  if (s->scheduler) {
-    algo = dlsym(object, s->scheduler);
-    if (!algo) {
-      free(params);
-      LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler);
-      return -15;
-    }
-  }
-  return ul->addmod_slice(ul->slices, s->id, l, algo, params);
-}
-
-int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) {
-  if (!mac_is_present(mod_id)) return 0;
-  const int idx = flexran_find_ul_slice(mod_id, s->id);
-  if (idx < 0) return 0;
-  pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul;
-  return ul->remove_slice(ul->slices, idx);
-}
-
-int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) {
-  if (!mac_is_present(mod_id)) return -1;
-  slice_info_t *si = RC.mac[mod_id]->pre_processor_ul.slices;
-  for (int i = 0; i < si->num; ++i)
-    if (si->s[i]->id == slice_id)
-      return i;
-  return -1;
-}
-
-void flexran_get_ul_slice(mid_t mod_id,
-                          int slice_idx,
-                          Protocol__FlexSlice *slice,
-                          Protocol__FlexSliceAlgorithm algo) {
-  if (!mac_is_present(mod_id)) return;
-  slice_t *s_ = RC.mac[mod_id]->pre_processor_ul.slices->s[slice_idx];
-  slice->has_id = 1;
-  slice->id = s_->id;
-  slice->label = s_->label;
-  slice->scheduler = s_->ul_algo.name;
-  slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET;
-  switch (algo) {
-    case PROTOCOL__FLEX_SLICE_ALGORITHM__Static:
-      slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic));
-      if (!slice->static_) return;
-      protocol__flex_slice_static__init(slice->static_);
-      slice->static_->has_poslow = 1;
-      slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow;
-      slice->static_->has_poshigh = 1;
-      slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh;
-      slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC;
-      break;
-    default:
-      break;
-  }
-
-}
-
-int flexran_get_num_ul_slices(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return 0;
-  if (!RC.mac[mod_id]->pre_processor_ul.slices) return 0;
-  return RC.mac[mod_id]->pre_processor_ul.slices->num;
-}
-
-char *flexran_get_dl_scheduler_name(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return NULL;
-  return RC.mac[mod_id]->pre_processor_dl.dl_algo.name;
-}
-
-int flexran_set_dl_scheduler(mid_t mod_id, char *sched, void *object) {
-  if (!mac_is_present(mod_id)) return -1;
-  void *d = dlsym(object, sched);
-  if (!d) return -2;
-  pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl;
-  dl_pp->dl_algo.unset(&dl_pp->dl_algo.data);
-  dl_pp->dl_algo = *(default_sched_dl_algo_t *) d;
-  dl_pp->dl_algo.data = dl_pp->dl_algo.setup();
-  return 0;
-}
-
-char *flexran_get_ul_scheduler_name(mid_t mod_id) {
-  if (!mac_is_present(mod_id)) return NULL;
-  return RC.mac[mod_id]->pre_processor_ul.ul_algo.name;
-}
-
-int flexran_set_ul_scheduler(mid_t mod_id, char *sched, void *object) {
-  if (!mac_is_present(mod_id)) return -1;
-  void *d = dlsym(object, sched);
-  if (!d) return -2;
-  pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul;
-  ul_pp->ul_algo.unset(&ul_pp->ul_algo.data);
-  ul_pp->ul_algo = *(default_sched_ul_algo_t *) d;
-  ul_pp->ul_algo.data = ul_pp->ul_algo.setup();
-  return 0;
-}
-
-/************************** S1AP **************************/
-int flexran_get_s1ap_mme_pending(mid_t mod_id){
-  if (!rrc_is_present(mod_id)) return -1;
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return -1;
-  return s1ap->s1ap_mme_pending_nb;
-}
-
-int flexran_get_s1ap_mme_connected(mid_t mod_id){
-  if (!rrc_is_present(mod_id)) return -1;
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return -1;
-  return s1ap->s1ap_mme_associated_nb;
-}
-
-char* flexran_get_s1ap_enb_s1_ip(mid_t mod_id){
-  if (!rrc_is_present(mod_id)) return NULL;
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return NULL;
-  if (s1ap->eNB_s1_ip.ipv4)
-    return &s1ap->eNB_s1_ip.ipv4_address[0];
-  if (s1ap->eNB_s1_ip.ipv6)
-    return &s1ap->eNB_s1_ip.ipv6_address[0];
-  return NULL;
-}
-
-char* flexran_get_s1ap_enb_name(mid_t mod_id){
-  if (!rrc_is_present(mod_id)) return NULL;
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return NULL;
-  return s1ap->eNB_name;
-}
-
-int flexran_get_s1ap_nb_mme(mid_t mod_id) {
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return 0;
-  struct s1ap_eNB_mme_data_s *mme = NULL;
-  int count = 0;
-  RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
-    count++;
-  }
-  return count;
-}
-
-int flexran_get_s1ap_nb_ue(mid_t mod_id) {
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return 0;
-  struct s1ap_eNB_ue_context_s *ue = NULL;
-  int count = 0;
-  RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head) {
-    count++;
-  }
-  return count;
-}
-
-int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apMme * mme_conf){
-  if (!rrc_is_present(mod_id)) return -1;
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return -1;
-
-  struct served_gummei_s   *gummei_p = NULL;
-  struct plmn_identity_s   *served_plmn_p = NULL;
-  struct served_group_id_s *group_id_p = NULL;
-  struct mme_code_s        *mme_code_p = NULL;
-  int i = 0;
-  Protocol__FlexGummei  **served_gummeis;
-  Protocol__FlexPlmn    **requested_plmns;
-
-  struct s1ap_eNB_mme_data_s *mme = NULL;
-
-  RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head){
-    if (mme_index == 0) break;
-    mme_index--;
-  }
-  if (mme_index > 0) return -1;
-
-  if (mme->mme_s1_ip.ipv4) {
-    mme_conf->s1_ip = (char*) &mme->mme_s1_ip.ipv4_address[0];
-  } else if (mme->mme_s1_ip.ipv6) {
-    mme_conf->s1_ip = (char*) &mme->mme_s1_ip.ipv6_address[0];
-  }
-  mme_conf->name = mme->mme_name;
-  mme_conf->has_state = 1;
-  mme_conf->state = mme->state;
-
-  mme_conf->n_served_gummeis = 0;
-  STAILQ_FOREACH(gummei_p, &mme->served_gummei, next) {
-    mme_conf->n_served_gummeis++;
-  }
-  if (mme_conf->n_served_gummeis > 0) {
-    served_gummeis = calloc(mme_conf->n_served_gummeis, sizeof(Protocol__FlexGummei*));
-    if(served_gummeis == NULL) return -1;
-
-    STAILQ_FOREACH(gummei_p, &mme->served_gummei, next) {
-      served_plmn_p = STAILQ_FIRST(&gummei_p->served_plmns);
-      group_id_p = STAILQ_FIRST(&gummei_p->served_group_ids);
-      mme_code_p = STAILQ_FIRST(&gummei_p->mme_codes);
-
-      served_gummeis[i] = malloc(sizeof(Protocol__FlexGummei));
-      if (!served_gummeis[i]) return -1;
-      protocol__flex_gummei__init(served_gummeis[i]);
-      served_gummeis[i]->plmn = malloc(sizeof(Protocol__FlexPlmn));
-      if (!served_gummeis[i]->plmn) return -1;
-      protocol__flex_plmn__init(served_gummeis[i]->plmn);
-
-      if (served_plmn_p) {
-        served_gummeis[i]->plmn->has_mcc = 1;
-        served_gummeis[i]->plmn->mcc = served_plmn_p->mcc;
-        served_gummeis[i]->plmn->has_mnc = 1;
-        served_gummeis[i]->plmn->mnc = served_plmn_p->mnc;
-        served_gummeis[i]->plmn->has_mnc_length = 1;
-        served_gummeis[i]->plmn->mnc_length = served_plmn_p-> mnc_digit_length;
-        STAILQ_NEXT(served_plmn_p, next);
-      }
-      if (group_id_p) {
-        served_gummeis[i]->has_mme_group_id = 1;
-        served_gummeis[i]->mme_group_id = group_id_p->mme_group_id;
-        STAILQ_NEXT(group_id_p, next);
-      }
-      if (mme_code_p){
-        served_gummeis[i]->has_mme_code = 1;
-        served_gummeis[i]->mme_code = mme_code_p->mme_code;
-        STAILQ_NEXT(mme_code_p, next);
-      }
-      i++;
-    }
-
-    mme_conf->served_gummeis = served_gummeis;
-  }
-
-  // requested PLMNS
-  mme_conf->n_requested_plmns = mme->broadcast_plmn_num;
-  if (mme_conf->n_requested_plmns > 0){
-    requested_plmns = calloc(mme_conf->n_requested_plmns, sizeof(Protocol__FlexPlmn*));
-    if(requested_plmns == NULL) return -1;
-    for(int i = 0; i < mme_conf->n_requested_plmns; i++) {
-      requested_plmns[i] = malloc(sizeof(Protocol__FlexPlmn));
-      if (!requested_plmns[i]) return -1;
-      protocol__flex_plmn__init(requested_plmns[i]);
-      requested_plmns[i]->mcc = s1ap->mcc[mme->broadcast_plmn_index[i]];
-      requested_plmns[i]->has_mcc = 1;
-      requested_plmns[i]->mnc = s1ap->mnc[mme->broadcast_plmn_index[i]];
-      requested_plmns[i]->has_mnc = 1;
-      requested_plmns[i]->mnc_length = s1ap->mnc_digit_length[mme->broadcast_plmn_index[i]];
-      requested_plmns[i]->has_mnc_length = 1;
-    }
-    mme_conf->requested_plmns = requested_plmns;
-  }
-
-  mme_conf->has_rel_capacity = 1;
-  mme_conf->rel_capacity = mme->relative_mme_capacity;
-  return 0;
-}
-
-int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) {
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return -1;
-  if (!rrc_is_present(mod_id)) return -2;
-
-  /* Reconstruct S1AP_REGISTER_ENB_REQ */
-  MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, 0, S1AP_REGISTER_ENB_REQ);
-  RCconfig_S1(m, mod_id);
-
-  const int CC_id = 0;
-  eNB_RRC_INST *rrc = RC.rrc[CC_id];
-  RrcConfigurationReq *conf = &rrc->configuration;
-  S1AP_REGISTER_ENB_REQ(m).num_plmn = conf->num_plmn;
-  for (int i = 0; i < conf->num_plmn; ++i) {
-    S1AP_REGISTER_ENB_REQ(m).mcc[i] = conf->mcc[i];
-    S1AP_REGISTER_ENB_REQ(m).mnc[i] = conf->mnc[i];
-    S1AP_REGISTER_ENB_REQ(m).mnc_digit_length[i] = conf->mnc_digit_length[i];
-  }
-
-  /* reconstruct MME list, it might have been updated since initial
-   * configuration */
-  S1AP_REGISTER_ENB_REQ(m).nb_mme = 0;
-  struct s1ap_eNB_mme_data_s *mme = NULL;
-  RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
-    const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme;
-    S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = mme->mme_s1_ip.ipv4;
-    strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme->mme_s1_ip.ipv4_address);
-    S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = mme->mme_s1_ip.ipv6;
-    strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6_address, mme->mme_s1_ip.ipv6_address);
-    S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = mme->broadcast_plmn_num;
-    for (int i = 0; i < mme->broadcast_plmn_num; ++i)
-      S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = mme->broadcast_plmn_index[i];
-    S1AP_REGISTER_ENB_REQ(m).mme_port[n] = mme->mme_port;
-    S1AP_REGISTER_ENB_REQ(m).nb_mme += 1;
-  }
-
-  if (S1AP_REGISTER_ENB_REQ(m).nb_mme + n_mme > S1AP_MAX_NB_MME_IP_ADDRESS)
-    return -1;
-
-  const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme;
-  strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]);
-  S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1;
-  S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0;
-  S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn;
-  for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i)
-    S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i;
-  S1AP_REGISTER_ENB_REQ(m).mme_port[n] = S1AP_PORT_NUMBER;
-  S1AP_REGISTER_ENB_REQ(m).nb_mme += 1;
-
-  itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m);
-
-  return 0;
-}
-
-int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) {
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return -1;
-  struct s1ap_eNB_mme_data_s *mme = NULL;
-  RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
-    if (mme->mme_s1_ip.ipv4
-        && strncmp(mme->mme_s1_ip.ipv4_address, mme_ipv4[0], 16) == 0)
-        break;
-  }
-  if (!mme)
-    return -2;
-
-  MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, 0, SCTP_CLOSE_ASSOCIATION);
-  SCTP_CLOSE_ASSOCIATION(m).assoc_id = mme->assoc_id;
-  itti_send_msg_to_task (TASK_SCTP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m);
-
-  switch (mme->state) {
-    case S1AP_ENB_STATE_WAITING:
-      s1ap->s1ap_mme_nb -= 1;
-      if (s1ap->s1ap_mme_pending_nb > 0)
-        s1ap->s1ap_mme_pending_nb -= 1;
-      break;
-    case S1AP_ENB_STATE_CONNECTED:
-    case S1AP_ENB_OVERLOAD: /* I am not sure the decrements are right here */
-      s1ap->s1ap_mme_nb -= 1;
-      s1ap->s1ap_mme_associated_nb -= 1;
-      break;
-    case S1AP_ENB_STATE_DISCONNECTED:
-    default:
-      break;
-  }
-  RB_REMOVE(s1ap_mme_map, &s1ap->s1ap_mme_head, mme);
-
-  return 0;
-}
-
-int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id) {
-  if (!rrc_is_present(mod_id))
-    return -1;
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap)
-    return -2;
-
-  eNB_RRC_INST *rrc = RC.rrc[CC_id];
-  RrcConfigurationReq *conf = &rrc->configuration;
-
-  uint8_t num_plmn_old = conf->num_plmn;
-  uint16_t mcc[PLMN_LIST_MAX_SIZE];
-  uint16_t mnc[PLMN_LIST_MAX_SIZE];
-  uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE];
-  for (int i = 0; i < num_plmn_old; ++i) {
-    mcc[i] = conf->mcc[i];
-    mnc[i] = conf->mnc[i];
-    mnc_digit_length[i] = conf->mnc_digit_length[i];
-  }
-
-  conf->num_plmn = (uint8_t) n_plmn;
-  for (int i = 0; i < conf->num_plmn; ++i) {
-    conf->mcc[i] = plmn_id[i]->mcc;
-    conf->mnc[i] = plmn_id[i]->mnc;
-    conf->mnc_digit_length[i] = plmn_id[i]->mnc_length;
-  }
-
-  rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id];
-  extern uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,
-                         int Mod_id,
-                         int CC_id,
-                         BOOLEAN_t brOption,
-                         RrcConfigurationReq *configuration);
-  carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, false, conf);
-  if (carrier->sizeof_SIB1 < 0)
-    return -1337; /* SIB1 encoding failed, hell will probably break loose */
-
-  s1ap->num_plmn = (uint8_t) n_plmn;
-  for (int i = 0; i < conf->num_plmn; ++i) {
-    s1ap->mcc[i] = plmn_id[i]->mcc;
-    s1ap->mnc[i] = plmn_id[i]->mnc;
-    s1ap->mnc_digit_length[i] = plmn_id[i]->mnc_length;
-  }
-
-  int bpn_failed = 0;
-  struct s1ap_eNB_mme_data_s *mme = NULL;
-  RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) {
-    for (int i = 0; i < mme->broadcast_plmn_num; ++i) {
-      /* search the new index and update. If we don't find, we count this using
-       * bpn_failed to now how many broadcast_plmns could not be updated */
-      int idx = mme->broadcast_plmn_index[i];
-      int omcc = mcc[idx];
-      int omnc = mnc[idx];
-      int omncl = mnc_digit_length[idx];
-      int j = 0;
-      for (j = 0; j < s1ap->num_plmn; ++j) {
-        if (s1ap->mcc[j] == omcc
-            && s1ap->mnc[j] == omnc
-            && s1ap->mnc_digit_length[j] == omncl) {
-          mme->broadcast_plmn_index[i] = j;
-          break;
-        }
-      }
-      if (j == s1ap->num_plmn) /* could not find the old PLMN in the new ones */
-        bpn_failed++;
-    }
-  }
-  if (bpn_failed > 0)
-    return -10000 - bpn_failed;
-  return 0;
-}
-
-int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){
-  if (!rrc_is_present(mod_id)) return -1;
-  s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id);
-  if (!s1ap) return -1;
-
-  uint32_t enb_ue_s1ap_id = flexran_get_rrc_enb_ue_s1ap_id(mod_id, rnti);
-  struct s1ap_eNB_ue_context_s *ue = NULL;
-  RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head){
-    if (ue->eNB_ue_s1ap_id == enb_ue_s1ap_id) break;
-  }
-  if (!ue) return 0; // UE does not exist: it might be connected but CN did not answer
-
-  if (ue->mme_ref->mme_s1_ip.ipv4)
-    ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv4_address[0];
-  else if (ue->mme_ref->mme_s1_ip.ipv6)
-    ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv6_address[0];
-
-  ue_conf->has_enb_ue_s1ap_id = 1;
-  ue_conf->enb_ue_s1ap_id = ue->eNB_ue_s1ap_id;
-  ue_conf->has_mme_ue_s1ap_id = 1;
-  ue_conf->mme_ue_s1ap_id = ue->mme_ue_s1ap_id;
-
-  ue_conf->selected_plmn = malloc(sizeof(Protocol__FlexPlmn));
-  if (!ue_conf->selected_plmn) return -1;
-  protocol__flex_plmn__init(ue_conf->selected_plmn);
-
-  ue_conf->selected_plmn->has_mcc = 1;
-  ue_conf->selected_plmn->mcc = s1ap->mcc[ue->selected_plmn_identity];
-  ue_conf->selected_plmn->has_mnc = 1;
-  ue_conf->selected_plmn->mnc = s1ap->mnc[ue->selected_plmn_identity];
-  ue_conf->selected_plmn->has_mnc_length = 1;
-  ue_conf->selected_plmn->mnc_length = s1ap->mnc_digit_length[ue->selected_plmn_identity];
-  return 0;
-}
-
-/**************************** General BS info  ****************************/
-uint64_t flexran_get_bs_id(mid_t mod_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-
-  return RC.rrc[mod_id]->nr_cellid;
-}
-
-size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps) {
-  if (!caps) return 0;
-
-  if (!rrc_is_present(mod_id)) return 0;
-
-  size_t n_caps = 0;
-
-  switch (RC.rrc[mod_id]->node_type) {
-    case ngran_eNB_CU:
-    case ngran_ng_eNB_CU:
-    case ngran_gNB_CU:
-    case ngran_gNB_CUCP:
-    case ngran_gNB_CUUP:
-      n_caps = 4;
-      *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability));
-      AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n",
-                  n_caps * sizeof(Protocol__FlexBsCapability));
-      (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP;
-      (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP;
-      (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__RRC;
-      (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__S1AP;
-      break;
-    case ngran_eNB_DU:
-    case ngran_gNB_DU:
-      n_caps = 5;
-      *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability));
-      AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n",
-                  n_caps * sizeof(Protocol__FlexBsCapability));
-      (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY;
-      (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY;
-      (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC;
-      (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC;
-      (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC;
-      break;
-    case ngran_eNB:
-    case ngran_ng_eNB:
-    case ngran_gNB:
-      n_caps = 9;
-      *caps = calloc(n_caps, sizeof(Protocol__FlexBsCapability));
-      AssertFatal(*caps, "could not allocate %zu bytes for Protocol__FlexBsCapability array\n",
-                  n_caps * sizeof(Protocol__FlexBsCapability));
-      (*caps)[0] = PROTOCOL__FLEX_BS_CAPABILITY__LOPHY;
-      (*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__HIPHY;
-      (*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__LOMAC;
-      (*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC;
-      (*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC;
-      (*caps)[5] = PROTOCOL__FLEX_BS_CAPABILITY__PDCP;
-      (*caps)[6] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP;
-      (*caps)[7] = PROTOCOL__FLEX_BS_CAPABILITY__RRC;
-      (*caps)[8] = PROTOCOL__FLEX_BS_CAPABILITY__S1AP;
-      break;
-    case ngran_eNB_MBMS_STA:
-      AssertFatal(0, "MBMS STA not supported by FlexRAN!\n");
-     break;
-  }
-
-  return n_caps;
-}
-
-uint32_t flexran_get_capabilities_mask(mid_t mod_id) {
-  if (!rrc_is_present(mod_id)) return 0;
-  uint32_t mask = 0;
-  switch (RC.rrc[mod_id]->node_type) {
-    case ngran_eNB_CU:
-    case ngran_ng_eNB_CU:
-    case ngran_gNB_CU:
-    case ngran_gNB_CUCP:
-    case ngran_gNB_CUUP:
-      mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP);
-      break;
-    case ngran_eNB_DU:
-    case ngran_gNB_DU:
-      mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC);
-      break;
-    case ngran_eNB:
-    case ngran_ng_eNB:
-    case ngran_gNB:
-      mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC)
-           | (1 << PROTOCOL__FLEX_BS_CAPABILITY__S1AP);
-      break;
-    case ngran_eNB_MBMS_STA:
-      AssertFatal(0, "MBMS STA not supported by FlexRAN!\n");
-     break;
-  }
-
-  return mask;
-}
-
-size_t flexran_get_splits(mid_t mod_id, Protocol__FlexBsSplit **splits) {
-  size_t n_splits = 0;
-  *splits = NULL;
-  if (rrc_is_present(mod_id) && !NODE_IS_MONOLITHIC(RC.rrc[mod_id]->node_type))
-    n_splits++;
-  if (NFAPI_MODE != NFAPI_MONOLITHIC)
-    n_splits++;
-  if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south != LOCAL_RF)
-    n_splits++;
-  if (n_splits == 0)
-    return 0;
-
-  AssertFatal(n_splits < 3, "illegal number of splits (%lu)\n", n_splits);
-  *splits = calloc(n_splits, sizeof(Protocol__FlexBsSplit));
-  AssertFatal(*splits, "could not allocate Protocol__FlexBsSplit array\n");
-  int n = 0;
-  if (rrc_is_present(mod_id) && !NODE_IS_MONOLITHIC(RC.rrc[mod_id]->node_type))
-    (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__F1;
-  if (NFAPI_MODE != NFAPI_MONOLITHIC)
-    (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__nFAPI;
-  if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south == REMOTE_IF4p5)
-    (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__IF4p5;
-  if (RC.ru && RC.ru[mod_id] && RC.ru[mod_id]->if_south == REMOTE_IF5)
-    (*splits)[n++] = PROTOCOL__FLEX_BS_SPLIT__IF5;
-  DevAssert(n == n_splits);
-  return n_splits;
-}
diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c
index 08a5b906eedce8060e5413a0db9dd4f8c0e1c219..afb4a1048af9b4c4a585f0288471875c3a71c601 100644
--- a/openair2/F1AP/dummy_enb.c
+++ b/openair2/F1AP/dummy_enb.c
@@ -52,3 +52,10 @@ abort();
 int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) {
   abort();
 }
+
+int rrc_gNB_generate_pcch_msg(uint32_t tmsi,
+                              uint8_t paging_drx,
+                              instance_t instance,
+                              uint8_t CC_id) {
+  abort();
+}
diff --git a/openair2/F1AP/f1ap_cu_paging.c b/openair2/F1AP/f1ap_cu_paging.c
index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..f0e68bf1fcf57fc3240b821685aa9e1e84ce9225 100644
--- a/openair2/F1AP/f1ap_cu_paging.c
+++ b/openair2/F1AP/f1ap_cu_paging.c
@@ -19,8 +19,8 @@
  *      contact@openairinterface.org
  */
 
-/*! \file f1ap_du_interface_management.h
- * \brief f1ap interface management for DU
+/*! \file f1ap_cu_paging.c
+ * \brief f1ap interface paging for CU
  * \author EURECOM/NTUST
  * \date 2018
  * \version 0.1
@@ -28,4 +28,93 @@
  * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
  * \note
  * \warning
- */
\ No newline at end of file
+ */
+
+#include "f1ap_common.h"
+#include "f1ap_encoder.h"
+#include "f1ap_itti_messaging.h"
+#include "f1ap_cu_paging.h"
+
+extern f1ap_setup_req_t *f1ap_du_data_from_du;
+
+int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging) {
+  F1AP_F1AP_PDU_t pdu = {0};
+
+  pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
+  asn1cCalloc(pdu.choice.initiatingMessage, msg);
+  msg->procedureCode = F1AP_ProcedureCode_id_Paging;
+  msg->criticality = F1AP_Criticality_reject;
+  msg->value.present = F1AP_InitiatingMessage__value_PR_Paging;
+
+  /* mandatory */
+  /* UEIdentityIndexValue */
+  {
+    asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
+                     F1AP_PagingIEs_t, ie);
+    ie->id = F1AP_ProtocolIE_ID_id_UEIdentityIndexValue;
+    ie->criticality = F1AP_Criticality_reject;
+    ie->value.present = F1AP_PagingIEs__value_PR_UEIdentityIndexValue;
+    ie->value.choice.UEIdentityIndexValue.present =
+        F1AP_UEIdentityIndexValue_PR_indexLength10;
+    UEIDENTITYINDEX_TO_BIT_STRING(
+        paging->ueidentityindexvalue,
+        &ie->value.choice.UEIdentityIndexValue.choice.indexLength10);
+  }
+
+  /* mandatory */
+  /* PagingIdentity */
+  {
+    asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
+                     F1AP_PagingIEs_t, ie);
+    ie->id = F1AP_ProtocolIE_ID_id_PagingIdentity;
+    ie->criticality = F1AP_Criticality_reject;
+    ie->value.present = F1AP_PagingIEs__value_PR_PagingIdentity;
+    ie->value.choice.PagingIdentity.present =
+        F1AP_PagingIdentity_PR_cNUEPagingIdentity;
+    asn1cCalloc(ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity, id);
+    id->present = F1AP_CNUEPagingIdentity_PR_fiveG_S_TMSI;
+    FIVEG_S_TMSI_TO_BIT_STRING(paging->fiveg_s_tmsi, &id->choice.fiveG_S_TMSI);
+  }
+
+  /* optional */
+  /* PagingDRX */
+  {
+    asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
+                     F1AP_PagingIEs_t, ie);
+    ie->id = F1AP_ProtocolIE_ID_id_PagingDRX;
+    ie->criticality = F1AP_Criticality_ignore;
+    ie->value.present = F1AP_PagingIEs__value_PR_PagingDRX;
+    ie->value.choice.PagingDRX = paging->paging_drx;
+  }
+
+  /* mandatory */
+  /* PagingCell_list */
+  {
+    asn1cSequenceAdd(msg->value.choice.Paging.protocolIEs.list,
+                     F1AP_PagingIEs_t, ie);
+    ie->id = F1AP_ProtocolIE_ID_id_PagingCell_List;
+    ie->criticality = F1AP_Criticality_reject;
+    ie->value.present = F1AP_PagingIEs__value_PR_PagingCell_list;
+    asn1cSequenceAdd(ie->value.choice.PagingCell_list,
+                     F1AP_PagingCell_ItemIEs_t, itemies);
+    itemies->id = F1AP_ProtocolIE_ID_id_PagingCell_Item;
+    itemies->criticality = F1AP_Criticality_reject;
+    itemies->value.present = F1AP_PagingCell_ItemIEs__value_PR_PagingCell_Item;
+    F1AP_NRCGI_t *nRCGI = &itemies->value.choice.PagingCell_Item.nRCGI;
+    MCC_MNC_TO_PLMNID(paging->mcc, paging->mnc, paging->mnc_digit_length,
+                      &nRCGI->pLMN_Identity);
+    NR_CELL_ID_TO_BIT_STRING(paging->nr_cellid, &nRCGI->nRCellIdentity);
+  }
+
+  uint8_t *buffer;
+  uint32_t len;
+  /* encode */
+  if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
+    LOG_E(F1AP, "Failed to encode F1 Paging failure\n");
+    ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
+    return -1;
+  }
+  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_F1AP_F1AP_PDU, &pdu);
+  f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0);
+  return 0;
+}
diff --git a/openair2/F1AP/f1ap_cu_paging.h b/openair2/F1AP/f1ap_cu_paging.h
index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..5cff651fcc4d823ef03be0f6c50ef9b0c1aee5e1 100644
--- a/openair2/F1AP/f1ap_cu_paging.h
+++ b/openair2/F1AP/f1ap_cu_paging.h
@@ -19,8 +19,8 @@
  *      contact@openairinterface.org
  */
 
-/*! \file f1ap_du_interface_management.h
- * \brief f1ap interface management for DU
+/*! \file f1ap_cu_paging.h
+ * \brief f1ap interface paging for CU
  * \author EURECOM/NTUST
  * \date 2018
  * \version 0.1
@@ -28,4 +28,9 @@
  * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
  * \note
  * \warning
- */
\ No newline at end of file
+ */
+
+#ifndef F1AP_CU_PAGING_H_
+#define F1AP_CU_PAGING_H_
+int CU_send_Paging(instance_t instance, f1ap_paging_ind_t *paging);
+#endif /* F1AP_DU_PAGING_H_ */
diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c
index d8ce0c7868937f3eb988b28a19f5f56ba9a5df89..de6abf0a7b41e876e9f1a861acdec6fc13891fdb 100644
--- a/openair2/F1AP/f1ap_cu_task.c
+++ b/openair2/F1AP/f1ap_cu_task.c
@@ -34,6 +34,7 @@
 #include "f1ap_cu_interface_management.h"
 #include "f1ap_cu_rrc_message_transfer.h"
 #include "f1ap_cu_ue_context_management.h"
+#include "f1ap_cu_paging.h"
 #include "f1ap_cu_task.h"
 #include <openair3/ocp-gtpu/gtp_itf.h>
 
@@ -195,6 +196,12 @@ void *F1AP_CU_task(void *arg) {
                                            &F1AP_UE_CONTEXT_RELEASE_CMD(received_msg));
         break;
 
+      case F1AP_PAGING_IND:
+        LOG_I(F1AP, "CU Task Received F1AP_PAGING_IND\n");
+        CU_send_Paging(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
+                       &F1AP_PAGING_IND(received_msg));
+        break;
+
       //    case F1AP_SETUP_RESPONSE: // This is from RRC
       //    CU_send_F1_SETUP_RESPONSE(instance, *f1ap_setup_ind, &(F1AP_SETUP_RESP) f1ap_setup_resp)
       //        break;
diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c
index 47e1f274d3f22bc217a620fff92bcded451463af..04c4ae18ee9129c639d4725037954f933efe8214 100644
--- a/openair2/F1AP/f1ap_decoder.c
+++ b/openair2/F1AP/f1ap_decoder.c
@@ -83,6 +83,10 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) {
       LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__);
       break;
 
+    case F1AP_ProcedureCode_id_Paging:
+      LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_Paging\n", __func__);
+      break;
+
     // case F1AP_ProcedureCode_id_InitialContextSetup:
     //   res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu);
     //   message_id = F1AP_INITIAL_CONTEXT_SETUP_LOG;
diff --git a/openair2/F1AP/f1ap_du_paging.c b/openair2/F1AP/f1ap_du_paging.c
index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..46f17fd64d0430b970dcd07534786cb93b70dfd8 100644
--- a/openair2/F1AP/f1ap_du_paging.c
+++ b/openair2/F1AP/f1ap_du_paging.c
@@ -28,4 +28,70 @@
  * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
  * \note
  * \warning
- */
\ No newline at end of file
+ */
+#include "f1ap_common.h"
+#include "f1ap_du_paging.h"
+#include "conversions.h"
+#include "asn1_conversions.h"
+#include "openair2/RRC/LTE/rrc_proto.h"
+
+int DU_handle_Paging(instance_t       instance,
+                     uint32_t         assoc_id,
+                     uint32_t         stream,
+                     F1AP_F1AP_PDU_t *pdu) {
+  F1AP_Paging_t *paging;
+  F1AP_PagingIEs_t *ie;
+  long tmsi;
+  uint8_t pagingdrx;
+  uint8_t  *fiveg_tmsi_buf = NULL;
+
+  DevAssert(pdu);
+
+  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, pdu);
+  }
+
+  paging = &pdu->choice.initiatingMessage->value.choice.Paging;
+  // get UEIdentityIndexValue
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
+                             F1AP_ProtocolIE_ID_id_UEIdentityIndexValue, true);
+
+  LOG_D(F1AP, "indexLength10 %d\n", BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue.choice.indexLength10));
+
+  // get PagingIdentity
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
+                             F1AP_ProtocolIE_ID_id_PagingIdentity, true);
+
+  if(ie != NULL){
+    fiveg_tmsi_buf = ie->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf;
+
+    tmsi = ((long)fiveg_tmsi_buf[0] << 40) +
+           ((long)fiveg_tmsi_buf[1] << 32) +
+           (fiveg_tmsi_buf[2] << 24) +
+           (fiveg_tmsi_buf[3] << 16) +
+           (fiveg_tmsi_buf[4] << 8) +
+           fiveg_tmsi_buf[5];
+
+    LOG_D(F1AP, "tmsi %ld\n", tmsi);
+  }
+
+  // get PagingDRX
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
+                             F1AP_ProtocolIE_ID_id_PagingDRX, true);
+
+  if(ie != NULL) {
+    pagingdrx = (uint8_t)ie->value.choice.PagingDRX;
+  }
+
+  LOG_D(F1AP, "pagingdrx %u\n", pagingdrx);
+
+  // get PagingCell_List
+  F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_PagingIEs_t, ie, paging,
+                             F1AP_ProtocolIE_ID_id_PagingCell_List, true);
+
+  for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+    rrc_gNB_generate_pcch_msg((uint32_t)tmsi, pagingdrx, instance, CC_id);
+  }
+
+  return 0;
+}
\ No newline at end of file
diff --git a/openair2/F1AP/f1ap_du_paging.h b/openair2/F1AP/f1ap_du_paging.h
index b6bbedba2f0ed9c62704a0f9fdcf52c3e182ed60..3e1806ae0223c9096c0b1aa28c48134de42fc32a 100644
--- a/openair2/F1AP/f1ap_du_paging.h
+++ b/openair2/F1AP/f1ap_du_paging.h
@@ -28,4 +28,14 @@
  * \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
  * \note
  * \warning
- */
\ No newline at end of file
+ */
+
+#ifndef F1AP_DU_PAGING_H_
+#define F1AP_DU_PAGING_H_
+
+int DU_handle_Paging(instance_t       instance,
+                     uint32_t         assoc_id,
+                     uint32_t         stream,
+                     F1AP_F1AP_PDU_t *pdu);
+
+#endif /* F1AP_DU_PAGING_H_ */
diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c
index 0812a976f634363b81f7368a56269540129675ab..f3db249e096258cef36ad4f6dbb7088b4bc50071 100644
--- a/openair2/F1AP/f1ap_handlers.c
+++ b/openair2/F1AP/f1ap_handlers.c
@@ -38,6 +38,7 @@
 #include "f1ap_du_rrc_message_transfer.h"
 #include "f1ap_cu_ue_context_management.h"
 #include "f1ap_du_ue_context_management.h"
+#include "f1ap_du_paging.h"
 
 /* Handlers matrix. Only f1 related procedure present here */
 f1ap_message_processing_t f1ap_messages_processing[][3] = {
@@ -61,7 +62,7 @@ f1ap_message_processing_t f1ap_messages_processing[][3] = {
   { 0, 0, 0 }, /* UEInactivityNotification */
   { 0, 0, 0 }, /* GNBDUResourceCoordination */
   { 0, 0, 0 }, /* SystemInformationDeliveryCommand */
-  { 0, 0, 0 }, /* Paging */
+  { DU_handle_Paging, 0, 0 }, /* Paging */
   { 0, 0, 0 }, /* Notify */
   { 0, 0, 0 }, /* WriteReplaceWarning */
   { 0, 0, 0 }, /* PWSCancel */
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 10a03e30af00a4f037a8ff238714f5cb15735654..1f98723deb667ca9242c8194750fce7ecb4259bb 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -273,7 +273,7 @@ typedef struct {
 
 // DCI pdu structures. Used by both gNB and UE.
 typedef struct {
-  uint16_t val;
+  uint32_t val;
   uint8_t nbits;
 } dci_field_t;
 
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index e5b7e741693151e6d616f1e4213f7caf8ca36a4e..fb20092ed53a51f6a8ad15a374e54324aefe76ce 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -2476,7 +2476,7 @@ static inline uint8_t get_table_idx(uint8_t mcs_table, uint8_t dci_format, uint8
 // Table 5.1.2.2.1-1 38.214
 uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) {
   
-  AssertFatal(bwp_size<276,"BWP Size > 275\n");
+  AssertFatal(bwp_size < 276,"Invalid BWP Size > 275\n");
   
   if (bwp_size < 37)  return (rbg_size_config ? 4 : 2);
   if (bwp_size < 73)  return (rbg_size_config ? 8 : 4);
@@ -2487,8 +2487,7 @@ uint8_t getRBGSize(uint16_t bwp_size, long rbg_size_config) {
 uint8_t getNRBG(uint16_t bwp_size, uint16_t bwp_start, long rbg_size_config) {
 
   uint8_t rbg_size = getRBGSize(bwp_size,rbg_size_config);
-
-  return (uint8_t)ceil((bwp_size+(bwp_start % rbg_size))/rbg_size);
+  return (uint8_t)ceil((float)(bwp_size+(bwp_start % rbg_size))/(float)rbg_size);
 }
 
 uint8_t getAntPortBitWidth(NR_SetupRelease_DMRS_DownlinkConfig_t *typeA, NR_SetupRelease_DMRS_DownlinkConfig_t *typeB) {
@@ -2770,7 +2769,7 @@ uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servi
                                        NR_PUSCH_Config_t *pusch_Config,
                                        NR_SRS_Config_t *srs_config,
                                        nr_srs_feedback_t *srs_feedback,
-                                       uint16_t *val)
+                                       uint32_t *val)
 {
   uint8_t nbits = 0;
 
@@ -2892,7 +2891,7 @@ uint8_t compute_precoding_information(NR_PUSCH_Config_t *pusch_Config,
                                       dci_field_t srs_resource_indicator,
                                       nr_srs_feedback_t *srs_feedback,
                                       const uint8_t *nrOfLayers,
-                                      uint16_t *val) {
+                                      uint32_t *val) {
 
   // It is only applicable to codebook based transmission. This field occupies 0 bits for non-codebook based
   // transmission. It also occupies 0 bits for codebook based transmission using a single antenna port.
@@ -3191,10 +3190,15 @@ uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDownlinkBWP,
     case NR_UL_DCI_FORMAT_0_0:
       /// fixed: Format identifier 1, Hop flag 1, MCS 5, NDI 1, RV 2, HARQ PID 4, PUSCH TPC 2 Time Domain assgnmt 4 --20
       size += 20;
-      size += (uint8_t)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); // Freq domain assignment -- hopping scenario to be updated
+      dci_pdu->frequency_domain_assignment.nbits = (uint8_t)ceil(log2((N_RB * (N_RB + 1)) >>1)); // Freq domain assignment -- hopping scenario to be updated
+      size += dci_pdu->frequency_domain_assignment.nbits;
       int dci_10_size = nr_dci_size(initialDownlinkBWP,initialUplinkBWP,cg,dci_pdu,NR_DL_DCI_FORMAT_1_0, rnti_type, N_RB, bwp_id, coreset_id, cset0_bwp_size);
-      AssertFatal(dci_10_size >= size, "NR_UL_DCI_FORMAT_0_0 size is bigger than NR_DL_DCI_FORMAT_1_0! 3GPP TS 38.212 Section 7.3.1.0: DCI size alignment is not fully implemented");
-      size += dci_10_size - size; // Padding to match 1_0 size
+      if(dci_10_size >= size)
+        size += dci_10_size - size; // Padding to match 1_0 size
+      else {
+        dci_pdu->frequency_domain_assignment.nbits -= (size - dci_10_size);
+        size = dci_10_size;
+      }
       // UL/SUL indicator assumed to be 0
       break;
 
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 507d4469a51eada0e71b31515c236b0399eeba16..7f88216cbd59d68ffefebe50975c7aeacb987ccf 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -32,10 +32,8 @@
 #define __LAYER2_NR_MAC_COMMON_H__
 
 #include "NR_MIB.h"
-#include "NR_PDSCH-Config.h"
 #include "NR_CellGroupConfig.h"
 #include "nr_mac.h"
-#include "openair1/PHY/impl_defs_nr.h"
 #include "common/utils/nr/nr_common.h"
 
 typedef enum {
@@ -68,14 +66,14 @@ uint8_t compute_srs_resource_indicator(NR_PUSCH_ServingCellConfig_t *pusch_servi
                                        NR_PUSCH_Config_t *pusch_Config,
                                        NR_SRS_Config_t *srs_config,
                                        nr_srs_feedback_t *srs_feedback,
-                                       uint16_t *val);
+                                       uint32_t *val);
 
 uint8_t compute_precoding_information(NR_PUSCH_Config_t *pusch_Config,
                                       NR_SRS_Config_t *srs_config,
                                       dci_field_t srs_resource_indicator,
                                       nr_srs_feedback_t *srs_feedback,
                                       const uint8_t *nrOfLayers,
-                                      uint16_t *val);
+                                      uint32_t *val);
 
 uint16_t nr_dci_size(const NR_BWP_DownlinkCommon_t *initialDLBWP,
                      const NR_BWP_UplinkCommon_t *initialULBWP,
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index 909a0428d4c39a9429f2f31835684829a2a837f6..a9160e84ba30ca6fe426b8f52a019f85fbaa6cf6 100644
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -432,7 +432,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac,
     @returns void
     */
 
-void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format){
+void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint32_t *bwp_ind, uint8_t *dci_format)
+{
 
   NR_ServingCellConfig_t *scd = mac->cg->spCellConfig->spCellConfigDedicated;
 
@@ -471,7 +472,6 @@ void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format
   }
 
   LOG_D(MAC, "In %s setting DL_BWP_Id %ld UL_BWP_Id %ld \n", __FUNCTION__, mac->DL_BWP_Id, mac->UL_BWP_Id);
-
 }
 
 /** \brief This function is relavant for the UE procedures for control. It loads the search spaces, the BWPs and the CORESETs into the MAC instance and
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index e5fe2e377f8431a366784238cded580f6b85a7c9..18c34d29e0260d01996c9a886a6b17a0a5389736 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -228,7 +228,6 @@ typedef struct {
 
 typedef enum {
   RA_UE_IDLE = 0,
-  GENERATE_IDLE = 0,
   GENERATE_PREAMBLE = 1,
   WAIT_RAR = 2,
   WAIT_CONTENTION_RESOLUTION = 3,
@@ -281,8 +280,8 @@ typedef struct {
   uint8_t RA_active;
   /// Random-access preamble index
   int ra_PreambleIndex;
-  /// Flag for the Msg1 generation: enabled at every occurrence of nr prach slot
-  RA_state_t generate_nr_prach;
+  // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble
+  uint8_t ssb_nb_in_ro;
 
   /// Random-access window counter
   int16_t RA_window_cnt;
@@ -385,6 +384,7 @@ typedef struct {
   long                            physCellId;
   ////  MAC config
   int                             first_sync_frame;
+  bool                            sib1_decoded;
   NR_DRX_Config_t                 *drx_Config;
   NR_SchedulingRequestConfig_t    *schedulingRequestConfig;
   NR_BSR_Config_t                 *bsr_Config;
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 97deda6d81980fe3b83f519ae582de9f79a94ab0..b8b533705a093dbc38150d977936569d9646a4bb 100644
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -406,8 +406,7 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4
 @param gNB_id gNB index
 @param nr_slot_tx slot for PRACH transmission
 @returns indication to generate PRACH to phy */
-uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
-                       module_id_t mod_id,
+uint8_t nr_ue_get_rach(module_id_t mod_id,
                        int CC_id,
                        frame_t frame,
                        uint8_t gNB_id,
@@ -423,7 +422,6 @@ void nr_get_prach_resources(module_id_t mod_id,
                             int CC_id,
                             uint8_t gNB_id,
                             NR_PRACH_RESOURCES_t *prach_resources,
-                            fapi_nr_ul_config_prach_pdu *prach_pdu,
                             NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
 
 void init_RA(module_id_t mod_id,
@@ -453,7 +451,7 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd
 
 void build_ssb_to_ro_map(NR_UE_MAC_INST_t *mac);
 
-void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint16_t *bwp_ind, uint8_t *dci_format);
+void config_bwp_ue(NR_UE_MAC_INST_t *mac, uint32_t *bwp_ind, uint8_t *dci_format);
 
 void configure_ss_coreset(NR_UE_MAC_INST_t *mac,
                           NR_ServingCellConfig_t *scd,
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index 1e254ded42d78b849ecece1a9be4e9f446dd7e42..e9eb77b9c1d8f96057e6d03a8d3f718441af5b04 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -51,6 +51,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
     //init mac here
     nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST);
     nr_ue_mac_inst->first_sync_frame = -1;
+    nr_ue_mac_inst->sib1_decoded = false;
 
     for (int j=0;j<NB_NR_UE_MAC_INST;j++) {
 	nr_ue_init_mac(j);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
index b205c6356fdf47941407e08274f9ce332820f28c..8b71713eb6b2e2c9db1778e504c1b8b1aa0fa2c8 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -31,7 +31,6 @@
  */
 
 /* RRC */
-#include "NR_RACH-ConfigCommon.h"
 #include "RRC/NR_UE/rrc_proto.h"
 
 /* MAC */
@@ -403,7 +402,7 @@ int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t m
   return receivedTargerPower;
 }
 
-void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){
+void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon){
 
   // Determine the SSB to RACH mapping ratio
   // =======================================
@@ -467,7 +466,7 @@ void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_
   if ((true == multiple_ssb_per_ro) && (ssb_rach_ratio > 1)) {
     total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio;
 
-    ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro;
+    ssb_nb_in_ro = ra->ssb_nb_in_ro;
     ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
   } else {
     total_preambles_per_ssb = numberOfRA_Preambles;
@@ -657,7 +656,6 @@ void nr_get_prach_resources(module_id_t mod_id,
                             int CC_id,
                             uint8_t gNB_id,
                             NR_PRACH_RESOURCES_t *prach_resources,
-                            fapi_nr_ul_config_prach_pdu *prach_pdu,
                             NR_RACH_ConfigDedicated_t *rach_ConfigDedicated){
 
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
@@ -667,7 +665,7 @@ void nr_get_prach_resources(module_id_t mod_id,
     mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup : 
     mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
 
-  LOG_D(PHY, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3);
+  LOG_D(MAC, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3);
 
   if (rach_ConfigDedicated) {
     if (rach_ConfigDedicated->cfra){
@@ -679,7 +677,7 @@ void nr_get_prach_resources(module_id_t mod_id,
     /* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we
              can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */
     int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm) : 0;
-    ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu);
+    ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon);
     ra_preambles_config(prach_resources, mac, dl_pathloss);
     LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex);
   }
@@ -738,8 +736,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot
  * @gNB_id              gNB ID
  * @nr_slot_tx          current UL TX slot
  */
-uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
-                       module_id_t mod_id,
+uint8_t nr_ue_get_rach(module_id_t mod_id,
                        int CC_id,
                        frame_t frame,
                        uint8_t gNB_id,
@@ -896,13 +893,11 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
         if(ra->cfra) {
           // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
           nr_ra_succeeded(mod_id, frame, nr_slot_tx);
-        } else {
-          ra->generate_nr_prach = GENERATE_IDLE;
         }
 
       } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) {
 
-        LOG_I(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx);
+        LOG_W(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx);
 
         nr_ra_failed(mod_id, CC_id, prach_resources, frame, nr_slot_tx);
 
@@ -912,8 +907,8 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
 
         // Fill in preamble and PRACH resources
         ra->RA_window_cnt--;
-        if (ra->generate_nr_prach == GENERATE_PREAMBLE) {
-          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
+        if (ra->ra_state == GENERATE_PREAMBLE) {
+          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, rach_ConfigDedicated);
         }
       } else if (ra->RA_backoff_cnt > 0) {
 
@@ -921,10 +916,9 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
 
         ra->RA_backoff_cnt--;
 
-        if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) {
-          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
+        if ((ra->RA_backoff_cnt > 0 && ra->ra_state == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) {
+          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, rach_ConfigDedicated);
         }
-
       }
     }
   }
@@ -933,8 +927,7 @@ uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
     nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources);
   }
 
-  LOG_D(MAC,"ra->generate_nr_prach %d ra->ra_state %d (GENERATE_IDLE %d)\n",ra->generate_nr_prach,ra->ra_state,GENERATE_IDLE);
-  return ra->generate_nr_prach;
+  return ra->ra_state;
 }
 
 void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
@@ -1041,7 +1034,6 @@ void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
 
   LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id);
   ra->RA_active = 0;
-  ra->generate_nr_prach = GENERATE_IDLE;
   ra->ra_state = RA_SUCCEEDED;
 
 }
@@ -1060,7 +1052,6 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res
 
   ra->first_Msg3 = 1;
   ra->ra_PreambleIndex = -1;
-  ra->generate_nr_prach = RA_FAILED;
   ra->ra_state = RA_UE_IDLE;
 
   prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 4cf87ebcbd210e7778b3561fc017c7cbe3b65880..cef268d517b59ce1815617d580dccd23b624f1e7 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -39,10 +39,6 @@
 
 /* RRC*/
 #include "RRC/NR_UE/rrc_proto.h"
-#include "NR_RACH-ConfigCommon.h"
-#include "NR_RACH-ConfigGeneric.h"
-#include "NR_FrequencyInfoDL.h"
-#include "NR_PDCCH-ConfigCommon.h"
 
 /* MAC */
 #include "NR_MAC_COMMON/nr_mac.h"
@@ -374,7 +370,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
     else
       ssb_sc_offset_norm = ssb_subcarrier_offset;
 
-    if (mac->first_sync_frame == -1)
+    if (!mac->sib1_decoded) {
       nr_ue_sib1_scheduler(module_id,
                            cc_id,
                            ssb_start_symbol,
@@ -384,18 +380,20 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
                            ssb_start_subcarrier,
                            mac->frequency_range,
                            phy_data);
+      mac->first_sync_frame = frame;
+    }
   }
   else {
     NR_ServingCellConfigCommon_t *scc = mac->scc;
     scs_ssb = *scc->ssbSubcarrierSpacing;
     band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
     ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index);
+    if (mac->first_sync_frame == -1)
+      mac->first_sync_frame = frame;
   }
 
   mac->dl_config_request.sfn = frame;
   mac->dl_config_request.slot = ssb_start_symbol/14;
-  if (mac->first_sync_frame == -1)
-    mac->first_sync_frame = frame;
 
   return 0;
 }
@@ -408,6 +406,8 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id,
                                 uint32_t pdu_len) {
   if(ack_nack) {
     LOG_D(NR_MAC, "Decoding NR-BCCH-DL-SCH-Message (SIB1 or SI)\n");
+    NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
+    mac->sib1_decoded = true;
     nr_mac_rrc_data_ind_ue(module_id, cc_id, gNB_index, 0, 0, 0, NR_BCCH_DL_SCH, (uint8_t *) pduP, pdu_len);
   }
   else
@@ -425,11 +425,11 @@ uint32_t get_ssb_frame(uint32_t test){
  * These tables and functions are going to be called by function nr_ue_process_dci
  */
 int8_t nr_ue_process_dci_freq_dom_resource_assignment(nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu,
-						      fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
-						      uint16_t n_RB_ULBWP,
-						      uint16_t n_RB_DLBWP,
-						      uint16_t riv
-						      ){
+                                                      fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu,
+                                                      uint16_t n_RB_ULBWP,
+                                                      uint16_t n_RB_DLBWP,
+                                                      uint16_t riv)
+{
 
   /*
    * TS 38.214 subclause 5.1.2.2 Resource allocation in frequency domain (downlink)
@@ -3248,7 +3248,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
 #endif
         if (dci_pdu_rel15->format_indicator == 1)
           return 1; // discard dci, format indicator not corresponding to dci_format
-	fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
+	fsize = dci_pdu_rel15->frequency_domain_assignment.nbits;
 	pos+=fsize;
 	dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
 #ifdef DEBUG_EXTRACT_DCI
@@ -3312,7 +3312,7 @@ static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac,
 #endif
         if (dci_pdu_rel15->format_indicator == 1)
           return 1; // discard dci, format indicator not corresponding to dci_format
-	fsize = (int)ceil( log2( (N_RB_UL*(N_RB_UL+1))>>1 ) );
+	fsize = dci_pdu_rel15->frequency_domain_assignment.nbits;
 	pos+=fsize;
 	dci_pdu_rel15->frequency_domain_assignment.val = (*dci_pdu>>(dci_size-pos))&((1<<fsize)-1);
 #ifdef DEBUG_EXTRACT_DCI
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index a51ebfa868c2a20c56a48132c38fbf41babe21c6..902bb2aec8ba1b0473a95616c118be1efc3d6244 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -35,13 +35,6 @@
 /* exe */
 #include <common/utils/nr/nr_common.h>
 
-/* RRC*/
-#include "RRC/NR_UE/rrc_proto.h"
-#include "NR_RACH-ConfigCommon.h"
-#include "NR_RACH-ConfigGeneric.h"
-#include "NR_FrequencyInfoDL.h"
-#include "NR_PDCCH-ConfigCommon.h"
-
 /* MAC */
 #include "NR_MAC_COMMON/nr_mac.h"
 #include "NR_MAC_COMMON/nr_mac_common.h"
@@ -1154,8 +1147,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
   } else if (ul_info) {
 
     int cc_id             = ul_info->cc_id;
-    //frame_t rx_frame      = ul_info->frame_rx;
-    //slot_t rx_slot        = ul_info->slot_rx;
     frame_t frame_tx      = ul_info->frame_tx;
     slot_t slot_tx        = ul_info->slot_tx;
     module_id_t mod_id    = ul_info->module_id;
@@ -1169,6 +1160,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
       LOG_E(NR_MAC, "mac->ul_config is null!\n");
     }
 
+    nr_ue_get_rach(mod_id, cc_id, frame_tx, gNB_index, slot_tx);
     // Periodic SRS scheduling
     nr_ue_periodic_srs_scheduling(mod_id, frame_tx, slot_tx);
 
@@ -2659,12 +2651,12 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) {
 // - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config
 void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) {
 
-  uint16_t format, format0, format1, ncs;
-  int is_nr_prach_slot;
-  prach_occasion_info_t *prach_occasion_info_p;
-
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP);
   RA_config_t *ra = &mac->ra;
+  ra->RA_offset = 2; // to compensate the rx frame offset at the gNB
+  if(ra->ra_state != GENERATE_PREAMBLE)
+    return;
+
   fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, slotP);
   if (!ul_config) {
     LOG_E(NR_MAC, "mac->ul_config is null! \n");
@@ -2683,8 +2675,6 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
   else           setup = scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
   NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
 
-  ra->RA_offset = 2; // to compensate the rx frame offset at the gNB
-  ra->generate_nr_prach = GENERATE_IDLE; // Reset flag for PRACH generation
   NR_TDD_UL_DL_ConfigCommon_t *tdd_config = scc==NULL ? scc_SIB->tdd_UL_DL_ConfigurationCommon : scc->tdd_UL_DL_ConfigurationCommon;
 
   if (is_nr_UL_slot(tdd_config, slotP, mac->frame_type)) {
@@ -2694,22 +2684,21 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
     uint8_t selected_gnb_ssb_idx = mac->mib_ssb;
 
     // Get any valid PRACH occasion in the current slot for the selected SSB index
-    is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx,
+    prach_occasion_info_t *prach_occasion_info_p;
+    int is_nr_prach_slot = get_nr_prach_info_from_ssb_index(selected_gnb_ssb_idx,
                                                        (int)frameP,
                                                        (int)slotP,
                                                         &prach_occasion_info_p);
 
-    if (is_nr_prach_slot && ra->ra_state == GENERATE_PREAMBLE) {
+    if (is_nr_prach_slot) {
       AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n");
 
-      ra->generate_nr_prach = GENERATE_PREAMBLE;
-
       init_RA(module_idP, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated);
       nr_get_RA_window(mac);
 
-      format = prach_occasion_info_p->format;
-      format0 = format & 0xff;        // single PRACH format
-      format1 = (format >> 8) & 0xff; // dual PRACH format
+      uint16_t format = prach_occasion_info_p->format;
+      uint16_t format0 = format & 0xff;        // single PRACH format
+      uint16_t format1 = (format >> 8) & 0xff; // dual PRACH format
       AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
                   "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
 
@@ -2723,7 +2712,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
 
       memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu));
 
-      ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
+      uint16_t ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig);
 
       prach_config_pdu->phys_cell_id = mac->physCellId;
       prach_config_pdu->num_prach_ocas = 1;
@@ -2736,15 +2725,17 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
       prach_config_pdu->restricted_set = prach_config->restricted_set_config;
       prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1;
 
-      LOG_D(NR_MAC,"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n",
+      LOG_I(NR_MAC,"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n",
             frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra);
 
       // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO)
-      for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) {
-        if (prach_occasion_info_p->mapped_ssb_idx[prach_config_pdu->ssb_nb_in_ro] == selected_gnb_ssb_idx)
+      for (int ssb_nb_in_ro=0; ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; ssb_nb_in_ro++) {
+        if (prach_occasion_info_p->mapped_ssb_idx[ssb_nb_in_ro] == selected_gnb_ssb_idx) {
+          ra->ssb_nb_in_ro = ssb_nb_in_ro;
           break;
+        }
       }
-      AssertFatal(prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx);
+      AssertFatal(ra->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb, "%u not found in the mapped SSBs to the PRACH occasion", selected_gnb_ssb_idx);
 
       if (format1 != 0xff) {
         switch(format0) { // dual PRACH format
@@ -2800,7 +2791,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
         }
       } // if format1
 
-      nr_get_prach_resources(module_idP, 0, 0, &ra->prach_resources, prach_config_pdu, ra->rach_ConfigDedicated);
+      nr_get_prach_resources(module_idP, 0, 0, &ra->prach_resources, ra->rach_ConfigDedicated);
       prach_config_pdu->ra_PreambleIndex = ra->ra_PreambleIndex;
       prach_config_pdu->prach_tx_power = get_prach_tx_power(module_idP);
       set_ra_rnti(mac, prach_config_pdu);
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 4334525637e9d56b62782129f4a8d02ad951d4f7..e1ec0f6bafadf4440b8c1584dafcc64ee30a697b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -513,7 +513,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
     int nr_ulstart_slot = 0;
     if (tdd) {
       nr_dl_slots = tdd->nrofDownlinkSlots + (tdd->nrofDownlinkSymbols != 0);
-      nr_ulstart_slot = tdd->nrofDownlinkSlots;
+      nr_ulstart_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols);
       nr_slots_period /= get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
     }
     else
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 36dc919ad37ab0f98fb455e09f864d95a17670cf..35850a1a2d71660abbe23b16a8b8eda32b0d3bab 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -893,7 +893,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
   const int n_slots_frame = nr_slots_per_frame[mu];
   uint8_t k2 = 0;
   if (frame_type == TDD) {
-    int msg3_slot = tdd->nrofDownlinkSlots; // first uplink slot
+    int msg3_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols);
     if (tdd->nrofUplinkSymbols < 3)
       msg3_slot++; // we can't trasmit msg3 in mixed slot if there are less than 3 symbols
     else {
@@ -1934,10 +1934,6 @@ void nr_fill_rar(uint8_t Mod_idP,
   NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) (dlsch_buffer + 1);
   NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 2);
   unsigned char csi_req = 0, tpc_command;
-  //uint8_t N_UL_Hop;
-  uint8_t valid_bits;
-  uint32_t ul_grant;
-  uint16_t f_alloc, prb_alloc, bwp_size, truncation=0;
 
   tpc_command = 3; // this is 0 dB
 
@@ -1973,24 +1969,15 @@ void nr_fill_rar(uint8_t Mod_idP,
 
   ra->msg3_TPC = tpc_command;
 
-  bwp_size = pusch_pdu->bwp_size;
-  prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size);
-  if (bwp_size>180) {
-    AssertFatal(1==0,"Initial UBWP larger than 180 currently not supported");
-  }
-  else {
-    valid_bits = (uint8_t)ceil(log2(bwp_size*(bwp_size+1)>>1));
-  }
-
-  if (pusch_pdu->frequency_hopping){
+  if (pusch_pdu->frequency_hopping)
     AssertFatal(1==0,"PUSCH with frequency hopping currently not supported");
-  } else {
-    for (int i=0; i<valid_bits; i++)
-      truncation |= (1<<i);
-    f_alloc = (prb_alloc&truncation);
-  }
 
-  ul_grant = csi_req | (tpc_command << 1) | (pusch_pdu->mcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26);
+  int bwp_size = pusch_pdu->bwp_size;
+  int prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size);
+  int valid_bits = 14;
+  int f_alloc = prb_alloc & ((1 << valid_bits) - 1);
+
+  uint32_t ul_grant = csi_req | (tpc_command << 1) | (pusch_pdu->mcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26);
 
   rar->UL_GRANT_1 = (uint8_t) (ul_grant >> 24) & 0x07;
   rar->UL_GRANT_2 = (uint8_t) (ul_grant >> 16) & 0xff;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index af76867ef345de9ebda6288434586eeb4e593d04..c400a8ac1366d244c6320cc159d736b15636043e 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -64,7 +64,7 @@ const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon
 
   if (tdd && tdd->nrofDownlinkSymbols > 1) { // if there is a mixed slot where we can transmit DL
     const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
-    if ((slot%nr_slots_period) == tdd->nrofDownlinkSlots)
+    if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
       return 2;
   }
   return 0; // if FDD or not mixed slot in TDD, for now use default TDA
@@ -628,7 +628,7 @@ void pf_dl(module_id_t module_id,
     }
   }
 
-  qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
+  qsort(UE_sched, sizeofArray(UE_sched), sizeof(UEsched_t), comparator);
   UEsched_t *iterator = UE_sched;
 
   const int min_rbSize = 5;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index e9ca17bd1a7bb3684bdbe81eb1a94e207f4923e6..403ae15df779d221e199f75e6e96a9403c275c6a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -1670,7 +1670,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       pos=1;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos);
       // Freq domain assignment  max 16 bit
-      fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1));
+      fsize = dci_pdu_rel15->frequency_domain_assignment.nbits;
       pos+=fsize;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos);
       // Time domain assignment 4bit
@@ -1695,7 +1695,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       pos+=2;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->tpc & 0x3) << (dci_size - pos);
       // Padding bits
-      for (int a = pos; a < 32; a++)
+      for (int a = pos; a < dci_size; a++)
         *dci_pdu |= ((uint64_t)dci_pdu_rel15->padding & 1) << (dci_size - pos++);
       // UL/SUL indicator – 1 bit
       /* commented for now (RK): need to get this from BWP descriptor
@@ -1723,7 +1723,7 @@ void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc,
       pos=1;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->format_indicator & 1) << (dci_size - pos);
       // Freq domain assignment  max 16 bit
-      fsize = (int)ceil(log2((N_RB * (N_RB + 1)) >> 1));
+      fsize = dci_pdu_rel15->frequency_domain_assignment.nbits;
       pos+=fsize;
       *dci_pdu |= ((uint64_t)dci_pdu_rel15->frequency_domain_assignment.val & ((1 << fsize) - 1)) << (dci_size - pos);
       // Time domain assignment 4bit
@@ -2756,23 +2756,21 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
 }
 
 
-void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
+int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
                                 nr_dci_format_t dci_format,
                                 uint8_t *pdsch_to_harq_feedback) {
 
   if (dci_format == NR_DL_DCI_FORMAT_1_0) {
-    for (int i=0; i<8; i++)
-      pdsch_to_harq_feedback[i] = i+1;
+    for (int i = 0; i < 8; i++)
+      pdsch_to_harq_feedback[i] = i + 1;
+    return 8;
   }
   else {
-    AssertFatal(pucch_Config!=NULL,"pucch_Config shouldn't be null here\n");
-    if(pucch_Config->dl_DataToUL_ACK != NULL) {
-      for (int i=0; i<8; i++) {
-        pdsch_to_harq_feedback[i] = *pucch_Config->dl_DataToUL_ACK->list.array[i];
-      }
+    AssertFatal(pucch_Config != NULL && pucch_Config->dl_DataToUL_ACK != NULL,"dl_DataToUL_ACK shouldn't be null here\n");
+    for (int i = 0; i < pucch_Config->dl_DataToUL_ACK->list.count; i++) {
+      pdsch_to_harq_feedback[i] = *pucch_Config->dl_DataToUL_ACK->list.array[i];
     }
-    else
-      AssertFatal(0==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n");
+    return pucch_Config->dl_DataToUL_ACK->list.count;
   }
 }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index a9386e6c2332ec26aebb44bb1cd6795196c79248..f2d4c7946d1da22d6fa4f5bbf630680a7cbee85a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -135,7 +135,7 @@ int get_pucch_index(int frame, int slot, int n_slots_frame, const NR_TDD_UL_DL_P
 {
   // PUCCH structures are indexed by slot in the PUCCH period determined by sched_pucch_size number of UL slots
   // this functions return the index to the structure for slot passed to the function
-  const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0;
+  const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
   const int n_ul_slots_period = tdd ? tdd->nrofUplinkSlots + (tdd->nrofUplinkSymbols > 0 ? 1 : 0) : n_slots_frame;
   const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
   const int n_ul_slots_frame = n_slots_frame / nr_slots_period * n_ul_slots_period;
@@ -1099,7 +1099,7 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
   const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   AssertFatal(tdd || mac->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n");
   const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame;
-  const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0;
+  const int first_ul_slot_period = tdd ? get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols) : 0;
 
   NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
   NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config;
@@ -1112,9 +1112,9 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
    dci_format = UE->current_DL_BWP.dci_format;
 
   uint8_t pdsch_to_harq_feedback[8];
-  get_pdsch_to_harq_feedback(pucch_Config, dci_format, pdsch_to_harq_feedback);
+  int fb_size = get_pdsch_to_harq_feedback(pucch_Config, dci_format, pdsch_to_harq_feedback);
 
-  for (int f=0; f<8; f++) {
+  for (int f = 0; f < fb_size; f++) {
     // can't schedule ACKNACK before minimum feedback time
     if(pdsch_to_harq_feedback[f] < minfbtime)
       continue;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index d6a9553c1075899ae5a8e6fb676178095452ed6d..0d25e160fa8f01173bceb3e7584f32564ec58531 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -47,7 +47,7 @@ const int get_ul_tda(gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *sc
 
   if (tdd && tdd->nrofUplinkSymbols > 1) { // if there is uplink symbols in mixed slot
     const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
-    if ((slot%nr_slots_period) == tdd->nrofDownlinkSlots)
+    if ((slot % nr_slots_period) == tdd->nrofDownlinkSlots)
       return 2;
   }
 
@@ -1305,8 +1305,7 @@ long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList,
     return 3;
 }
 
-static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
-			      int CC_id,  NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity)
+static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, int CC_id,  NR_UE_info_t* UE, frame_t frame, sub_frame_t slot, uint32_t ulsch_max_frame_inactivity)
 {
   const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
   const int now = frame * n + slot;
@@ -1317,10 +1316,9 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
       scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   int num_slots_per_period;
   int last_ul_slot;
-  int tdd_period_len[8] = {500,625,1000,1250,2000,2500,5000,10000};
   if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot)
-    num_slots_per_period = n*tdd_period_len[tdd->dl_UL_TransmissionPeriodicity]/10000;
-    last_ul_slot=1+tdd->nrofDownlinkSlots;
+    num_slots_per_period =  n / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity);
+    last_ul_slot = 1 + tdd->nrofDownlinkSlots;
   } else {
     num_slots_per_period = n;
     last_ul_slot = sched_ctrl->last_ul_slot;
@@ -1705,7 +1703,7 @@ void pf_ul(module_id_t module_id,
     curUE++;
   }
 
-  qsort(UE_sched, sizeof(*UE_sched), sizeofArray(UE_sched), comparator);
+  qsort(UE_sched, sizeofArray(UE_sched), sizeof(UEsched_t), comparator);
   UEsched_t *iterator=UE_sched;
 
   /* Loop UE_sched to find max coeff and allocate transmission */
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index 51b261ddf1abeffb3e0c74ccff1ced0b92d05586..fc569c4eee1d14432b36d6e82f3e743332fa793b 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -221,9 +221,9 @@ int nr_acknack_scheduling(gNB_MAC_INST *mac,
                           int r_pucch,
                           int do_common);
 
-void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
-                                nr_dci_format_t dci_format,
-                                uint8_t *pdsch_to_harq_feedback);
+int get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config,
+                               nr_dci_format_t dci_format,
+                               uint8_t *pdsch_to_harq_feedback);
   
 void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu,
                                   nr_scs_e scs_common,
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 31dbfefd5ea4ee11e9898e71c4262b04f5124d83..d841260475918ee1ca88f0498a0d749069771bef 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -758,8 +758,8 @@ static void add_rlc_srb(int rnti, struct NR_SRB_ToAddMod *s, NR_RLC_BearerConfig
     poll_byte = -1;
     max_retx_threshold = 8;
     sn_field_length = 12;
-    nr_rlc_am = new_nr_rlc_entity_am(10000000,
-                                     10000000,
+    nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
+                                     RLC_TX_MAXSIZE,
                                      deliver_sdu, ue,
                                      successful_delivery, ue,
                                      max_retx_reached, ue,
@@ -840,8 +840,8 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_
   if (ue->drb[drb_id-1] != NULL) {
     LOG_W(RLC, "%s:%d:%s: DRB %d already exists for UE with RNTI %04x, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
   } else {
-    nr_rlc_am = new_nr_rlc_entity_am(10000000,
-                                     10000000,
+    nr_rlc_am = new_nr_rlc_entity_am(RLC_RX_MAXSIZE,
+                                     RLC_TX_MAXSIZE,
                                      deliver_sdu, ue,
                                      successful_delivery, ue,
                                      max_retx_reached, ue,
@@ -912,8 +912,8 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_
   if (ue->drb[drb_id-1] != NULL) {
     LOG_W(RLC, "DEBUG add_drb_um %s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
   } else {
-    nr_rlc_um = new_nr_rlc_entity_um(100000000,
-                                     100000000,
+    nr_rlc_um = new_nr_rlc_entity_um(RLC_RX_MAXSIZE,
+                                     RLC_TX_MAXSIZE,
                                      deliver_sdu, ue,
                                      t_reassembly,
                                      sn_field_length);
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 28237903af473bbd2bb121cb7caaef420552fd5b..49305421af56a9a9b76e840e843f204dfa9305af 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -692,8 +692,7 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
 
     if (pthread_mutex_lock(&mac->mutex_dl_info)) abort();
 
-    if (dl_tti_request)
-    {
+    if (dl_tti_request) {
         frame = dl_tti_request->SFN;
         slot = dl_tti_request->Slot;
         LOG_D(NR_PHY, "[%d, %d] dl_tti_request\n", frame, slot);
@@ -705,40 +704,34 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
        incoming tx_data_request is also destined for the current UE. If the
        RAR hasn't been processed yet, we do not want to be filtering the
        tx_data_requests. */
-    if (tx_data_request)
-    {
+    if (tx_data_request) {
         if (mac->nr_ue_emul_l1.expected_sib ||
             mac->nr_ue_emul_l1.expected_rar ||
-            mac->nr_ue_emul_l1.expected_dci)
-        {
+            mac->nr_ue_emul_l1.expected_dci) {
             frame = tx_data_request->SFN;
             slot = tx_data_request->Slot;
             LOG_D(NR_PHY, "[%d, %d] PDSCH in tx_request\n", frame, slot);
             copy_tx_data_req_to_dl_info(&mac->dl_info, tx_data_request);
         }
-        else
-        {
+        else {
             LOG_D(NR_MAC, "Unexpected tx_data_req\n");
         }
         free_and_zero(tx_data_request);
     }
-    else if (ul_dci_request)
-    {
+    else if (ul_dci_request) {
         frame = ul_dci_request->SFN;
         slot = ul_dci_request->Slot;
         LOG_D(NR_PHY, "[%d, %d] ul_dci_request\n", frame, slot);
         copy_ul_dci_data_req_to_dl_info(&mac->dl_info, ul_dci_request);
         free_and_zero(ul_dci_request);
     }
-    else if (ul_tti_request)
-    {
+    else if (ul_tti_request) {
         frame = ul_tti_request->SFN;
         slot = ul_tti_request->Slot;
         LOG_T(NR_PHY, "[%d, %d] ul_tti_request\n", frame, slot);
         copy_ul_tti_data_req_to_dl_info(&mac->dl_info, ul_tti_request);
     }
-    else
-    {
+    else {
         if (pthread_mutex_unlock(&mac->mutex_dl_info)) abort();
         LOG_T(NR_MAC, "All indications were NULL in %s\n", __FUNCTION__);
         return;
@@ -762,15 +755,12 @@ void check_and_process_dci(nfapi_nr_dl_tti_request_t *dl_tti_request,
     ul_info.slot_rx = slot;
     ul_info.slot_tx = (slot + slot_ahead) % slots_per_frame;
     ul_info.frame_tx = (ul_info.slot_rx + slot_ahead >= slots_per_frame) ? ul_info.frame_rx + 1 : ul_info.frame_rx;
-    ul_info.ue_sched_mode = SCHED_PUSCH;
-    if (mac->scc || mac->scc_SIB)
-    {
+    if (mac->scc || mac->scc_SIB) {
         if (is_nr_UL_slot(mac->scc ?
                           mac->scc->tdd_UL_DL_ConfigurationCommon :
                           mac->scc_SIB->tdd_UL_DL_ConfigurationCommon,
                           ul_info.slot_tx,
-                          mac->frame_type) && mac->ra.ra_state != RA_SUCCEEDED)
-        {
+                          mac->frame_type) && mac->ra.ra_state != RA_SUCCEEDED) {
             nr_ue_scheduler(NULL, &ul_info);
             nr_ue_prach_scheduler(ul_info.module_id, ul_info.frame_tx, ul_info.slot_tx);
         }
@@ -1137,8 +1127,8 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
   NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
 
   NR_TDD_UL_DL_ConfigCommon_t *tdd_UL_DL_ConfigurationCommon = mac->scc != NULL ? mac->scc->tdd_UL_DL_ConfigurationCommon : mac->scc_SIB->tdd_UL_DL_ConfigurationCommon;
-  LOG_T(NR_MAC, "In %s():%d not calling scheduler. sched mode = %d and mac->ra.ra_state = %d\n",
-        __FUNCTION__, __LINE__, ul_info->ue_sched_mode, mac->ra.ra_state);
+  LOG_T(NR_MAC, "In %s():%d not calling scheduler mac->ra.ra_state = %d\n",
+        __FUNCTION__, __LINE__, mac->ra.ra_state);
 
   ret = nr_ue_scheduler(NULL, ul_info);
   if (is_nr_UL_slot(tdd_UL_DL_ConfigurationCommon, ul_info->slot_tx, mac->frame_type)) {
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
index 722b1be9ec580fbb4ab97589f1f4544ebd13b6af..e3adfe7d5344bf370d8c70eb06e214e098af173f 100755
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h
@@ -46,11 +46,6 @@ extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
 
 typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
 
-typedef enum {
-  SCHED_PUSCH,
-  SCHED_PUCCH,
-} NR_UE_SCHED_MODE_t;
-
 typedef struct {
     /// module id
   module_id_t module_id;
@@ -112,7 +107,6 @@ typedef struct {
     /// dci reception indication structure
     fapi_nr_dci_indication_t *dci_ind;
 
-    NR_UE_SCHED_MODE_t ue_sched_mode;
     void *phy_data;
 
 } nr_uplink_indication_t;
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index 4d1dfaf5aa46e7fec35a9d4cfa4de77166c3af32..f0fc2275ac431096878d6ae46ac5596247a555d4 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -917,11 +917,13 @@ typedef struct UE_RRC_INST_s {
 } UE_RRC_INST;
 
 typedef struct UE_PF_PO_s {
-  bool      enable_flag;  /* flag indicate whether current object is used */
+  bool enable_flag;  /* flag indicate whether current object is used */
   uint16_t ue_index_value;  /* UE index value */
   uint8_t PF_min;  /* minimal value of Paging Frame (PF) */
   uint8_t PO;  /* Paging Occasion (PO) */
   uint32_t T;  /* DRX cycle */
+  uint8_t PF_offset;
+  uint8_t i_s;
 } UE_PF_PO_t;
 
 #include "rrc_proto.h"
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index c52fe891eb2a62185c2af3fc000d243a4e024e14..831d60dad7244e14b5af20f7c4ac8389c246a155 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -74,6 +74,8 @@
 #include "NR_RRCReconfigurationComplete-IEs.h"
 #include "NR_DLInformationTransfer.h"
 #include "NR_RRCReestablishmentRequest.h"
+#include "NR_PCCH-Message.h"
+#include "NR_PagingRecord.h"
 #include "NR_UE-CapabilityRequestFilterNR.h"
 #include "common/utils/nr/nr_common.h"
 #if defined(NR_Rel16)
@@ -136,6 +138,7 @@
 #include "intertask_interface.h"
 
 #include "common/ran_context.h"
+#include "conversions.h"
 
 //#define XER_PRINT
 
@@ -223,16 +226,16 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) {
 
   AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n");
   int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
-  frequency_range_t frequency_range = band<100?FR1:FR2;
+  frequency_range_t frequency_range = band < 100 ? FR1 : FR2;
   int ssb_subcarrier_offset = 31; // default value for NSA
   if (get_softmodem_params()->sa) {
     uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
     int scs_scaling = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1;
-    ssb_subcarrier_offset = (absolute_diff/scs_scaling)%24;
+    ssb_subcarrier_offset = (absolute_diff/scs_scaling) % 24;
     if(frequency_range == FR2)
       ssb_subcarrier_offset >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for now)
   }
-  mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset&15;
+  mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset & 15;
 
   /*
   * The SIB1 will be sent in this allocation (Type0-PDCCH) : 38.213, 13-4 Table and 38.213 13-11 to 13-14 tables
@@ -739,7 +742,7 @@ void fill_initial_SpCellConfig(int uid,
 
   scheduling_request_config(scc, pucch_Config);
 
-  set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME);
+  set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing);
 
   SpCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->initialDownlinkBWP));
   NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP;
@@ -1193,8 +1196,7 @@ void fill_initial_cellGroupConfig(int uid,
   cellGroupConfig->mac_CellGroupConfig                                      = mac_CellGroupConfig;
 
   physicalCellGroupConfig                                                   = calloc(1,sizeof(*physicalCellGroupConfig));
-  physicalCellGroupConfig->p_NR_FR1                                         = calloc(1,sizeof(*physicalCellGroupConfig->p_NR_FR1));
-  *physicalCellGroupConfig->p_NR_FR1                                        = 10;
+  physicalCellGroupConfig->p_NR_FR1                                         = NULL;
   physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook                          = NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic;
   cellGroupConfig->physicalCellGroupConfig                                  = physicalCellGroupConfig;
   
@@ -2098,3 +2100,42 @@ NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf)
 
   return mc;
 }
+
+uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi) {
+  LOG_D(NR_RRC, "[gNB %d] do_NR_Paging start\n", Mod_id);
+  NR_PCCH_Message_t pcch_msg;
+  pcch_msg.message.present           = NR_PCCH_MessageType_PR_c1;
+  asn1cCalloc(pcch_msg.message.choice.c1, c1);
+  c1->present = NR_PCCH_MessageType__c1_PR_paging;
+  c1->choice.paging = CALLOC(1, sizeof(NR_Paging_t));
+  c1->choice.paging->pagingRecordList = CALLOC(
+      1, sizeof(*pcch_msg.message.choice.c1->choice.paging->pagingRecordList));
+  c1->choice.paging->nonCriticalExtension = NULL;
+  asn_set_empty(&c1->choice.paging->pagingRecordList->list);
+  c1->choice.paging->pagingRecordList->list.count = 0;
+
+  asn1cSequenceAdd(c1->choice.paging->pagingRecordList->list, NR_PagingRecord_t,
+                   paging_record_p);
+  /* convert ue_paging_identity_t to PagingUE_Identity_t */
+  paging_record_p->ue_Identity.present = NR_PagingUE_Identity_PR_ng_5G_S_TMSI;
+  // set ng_5G_S_TMSI
+  INT32_TO_BIT_STRING(tmsi, &paging_record_p->ue_Identity.choice.ng_5G_S_TMSI);
+
+  /* add to list */
+  LOG_D(NR_RRC, "[gNB %d] do_Paging paging_record: PagingRecordList.count %d\n",
+        Mod_id, c1->choice.paging->pagingRecordList->list.count);
+  asn_enc_rval_t enc_rval = uper_encode_to_buffer(
+      &asn_DEF_NR_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE);
+  ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NR_PCCH_Message, &pcch_msg);
+  if(enc_rval.encoded == -1) {
+    LOG_I(NR_RRC, "[gNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+          enc_rval.failed_type->name, enc_rval.encoded);
+    return -1;
+  }
+
+  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
+    xer_fprint(stdout, &asn_DEF_NR_PCCH_Message, (void *)&pcch_msg);
+  }
+
+  return((enc_rval.encoded+7)/8);
+}
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index 997adb2bd27d7fd1266fa692c598f9e6e86b11f4..241c2deb483bd08b38ec6b545ad6411728dd9d42 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -193,5 +193,6 @@ do_RRCReestablishmentComplete(
     int64_t rrc_TransactionIdentifier);
 
 NR_MeasConfig_t *get_defaultMeasConfig(const gNB_RrcConfigurationReq *conf);
+uint8_t do_NR_Paging(uint8_t Mod_id, uint8_t *buffer, uint32_t tmsi);
 
 #endif  /* __RRC_NR_MESSAGES_ASN1_MSG__H__ */
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index e0ffa29bf77f2759b268140d7312f93d716b4888..7476286d5f9ade279b5b644605e2ad3908a8ae3a 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -756,14 +756,18 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
   }
 }
 
-void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time) {
-
+void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time, NR_SubcarrierSpacing_t subcarrierSpacing)
+{
   pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK));
+  const int n_slots_frame = slotsperframe[subcarrierSpacing];
   long *delay[8];
-  for (int i=0;i<8;i++) {
-    delay[i] = calloc(1,sizeof(*delay[i]));
-    *delay[i] = i+min_feedback_time;
-    ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
+  for (int i = 0; i < 8; i++) {
+    int curr_delay = i + min_feedback_time;
+    if (curr_delay <= n_slots_frame) {
+      delay[i] = calloc(1,sizeof(*delay[i]));
+      *delay[i] = curr_delay;
+      ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]);
+    }
   }
 }
 
@@ -886,7 +890,7 @@ static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedul
   const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL;
   int sr_slot = 1; // in FDD SR in slot 1
   if(tdd)
-    sr_slot = tdd->nrofDownlinkSlots; // SR in the first uplink slot
+    sr_slot = get_first_ul_slot(tdd->nrofDownlinkSlots, tdd->nrofDownlinkSymbols, tdd->nrofUplinkSymbols);
 
   schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
 
@@ -1238,7 +1242,7 @@ void config_uplinkBWP(NR_BWP_Uplink_t *ubwp,
   config_pucch_resset1(pucch_Config, uecap);
   set_pucch_power_config(pucch_Config, configuration->do_CSIRS);
   scheduling_request_config(scc, pucch_Config);
-  set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME);
+  set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
 
   NR_PUSCH_Config_t *pusch_Config = NULL;
   if(servingcellconfigdedicated->uplinkConfig->uplinkBWP_ToAddModList &&
@@ -1286,7 +1290,7 @@ void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc, NR_CSI_Re
   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 = MAX_MOBILES_PER_GNB * 2 * n_slots_period / n_ul_slots_period; // 2 reports per UE
   AssertFatal(ideal_period < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n");
-  const int first_ul_slot_period = tdd ? tdd->nrofDownlinkSlots : 0;
+  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 offset = first_ul_slot_period + idx % n_ul_slots_period + (idx / n_ul_slots_period) * n_slots_period;
 
diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h
index 52dd065b7d2b80ca9179c3dd2f8d5332af97ea43..d100750eac9cc073621073bc17f7411eefe72c61 100644
--- a/openair2/RRC/NR/nr_rrc_config.h
+++ b/openair2/RRC/NR/nr_rrc_config.h
@@ -57,7 +57,7 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc
 void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay);
 void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, NR_UE_NR_Capability_t *uecap);
 void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, NR_UE_NR_Capability_t *uecap);
-void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time);
+void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time, NR_SubcarrierSpacing_t subcarrierSpacing);
 void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs);
 void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc,
                                NR_PUCCH_Config_t *pucch_Config);
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index e720a132d22db728d3fe3d7fa40a447154bdbb5c..b35387d1f9eb3350c457b791ae8f29c2313ab783 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -236,4 +236,10 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
                       uint8_t *const kUPenc,
                       uint8_t *const kUPint,
                       struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
+
+int rrc_gNB_generate_pcch_msg(uint32_t tmsi,
+                              uint8_t paging_drx,
+                              instance_t instance,
+                              uint8_t CC_id);
+
 #endif
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index c51c7a8d11cfc3ca426ca3c5b1e8c5523fc0392c..683f33ed85842fa8dacc45bf7db3b1e0d6f77e8a 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -4149,6 +4149,9 @@ void *rrc_gnb_task(void *args_p) {
       case E1AP_BEARER_CONTEXT_SETUP_RESP:
         LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_SETUP_RESP for instance %d\n", (int)instance);
         rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance);
+
+      case NGAP_PAGING_IND:
+        rrc_gNB_process_PAGING_IND(msg_p, msg_name_p, instance);
         break;
 
       default:
@@ -4349,6 +4352,130 @@ rrc_gNB_generate_RRCRelease(
     ue_context_pP->ue_context.ue_release_timer_rrc = 1;
   }
 }
+
+int rrc_gNB_generate_pcch_msg(uint32_t tmsi, uint8_t paging_drx, instance_t instance, uint8_t CC_id){
+  const unsigned int Ttab[4] = {32,64,128,256};
+  uint8_t Tc;
+  uint8_t Tue;
+  uint32_t pfoffset;
+  uint32_t N;  /* N: min(T,nB). total count of PF in one DRX cycle */
+  uint32_t Ns = 0;  /* Ns: max(1,nB/T) */
+  uint8_t i_s;  /* i_s = floor(UE_ID/N) mod Ns */
+  uint32_t T;  /* DRX cycle */
+  uint32_t length;
+  uint8_t buffer[RRC_BUF_SIZE];
+  struct NR_SIB1 *sib1 = RC.nrrrc[instance]->carrier.siblock1->message.choice.c1->choice.systemInformationBlockType1;
+
+  /* get default DRX cycle from configuration */
+  Tc = sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.defaultPagingCycle;
+
+  Tue = paging_drx;
+  /* set T = min(Tc,Tue) */
+  T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
+  /* set N = PCCH-Config->nAndPagingFrameOffset */
+  switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present) {
+    case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneT:
+      N = T;
+      pfoffset = 0;
+      break;
+    case NR_PCCH_Config__nAndPagingFrameOffset_PR_halfT:
+      N = T/2;
+      pfoffset = 1;
+      break;
+    case NR_PCCH_Config__nAndPagingFrameOffset_PR_quarterT:
+      N = T/4;
+      pfoffset = 3;
+      break;
+    case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneEighthT:
+      N = T/8;
+      pfoffset = 7;
+      break;
+    case NR_PCCH_Config__nAndPagingFrameOffset_PR_oneSixteenthT:
+      N = T/16;
+      pfoffset = 15;
+      break;
+    default:
+      LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg:  pfoffset error (pfoffset %d)\n",
+            instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.nAndPagingFrameOffset.present);
+      return (-1);
+
+  }
+
+  switch (sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns) {
+    case NR_PCCH_Config__ns_four:
+      if(*sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->pagingSearchSpace == 0){
+        LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg:  ns error only 1 or 2 is allowed when pagingSearchSpace is 0\n",
+              instance);
+        return (-1);
+      } else {
+        Ns = 4;
+      }
+      break;
+    case NR_PCCH_Config__ns_two:
+      Ns = 2;
+      break;
+    case NR_PCCH_Config__ns_one:
+      Ns = 1;
+      break;
+    default:
+      LOG_E(RRC, "[gNB %ld] In rrc_gNB_generate_pcch_msg: ns error (ns %ld)\n",
+            instance, sib1->servingCellConfigCommon->downlinkConfigCommon.pcch_Config.ns);
+      return (-1);
+  }
+
+  /* insert data to UE_PF_PO or update data in UE_PF_PO */
+  pthread_mutex_lock(&ue_pf_po_mutex);
+  uint8_t i = 0;
+
+  for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
+    if ((UE_PF_PO[CC_id][i].enable_flag == true && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(tmsi%1024))
+        || (UE_PF_PO[CC_id][i].enable_flag != true)) {
+      /* set T = min(Tc,Tue) */
+      UE_PF_PO[CC_id][i].T = T;
+      /* set UE_ID */
+      UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)(tmsi%1024);
+      /* calculate PF and PO */
+      /* set PF_min and PF_offset: (SFN + PF_offset) mod T = (T div N)*(UE_ID mod N) */
+      UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N);
+      UE_PF_PO[CC_id][i].PF_offset = pfoffset;
+      /* set i_s */
+      /* i_s = floor(UE_ID/N) mod Ns */
+      i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
+      UE_PF_PO[CC_id][i].i_s = i_s;
+
+      // TODO,set PO
+
+      if (UE_PF_PO[CC_id][i].enable_flag == true) {
+        //paging exist UE log
+        LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Update exist UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value,
+              T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset);
+      } else {
+        /* set enable_flag */
+        UE_PF_PO[CC_id][i].enable_flag = true;
+        //paging new UE log
+        LOG_D(NR_RRC,"[gNB %ld] CC_id %d In rrc_gNB_generate_pcch_msg: Insert a new UE %d, T %d, N %d, PF %d, i_s %d, PF_offset %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value,
+              T, N, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].i_s, UE_PF_PO[CC_id][i].PF_offset);
+      }
+      break;
+    }
+  }
+
+  pthread_mutex_unlock(&ue_pf_po_mutex);
+
+  /* Create message for PDCP (DLInformationTransfer_t) */
+  length = do_NR_Paging (instance,
+                         buffer,
+                         tmsi);
+
+  if (length == -1) {
+    LOG_I(NR_RRC, "do_Paging error\n");
+    return -1;
+  }
+  // TODO, send message to pdcp
+
+  return 0;
+}
+
 void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe)
 {
   MessageDef *message_p;
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index 8c263afbd6693a7b75c42f19e0d40171380f9e5d..98f76932fad241c109686d0b46a9561828ba272c 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -1706,3 +1706,37 @@ void nr_rrc_rx_tx(void) {
 
 }
 
+/*------------------------------------------------------------------------------*/
+int rrc_gNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance) {
+
+  for (uint16_t tai_size = 0; tai_size < NGAP_PAGING_IND(msg_p).tai_size; tai_size++) {
+    LOG_I(NR_RRC,"[gNB %ld] In NGAP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc,
+          NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, NGAP_PAGING_IND(msg_p).tac[tai_size]);
+
+    for (uint8_t j = 0; j < RC.nrrrc[instance]->configuration.num_plmn; j++) {
+      if (RC.nrrrc[instance]->configuration.mcc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc
+          && RC.nrrrc[instance]->configuration.mnc[j] == NGAP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
+          && RC.nrrrc[instance]->configuration.tac == NGAP_PAGING_IND(msg_p).tac[tai_size]) {
+        for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+          if (NODE_IS_CU(RC.nrrrc[instance]->node_type)) {
+            MessageDef *m = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_PAGING_IND);
+            F1AP_PAGING_IND (m).mcc              = RC.nrrrc[j]->configuration.mcc[0];
+            F1AP_PAGING_IND (m).mnc              = RC.nrrrc[j]->configuration.mnc[0];
+            F1AP_PAGING_IND (m).mnc_digit_length = RC.nrrrc[j]->configuration.mnc_digit_length[0];
+            F1AP_PAGING_IND (m).nr_cellid        = RC.nrrrc[j]->nr_cellid;
+            F1AP_PAGING_IND (m).ueidentityindexvalue = (uint16_t)(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi%1024);
+            F1AP_PAGING_IND (m).fiveg_s_tmsi = NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi;
+            F1AP_PAGING_IND (m).paging_drx = NGAP_PAGING_IND(msg_p).paging_drx;
+            LOG_E(F1AP, "ueidentityindexvalue %u fiveg_s_tmsi %ld paging_drx %u\n", F1AP_PAGING_IND (m).ueidentityindexvalue, F1AP_PAGING_IND (m).fiveg_s_tmsi, F1AP_PAGING_IND (m).paging_drx);
+            itti_send_msg_to_task(TASK_CU_F1, instance, m);
+          } else {
+            rrc_gNB_generate_pcch_msg(NGAP_PAGING_IND(msg_p).ue_paging_identity.s_tmsi.m_tmsi,(uint8_t)NGAP_PAGING_IND(msg_p).paging_drx, instance, CC_id);
+          } // end of nodetype check
+        } // end of cc loop
+      } // end of mcc mnc check
+    } // end of num_plmn
+  } // end of tai size
+
+  return 0;
+}
+
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.h b/openair2/RRC/NR/rrc_gNB_NGAP.h
index 548c51c7f65cb825cad410cfffd14deb874e236c..6c8a861f03ec50a32099d880ac8fc3b0e3efd441 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.h
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.h
@@ -195,4 +195,11 @@ rrc_gNB_get_ue_context_from_ngap_ids(
     const uint16_t    ue_initial_idP,
     const uint32_t    gNB_ue_ngap_idP
 );
+
+int
+rrc_gNB_process_PAGING_IND(
+    MessageDef *msg_p,
+    const char *msg_name,
+    instance_t instance);
+
 #endif
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 0e5a199dd60986177b2e750f619df410fa6483f8..159144b406e34c38b93b25b35fd66fe957fbb2ec 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -139,8 +139,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
   secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig));
   secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH=NULL;
   secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUSCH=NULL;
-  secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1=calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1));
-  *secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1=20;
+  secondaryCellGroup->physicalCellGroupConfig->p_NR_FR1 = NULL;
   secondaryCellGroup->physicalCellGroupConfig->pdsch_HARQ_ACK_Codebook=NR_PhysicalCellGroupConfig__pdsch_HARQ_ACK_Codebook_dynamic;
   secondaryCellGroup->physicalCellGroupConfig->tpc_SRS_RNTI=NULL;
   secondaryCellGroup->physicalCellGroupConfig->tpc_PUCCH_RNTI=NULL;
diff --git a/openair2/UTIL/MATH/random.c b/openair2/UTIL/MATH/random.c
deleted file mode 100644
index 30a6e9b1abba957f3257b924c67bb789bbe8c35a..0000000000000000000000000000000000000000
--- a/openair2/UTIL/MATH/random.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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
- */
-
-/*
-                                 random.c
-                             -------------------
-  AUTHOR  : Lionel GAUTHIER
-  COMPANY : EURECOM
-  EMAIL   : Lionel.Gauthier@eurecom.fr
- ***************************************************************************/
-#include "rtos_header.h"
-#include "platform_types.h"
-
-#include <sys/time.h>
-
-
-/* Random generators */
-#define FACTOR       16807
-#define LASTXN       127773
-#define UPTOMOD     -2836
-
-static int      seed;
-
-
-void
-init_uniform (void)
-{
-  struct timeval  tv;
-  struct timezone tz;
-
-  gettimeofday (&tv, &tz);
-  seed = (int) tv.tv_usec;
-#ifdef NODE_MT
-#warning TO DO seed = mobileId
-  //seed += mobileId;
-#endif
-#ifdef NODE_RG
-#warning TO DO seed = rgId
-  //seed += rgId;
-#endif
-}
-
-
-int
-uniform (void)
-{
-  static int      times, rest, prod1, prod2;
-
-  times = seed / LASTXN;
-  rest = seed - times * LASTXN;
-  prod1 = times * UPTOMOD;
-  prod2 = rest * FACTOR;
-  seed = prod1 + prod2;
-
-  return seed;
-}
diff --git a/openair2/UTIL/OSA/osa_defs.h b/openair2/UTIL/OSA/osa_defs.h
index e845315922ceaafe585c1a04adfb2bdb8bd84a60..84cdf4aac3125af770ccbf501d026a2c476abba1 100644
--- a/openair2/UTIL/OSA/osa_defs.h
+++ b/openair2/UTIL/OSA/osa_defs.h
@@ -61,6 +61,8 @@ int derive_key(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
 int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
                const uint8_t key[32], uint8_t **out);
 
+int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star);
+
 //#define derive_key_nas_enc(aLGiD, kEY, kNAS)    derive_key(NAS_ENC_ALG, aLGiD, kEY, kNAS)
 
 //#define derive_key_nas_int(aLGiD, kEY, kNAS)    derive_key(NAS_INT_ALG, aLGiD, kEY, kNAS)
diff --git a/openair2/UTIL/OSA/osa_internal.h b/openair2/UTIL/OSA/osa_internal.h
index f4a70c7e95415cef89c805cdaf6de7bc81ee0dfd..d66a42947289c50fc7c2a7efdd470a8c21548ee6 100644
--- a/openair2/UTIL/OSA/osa_internal.h
+++ b/openair2/UTIL/OSA/osa_internal.h
@@ -37,6 +37,7 @@
 #define FC_KASME_TO_CK  (0x16)
 
 #define NR_FC_ALG_KEY_DER  (0x69)
+#define NR_FC_ALG_KEY_NG_RAN_STAR_DER  (0x70)
 
 #ifndef hton_int32
 # define hton_int32(x)   \
diff --git a/openair2/UTIL/OSA/osa_key_deriver.c b/openair2/UTIL/OSA/osa_key_deriver.c
index c02b99949066f301b0291fac20235728c4d8230b..a685eec729709aff75350263631a9469f29c418f 100644
--- a/openair2/UTIL/OSA/osa_key_deriver.c
+++ b/openair2/UTIL/OSA/osa_key_deriver.c
@@ -127,40 +127,38 @@ int nr_derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
   return 0;
 }
 
-/*
-int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
+int nr_derive_key_ng_ran_star(uint16_t pci, uint64_t nr_arfcn_dl, const uint8_t key[32], uint8_t *key_ng_ran_star)
 {
-    uint8_t string[7];
+  uint8_t *out;
+  uint8_t s[10];
 
-    // FC
-    string[0] = FC_KENB;
-    // P0 = Uplink NAS count
-    string[1] = (nas_count & 0xff000000) >> 24;
-    string[2] = (nas_count & 0x00ff0000) >> 16;
-    string[3] = (nas_count & 0x0000ff00) >> 8;
-    string[4] = (nas_count & 0x000000ff);
+  /* FC */
+  s[0] = NR_FC_ALG_KEY_NG_RAN_STAR_DER;
 
-    // Length of NAS count
-    string[5] = 0x00;
-    string[6] = 0x04;
+  /* P0 = PCI */
+  s[1] = (pci & 0x0000ff00) >> 8;
+  s[2] = (pci & 0x000000ff);
 
-#if defined(SECU_DEBUG)
-    {
-        int i;
-        char payload[6 * sizeof(string) + 1];
-        int  index = 0;
-
-        for (i = 0; i < sizeof(string); i++)
-            index += sprintf(&payload[index], "0x%02x ", string[i]);
-        LOG_D(OSA, "KeNB deriver input string: %s\n", payload);
-    }
-#endif
+  /* L0 = length(P0) = 2 */
+  s[3] = 0x00;
+  s[4] = 0x02;
+
+  /* P1 = NR ARFCN */
+  s[5] = (nr_arfcn_dl & 0x00ff0000) >> 16;
+  s[6] = (nr_arfcn_dl & 0x0000ff00) >> 8;
+  s[7] = (nr_arfcn_dl & 0x000000ff);
+
+  /* L1 = length(P1) = 3 */
+  s[8] = 0x00;
+  s[9] = 0x03;
 
-    kdf(string, 7, key, 32, keNB, 32);
+  kdf(s, 10, key, 32, &out, 32);
 
-    return 0;
+  memcpy(key_ng_ran_star, out, 32);
+  free(out);
+
+  return 0;
 }
-*/
 
 int derive_skgNB(const uint8_t *keNB, const uint16_t sk_counter, uint8_t *skgNB)
 {
diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h
index ad53c6f27d8243b247092f2ac54c5b1ec61079e3..6e961781f0fda11274f8cd144904e055fe3960bd 100644
--- a/openair3/UTILS/conversions.h
+++ b/openair3/UTILS/conversions.h
@@ -544,6 +544,27 @@ do {                                                    \
     (bITsTRING)->bits_unused = 4;                       \
 } while(0)
 
+#define UEIDENTITYINDEX_TO_BIT_STRING(mACRO, bITsTRING)          \
+do {                                                    \
+    (bITsTRING)->buf = calloc(2, sizeof(uint8_t));      \
+    (bITsTRING)->buf[0] = (mACRO) >> 2;                 \
+    (bITsTRING)->buf[1] = ((mACRO) & 0x03)<<6;            \
+    (bITsTRING)->size = 2;                              \
+    (bITsTRING)->bits_unused = 6;                       \
+} while(0)
+
+#define FIVEG_S_TMSI_TO_BIT_STRING(mACRO, bITsTRING)      \
+do {                                                    \
+    (bITsTRING)->buf = calloc(6, sizeof(uint8_t));      \
+    (bITsTRING)->buf[0] = ((mACRO) >> 40) & 0xff;       \
+    (bITsTRING)->buf[1] = ((mACRO) >> 32) & 0xff;       \
+    (bITsTRING)->buf[2] = ((mACRO) >> 24) & 0xff;       \
+    (bITsTRING)->buf[3] = ((mACRO) >> 16) & 0xff;       \
+    (bITsTRING)->buf[4] = ((mACRO) >> 8 ) & 0xff;       \
+    (bITsTRING)->buf[5] = ((mACRO) & 0xff);             \
+    (bITsTRING)->size = 6;                              \
+    (bITsTRING)->bits_unused = 0;                       \
+} while(0)
 
 /* Used to format an uint32_t containing an ipv4 address */
 #define IPV4_ADDR    "%u.%u.%u.%u"
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index dd781a225e0188eb53667bce3f672e5e38d78e5d..84307ee39a52a58e1eccafbd9278f81b31087a83 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -19,7 +19,7 @@ extern "C" {
 #include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h>
 #include <openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h>
 #include "openair2/SDAP/nr_sdap/nr_sdap.h"
-//#include <openair1/PHY/phy_extern.h>
+#include "sim.h"
 
 #pragma pack(1)
 
@@ -143,6 +143,12 @@ class gtpEndPoints {
   // the instance id will be the Linux socket handler, as this is uniq
   map<uint64_t, gtpEndPoint> instances;
 
+  gtpEndPoints() {
+    unsigned int seed;
+    fill_random(&seed, sizeof(seed));
+    srandom(seed);
+  }
+
   ~gtpEndPoints() {
     // automatically close all sockets on quit
     for (const auto &p : instances)
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
index ca9f853b6995b83c6d380394620708f1d441d30b..c4b4774e48cba676c904d05b33b642402d1d090c 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
@@ -154,64 +154,6 @@ gNBs =
 
   );
 
-# Dedicated Serving Cell Configuration
-servingCellConfigDedicated = ({
-  # BWP-Downlink
-    # BWP 1 Configuration
-      dl_bwp-Id_1 = 1;
-      dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp1_subcarrierSpacing = 1;
-
-    # BWP 2 Configuration
-      dl_bwp-Id_2 = 2;
-      dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp2_subcarrierSpacing = 1;
-
-    # BWP 3 Configuration
-      dl_bwp-Id_3 = 3;
-      dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp3_subcarrierSpacing = 1;
-
-    firstActiveDownlinkBWP-Id = 1;  #BWP-Id
-    defaultDownlinkBWP-Id     = 1;  #BWP-Id
-
-    # bwp-InactivityTimer                 ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30,
-    #                                                ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500,
-    #                                                ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8,
-    #                                                spare7, spare6, spare5, spare4, spare3, spare2, spare1 }
-
-  # UplinkConfig
-    # BWP-Uplink
-      # BWP 1 Configuration
-        ul_bwp-Id_1 = 1;
-        ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp1_subcarrierSpacing = 1;
-
-      # BWP 2 Configuration
-        ul_bwp-Id_2 = 2;
-        ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp2_subcarrierSpacing = 1;
-
-      # BWP 3 Configuration
-        ul_bwp-Id_3 = 3;
-        ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp3_subcarrierSpacing = 1;
-
-      firstActiveUplinkBWP-Id = 1;  #BWP-Id
-  }
-);
 
     # ------- SCTP definitions
     SCTP :
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf
index f73a060b0191054e6529c633b0fe87feff4385a8..7e67d417d1c876ddf50f95a8d2e345571db8489b 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band77.fr1.273PRB.2x2.usrpn300.conf
@@ -49,8 +49,7 @@ gNBs = (
 
       # initialDownlinkBWP
         # genericParameters
-        # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
-        initialDLBWPlocationAndBandwidth                = 31624;
+        initialDLBWPlocationAndBandwidth                = 1099;
         # subcarrierSpacing
         # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialDLBWPsubcarrierSpacing                   = 1;
@@ -72,7 +71,7 @@ gNBs = (
 
       # initialUplinkBWP
         # genericParameters
-        initialULBWPlocationAndBandwidth                = 31624;
+        initialULBWPlocationAndBandwidth                = 1099;
         # subcarrierSpacing
         # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                   = 1;
@@ -157,40 +156,6 @@ gNBs = (
   );
 
 
-  # Dedicated Serving Cell Configuration
-  servingCellConfigDedicated = (
-  {
-    # BWP-Downlink
-      # BWP 1 Configuration
-      dl_bwp-Id_1 = 1;
-      dl_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp1_subcarrierSpacing = 1;
-
-    firstActiveDownlinkBWP-Id = 1;  #BWP-Id
-    defaultDownlinkBWP-Id     = 1;  #BWP-Id
-
-    # bwp-InactivityTimer                 ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30,
-    #                                                ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500,
-    #                                                ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8,
-    #                                                spare7, spare6, spare5, spare4, spare3, spare2, spare1 }
-
-    # UplinkConfig
-      # BWP-Uplink
-        # BWP 1 Configuration
-        ul_bwp-Id_1 = 1;
-        ul_bwp1_locationAndBandwidth = 1099; // RBstart=0, L=273 (100 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp1_subcarrierSpacing = 1;
-
-      firstActiveUplinkBWP-Id = 1;  #BWP-Id
-  }
-  );
-
-
-
   # ------- SCTP definitions
   SCTP :
   {
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
index 8bc681c67dc283418a95d39ddb59aec70bbfb0ce..4d3b120ab1f1d3a8ae01685d9562980b1608196b 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
@@ -158,65 +158,6 @@ gNBs =
 
   );
 
-# Dedicated Serving Cell Configuration
-servingCellConfigDedicated = ({
-  # BWP-Downlink
-    # BWP 1 Configuration
-      dl_bwp-Id_1 = 1;
-      dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp1_subcarrierSpacing = 1;
-
-    # BWP 2 Configuration
-      dl_bwp-Id_2 = 2;
-      dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp2_subcarrierSpacing = 1;
-
-    # BWP 3 Configuration
-      dl_bwp-Id_3 = 3;
-      dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp3_subcarrierSpacing = 1;
-
-    firstActiveDownlinkBWP-Id = 1;  #BWP-Id
-    defaultDownlinkBWP-Id     = 1;  #BWP-Id
-
-    # bwp-InactivityTimer                 ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30,
-    #                                                ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500,
-    #                                                ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8,
-    #                                                spare7, spare6, spare5, spare4, spare3, spare2, spare1 }
-
-  # UplinkConfig
-    # BWP-Uplink
-      # BWP 1 Configuration
-        ul_bwp-Id_1 = 1;
-        ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp1_subcarrierSpacing = 1;
-
-      # BWP 2 Configuration
-        ul_bwp-Id_2 = 2;
-        ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp2_subcarrierSpacing = 1;
-
-      # BWP 3 Configuration
-        ul_bwp-Id_3 = 3;
-        ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp3_subcarrierSpacing = 1;
-
-      firstActiveUplinkBWP-Id = 1;  #BWP-Id
-  }
-);
-
     # ------- SCTP definitions
     SCTP :
     {
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf
index 513c167a690a535176b9a4d09d80ae21d5ad168e..785d06dde08ba067f36a61f309c3cfe1dc6a64d1 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf
@@ -50,8 +50,7 @@ gNBs =
         dl_carrierBandwidth                                         = 217;
      #initialDownlinkBWP
       #genericParameters
-       # this is RBstart=0,L=162 (275*(275-L+1))+(274-RBstart))
-       initialDLBWPlocationAndBandwidth                             = 31624;
+       initialDLBWPlocationAndBandwidth                             = 16499;
        #
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
@@ -72,7 +71,7 @@ gNBs =
       pMax                                                          = 20;
      #initialUplinkBWP
       #genericParameters
-        initialULBWPlocationAndBandwidth                            = 31624;
+        initialULBWPlocationAndBandwidth                            = 16499;
 # subcarrierSpacing
 # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
         initialULBWPsubcarrierSpacing                               = 1;
@@ -159,39 +158,6 @@ gNBs =
   );
 
 
-# Dedicated Serving Cell Configuration
-servingCellConfigDedicated = ({
-  # BWP-Downlink
-    # BWP 1 Configuration
-      dl_bwp-Id_1 = 1;
-      dl_bwp1_locationAndBandwidth = 16499; // RBstart=0, L=217 (80 MHz BW)
-      # subcarrierSpacing
-      # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-      dl_bwp1_subcarrierSpacing = 1;
-
-    firstActiveDownlinkBWP-Id = 1;  #BWP-Id
-    defaultDownlinkBWP-Id     = 1;  #BWP-Id
-
-    # bwp-InactivityTimer                 ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30,
-    #                                                ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500,
-    #                                                ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8,
-    #                                                spare7, spare6, spare5, spare4, spare3, spare2, spare1 }
-
-  # UplinkConfig
-    # BWP-Uplink
-      # BWP 1 Configuration
-        ul_bwp-Id_1 = 1;
-        ul_bwp1_locationAndBandwidth = 16499; // RBstart=0, L=217 (80 MHz BW)
-        # subcarrierSpacing
-        # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
-        ul_bwp1_subcarrierSpacing = 1;
-
-      firstActiveUplinkBWP-Id = 1;  #BWP-Id
-  }
-);
-
-
-
     # ------- SCTP definitions
     SCTP :
     {