diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index b84ffd38a0a18f6729e9299e9ea8d0bd590f017f..76f2a485eab0ec00e54371ed1870537cec32ab60 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1605,7 +1605,7 @@ add_library(PHY_MEX ${PHY_MEX_UE} ${CONFIG_LIB})
 #Layer 2 library
 #####################
 set(MAC_DIR ${OPENAIR2_DIR}/LAYER2/MAC)
-set(NR_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
+set(NR_GNB_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
 set(NR_UE_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_UE)
 set(PHY_INTERFACE_DIR ${OPENAIR2_DIR}/PHY_INTERFACE)
 set(NR_PHY_INTERFACE_DIR ${OPENAIR2_DIR}/NR_PHY_INTERFACE)
@@ -1757,14 +1757,17 @@ set (MAC_SRC
 
 set (MAC_NR_SRC
   ${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c
-  ${NR_MAC_DIR}/main.c
-  ${NR_MAC_DIR}/config.c
-  ${NR_MAC_DIR}/gNB_scheduler.c
-  ${NR_MAC_DIR}/gNB_scheduler_bch.c
-  ${NR_MAC_DIR}/gNB_scheduler_dlsch.c
-  ${NR_MAC_DIR}/gNB_scheduler_ulsch.c
-  ${NR_MAC_DIR}/gNB_scheduler_primitives.c
-  ${NR_MAC_DIR}/gNB_scheduler_phytest.c
+  ${NR_GNB_MAC_DIR}/main.c
+  ${NR_GNB_MAC_DIR}/config.c
+  ${NR_GNB_MAC_DIR}/gNB_scheduler.c
+  ${NR_GNB_MAC_DIR}/gNB_scheduler_bch.c
+  ${NR_GNB_MAC_DIR}/gNB_scheduler_dlsch.c
+  ${NR_GNB_MAC_DIR}/gNB_scheduler_ulsch.c
+  ${NR_GNB_MAC_DIR}/gNB_scheduler_primitives.c
+  ${NR_GNB_MAC_DIR}/gNB_scheduler_phytest.c
+  ${NR_GNB_MAC_DIR}/gNB_scheduler_RA.c
+  ${NR_UE_MAC_DIR}/nr_l1_helpers.c
+  ${NR_UE_MAC_DIR}/nr_ra_procedures.c
  )
 
 
@@ -1776,7 +1779,6 @@ set (MAC_SRC_UE
   ${MAC_DIR}/l1_helpers.c
   ${MAC_DIR}/rar_tools_ue.c
   ${MAC_DIR}/config_ue.c
-  
  )
  
 set (MAC_NR_SRC_UE
@@ -1786,6 +1788,9 @@ set (MAC_NR_SRC_UE
   ${NR_UE_MAC_DIR}/main_ue_nr.c
   ${NR_UE_MAC_DIR}/nr_ue_procedures.c
   ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
+  ${NR_UE_MAC_DIR}/nr_l1_helpers.c
+  ${NR_UE_MAC_DIR}/nr_ra_procedures.c
+  ${NR_UE_MAC_DIR}/rar_tools_nrUE.c
 )
 
 set (ENB_APP_SRC
@@ -1849,7 +1854,7 @@ add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
 add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c)
 
 include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
-include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
+include_directories("${OPENAIR2_DIR}/LAYER2")
 include_directories("${OPENAIR1_DIR}/SCHED_NR_UE")
 #include_directories("${NFAPI_USER_DIR}"")
 
@@ -2636,9 +2641,9 @@ add_executable(nr-uesoftmodem
 target_link_libraries (nr-uesoftmodem
   -Wl,--start-group
   RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
+  PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
+  NFAPI_USER_LIB S1AP_LIB S1AP_ENB
   ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES} 
-  PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON S1AP_LIB S1AP_ENB
-  NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
   -Wl,--end-group z dl)
 
 target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES})
diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c
index 0302697e5b7d70350128368ae8b30b3ee6349f94..dedee9b651a46641eb5953ff91bc78e8314d6915 100644
--- a/executables/nr-gnb.c
+++ b/executables/nr-gnb.c
@@ -63,7 +63,7 @@
 
 
 #include "LAYER2/MAC/mac.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 #include "LAYER2/MAC/mac_proto.h"
 #include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface.h"
diff --git a/executables/nr-ru.c b/executables/nr-ru.c
index 42d7a2a48a094e85a4de018e97519504be900043..1e6ae12e0957a4d5e64414d57d7546141576c99b 100644
--- a/executables/nr-ru.c
+++ b/executables/nr-ru.c
@@ -72,7 +72,7 @@
 #include "SCHED_NR/sched_nr.h"
 
 #include "LAYER2/MAC/mac.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 #include "LAYER2/MAC/mac_proto.h"
 #include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface.h"
diff --git a/executables/nr-ue.c b/executables/nr-ue.c
index d8eda68d05fd15d08fa8c50e814a28addcbd0595..bbdcd0c29c62928a6187862e86f1771f8ad8b9b1 100644
--- a/executables/nr-ue.c
+++ b/executables/nr-ue.c
@@ -21,7 +21,7 @@
 #include "executables/thread-common.h"
 #include "executables/nr-uesoftmodem.h"
 
-#include "LAYER2/NR_MAC_UE/mac.h"
+#include "NR_MAC_UE/mac.h"
 //#include "RRC/LTE/rrc_extern.h"
 #include "PHY_INTERFACE/phy_interface_extern.h"
 
@@ -32,7 +32,7 @@
 #include "PHY/phy_extern_nr_ue.h"
 #include "PHY/INIT/phy_init.h"
 #include "PHY/MODULATION/modulation_UE.h"
-#include "LAYER2/NR_MAC_UE/mac_proto.h"
+#include "NR_MAC_UE/mac_proto.h"
 #include "RRC/NR_UE/rrc_proto.h"
 
 //#ifndef NO_RAT_NR
diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c
index fb0f18f2f50134bc2978e1e83617fdb019da7d08..e2f32529a174c34f3dc8c17d13122ae933f72a38 100644
--- a/executables/nr-uesoftmodem.c
+++ b/executables/nr-uesoftmodem.c
@@ -72,8 +72,8 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "PHY/INIT/phy_init.h"
 #include "system.h"
 #include <openair2/RRC/NR_UE/rrc_proto.h>
-#include <openair2/LAYER2/NR_MAC_UE/mac_defs.h>
-#include <openair2/LAYER2/NR_MAC_UE/mac_proto.h>
+#include "NR_MAC_UE/mac_defs.h"
+#include "NR_MAC_UE/mac_proto.h"
 #include <openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h>
 #include <openair1/SCHED_NR_UE/fapi_nr_ue_l1.h>
 
diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h
index 891b97514c2bc51e51c0369e6df1916b0eee576b..3438f31373f193117ee53f5dac00773577a78a3a 100644
--- a/executables/nr-uesoftmodem.h
+++ b/executables/nr-uesoftmodem.h
@@ -4,7 +4,7 @@
 #include <executables/softmodem-common.h>
 #include "PHY/defs_nr_UE.h"
 #include "SIMULATION/ETH_TRANSPORT/proto.h"
-#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
+#include "NR_MAC_gNB/mac_proto.h"
 
 /***************************************************************************************************************************************/
 /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
index cbcd26c3e352ba2c9679dbbf4c2f55319577a3ab..4b0720078a8b3d399db718ffb9111f238f0c02ab 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h
@@ -18,6 +18,7 @@
 #define FAPI_NR_RX_PDU_TYPE_SIB 0x02 
 #define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03 
 #define FAPI_NR_DCI_IND 0x04
+#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
 
 #define FAPI_NR_SIBS_MASK_SIB1 0x1
 
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index df9747104a196f1b0b6829c5e78ce3334cf2030e..3c93442c8d691430240c7318bb54943e8db96e4a 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -38,7 +38,6 @@
 #include "PHY/NR_TRANSPORT/nr_ulsch.h"
 #include "PHY/NR_REFSIG/nr_refsig.h"
 #include "SCHED_NR/fapi_nr_l1.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
 #include "nfapi_nr_interface.h"
 
 /*
diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
index e1b80a87a2f16e0d279997e3d512c4caa92366db..82ad498c2a62a64a49118bf074b0c40c83869796 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c
@@ -110,23 +110,25 @@ void nr_fill_du(uint8_t prach_fmt)
 int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) {
 
   uint8_t prach_ConfigIndex  = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
-  /*
+
   // For FR1 paired
-  if (((frame%table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][3]) &&
-  ((table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][4]&(1<<subframe)) == 1)) {
-  // using table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
-  return(1);
-  } else {
-  return(0);
-  }
-  */
+  if (frame_parms->frame_type == FDD && frame_parms->freq_range == nr_FR1){
+    if (((frame%table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][3]) &&
+    ((table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][4]&(1<<subframe)) == 1)) {
+    // using table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
+    return 1;
+    } else {
+    return 0;
+    }
+  } else if (frame_parms->frame_type == TDD && frame_parms->freq_range == nr_FR1) {
   // For FR1 unpaired
-  if (((frame%table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][3]) &&
-      ((table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]&(1<<subframe)) == 1)) {
-    // using table 6.3.3.2-2: Random access configurations for FR1 and unpaired
-    return(1);
-  } else {
-    return(0);
+    if (((frame%table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][3]) &&
+        ((table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]&(1<<subframe)) == 1)) {
+      // using table 6.3.3.2-2: Random access configurations for FR1 and unpaired
+      return 1;
+    } else {
+      return 0;
+    }
   }
   /*
   // For FR2: FIXME
diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
index 68b9e44d63b21af50aa36dceae69a02b116d05db..af06f9a98f3d69eea929221af3aac45852b4575b 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h
@@ -90,6 +90,6 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
                         uint32_t rx_power_fil_dB,
                         uint8_t eNB_id);
 
-int16_t nr_get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index);
 
 #endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
index a98820b69cb4c6d940f8252b9756da8b06b90024..1e46cde82eec1ef2019fc519995a99cb6d0f7c8d 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c
@@ -41,9 +41,6 @@
 
 #include "T.h"
 
-
-
-
 extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
 extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
 extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
@@ -59,13 +56,6 @@ extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
 extern uint16_t nr_du[838];
 extern int16_t nr_ru[2*839];
 
-
-
-
-
-
-
-
 int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf )
 {
 
diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h
index aaee08a554bf9fe27c8ce5742531f3d4c29e1bd6..4877b93007ccc6a10f1be9e07f7a303daeb1b8f8 100644
--- a/openair1/PHY/TOOLS/nr_phy_scope.h
+++ b/openair1/PHY/TOOLS/nr_phy_scope.h
@@ -26,7 +26,7 @@
 #include <simple_executable.h>
 #include <common/utils/system.h>
 #include <openairinterface5g_limits.h>
-#include <openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
+#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
 #include "common/ran_context.h"
 #include <openair1/PHY/defs_gNB.h>
 #include <forms.h>
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index 1ad0c7529e28129617409a9a9494c4ade586ea60..e88bfd77689d55ad5e085d4610d7a98cb74ebf3e 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -930,7 +930,7 @@ typedef struct {
   uint8_t               pucch_sel[10];
   uint8_t               pucch_payload[22];
 
-  UE_MODE_t        UE_mode[NUMBER_OF_CONNECTED_eNB_MAX];
+  UE_MODE_t           UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
   /// cell-specific reference symbols
   uint32_t lte_gold_table[7][20][2][14];
 
@@ -967,10 +967,10 @@ typedef struct {
 
 
 
-  unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX];
-  uint32_t  ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX];
-  unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX];
-  PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX];
+  unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_gNB_MAX];
+  uint32_t  ulsch_Msg3_frame[NUMBER_OF_CONNECTED_gNB_MAX];
+  unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_gNB_MAX];
+  NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX];
   int turbo_iterations, turbo_cntl_iterations;
   /// \brief ?.
   /// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 487b28473ffc497c96a9cfd35a47902444333e2d..5241f5736d53a71751752d873c271f9df6cc5749 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -223,6 +223,29 @@ typedef struct {
   NR_PRACH_CONFIG_INFO prach_ConfigInfo;
 } NR_PRACH_CONFIG_COMMON;
 
+typedef struct {
+  /// Preamble index for PRACH (0-63)
+  uint8_t ra_PreambleIndex;
+  /// RACH MaskIndex
+  uint8_t ra_RACH_MaskIndex;
+  /// Target received power at eNB (-120 ... -82 dBm)
+  uint32_t ra_PREAMBLE_RECEIVED_TARGET_POWER;
+  /// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex
+  uint8_t ra_TDD_map_index;
+  /// RA Preamble Power Ramping Step in dB
+  uint32_t RA_PREAMBLE_POWER_RAMPING_STEP;
+  ///
+  uint8_t RA_PREAMBLE_BACKOFF;
+  ///
+  uint8_t RA_SCALING_FACTOR_BI;
+  ///
+  uint8_t RA_PCMAX;
+  /// Corresponding RA-RNTI for UL-grant
+  uint16_t ra_RNTI;
+  /// Pointer to Msg3 payload for UL-grant
+  uint8_t *Msg3;
+} NR_PRACH_RESOURCES_t;
+
 typedef struct NR_DL_FRAME_PARMS {
   /// frequency range
   nr_frequency_range_e freq_range;
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index e34ce2b6debc06071e09fc363ce3ea274160c45b..c6aea2ec08d317645a51d379d86a5494acbf0d8c 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -218,6 +218,15 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
  */
 void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
 
+/*! \brief UE PRACH procedures.
+    @param
+    @param
+    @param
+ */
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode);
+
+int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t subframe);
+
 #if 0
 /*! \brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69.
   @param frame_parms Pointer to DL frame parameter descriptor
@@ -322,13 +331,14 @@ uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *phy_vars_ue,
                          uint8_t SR);
 
 #endif
+
 /*! \brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC.
   @param Mod_id Local UE index on which to act
   @param CC_id Component Carrier Index
-  @param eNB_index ID of eNB
+  @param gNB_index ID of gNB
   @returns UE mode
 */
-UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
+UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
 
 /*! \brief This function implements the power control mechanism for PUCCH from 36.213.
     @param phy_vars_ue PHY variables
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index c6a830a8da9f1ec365a4a49cfe528a45b05e9cf9..7dbb68cf3183dac930e16ac9df0a381854e95cea 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -58,7 +58,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
     NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
     NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
     //NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
-    PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
+    NR_PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
         
     //        PUCCH_ConfigCommon_nr_t    *pucch_config_common = PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
     //        PUCCH_Config_t             *pucch_config_dedicated = PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index e8e3ac66eefddcb927ef53f847cecd3b7a267e90..5a292661fde14021abbcc348ec6ae938487b04ec 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -66,6 +66,7 @@
 #endif
 
 #include "LAYER2/NR_MAC_UE/mac_defs.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
 #include "common/utils/LOG/log.h"
 
 #ifdef EMOS
@@ -308,51 +309,6 @@ void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
   write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
 }
 
-void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
-  // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
-  // for more flexibility
-
-  uint8_t i,j,k,s;
-  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-
-  //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
-  for(int l=0; l<RX_NB_TH; l++) {
-    for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
-      for(j=0; j<2; j++) {
-	//DL HARQ
-	if(ue->dlsch[l][i][j]) {
-	  for(k=0; k<NR_MAX_DLSCH_HARQ_PROCESSES && ue->dlsch[l][i][j]->harq_processes[k]; k++) {
-	    ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE;
-	    for (s=0; s<10; s++) {
-	      // reset ACK/NACK bit to DTX for all nr_tti_rxs s = 0..9
-	      ue->dlsch[l][i][j]->harq_ack[s].ack = 2;
-	      ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0;
-	      ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff;
-	      ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff;
-	    }
-	  }
-	}
-      }
-
-      //UL HARQ
-      if(ue->ulsch[i]) {
-	for(k=0; k<NR_MAX_ULSCH_HARQ_PROCESSES && ue->ulsch[i]->harq_processes[k]; k++) {
-	  ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE;
-	  //Set NDIs for all UL HARQs to 0
-	  //  ue->ulsch[i]->harq_processes[k]->Ndi = 0;
-
-	}
-      }
-
-      // flush Msg3 buffer
-      ue->ulsch_Msg3_active[i] = 0;
-
-    }
-  }
-}
-
 void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 {
 
@@ -388,25 +344,6 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
   }
 
 
-}
-
-UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
-{
-
-  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
-
-}
-void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance) {
-
-  ue->timing_advance = timing_advance*4;
-
-
-#ifdef DEBUG_PHY_PROC
-  /* TODO: fix this log, what is 'HW timing advance'? */
-  /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx_rx, ue->timing_advance);*/
-  LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
-#endif
-
 }
 
 uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
@@ -1399,6 +1336,9 @@ void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_
 
 #endif
 
+UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){ // TBR generate enum for NR
+  return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]);
+}
 
 void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
 
@@ -1421,7 +1361,23 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_com
   LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %u\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
 }
 
+void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance) {
+
+/* TODO TBR FIX THIS 
+
+ue->timing_advance = timing_advance*4;
+
+#ifdef DEBUG_PHY_PROC
+  // TODO: fix this log, what is 'HW timing advance'?
+  //LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx_rx, ue->timing_advance);
+  LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
+#endif
+  */
+
+}
+
 #if 0
+
 void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,
 								UE_nr_rxtx_proc_t *proc,
 								uint8_t eNB_id,
@@ -2329,11 +2285,12 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_
 void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
                             UE_nr_rxtx_proc_t *proc,
                             uint8_t gNB_id,
-                            uint8_t thread_id)
-{
+                            uint8_t thread_id){
   //int32_t ulsch_start=0;
   int slot_tx = proc->nr_tti_tx;
   int frame_tx = proc->frame_tx;
+  uint8_t harq_pid = 0; // TBR 
+  runmode_t mode = normal_txrx; // TBR set proper mode
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
 
@@ -2343,15 +2300,12 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
   start_meas(&ue->phy_proc_tx);
 #endif
 
-  uint8_t harq_pid = 0; //temporary implementation
-
   nr_ue_ulsch_procedures(ue,
                          harq_pid,
                          slot_tx,
                          thread_id,
                          gNB_id);
 
-
 /*
   if (ue->UE_mode[eNB_id] == PUSCH) {
     // check if we need to use PUCCH 1a/1b
@@ -2361,7 +2315,6 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
   } // UE_mode==PUSCH
 */
 
-
   nr_ue_pusch_common_procedures(ue,
                                 harq_pid,
                                 slot_tx,
@@ -2369,23 +2322,20 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
                                 gNB_id,
                                 &ue->frame_parms);
 
-  //LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1);
-
-/*
-  if ((ue->UE_mode[eNB_id] == PRACH) &&
-      (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
+  /* RACH */
+  if ((ue->UE_mode[gNB_id] == PRACH) && (ue->frame_parms.prach_config_common.prach_Config_enabled == 1)) {
 
     // check if we have PRACH opportunity
-
-    if (is_prach_subframe(&ue->frame_parms,frame_tx,nr_tti_tx)) {
-
-      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
+    if (is_nr_prach_subframe(&ue->frame_parms, frame_tx, slot_tx)) {
+      // TBR TODO FIX this works only for TDD but it enters phy_procedures_nrUE_TX only when mode is FDD
+      printf("the value of is_nr_prach subframe is %d\n", is_nr_prach_subframe(&ue->frame_parms, frame_tx, slot_tx)); // TBR debug
+      nr_ue_prach_procedures(ue, proc, gNB_id, mode);
     }
-  } // mode is PRACH
+  }
   else {
-    ue->generate_prach=0;
+    ue->generate_nr_prach = 0;
   }
-*/
+/* RACH */
 
   LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
 
@@ -2396,139 +2346,6 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
 
 }
 
-
-void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
-
-  int frame_tx = proc->frame_tx;
-  int nr_tti_tx = proc->nr_tti_tx;
-  int prach_power;
-  uint16_t preamble_tx=ue->prach_resources[0]->ra_PreambleIndex;
-  PRACH_RESOURCES_t prach_resources;
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
-
-  ue->generate_nr_prach=0;
- if (ue->mac_enabled==0){
-    ue->prach_resources[eNB_id] = &prach_resources;
- ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
-  ue->prach_resources[eNB_id]->ra_TDD_map_index = 0;
-  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
-  ue->prach_resources[eNB_id]->ra_RNTI = 93;
- }
-
-  if (ue->mac_enabled==1){
-
-    // ask L2 for RACH transport
-    if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
-      LOG_D(PHY,"Getting PRACH resources\n");
-      //ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,ue->CC_id,frame_tx,eNB_id,nr_tti_tx);   
-   // LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);  
-   // LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
-  }
-}
-
-if (ue->prach_resources[eNB_id]!=NULL) {
-
-  ue->generate_nr_prach=1;
-  ue->prach_cnt=0;
-#ifdef SMBV
-ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
-#endif
-
-#ifdef OAI_EMU
-  ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
-#endif
-
-  if (abstraction_flag == 0) {
-
-    LOG_I(PHY,"mode %d\n",mode);
-
-    if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
-
-      ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id);
-    }
-    else {
-      ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
-      ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx; 
-    }
-
-   LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d,  P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
-	  ue->Mod_id,
-	  frame_tx,
-	  nr_tti_tx,
-	  ue->prach_resources[eNB_id]->ra_PreambleIndex,
-	  get_nr_PL(ue,eNB_id),
-	  ue->tx_power_dBm[nr_tti_tx],
-	  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
-	  ue->prach_resources[eNB_id]->ra_TDD_map_index,
-	  ue->prach_resources[eNB_id]->ra_RNTI);
-
-    ue->tx_total_RE[nr_tti_tx] = 96;
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
-    ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
-					     ue->tx_power_max_dBm,
-					     ue->frame_parms.N_RB_UL,
-					     6);
-#else
-   ue->prach_vars[eNB_id]->amp = AMP;
-#endif
-   if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
-      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
-	    ue->Mod_id,
-	    proc->frame_rx,
-	    proc->nr_tti_tx,
-	    ue->tx_power_dBm[nr_tti_tx],
-	    ue->prach_vars[eNB_id]->amp);
-
-
-   //       start_meas(&ue->tx_prach);
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
-
-//    prach_power = generate_nr_prach(ue,eNB_id,nr_tti_tx,frame_tx);
-prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
-    //      stop_meas(&ue->tx_prach);
-    LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
-	  ue->Mod_id,
-	  get_nr_PL(ue,eNB_id),
-	  ue->tx_power_dBm[nr_tti_tx],
-	  dB_fixed(prach_power),
-	  ue->prach_vars[eNB_id]->amp);
-  }/* else {
-    UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
-    UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
-  }*/ // commented for compiling as abstraction flag is 0
-
-  if (ue->mac_enabled==1){
-    //mac_xface->Msg1_transmitted(ue->Mod_id,ue->CC_id,frame_tx,eNB_id);
- }
-
-LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
-      ue->Mod_id,frame_tx,nr_tti_tx,eNB_id,
-      ue->prach_resources[eNB_id]->ra_PreambleIndex,
-      ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id),
-      get_nr_PL(ue,eNB_id));
-
-}
-
-
-// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
-if (mode == calib_prach_tx)
-  ue->prach_resources[eNB_id]=NULL;
-
-LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n",
-      ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt);
-
-ue->prach_cnt++;
-
-if (ue->prach_cnt==3)
-  ue->generate_nr_prach=0;
-
-VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
-}
-
 /*
 void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
 {
@@ -3349,19 +3166,17 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
     } // CRNTI active
   }
 }
-#if 0
-void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
 
+/*void nr_process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) { // TBR todo
   int frame_rx = proc->frame_rx;
   int nr_tti_rx = proc->nr_tti_rx;
   int timing_advance;
   NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
   int harq_pid = 0;
   uint8_t *rar;
-  /*
-  uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
-  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
-  */
+
+  // uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
+  // uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
 
   LOG_D(PHY,"[UE  %d][RAPROC] Frame %d nr_tti_rx %d Received RAR  mode %d\n",
 	ue->Mod_id,
@@ -3377,28 +3192,24 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
 	    nr_tti_rx,
 	    ue->prach_resources[eNB_id]->ra_PreambleIndex);
       
-      /*      timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
-	      ue->CC_id,
-	      frame_rx,
-	      ue->prach_resources[eNB_id]->ra_RNTI,
-	      dlsch0->harq_processes[0]->b,
-	      &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
-	      ue->prach_resources[eNB_id]->ra_PreambleIndex,
-	      dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
-      */
-      /*
-      ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
-      ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
-      */
+      // TBR restore
+      // timing_advance = nr_ue_process_rar(ue->Mod_id, ue->CC_id, frame_rx,
+	    // ue->prach_resources[eNB_id]->ra_RNTI, dlsch0->harq_processes[0]->b,
+	    // &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+	    // ue->prach_resources[eNB_id]->ra_PreambleIndex, dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
+      
+      // ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
+      // ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
 
       if (timing_advance!=0xffff) {
 
-	LOG_D(PHY,"[UE  %d][RAPROC] Frame %d nr_tti_rx %d Got rnti %x and timing advance %d from RAR\n",
-              ue->Mod_id,
-              frame_rx,
-              nr_tti_rx,
-              ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
-              timing_advance);
+  // TBR restore 
+  // LOG_D(PHY,"[UE  %d][RAPROC] Frame %d nr_tti_rx %d Got rnti %x and timing advance %d from RAR\n",
+  //             ue->Mod_id,
+  //             frame_rx,
+  //             nr_tti_rx,
+  //             ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
+  //             timing_advance);
 
 	// remember this c-rnti is still a tc-rnti
 
@@ -3409,11 +3220,12 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
 	      
 	if (mode!=debug_prach) {
 	  ue->ulsch_Msg3_active[eNB_id]=1;
-	  nr_get_Msg3_alloc(&ue->frame_parms,
-			    nr_tti_rx,
-			    frame_rx,
-			    &ue->ulsch_Msg3_frame[eNB_id],
-			    &ue->ulsch_Msg3_subframe[eNB_id]);
+    // TBR nr_get_Msg3_alloc has to be fixed
+	  // nr_get_Msg3_alloc(&ue->frame_parms,
+		// 	    nr_tti_rx,
+		// 	    frame_rx,
+		// 	    &ue->ulsch_Msg3_frame[eNB_id],
+		// 	    &ue->ulsch_Msg3_subframe[eNB_id]);
 	  
 	  LOG_D(PHY,"[UE  %d][RAPROC] Got Msg3_alloc Frame %d nr_tti_rx %d: Msg3_frame %d, Msg3_subframe %d\n",
 		ue->Mod_id,
@@ -3424,11 +3236,11 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
 	  harq_pid = nr_subframe2harq_pid(&ue->frame_parms,
 					  ue->ulsch_Msg3_frame[eNB_id],
 					  ue->ulsch_Msg3_subframe[eNB_id]);
-	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+	  //ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; // TODO TBR fix this when HARQ is ready
 	  
 	  ue->UE_mode[eNB_id] = RA_RESPONSE;
 	  //      ue->Msg3_timer[eNB_id] = 10;
-	  ue->ulsch[eNB_id]->power_offset = 6;
+	  //ue->ulsch[eNB_id]->power_offset = 6; // TODO TBR fix this
 	  ue->ulsch_no_allocation_counter[eNB_id] = 0;
 	}
       } else { // PRACH preamble doesn't match RAR
@@ -3443,9 +3255,7 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
     timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
     nr_process_timing_advance_rar(ue,proc,timing_advance);
   }
-
-}
-#endif
+}*/
 
 void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
        UE_nr_rxtx_proc_t *proc,
@@ -3540,13 +3350,13 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
     if (frame_rx < *dlsch_errors)
       *dlsch_errors=0;
 
-    if (pdsch==RA_PDSCH) {
+    if (pdsch == RA_PDSCH) {
       if (ue->prach_resources[eNB_id]!=NULL)
-	dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+	      dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
       else {
-	LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,nr_tti_rx);
-	//mac_xface->macphy_exit("prach_resources is NULL");
-	return;
+	      LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_tti_rx);
+	      //mac_xface->macphy_exit("prach_resources is NULL");
+	      return;
       }
     }
 
@@ -3734,7 +3544,15 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
       dl_indication.proc=proc;
 
       //dl_indication.rx_ind->number_pdus
-      rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
+      switch (pdsch) {
+        case RA_PDSCH:
+        rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_RAR;
+        break;
+        case PDSCH:
+        rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
+        break;
+      }
+
       rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
       rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
       LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
@@ -4367,11 +4185,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
     nr_ue_pdsch_procedures(ue,
-			   proc,
-			   eNB_id,
-			   SI_PDSCH,
-			   ue->dlsch_SI[eNB_id],
-			   NULL);
+                          proc,
+                          eNB_id,
+                          SI_PDSCH,
+                          ue->dlsch_SI[eNB_id],
+                          NULL);
     
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
   }
@@ -4380,11 +4198,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
     nr_ue_pdsch_procedures(ue,
-			   proc,
-			   eNB_id,
-			   P_PDSCH,
-			   ue->dlsch_p[eNB_id],
-			   NULL);
+                          proc,
+                          eNB_id,
+                          P_PDSCH,
+                          ue->dlsch_p[eNB_id],
+                          NULL);
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
   }
@@ -4393,13 +4211,37 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
   if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
     nr_ue_pdsch_procedures(ue,
-			   proc,
-			   eNB_id,
-			   RA_PDSCH,
-			   ue->dlsch_ra[eNB_id],
-			   NULL);
+                          proc,
+                          eNB_id,
+                          RA_PDSCH,
+                          ue->dlsch_ra[eNB_id],
+                          NULL);
+
+    // #if UE_TIMING_TRACE
+    //   start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+    // #endif
 
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
+    nr_ue_dlsch_procedures(ue,
+                           proc,
+                           eNB_id,
+                           RA_PDSCH,
+                           ue->dlsch_ra[eNB_id],
+                           NULL,
+                           &ue->dlsch_ra_errors[eNB_id],
+                           mode);
+
+     // #if UE_TIMING_TRACE
+     //   stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
+     #if DISABLE_LOG_X
+      printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
+      printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+     #else
+      LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+      LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
+     #endif
+     // #endif
+
+     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
   }
     
   // do procedures for C-RNTI
@@ -4639,3 +4481,134 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,
     return(0);
 }
 
+void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode) {
+  /* TBR
+  // here params are hardcoded */
+  int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power;
+  uint16_t preamble_tx=ue->prach_resources[0]->ra_PreambleIndex; //uint16_t preamble_tx=50; // TBR
+  NR_PRACH_RESOURCES_t prach_resources;
+  uint8_t mod_id = ue->Mod_id;
+  NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
+  UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id);
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
+
+  ue->generate_nr_prach = 0;
+ if (ue->mac_enabled == 0){
+   ue->prach_resources[gNB_id] = &prach_resources;  // TBR double check pointer
+   ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;
+   ue->prach_resources[gNB_id]->ra_TDD_map_index = 0;
+   // ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; // TBR
+   // ue->prach_resources[gNB_id]->ra_RNTI = 93; // TBR
+ } else {
+    // ask L2 for RACH transport
+    /* TBR
+    // check if these modes are active */
+    if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
+      LOG_D(PHY,"Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx);
+      ue->prach_resources[gNB_id] = nr_ue_get_rach(mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx);
+      // LOG_D(PHY,"Got prach_resources for gNB %d address %p, RRCCommon %p\n", gNB_id, ue->prach_resources[gNB_id], UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); // TBR update this
+    }
+  }
+
+  if (ue->prach_resources[gNB_id]!=NULL) {
+
+    ue->generate_nr_prach = 1;
+    ue->prach_cnt = 0;
+
+    #ifdef SMBV // TBR
+      ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;
+    #endif
+
+    #ifdef OAI_EMU // TBR
+      ue->prach_PreambleIndex=ue->prach_resources[gNB_id]->ra_PreambleIndex;
+    #endif
+
+  // if (abstraction_flag == 0) { // TBR
+
+    LOG_I(PHY,"mode %d\n",mode);
+
+      if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
+        /* TODO TBR
+        // check if ra_PREAMBLE_RECEIVED_TARGET_POWER is filled id */
+        ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER + get_nr_PL(ue,gNB_id);
+        /* TODO TBR
+        DEBUG ONLY */
+        printf("ue->tx_power_dBm[nr_tti_tx] %d ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER %d get_nr_PL(ue,gNB_id) %d\n", ue->tx_power_dBm[nr_tti_tx], ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, get_nr_PL(ue,gNB_id));
+      } else {
+        ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
+        ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;  /* TODO TBR this is hardcoded */
+      }
+
+      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", ue->Mod_id,
+        frame_tx,
+        nr_tti_tx,
+        ue->prach_resources[gNB_id]->ra_PreambleIndex,
+        get_nr_PL(ue,gNB_id),
+        ue->tx_power_dBm[nr_tti_tx],
+        ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
+        ue->prach_resources[gNB_id]->ra_TDD_map_index,
+        ue->prach_resources[gNB_id]->ra_RNTI);
+
+    ue->tx_total_RE[nr_tti_tx] = 96;  /* TODO TBR this is hardcoded */
+
+    #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
+    ue->prach_vars[gNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], /* TODO TBR get_tx_amp is still valid for NR ? */
+                                             ue->tx_power_max_dBm,
+                                             ue->frame_parms.N_RB_UL,
+                                             6);  /* TODO TBR why 6 ? */
+    #else
+      ue->prach_vars[gNB_id]->amp = AMP;  /* TODO TBR where does this come from ? */
+    #endif
+
+    if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) /* TODO TBR double check where calibration prach tx is handled */
+      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
+        ue->Mod_id,
+        proc->frame_rx,
+        proc->nr_tti_tx,
+        ue->tx_power_dBm[nr_tti_tx],
+        ue->prach_vars[gNB_id]->amp);
+
+    // start_meas(&ue->tx_prach);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
+
+    // prach_power = generate_nr_prach(ue,gNB_id,nr_tti_tx,frame_tx);
+    prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator /* TODO TBR this is hardcoded */
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
+    //      stop_meas(&ue->tx_prach);
+    LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
+      ue->Mod_id,
+      get_nr_PL(ue,gNB_id),
+      ue->tx_power_dBm[nr_tti_tx],
+      dB_fixed(prach_power),
+      ue->prach_vars[gNB_id]->amp);
+    // } else {
+    //  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
+    //  UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
+    // } // commented for compiling as abstraction flag is 0
+
+    if (ue->mac_enabled == 1)
+      // nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); TBR
+
+
+    LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
+      ue->Mod_id,frame_tx,nr_tti_tx,gNB_id,
+      ue->prach_resources[gNB_id]->ra_PreambleIndex,
+      ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,gNB_id),
+      get_nr_PL(ue,gNB_id));
+  }
+
+  // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
+  if (mode == calib_prach_tx)
+    ue->prach_resources[gNB_id]=NULL;
+
+  LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt);
+
+  ue->prach_cnt++;
+
+  if (ue->prach_cnt == 3)
+    ue->generate_nr_prach = 0;
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
+}
\ No newline at end of file
diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
index 326c617dfb5413cffabd52a6b957a2c9574f1aa7..eb2ce3598f2589eeddff6e96763884daf37db758 100644
--- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
+++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c
@@ -37,7 +37,7 @@
 #include "PHY/defs_nr_UE.h"
 #include <openair1/SCHED/sched_common.h>
 #include <openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h>
-#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
 
 #ifndef NO_RAT_NR
 
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 473c86bed02d530011a56a73b695d45da10f129f..cc3517215e7ab75a31a10a770198e157e1c4e957 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -28,11 +28,9 @@
 #include "common/ran_context.h"
 #include "common/config/config_userapi.h"
 #include "common/utils/LOG/log.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
-#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_extern.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
+#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
+#include "LAYER2/NR_MAC_UE/mac_defs.h"
+#include "LAYER2/NR_MAC_UE/mac_extern.h"
 #include "PHY/defs_gNB.h"
 #include "PHY/defs_nr_common.h"
 #include "PHY/defs_nr_UE.h"
@@ -55,7 +53,7 @@
 #include "LAYER2/NR_MAC_UE/mac_proto.h"
 //#include "LAYER2/NR_MAC_gNB/mac_proto.h"
 //#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
 #include "NR_asn_constant.h"
 #include "RRC/NR/MESSAGES/asn1_msg.h"
 #include "openair1/SIMULATION/RF/rf.h"
diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c
index 33c00e82f4786cab2d21153d7de0e67ef3f418de..fac5d599c8a46e2de03d84e908e0e9f572bd731d 100644
--- a/openair1/SIMULATION/NR_PHY/prachsim.c
+++ b/openair1/SIMULATION/NR_PHY/prachsim.c
@@ -114,7 +114,7 @@ int main(int argc, char **argv)
   uint8_t subframe=9;
   uint16_t preamble_energy, preamble_tx=50, preamble_delay;
   uint16_t preamble_max,preamble_energy_max;
-  PRACH_RESOURCES_t prach_resources;
+  NR_PRACH_RESOURCES_t prach_resources;
   //uint8_t prach_fmt;
   //int N_ZC;
   int delay = 0;
@@ -518,8 +518,7 @@ int main(int argc, char **argv)
 			     0); //Nf */ //commented for testing purpose
 
   UE_nr_rxtx_proc_t proc={0};
-  nr_ue_prach_procedures(UE,&proc,0,0,0);
-
+  nr_ue_prach_procedures(UE,&proc,0,0);
 
   /* tx_lev_dB not used later, no need to set */
   //tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 2c397090bae1493c0487b577fe0e3af65d2d4d18..e53e28860253a2bb4e2216b7dd3f41a3bb52f93f 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -52,8 +52,9 @@
 #include "openair1/SIMULATION/TOOLS/sim.h"
 #include "openair1/SIMULATION/RF/rf.h"
 #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
-#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
-#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
+#include "LAYER2/NR_MAC_gNB/mac_proto.h"
 
 //#define DEBUG_ULSIM
 
diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c
index 9845adbeaa59844ce2da1faeaab8a9c9ea432b8b..1c8657aec10b8c48d98ce3fc31fcce1a79c4fd5c 100644
--- a/openair2/GNB_APP/gnb_config.c
+++ b/openair2/GNB_APP/gnb_config.c
@@ -54,7 +54,8 @@
 #include "common/config/config_userapi.h"
 //#include "RRC_config_tools.h"
 #include "gnb_paramdef.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
+
 #include "NR_asn_constant.h"
 #include "executables/thread-common.h"
 #include "NR_SCS-SpecificCarrier.h"
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 8d497c80d36505c7fb87b5e2ccc840b360163580..433a490c195fa49e71bc2989e123dc463d7a7294 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -35,7 +35,7 @@
 #include "LAYER2/MAC/mac_extern.h"
 
 #include "LAYER2/MAC/mac_proto.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
 #include "common/utils/LOG/log.h"
 #include "nfapi/oai_integration/vendor_ext.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
index 7202f2e5203bfd6a3af5e21b80df0416e4ca2648..bbccb9f707728bc04ec866e9b54970509772a65a 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h
@@ -41,6 +41,10 @@
 
 #define NR_BCCH_BCH 5    // MIB
 
+#define CCCH_PAYLOAD_SIZE_MAX 128
+
+#define RAR_PAYLOAD_SIZE_MAX  128
+
 //  For both DL/UL-SCH
 //  Except:
 //   - UL/DL-SCH: fixed-size MAC CE(known by LCID)
@@ -66,6 +70,12 @@
 //  F: lenght of L is 0:8 or 1:16 bits wide
 //  R: Reserved bit, set to zero.
 
+typedef enum {
+  RA_IDLE = 0,
+  WAIT_RAR = 1,
+  WAIT_CONTENTION_RESOLUTION = 2
+} RA_state_t;
+
 typedef struct {
     uint8_t LCID:6;     // octet 1 [5:0]
     uint8_t F:1;        // octet 1 [6]
@@ -92,6 +102,31 @@ typedef struct {
     uint8_t TAGID:2;        // octet 1 [7:6]
 } __attribute__ ((__packed__)) NR_MAC_CE_TA;
 
+// /*! \brief CCCH payload */ // TBR
+// typedef struct {
+//     uint8_t payload[CCCH_PAYLOAD_SIZE_MAX];
+// } __attribute__ ((__packed__)) CCCH_PDU;
+// 
+// /*! \brief RAR payload */ // TBR
+// typedef struct {
+//     uint8_t payload[RAR_PAYLOAD_SIZE_MAX];
+// } __attribute__ ((__packed__)) RAR_PDU;
+
+/*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */
+typedef struct {
+    uint8_t RAPID:6;
+    uint8_t T:1;
+    uint8_t E:1;
+} __attribute__ ((__packed__)) NR_RA_HEADER_RAPID;
+
+/*!\brief MAC header of Random Access Response for backoff indicator (BI)*/
+typedef struct {
+    uint8_t BI:4;
+    uint8_t R:2;
+    uint8_t T:1;
+    uint8_t E:1;
+} __attribute__ ((__packed__)) NR_RA_HEADER_BI;
+
 //  38.321 ch6.2.1, 38.331
 #define DL_SCH_LCID_CCCH                           0x00
 #define DL_SCH_LCID_DCCH                           0x01
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
similarity index 98%
rename from openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h
rename to openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 6b043963b01816d9e710fa50522814bea7081fbc..1891bd0ee98287579a1ed3500b9054f79247de06 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -32,6 +32,8 @@
 #ifndef __LAYER2_NR_MAC_COMMON_H__
 #define __LAYER2_NR_MAC_COMMON_H__
 
+#include "NR_PDSCH-Config.h"
+
 uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
 
 uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
index 10df4567c41608f09c12820805872a27f630b595..4bc462f759ffc7b2a9de6ee5bd8e237ebfed3114 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h
@@ -19,12 +19,12 @@
  *      contact@openairinterface.org
  */
 
-/*! \file extern.h
+/*! \file nr_mac_extern.h
 * \brief NR mac externs
-* \author G. Casati
+* \author  Navid Nikaein, Raymond Knopp, Guido Casati
 * \date 2019
 * \version 1.0
-* \email guido.casati@iis.fraunhofer.de
+* \email navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
 * @ingroup _mac
 
 */
@@ -32,10 +32,11 @@
 #ifndef __NR_MAC_EXTERN_H__
 #define __NR_MAC_EXTERN_H__
 
-//#include "PHY/defs_common.h"
-#include "nr_mac.h"
-#include "RRC/LTE/rrc_defs.h"
+#include "RRC/LTE/rrc_defs.h" // TBR
 #include "common/ran_context.h"
+#include "nr_mac.h"
+
+/*#include "PHY/defs_common.h"*/
 
 /* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
 extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
@@ -43,8 +44,6 @@ extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
 extern const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
 extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
 extern UE_RRC_INST *UE_rrc_inst;
-extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB];	// eNBxUE = 8x8
-extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB];	// eNBxUE = 8x8
 extern int cqi_to_mcs[16];
 extern uint32_t RRC_CONNECTION_FLAG;
 extern uint8_t rb_table[34];
@@ -52,6 +51,9 @@ extern mac_rlc_am_muilist_t rlc_am_mui;
 extern SCHEDULER_MODES global_scheduler_mode;
 extern unsigned char NB_UE_INST;*/
 
+
+extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB];	// eNBxUE = 8x8
+extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB];	// eNBxUE = 8x8
 extern unsigned char NB_INST;
 extern unsigned char NB_eNB_INST;
 extern unsigned char NB_RN_INST;
@@ -61,8 +63,15 @@ extern unsigned short NODE_ID[1];
 extern RAN_CONTEXT_t RC;
 extern int phy_test;
 extern uint8_t nfapi_mode;
+extern mac_rlc_am_muilist_t rlc_am_mui;
+extern SCHEDULER_MODES global_scheduler_mode;
 
 /*#if defined(PRE_SCD_THREAD)
+extern int cqi_to_mcs[16];
+extern uint32_t RRC_CONNECTION_FLAG;
+extern uint8_t rb_table[34];
+
+#if defined(PRE_SCD_THREAD)
 extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX];
 extern uint8_t dlsch_ue_select_tbl_in_use;
 extern uint8_t new_dlsch_ue_select_tbl_in_use;
@@ -70,4 +79,5 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
 extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
 #endif*/
 
+
 #endif //DEF_H
diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c
index c98302303496300fc9921f44b30f21c76c279124..6250b53dd3032fe630a67d2c39aa0b6a2d965a3f 100755
--- a/openair2/LAYER2/NR_MAC_UE/config_ue.c
+++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c
@@ -31,11 +31,11 @@
  */
 
 //#include "mac_defs.h"
-#include "mac_proto.h"
+#include "NR_MAC_UE/mac_proto.h"
 
 #include "NR_MAC-CellGroupConfig.h"
 
-#include "../NR_MAC_gNB/nr_mac_common.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
 #include "SCHED_NR/phy_frame_config_nr.h"
 
 int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index 37d1b1216dc766e96a02e3b37143f069b9dd42f4..ef733020e00d26d09f5e17e4ae628af8ab6cee29 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -37,6 +37,20 @@
 #include <stdlib.h>
 #include <string.h>
 #include "platform_types.h"
+
+/* PHY */
+#include "PHY/defs_nr_common.h"
+
+/* IF */
+#include "NR_IF_Module.h"
+#include "fapi_nr_ue_interface.h"
+
+/* MAC */
+#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
+#include "LAYER2/MAC/mac.h" // TBR
+
+/* RRC */
 #include "NR_DRX-Config.h"
 #include "NR_SchedulingRequestConfig.h"
 #include "NR_BSR-Config.h"
@@ -48,12 +62,11 @@
 #include "NR_PhysicalCellGroupConfig.h"
 #include "NR_SpCellConfig.h"
 #include "NR_ServingCellConfig.h"
-#include "fapi_nr_ue_interface.h"
-#include "NR_IF_Module.h"
-#include "../NR_MAC_gNB/nr_mac_common.h"
-#include "PHY/defs_nr_common.h"
+
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 
 #define NB_NR_UE_MAC_INST 1
+#define MAX_NUM_BWP 2
 
 typedef enum {
     SFN_C_MOD_2_EQ_0, 
@@ -61,14 +74,6 @@ typedef enum {
     SFN_C_IMPOSSIBLE
 } SFN_C_TYPE;
 
-
-#define MAX_NUM_BWP 2
-
-typedef enum {
-  RA_IDLE=0,
-  WAIT_RAR=1,
-  WAIT_CONTENTION_RESOLUTION=2
-} RA_state_t;
 /*!\brief Top level UE MAC structure */
 typedef struct {
 
@@ -76,13 +81,13 @@ typedef struct {
   NR_ServingCellConfig_t          *scd;
   int                             servCellIndex;
   ////  MAC config
-  NR_DRX_Config_t    	          *drx_Config;
+  NR_DRX_Config_t                 *drx_Config;
   NR_SchedulingRequestConfig_t    *schedulingRequestConfig;
-  NR_BSR_Config_t    	          *bsr_Config;
-  NR_TAG_Config_t	          *tag_Config;
-  NR_PHR_Config_t	          *phr_Config;
-  NR_RNTI_Value_t 	          *cs_RNTI;
-  NR_MIB_t 	                  *mib;
+  NR_BSR_Config_t                 *bsr_Config;
+  NR_TAG_Config_t                 *tag_Config;
+  NR_PHR_Config_t                 *phr_Config;
+  NR_RNTI_Value_t                 *cs_RNTI;
+  NR_MIB_t                         *mib;
 
   NR_BWP_Downlink_t               *DLbwp[MAX_NUM_BWP];
   NR_BWP_Uplink_t                 *ULbwp[MAX_NUM_BWP];
@@ -95,15 +100,67 @@ typedef struct {
   SFN_C_TYPE type0_pdcch_ss_sfn_c;
   uint32_t type0_pdcch_ss_n_c;
   uint32_t type0_pdcch_consecutive_slots;
-  /// state of RA procedure
-  RA_state_t ra_state;
-  ///     RA-rnti
-  uint16_t ra_rnti;
 
-  ///     Temporary CRNTI
-  uint16_t t_crnti;
-  ///     CRNTI
-  uint16_t crnti;
+  /* PDUs */
+  /// Outgoing CCCH pdu for PHY
+  CCCH_PDU CCCH_pdu;
+
+  /* Random Access parameters */
+  /// state of RA procedure
+  RA_state_t ra_state; // TBR
+  /// RACH ConfigCommon
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
+  /// RA-rnti
+  uint16_t ra_rnti; // TBR
+  /// Temporary CRNTI
+  uint16_t t_crnti; // TBR
+  /// CRNTI
+  uint16_t crnti; // TBR
+  /// number of attempt for rach
+  uint8_t RA_attempt_number;
+  /// Random-access procedure flag
+  uint8_t RA_active;
+  /// Random-access window counter
+  int8_t RA_window_cnt;
+  /// Random-access Msg3 size in bytes
+  uint8_t RA_Msg3_size;
+  /// Random-access prachMaskIndex
+  uint8_t RA_prachMaskIndex;
+  /// Flag indicating Preamble set (A,B) used for first Msg3 transmission
+  uint8_t RA_usedGroupA;
+  /// Random-access Resources
+  NR_PRACH_RESOURCES_t RA_prach_resources;
+  /// BeamfailurerecoveryConfig
+  NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig;
+  /// Preamble Tx Counter
+  uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
+  /// Preamble Power Ramping Counter
+  uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER;
+  /// Random-access backoff counter
+  int16_t RA_backoff_cnt;
+  /// Random-access variable for window calculation (frame of last change in window counter)
+  uint32_t RA_tx_frame;
+  /// Random-access variable for window calculation (subframe of last change in window counter)
+  uint8_t RA_tx_subframe;
+  /// Random-access Group B maximum path-loss
+  /// Random-access variable for backoff (frame of last change in backoff counter)
+  uint32_t RA_backoff_frame;
+  /// Random-access variable for backoff (subframe of last change in backoff counter)
+  uint8_t RA_backoff_subframe;
+  /// Random-access Group B maximum path-loss
+  uint16_t RA_maxPL;
+  /// Random-access Contention Resolution Timer active flag
+  uint8_t RA_contention_resolution_timer_active;
+  /// Random-access Contention Resolution Timer count value
+  uint8_t RA_contention_resolution_cnt;
+  /// Msg3 Delta Preamble
+  int8_t deltaPreamble_Msg3;
+  /// Flag to monitor if matching RAPID was received in RAR
+  uint8_t RA_RAPID_found;
+  /// UE_Mode variable should be used in the case of Phy_stub operation since we won't have access to PHY_VARS_UE
+  /// where the UE_mode originally is for the full stack operation mode. The transitions between the states of the UE_Mode
+  /// will be triggered within phy_stub_ue.c in this case
+  UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
 
   ////	FAPI-like interface message
   fapi_nr_tx_request_t tx_request;
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 36d285e320e416c7f14d3f0694e01322d6ddc6c7..061b1fa3995600c22e0bf37ea40901dc90fe6f79 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -124,8 +124,6 @@ uint32_t get_ssb_slot(uint32_t ssb_index);
 
 uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
 
-
-
 /* \brief Get payload (MAC PDU) from UE PHY
 @param module_idP Instance id of UE in machine
 @param CC_id Component Carrier index
@@ -170,5 +168,39 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
                          int nrofDownlinkSlots, int nrofDownlinkSymbols,
                          int nrofUplinkSlots,   int nrofUplinkSymbols);
 
+/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
+    @param Mod_id Module id of UE
+    @returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
+*/
+int8_t nr_get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id);
+
+/** \brief Function to compute DELTA_PREAMBLE from 38.321 subclause 7.3
+   (for RA power ramping procedure and Msg3 PUSCH power control policy)
+    @param Mod_id Module id of UE
+    @returns DELTA_PREAMBLE
+*/
+int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id);
+
+/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
+@param Mod_id Index of UE instance
+@param CC_id Index to a component carrier
+@param frame Frame index
+@param ra_rnti RA_RNTI value
+@param dlsch_buffer  Pointer to dlsch_buffer containing RAR PDU
+@param t_crnti Pointer to PHY variable containing the T_CRNTI
+@param preamble_index Preamble Index used by PHY to transmit the PRACH.  This should match the received RAR to trigger the rest of
+random-access procedure
+@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload
+@returns timing advance or 0xffff if preamble doesn't match
+*/
+uint16_t nr_ue_process_rar(const module_id_t mod_id,
+                           const int CC_id,
+                           const frame_t frameP,
+                           const rnti_t ra_rnti,
+                           uint8_t * const dlsch_buffer,
+                           rnti_t * const t_crnti,
+                           const uint8_t preamble_index,
+                           uint8_t * selected_rar_buffer);
+
 #endif
 /** @}*/
diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
index be1e85236087a4a84e3827dcba529f345480fc52..c057f5ee022bf69e4d82fa5b94d2bd98c058188d 100644
--- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
+++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c
@@ -31,8 +31,8 @@
  */
 
 //#include "defs.h"
-#include "mac_proto.h"
 #include "executables/nr-softmodem.h"
+#include "NR_MAC_UE/mac_proto.h"
 
 static NR_UE_MAC_INST_t *nr_ue_mac_inst; 
 
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
new file mode 100644
index 0000000000000000000000000000000000000000..85c8cf893522b1084afe7ee8ba84b610c2f18b15
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c
@@ -0,0 +1,155 @@
+/*
+ * 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 nr_l1_helper.c
+* \brief PHY helper function adapted to NR
+* \author Guido Casati
+* \date 2019
+* \version 1.0
+* \email guido.casati@iis.fraunhofer.de
+* @ingroup _mac
+
+*/
+
+#include "PHY/defs_common.h" // TBR
+#include "PHY/defs_nr_common.h"
+
+#include "mac_defs.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+
+/* 38.321 subclause 7.3 - return values are in dB */
+int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){
+
+    NR_UE_MAC_INST_t *nrUE_mac_inst = get_mac_inst(mod_id);
+    NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nrUE_mac_inst->nr_rach_ConfigCommon;
+
+    AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+
+    NR_SubcarrierSpacing_t scs = nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
+    uint8_t preambleFormat, prachConfigIndex;
+    lte_frame_type_t frame_type = TDD; // TODO TBR retrieve frame type. Currently hardcoded to TDD.
+                                       // was nr_UE_mac_inst[mod_id].tdd_Config 
+    nr_frequency_range_e fr = nr_FR1;  // TODO TBR retrieve frame type. Currently hardcoded to FR1.
+    int mu; 
+
+    switch (scs){
+      case NR_SubcarrierSpacing_kHz15:
+      mu = 0;
+      break;
+
+      case NR_SubcarrierSpacing_kHz30:
+      mu = 1;
+      break;
+
+      case NR_SubcarrierSpacing_kHz60:
+      mu = 2;
+      break;
+
+      case NR_SubcarrierSpacing_kHz120:
+      mu = 3;
+      break;
+
+      case NR_SubcarrierSpacing_kHz240:
+      mu = 4;
+      break;
+
+      case NR_SubcarrierSpacing_spare3:
+      mu = 5;
+      break;
+
+      case NR_SubcarrierSpacing_spare2:
+      mu = 6;
+      break;
+
+      case NR_SubcarrierSpacing_spare1:
+      mu = 7;
+      break;
+
+      default:
+      AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %d\n", scs);
+    }
+
+    prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
+    preambleFormat = get_nr_prach_fmt(prachConfigIndex,frame_type,fr);
+
+    switch (preambleFormat) {
+      // long preamble formats
+      case 0:
+      case 3:
+      return  0;
+
+      case 1:           
+      return -3;
+
+      case 2:
+      return -6;
+
+      // short preamble formats
+      case 0xa1:
+      case 0xb1:
+      return 8 + 3*mu;
+
+      case 0xa2:
+      case 0xb2:
+      case 0xc2:
+      return 5 + 3*mu;
+
+      case 0xa3:
+      case 0xb3:
+      return 3 + 3*mu;
+
+      case 0xb4:      
+      return 3*mu;
+
+      case 0xc0:
+      return 5 + 3*mu;
+
+      default:
+      AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, preambleFormat, prachConfigIndex);
+    }
+    return;
+}
+
+int8_t nr_get_Po_NOMINAL_PUSCH(module_id_t mod_id, uint8_t CC_id){
+  
+  NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
+  NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
+
+  //AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+  AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id);
+
+  int8_t receivedTargerPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower + nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
+
+  return receivedTargerPower;
+  //return (-120 + (nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower << 1) + nr_get_DELTA_PREAMBLE(mod_id, CC_id) );
+}
+
+/*int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id){ // TBR
+
+    AssertFatal(CC_id == 0,
+		"Transmission on secondary CCs is not supported yet\n");
+
+    LOG_D(MAC, "[PUSCH]%d dB\n",
+	  nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1);
+    return ((int8_t)
+	    (nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1));
+}*/
\ No newline at end of file
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
new file mode 100644
index 0000000000000000000000000000000000000000..501f96b7717f0db69ed4e6140a6839fb248aede4
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -0,0 +1,726 @@
+/*
+ * 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 ra_procedures.c
+ * \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15)
+ * \author R. Knopp, Navid Nikaein, Guido Casati
+ * \date 2019
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
+ * \note
+ * \warning
+ */
+
+#include "mac.h"
+// TBR missing NR_nr_UE_mac_inst in mac.h
+
+/*
+#include "common/utils/LOG/vcd_signal_dumper.h"
+#include "PHY_INTERFACE/phy_interface_extern.h"
+#include "SCHED_UE/sched_UE.h"
+#include "COMMON/mac_rrc_primitives.h"
+#include "RRC/LTE/rrc_extern.h"
+#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
+#include "common/utils/LOG/log.h"
+#include "UTIL/OPT/opt.h"
+#include "OCG.h"
+#include "OCG_extern.h"
+#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/
+
+/* Tools */
+#include "SIMULATION/TOOLS/sim.h"	// for taus
+
+/* RRC */
+#include "NR_RACH-ConfigCommon.h"
+
+/* PHY */
+#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
+#include "PHY/defs_common.h"
+#include "PHY/defs_nr_common.h"
+
+/* MAC */
+#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
+
+extern UE_MODE_t get_nrUE_mode(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id);
+
+extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
+extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
+
+//extern uint8_t  nfapi_mode; // TBR
+
+// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
+// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
+void nr_get_prach_resources(module_id_t mod_id,
+                            int CC_id,
+                            uint8_t gNB_id,
+                            uint8_t t_id,
+                            uint8_t first_Msg3,
+                            NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
+
+  NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
+  NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
+  NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &nr_UE_mac_inst->RA_BeamFailureRecoveryConfig;
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
+
+  int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, frequencyStart, i, deltaPreamble_Msg3;
+  uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size;
+  NR_RSRP_Range_t rsrp_ThresholdSSB;
+
+  /* TBR retrieve following params
+  // currently hardcoded */
+  prach_resources->ra_PreambleIndex = 51;
+
+  /*uint8_t Msg3_size = nr_UE_mac_inst->RA_Msg3_size;
+  uint8_t f_id = 0, num_prach = 0;*/
+
+  /*AssertFatal(CC_id == 0,
+  "Transmission on secondary CCs is not supported yet\n");
+  AssertFatal(nr_UE_mac_inst->nr_rach_ConfigCommon != NULL,
+  "[UE %d] FATAL  nr_rach_ConfigCommon is NULL !!!\n",
+  mod_id);*/
+
+  ///////////////////////////////////////////////////////////
+  //////////* UE Random Access Resource Selection *//////////
+  ///////////////////////////////////////////////////////////
+
+  //numberOfRA_Preambles = (1 + nr_rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2;
+  numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles;
+  rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; 
+  nr_UE_mac_inst->nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
+
+  /* TBR switch initialisation cases
+  - RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
+    - SSB selection, set prach_resources->ra_PreambleIndex
+  - RA initiated by PDCCH: ra_PreambleIndex provided by PDCCH && ra_PreambleIndex != 0b000000 
+    - set REAMBLE_INDEX to ra_PreambleIndex
+    - select the SSB signalled by PDCCH
+  - RA initiated for SI request:
+    - SSB selection, set prach_resources->ra_PreambleIndex */
+
+  // if (rach_ConfigDedicated) {	// This is for network controlled Mobility
+  //   // TBR operation for contention-free RA resources when:
+  //   // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
+  //   // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
+  //   prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
+  //   return;
+  // }
+
+  /* Contention-based RA preamble selection:
+   - TBR selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB */
+  if (!nr_rach_ConfigCommon->groupBconfigured) {
+    noGroupB = 1;
+  } else {
+    /* RA preambles group B is configured 
+    // - Defining the number of RA preambles in RA Preamble Group A for each SSB */
+    //sizeOfRA_PreamblesGroupA = (nr_rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2;
+    sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
+    switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
+    /* - Threshold to determine the groups of RA preambles */
+    case 0:
+    messageSizeGroupA = 56;
+    break;
+    case 1:
+    messageSizeGroupA = 144;
+    break;
+    case 2:
+    messageSizeGroupA = 208;
+    break;
+    case 3:
+    messageSizeGroupA = 256;
+    break;
+    case 4:
+    messageSizeGroupA = 282;
+    break;
+    case 5:
+    messageSizeGroupA = 480;
+    break;
+    case 6:
+    messageSizeGroupA = 640;
+    break;
+    case 7:
+    messageSizeGroupA = 800;
+    break;
+    case 8:
+    messageSizeGroupA = 1000;
+    break;
+    case 9:
+    messageSizeGroupA = 72;
+    break;
+    default:
+    AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %d\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
+    /* TBR cases 10 -15*/
+    }
+
+    /* - Power offset for preamble selection */
+    /* TBR: what value to use as default? */
+    messagePowerOffsetGroupB = -9999;
+    switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
+    case 0:
+    messagePowerOffsetGroupB = -9999;
+    break;
+    case 1:
+    messagePowerOffsetGroupB = 0;
+    break;
+    case 2:
+    messagePowerOffsetGroupB = 5;
+    break;
+    case 3:
+    messagePowerOffsetGroupB = 8;
+    break;
+    case 4:
+    messagePowerOffsetGroupB = 10;
+    break;
+    case 5:
+    messagePowerOffsetGroupB = 12;
+    break;
+    case 6:
+    messagePowerOffsetGroupB = 15;
+    break;
+    case 7:
+    messagePowerOffsetGroupB = 18;
+    break;
+    default:
+    AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %d\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
+    }
+
+    // TBR Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
+    nr_UE_mac_inst->deltaPreamble_Msg3 = 0;
+    deltaPreamble_Msg3 = nr_UE_mac_inst->deltaPreamble_Msg3;
+  }
+
+  PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
+  // PLThreshold =  prach_resources->RA_PCMAX - nr_get_DELTA_PREAMBLE(mod_id, CC_id) - nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id) - messagePowerOffsetGroupB;
+  // TBR Note Pcmax is set to 0 here, we have to fix this
+
+  /* Msg3 has not been transmitted yet */
+  if (first_Msg3 == 1) {
+    if (noGroupB == 1) {
+      // use Group A preamble
+      prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
+      prach_resources->ra_RACH_MaskIndex = 0;
+      nr_UE_mac_inst->RA_usedGroupA = 1;
+    } else if ((Msg3_size < messageSizeGroupA) && (get_PL(mod_id, 0, gNB_id) > PLThreshold)) {
+      // TBR update get_PL to NR
+      // TBR add condition for initiation by CCCH 
+      // Group B is configured and RA preamble Group A is used
+      prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
+      prach_resources->ra_RACH_MaskIndex = 0;
+      nr_UE_mac_inst->RA_usedGroupA = 1;
+    } else {
+      // Group B preamble is configured and used
+      // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
+      // the remaining belong to RA Preambles Group B
+      prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA
+        + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); 
+      prach_resources->ra_RACH_MaskIndex = 0;
+      nr_UE_mac_inst->RA_usedGroupA = 0;
+    }
+
+    //TBR check why this is here
+    // prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id);
+  } else {
+    // Msg3 is being retransmitted
+    if (nr_UE_mac_inst->RA_usedGroupA == 1) {
+     if (nr_rach_ConfigCommon->groupBconfigured){
+     	prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
+       } else {
+         prach_resources->ra_PreambleIndex = (taus()) & 0x3f; // TBR check this
+         prach_resources->ra_RACH_MaskIndex = 0;
+       } 
+     } else {
+       // TBR FIXME nr_rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero
+       prach_resources->ra_PreambleIndex =
+         sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
+       prach_resources->ra_RACH_MaskIndex = 0;
+     }
+    }
+
+   // TBR determine next available PRACH occasion
+    // - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
+    // - else if SSB is selected above
+    // - else if CSI-RS is selected above
+
+  /* // choose random PRACH resource in TDD
+  if (nr_UE_mac_inst->tdd_Config) {
+    num_prach = get_num_prach_tdd(mod_id);
+
+    if ((num_prach > 0) && (num_prach < 6))
+      prach_resources->ra_TDD_map_index = (taus() % num_prach);
+
+    f_id = get_fid_prach_tdd(mod_id, nr_UE_mac_inst [mod_id].RA_prach_resources->ra_TDD_map_index);
+  }*/
+
+  /////////////////////////////////////////////////////////////////////////////
+  //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
+  /////////////////////////////////////////////////////////////////////////////
+
+  // TBR condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
+  // TBR check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
+  if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER >1)
+    nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++;
+
+  //prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower +
+  // nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; // TBR
+  prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id);
+
+   /* RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
+   // 1) this does not apply to contention-free RA Preamble for beam failure recovery request
+   // 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
+   // 3) TBR extend this (e.g. f_id selection, ul_carrier_id are hardcoded) */
+
+   ul_carrier_id = 0; // UL carrier used for RA preamble transmission, hardcoded for NUL carrier
+   f_id = 0;
+   //frequencyStart = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
+
+   switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){
+    case 0:
+    msg1_FDM = 1;
+    break;
+    case 1:
+    msg1_FDM = 2;
+    break;
+    case 2:
+    msg1_FDM = 4;
+    break;
+    case 3:
+    msg1_FDM = 8;
+    break;
+    default:
+    AssertFatal(1 == 0,"Unknown msg1_FDM %d\n", nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM);
+   }
+
+   prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
+
+   // TBR this is for TDD FR1 only
+   SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]; 
+   s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5]; // starting symbol of the PRACH occasion
+
+   // pick the first slot of the PRACH occasion in a system frame (0 <= t_id <= 80)
+   for (i = 0; i < 10; i++){
+    if (((SFN_nbr & (1 << i)) >> i) == 1){
+      t_id = 2*i;
+      break;
+    }
+   }
+
+   prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
+}
+
+void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
+  #if 0 //TBR
+  AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+  
+  // start contention resolution timer
+  nr_UE_mac_inst->RA_attempt_number++;
+
+  if (opt_enabled) {
+    trace_pdu(DIRECTION_UPLINK, NULL, 0, mod_id, WS_NO_RNTI, nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, nr_UE_mac_inst->RA_attempt_number);
+    LOG_D(OPT, "[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x  with size %d\n", mod_id, frameP, 1, nr_UE_mac_inst->RA_Msg3_size);
+    }
+   #endif
+}
+
+
+void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
+  #if 0 // TBR
+  AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
+
+  LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n", mod_id, frameP);
+
+  // start contention resolution timer  
+  nr_UE_mac_inst->RA_contention_resolution_cnt = 0;
+  nr_UE_mac_inst->RA_contention_resolution_timer_active = 1;
+
+  if (opt_enabled) {
+    trace_pdu(DIRECTION_UPLINK, &nr_UE_mac_inst->CCCH_pdu.payload[0], nr_UE_mac_inst->RA_Msg3_size, mod_id, WS_C_RNTI, nr_UE_mac_inst->crnti, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, 0);
+	  LOG_D(OPT, "[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d   with size %d\n", mod_id, frameP, nr_UE_mac_inst->crnti /*nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex */, nr_UE_mac_inst->RA_Msg3_size);
+  }
+  #endif
+}
+
+/////////////////////////////////////////////////////////////////////////
+///////* Random Access Preamble Initialization (5.1.1 TS 38.321) *///////
+/////////////////////////////////////////////////////////////////////////
+/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300)
+/// Only one RA procedure is ongoing at any point in time in a MAC entity
+/// the RA procedure on a SCell shall only be initiated by PDCCH order
+
+NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id,
+                                     int CC_id,
+                                     UE_MODE_t UE_mode,
+                                     frame_t frame,
+                                     uint8_t gNB_id,
+                                     int nr_tti_tx){
+
+  NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
+  uint8_t size_sdu = 0, Nb_tb = 1, lcid = CCCH, dcch_header_len = 0, ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
+  // UE_MODE_t UE_mode;
+  uint16_t Size16, sdu_lengths;
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (struct NR_RACH_ConfigCommon_t *) NULL;
+  NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
+  int32_t frame_diff = 0;
+
+  // Modification for phy_stub_ue operation // TBR
+  // if(nfapi_mode == 3) { // phy_stub_ue mode
+  // UE_mode = nr_UE_mac_inst->UE_mode[CC_id];
+  // LOG_D(MAC, "ue_get_rach, UE_mode: %d", UE_mode);
+  // }
+  //  else // Full stack mode
+  // UE_mode = get_nrUE_mode(mod_id, CC_id, gNB_id); // TBR
+
+  AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
+
+  if (UE_mode == PRACH) {
+    LOG_D(MAC, "ue_get_rach, RA_active value: %d", nr_UE_mac_inst->RA_active);
+    if (nr_UE_mac_inst->nr_rach_ConfigCommon) {
+      nr_rach_ConfigCommon =	nr_UE_mac_inst->nr_rach_ConfigCommon;
+      printf("nr_rach_ConfigCommon from MAC nr_UE_mac_inst\n"); /* TBR DEBUG only */
+    } else return NULL;
+
+      /* TBR moved below
+      size_sdu = mac_rrc_nr_data_req(mod_id,
+        CC_id,
+        frame,
+        CCCH,
+        1,
+        &nr_UE_mac_inst->CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT) + 1], gNB_id, 0);*/
+
+    if (nr_UE_mac_inst->RA_active == 0) {
+      /* RA not active - checking if RRC is ready to initiate the RA procedure */
+
+      LOG_I(MAC, "RA not active\n");
+
+      /* TBR flush Msg3 Buffer 
+      this was done like this but at PHY level
+      for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
+        // flush Msg3 buffer
+        PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
+        ue->ulsch_Msg3_active[i] = 0;
+      }
+      */
+
+      nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
+      nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
+      prach_resources->RA_PREAMBLE_BACKOFF = 0;
+
+      /* TBR: if carrier to use is explicitly signalled do RA CARRIER SELECTION (SUL, NUL) this will set PCMAX */
+      prach_resources->RA_PCMAX = 0;
+
+      /* TBR: BWP operation (subclause 5.15 TS 38.321) */
+
+      /* Set RA_PREAMBLE_POWER_RAMPING_STEP */
+      switch (nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep){ // in dB
+       case 0:
+       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
+       break;
+       case 1:
+       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
+       break;
+       case 2:
+       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
+       break;
+       case 3:
+       prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
+       break;
+      }
+
+      prach_resources->RA_SCALING_FACTOR_BI = 1;
+
+      /* TBR: initialization by beam failure recovery */
+
+      /* TBR: initialization by handover */
+
+      /* size_sdu = mac_rrc_nr_data_req(mod_id,
+                                     CC_id, 
+                                     frame,
+                                     CCCH,
+                                     Nb_tb,
+                                     &nr_UE_mac_inst->CCCH_pdu.payload[sizeof(NR_MAC_SUBHEADER_SHORT) + 1]); */ 
+      // TBR mac_rrc_nr_data_req is a GNB func
+      // use nr_mac_rrc_data_ind_ue instead
+
+      // TBR fix CCCH PDU payload
+      Size16 = (uint16_t) size_sdu;
+
+      /* TBR FIX THIS
+
+      //  LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",mod_id,frame,size_sdu);
+      LOG_I(RRC,
+        "[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest gNB %d) --->][MAC_UE][MOD %02d][]\n",
+        frame, mod_id, gNB_id, mod_id);
+      LOG_I(MAC,
+        "[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",
+        mod_id, frame, size_sdu);
+
+      nr_UE_mac_inst->RA_RAPID_found = 0;
+      // TBR which frame and slot ?     
+      nr_UE_mac_inst->RA_tx_frame = frame;
+      nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
+      nr_UE_mac_inst->RA_backoff_frame = frame;
+      nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;*/
+
+      /*if (size_sdu > 0) { */
+        /* TBR initialisation by RRC
+        // PDU from CCCH */
+
+        LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame);
+
+        // TBR
+        /*nr_UE_mac_inst->RA_Msg3_size = size_sdu + sizeof(SCH_SUBHEADER_SHORT) + sizeof(SCH_SUBHEADER_SHORT);
+        nr_UE_mac_inst->RA_prachMaskIndex = 0;
+        prach_resources->Msg3 = nr_UE_mac_inst->CCCH_pdu.payload;
+        nr_UE_mac_inst->RA_backoff_cnt = 0;	// add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
+
+        AssertFatal(nr_rach_ConfigCommon != NULL,
+          "[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n",
+          mod_id, frame);
+        nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
+
+        if (nr_UE_mac_inst->RA_window_cnt == 9) {
+            nr_UE_mac_inst->RA_window_cnt = 10;	// Note: 9 subframe window doesn't exist, after 8 is 10!
+        }*/
+
+        // Fill in preamble and PRACH resources
+        nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, NULL);
+
+        /*generate_ulsch_header((uint8_t *) & nr_UE_mac_inst->CCCH_pdu.payload[0],	// mac header
+          1,        // num sdus
+          0,        // short pading
+          &Size16,  // sdu length
+          &lcid,    // sdu lcid
+          NULL,     // power headroom
+          NULL,     // crnti
+          NULL,     // truncated bsr
+          NULL,     // short bsr
+          NULL,     // long_bsr
+          1);       //post_padding*/
+        return (&nr_UE_mac_inst->RA_prach_resources);
+
+      /*} else if (nr_UE_mac_inst->scheduling_info.
+        BSR_bytes[nr_UE_mac_inst->scheduling_info.LCGID[DCCH]] > 0) {
+          // This is for triggering a transmission on DCCH using PRACH (during handover,
+          // or sending SR for example)
+
+          dcch_header_len = 2 + 2;	/// SHORT Subheader + C-RNTI control element
+           LOG_USEDINLOG_VAR(mac_rlc_status_resp_t,rlc_status)=mac_rlc_status_ind(mod_id,
+            nr_UE_mac_inst->crnti,
+            gNB_id, frame, nr_tti_tx,
+            ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6
+            #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 
+            ,0, 0
+            #endif
+            );
+
+          if (nr_UE_mac_inst->crnti_before_ho)
+            LOG_D(MAC,
+           "[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n",
+           mod_id, frame,
+           nr_UE_mac_inst->crnti,
+           nr_UE_mac_inst->crnti_before_ho,
+           rlc_status.bytes_in_buffer, dcch_header_len);
+          else
+            LOG_D(MAC,
+           "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
+           mod_id, frame, rlc_status.bytes_in_buffer,
+           dcch_header_len);
+
+          sdu_lengths = mac_rlc_data_req(mod_id, nr_UE_mac_inst->crnti, 
+            gNB_id, frame, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6,	//not used
+            (char *) &ulsch_buff[0]
+            #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+            ,0,0
+            #endif
+            );
+
+          if(sdu_lengths > 0)
+            LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n", mod_id, sdu_lengths);
+          else
+           LOG_E(MAC, "[UE %d] TX DCCH error\n", mod_id );
+
+          update_bsr(mod_id, frame, nr_tti_tx, gNB_id);
+          nr_UE_mac_inst->scheduling_info.BSR[nr_UE_mac_inst->
+            scheduling_info.LCGID[DCCH]] = locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE,
+            nr_UE_mac_inst
+            [mod_id].scheduling_info.BSR_bytes
+            [nr_UE_mac_inst
+            [mod_id].scheduling_info.LCGID
+            [DCCH]]);
+
+          //TBR: fill BSR infos in UL TBS
+
+          //header_len +=2;
+          nr_UE_mac_inst->RA_active = 1;
+          nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER =
+              1;
+          nr_UE_mac_inst->RA_Msg3_size =
+              size_sdu + dcch_header_len;
+          nr_UE_mac_inst->RA_prachMaskIndex = 0;
+          prach_resources->Msg3 =
+              ulsch_buff;
+          nr_UE_mac_inst->RA_backoff_cnt = 0;	// add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
+
+          AssertFatal(nr_rach_ConfigCommon != NULL,
+          	    "[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n",
+          	    mod_id, frame);
+          nr_UE_mac_inst->RA_window_cnt =
+              2 +
+              nr_rach_ConfigCommon->ra_SupervisionInfo.
+              ra_ResponseWindowSize;
+
+          if (nr_UE_mac_inst->RA_window_cnt == 9) {
+              nr_UE_mac_inst->RA_window_cnt = 10;	// Note: 9 subframe window doesn't exist, after 8 is 10!
+          }
+
+
+          nr_UE_mac_inst->RA_tx_frame = frame;
+          nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
+          nr_UE_mac_inst->RA_backoff_frame = frame;
+          nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;
+          // Fill in preamble and PRACH resource
+          nr_get_prach_resources(mod_id, CC_id, gNB_id,
+          		    nr_tti_tx, 1, NULL);
+          generate_ulsch_header((uint8_t *) ulsch_buff,	// mac header
+         		      1,	// num sdus
+         		      0,	// short pading
+         		      &Size16,	// sdu length
+         		      &lcid,	// sdu lcid
+         		      NULL,	// power headroom
+         		      &nr_UE_mac_inst->crnti,	// crnti
+         		      NULL,	// truncated bsr
+         		      NULL,	// short bsr
+         		      NULL,	// long_bsr
+         		      0);	//post_padding
+
+          return (&nr_UE_mac_inst->RA_prach_resources);
+        }*/
+    } else { // RACH is active
+
+      ////////////////////////////////////////////////////////////////
+      /////* Random Access Response reception (5.1.4 TS 38.321) */////
+      ////////////////////////////////////////////////////////////////
+      /// Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER
+      /// and RA_backoff_cnt
+
+      LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
+        mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt, nr_UE_mac_inst->RA_tx_frame, nr_UE_mac_inst->RA_tx_subframe);
+
+      // - TBR check
+      // compute backoff parameters
+      if (nr_UE_mac_inst->RA_backoff_cnt > 0){
+        frame_diff = (sframe_t) frame - nr_UE_mac_inst->RA_backoff_frame;
+        if (frame_diff < 0) frame_diff = -frame_diff;
+        nr_UE_mac_inst->RA_backoff_cnt -= ((10 * frame_diff) + (nr_tti_tx - nr_UE_mac_inst->RA_backoff_subframe));
+        nr_UE_mac_inst->RA_backoff_frame = frame;
+        nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;
+      }
+      // - TBR check
+      
+      // - TBR check
+      // compute RA window parameters
+      if (nr_UE_mac_inst->RA_window_cnt > 0){
+        frame_diff = (frame_t) frame - nr_UE_mac_inst->RA_tx_frame;
+        if (frame_diff < 0) frame_diff = -frame_diff;
+        nr_UE_mac_inst->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - nr_UE_mac_inst->RA_tx_subframe));
+        LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt);
+      }
+      // - TBR check
+
+      //if ((nr_UE_mac_inst->RA_window_cnt <= 0) && (nr_UE_mac_inst->RA_backoff_cnt <= 0)){
+      if ((nr_UE_mac_inst->RA_window_cnt <= 0) && (nr_UE_mac_inst->RA_RAPID_found == 0)){ // TODO TBR double check the condition
+        
+        LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n", mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt);
+        
+        nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++;
+
+        // - TBR check RA_tx_frame RA_tx_subframe
+        nr_UE_mac_inst->RA_tx_frame = frame;
+        nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
+        prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER += (prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1); // 2dB increments in ASN.1 definition
+        // - TBR check ra_PREAMBLE_RECEIVED_TARGET_POWER increment
+
+        int preambleTransMax = -1;
+
+        switch (nr_rach_ConfigCommon->rach_ConfigGeneric.preambleTransMax) {
+        case NR_RACH_ConfigGeneric__preambleTransMax_n3:
+          preambleTransMax = 3;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n4:
+          preambleTransMax = 4;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n5:
+          preambleTransMax = 5;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n6:
+          preambleTransMax = 6;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n7:
+          preambleTransMax = 7;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n8:
+          preambleTransMax = 8;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n10:
+          preambleTransMax = 10;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n20:
+          preambleTransMax = 20;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n50:
+          preambleTransMax = 50;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n100:
+          preambleTransMax = 100;
+          break;
+        case NR_RACH_ConfigGeneric__preambleTransMax_n200:
+          preambleTransMax = 200;
+          break;
+        }
+
+        if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
+
+          LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax);
+
+          // TBR select random backoff according to a uniform distribution between 0 and PREAMBLE_BACKOFF
+          // (rand() % prach_resources->RA_PREAMBLE_BACKOFF
+
+          // TODO TBR send message to RRC
+          nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
+          prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id); // TBR check if this is necessary
+        }
+
+        // TBR ra_SupervisionInfo.ra_ResponseWindowSize is missing
+        // nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
+        nr_UE_mac_inst->RA_backoff_cnt = 0;
+
+        // Fill in preamble and PRACH resources
+        nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, NULL);
+        return (&nr_UE_mac_inst->RA_prach_resources);
+      }
+    }
+  } else if (UE_mode == PUSCH) {
+      LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id);
+      AssertFatal(1 == 0, "");
+  }
+ return NULL;
+}
\ No newline at end of file
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 55ac0953989d135b687447dc5ecd142d9fe7f93f..e192bfb232d8bbd10206d2b6b2d93bde84290de0 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -30,36 +30,36 @@
  * \warning
  */
 
+
+#include <stdio.h>
+#include <math.h>
+
+/* exe */
 #include "executables/nr-softmodem.h"
 
-/* MAC related headers */
-#include "mac_proto.h"
+/* MAC */
 #include "mac_defs.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
-#include "mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac.h"
+#include "NR_MAC_UE/mac_proto.h"
+#include "NR_MAC_UE/mac_extern.h"
 #include "common/utils/nr/nr_common.h"
 
-//#include "LAYER2/MAC/mac_vars.h" // TODO Note that mac_vars.h is not NR specific and this should be updated
+//#include "LAYER2/MAC/mac_vars.h" // TBR Note that mac_vars.h is not NR specific and this should be updated
                                  // also, the use of the same should be updated in nr-softmodem and nr-uesoftmodem
 
-/* PHY UE related headers*/
+/* PHY UE */
 #include "SCHED_NR_UE/defs.h"
-
-#include "RRC/NR_UE/rrc_proto.h"
-#include "assertions.h"
 #include "PHY/defs_nr_UE.h"
 
 /*Openair Packet Tracer */
 #include "UTIL/OPT/opt.h"
 #include "OCG.h"
 
-/* log utils */
+/* utils */
+#include "assertions.h"
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 
-#include <stdio.h>
-#include <math.h>
-
 //#define ENABLE_MAC_PAYLOAD_DEBUG 1
 #define DEBUG_EXTRACT_DCI 1
 
diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd7e96eda5989e640b08415e89f1a6f615094f68
--- /dev/null
+++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c
@@ -0,0 +1,157 @@
+/*
+ * 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 rar_tools_nrUE.c
+ * \brief RA tools for NR UE
+ * \author Guido Casati
+ * \date 2019
+ * \version 1.0
+ * @ingroup _mac
+
+ */
+
+/* Sim */
+#include "SIMULATION/TOOLS/sim.h"
+
+/* Utils */
+#include "common/utils/LOG/log.h"
+#include "OCG.h"
+#include "OCG_extern.h"
+#include "UTIL/OPT/opt.h"
+
+/* Common */
+#include "common/ran_context.h"
+
+/* MAC */
+#include "NR_MAC_UE/mac.h"
+#include "NR_MAC_UE/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
+
+#define DEBUG_RAR
+
+uint16_t nr_ue_process_rar(const module_id_t mod_id,
+                           const int CC_id,
+                           const frame_t frameP,
+                           const rnti_t ra_rnti,
+                           uint8_t * const dlsch_buffer,
+                           rnti_t * const t_crnti,
+                           const uint8_t preamble_index,
+                           uint8_t * selected_rar_buffer/*output argument for storing the selected RAR header and RAR payload*/){
+
+    NR_UE_MAC_INST_t *nrUE_mac_inst = get_mac_inst(mod_id);
+
+    uint16_t ret = 0;		// return value
+
+    NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
+
+    // TODO TBR
+
+    //  NR_RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
+    uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
+
+    // get the last RAR payload for working with CMW500
+    uint8_t n_rarpy = 0;	// number of RAR payloads
+    uint8_t n_rarh = 0;		// number of MAC RAR subheaders
+    uint8_t best_rx_rapid = -1;	// the closest RAPID receive from all RARs
+    while (1) {
+	n_rarh++;
+	if (rarh->T == 1) {
+	    n_rarpy++;
+	    LOG_D(MAC, "RAPID %d\n", rarh->RAPID);
+	}
+
+	if (rarh->RAPID == preamble_index) {
+	    LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
+		  rarh->RAPID);
+	    rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
+	    nrUE_mac_inst->RA_RAPID_found = 1;
+	    break;
+	}
+
+	if (abs((int) rarh->RAPID - (int) preamble_index) <
+	    abs((int) best_rx_rapid - (int) preamble_index)) {
+	    best_rx_rapid = rarh->RAPID;
+	    rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
+	}
+
+	if (rarh->E == 0) {
+	    LOG_I(PHY, "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", best_rx_rapid);
+	    break;
+	} else {
+	    rarh++;
+	}
+    };
+    LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n",
+	  n_rarh, n_rarpy);
+
+    if (CC_id > 0) {
+	LOG_W(MAC, "Should not have received RAR on secondary CCs! \n");
+	return (0xffff);
+    }
+
+    LOG_I(MAC,
+	  "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
+	  mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2],
+	  rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
+#ifdef DEBUG_RAR
+    LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", mod_id, rarh->E);
+    LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", mod_id, rarh->T);
+    LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", mod_id,
+	  rarh->RAPID);
+
+    //  LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",mod_id,rar->R);
+    LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",
+	  mod_id, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
+    //  LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",mod_id,rar->hopping_flag);
+    //  LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",mod_id,rar->rb_alloc);
+    //  LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",mod_id,rar->mcs);
+    //  LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",mod_id,rar->TPC);
+    //  LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",mod_id,rar->UL_delay);
+    //  LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",mod_id,rar->cqi_req);
+    LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", mod_id,
+	  (uint16_t) rar[5] + (rar[4] << 8));
+#endif
+
+    if (opt_enabled) {
+	LOG_D(OPT,
+	      "[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n",
+	      mod_id, CC_id, frameP, ra_rnti);
+	/*trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
+		  mod_id, WS_RA_RNTI, ra_rnti, nrUE_mac_inst->rxFrame,
+		  nrUE_mac_inst->rxSubframe, 0, 0);*/ // TODO TBR fix rxframe and subframe
+    }
+
+    if (preamble_index == rarh->RAPID) { // TBR double check this
+	*t_crnti = (uint16_t) rar[5] + (rar[4] << 8);	//rar->t_crnti;
+	nrUE_mac_inst->crnti = *t_crnti;	//rar->t_crnti;
+	//return(rar->Timing_Advance_Command);
+	ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
+    } else {
+	nrUE_mac_inst->crnti = 0;
+	ret = (0xffff);
+    }
+
+    // move the selected RAR to the front of the RA_PDSCH buffer
+    memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
+    memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
+
+    return ret;
+}
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index c911fbd56a6c6aa5d53048131067815e014b4d0b..6f9f04c108211619b25db474df0697a221a5c6fe 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -44,7 +44,7 @@
 #include "SCHED_NR/phy_frame_config_nr.h"
 
 #include "NR_MIB.h"
-#include "nr_mac_common.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
 
 extern RAN_CONTEXT_t RC;
 //extern int l2_init_gNB(void);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
index ace9551d2f4ba603053b4086d4007b1bba3f42d6..5e7ad3848e94aa86c8082f8ac08f48419ce2056c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c
@@ -33,9 +33,9 @@
 #include "assertions.h"
 
 #include "LAYER2/MAC/mac.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 #include "LAYER2/MAC/mac_proto.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
 
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
@@ -365,10 +365,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
     schedule_nr_mib(module_idP, frame_txP, slot_txP);
   }
 
-  // TbD once RACH is available, start ta_timer when UE is connected
+  // TBR once RACH is available, start ta_timer when UE is connected
   if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--;
 
-  if (ue_sched_ctl->ta_timer == 0) {
+  if (ue_sched_ctl->ta_timer == 0) { // TBR check phy_test (see below)
     gNB->ta_command = ue_sched_ctl->ta_update;
     /* if time is up, then set the timer to not send it for 5 frames
     // regardless of the TA value */
@@ -380,8 +380,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
   }
 
   // Phytest scheduling
-  if (phy_test && slot_txP==1){
+  if (phy_test && slot_txP==1){ // TBR check phy_test
     nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL);
+    // This schedules Random-Access for NR starting in subframeP
+    nr_schedule_RA(module_idP, frame_txP, slot_txP);
     // resetting ta flag
     gNB->ta_len = 0;
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index d74df15eac813bb1137cf299a3c06c25d307684d..f98aebfb0d1ec3205cb7bfd8f88c92bf3bf62323 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -19,44 +19,541 @@
  *      contact@openairinterface.org
  */
 
-/*! \file gNB_scheduler_RA.c
- * \brief primitives used for random access
- * \author
- * \date
- * \email:
+/*! \file     gNB_scheduler_RA.c
+ * \brief     primitives used for random access
+ * \author    Guido Casati
+ * \date      2019
+ * \email:    guido.casati@iis.fraunhofer.de
  * \version
  */
 
-#include nr_mac_gNB.h
+#include "platform_types.h"
+#include "nr_mac_gNB.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 
-void
-schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
-{
+/* Openair Packet Tracer */
+#include "UTIL/OPT/opt.h"
 
-  eNB_MAC_INST *mac = RC.mac[module_idP];
-  COMMON_channels_t *cc = mac->common_channels;
-  RA_t *ra;
+// void nr_add_subframe(uint16_t *frameP, uint16_t *slotP, int offset){
+//     *frameP    = (*frameP + ((*slotP + offset) / 10)) % 1024;
+//     *slotP = ((*slotP + offset) % 10);
+// } // TBR fix
+
+// handles the event of MSG1 reception
+// TBR remove sub_frame_t
+void nr_initiate_ra_proc(module_id_t module_idP,
+                         int CC_id,
+                         frame_t frameP,
+                         sub_frame_t slotP,
+                         uint16_t preamble_index,
+                         int16_t timing_offset,
+                         uint16_t ra_rnti
+                         #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // TBR
+                         , uint8_t rach_resource_type
+                         #endif
+                         ){
   uint8_t i;
+  uint16_t msg2_frame = frameP, msg2_slot = slotP;
+  int offset;
+  NR_COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
+  NR_RA_t *ra = &cc->ra[0];
+  static uint8_t failure_cnt = 0;
+
+  /*#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+    struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
+    PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
+  
+    static uint8_t failure_cnt = 0;
+
+    if (cc->radioResourceConfigCommon_BR
+      && cc->radioResourceConfigCommon_BR->ext4) {
+      ext4_prach = cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
+      prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
+    }
+  #endif // #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
+
+    LOG_D(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  Initiating RA procedure for preamble index %d\n",
+      module_idP, CC_id, frameP, slotP, preamble_index);
+   /*#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+     LOG_D(MAC,
+     "[gNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  PRACH resource type %d\n",
+     module_idP, CC_id, frameP, slotP, rach_resource_type);
+   #endif*/
+
+
+
+  /*#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0))
+   if (prach_ParametersListCE_r13 && prach_ParametersListCE_r13->list.count < rach_resource_type) {
+     LOG_E(MAC,"[gNB %d][RAPROC] CC_id %d Received impossible PRACH resource type %d, 
+     only %d CE levels configured\n",
+     module_idP, CC_id, rach_resource_type,
+     (int) prach_ParametersListCE_r13->list.count);
+     return;
+   }
+  #endif // #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
+
+  /*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);*/
+
+  for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+    if (ra[i].state == IDLE) {
+      int loop = 0;
+      LOG_D(MAC, "Frame %d, Subframe %d: Activating RA process %d\n", frameP, slotP, i);
+      ra[i].state = MSG2;
+      ra[i].timing_offset = timing_offset;
+      ra[i].preamble_subframe = slotP;
+      /*#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+        ra[i].rach_resource_type = rach_resource_type;
+        ra[i].msg2_mpdcch_repetition_cnt = 0;
+        ra[i].msg4_mpdcch_repetition_cnt = 0;
+      #endif*/
+
+      /* TBR CHECK Fill in other TDD config. What about nfapi_mode? */
+      // if(cc->tdd_Config!=NULL){
+      //   // switch(cc->tdd_Config->subframeAssignment){ // TBR missing tdd_Config
+      //   //   default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
+      //   //   case 1 :
+      //   //     offset = 6;
+      //   //     break;
+      //   // }
+      // }else{//FDD
+      //     // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes
+      //     if (nfapi_mode)
+      //       offset = 7;
+      //     else
+      //       offset = 5;
+      // }
+
+      // nr_add_subframe(&msg2_frame, &msg2_slot, offset); // TBR
+
+      ra[i].Msg2_frame         = msg2_frame;
+      ra[i].Msg2_subframe      = msg2_slot;
+
+      LOG_D(MAC,"%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__,ra[i].Msg2_frame,ra[i].Msg2_subframe,frameP,slotP,offset);
+
+      ra[i].Msg2_subframe = (slotP + offset) % 10;
+      
+      /* TBR: find better procedure to allocate RNTI */
+      do {
+        #if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode
+        static int drnti[MAX_MOBILES_PER_GNB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 };
+        int j = 0;
+        int nb_ue = 0;
+        for (j = 0; j < MAX_MOBILES_PER_GNB; j++) {
+          if (UE_RNTI(module_idP, j) > 0) {
+            nb_ue++;
+          } else {
+            break;
+          }
+        }
+        if (nb_ue >= MAX_MOBILES_PER_GNB) {
+          printf("No more free RNTI available, increase MAX_MOBILES_PER_GNB\n");
+          abort();
+        }
+        ra[i].rnti = drnti[nb_ue];
+        #else 
+        ra[i].rnti = taus();
+        #endif
+        loop++;
+      }
+      /* While loop  
+      ** TBR: second condition is not correct, the rnti may be in use without
+      *  being in the MAC yet. To be refined.
+      ** 1024 and 60000 arbirarily chosen, not coming from standard */
+      while (loop != 100 /*&& !(find_nrUE_id(module_idP, ra[i].rnti) == -1 && ra[i].rnti >= 1024 && ra[i].rnti < 60000)*/); 
+      // TBR nr_find_ue
+        
+      if (loop == 100) {
+        printf("%s:%d:%s: FATAL ERROR! contact the authors\n",__FILE__, __LINE__, __FUNCTION__);
+        abort();
+      }
+      
+      ra[i].RA_rnti = ra_rnti;
+      ra[i].preamble_index = preamble_index;
+      failure_cnt = 0;
+
+      LOG_D(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state %d\n", module_idP, CC_id, frameP, ra[i].Msg2_frame, ra[i].Msg2_subframe, i, ra[i].rnti, ra[i].state);
+
+      return;
+    }
+  }
+
+  LOG_E(MAC,
+  "[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",
+  module_idP, CC_id, frameP, preamble_index);
+  
+  failure_cnt++;
+  
+  if(failure_cnt > 20) {
+    LOG_E(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP);
+    nr_clear_ra_proc(module_idP, CC_id, frameP);
+  }
+  
+}
+
+void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
+
+  gNB_MAC_INST *mac = RC.mac[module_idP];
+  NR_COMMON_channels_t *cc = mac->common_channels;
+  NR_RA_t *ra;
+  uint8_t i, CC_id = 0;
 
   start_meas(&mac->schedule_ra);
 
+  // for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+
+    for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
+
+      ra = (NR_RA_t *) & cc[CC_id].ra[i];
+      LOG_D(MAC,"RA[state:%d]\n",ra->state);
 
-  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      switch (ra->state){
+        case MSG2:
+        nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
+        break;
+        case MSG4:
+        generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
+        break;
+        case WAITMSG4ACK:
+        check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra);
+        break;
+      }
+    } // for i=0 .. N_RA_PROC-1
+  // } // CC_id
+  stop_meas(&mac->schedule_ra);
+}
+
+void nr_generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, 
+  sub_frame_t slotP, NR_RA_t * ra){
+
+  int first_rb, N_RB_DL;
+
+  gNB_MAC_INST *mac = RC.mac[module_idP];
+  NR_COMMON_channels_t *cc = mac->common_channels;
+  uint8_t *vrb_map = cc[CC_idP].vrb_map;
+
+//  /* TBR - MIGRATE TO THE NEW NFAPI */
+//  nfapi_nr_dl_tti_request_body_t *dl_req = &mac->DL_req[CC_idP].dl_config_request_body;
+//  nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
+//  nfapi_tx_request_pdu_t *TX_req;
+//
+//  /* TBR: BW should be retrieved from
+//  // NR_ServingCellConfigCommonSIB_t -> NR_BWP_DownlinkCommon_t -> NR_BWP_t
+//  N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
+//  // Temporary hardcoded
+//  */
+//  N_RB_DL = 106;
+//
+//  if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == slotP)) {
+//    
+//    LOG_D(MAC,"[gNB %d] CC_id %d Frame %d, slotP %d: 
+//      Generating RAR DCI, state %d\n",
+//      module_idP, CC_idP, frameP, slotP, ra->state);
+//
+//    // Allocate 4 PRBS starting in RB 0
+//    // commented out because preprocessor is missing
+//    /*first_rb = 0;
+//    vrb_map[first_rb] = 1;
+//    vrb_map[first_rb + 1] = 1;
+//    vrb_map[first_rb + 2] = 1;
+//    vrb_map[first_rb + 3] = 1;*/
+//
+//    memset((void *) dl_config_pdu, 0, sizeof(nfapi_nr_dl_config_request_pdu_t));
+//
+//    dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
+//    dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->RA_rnti;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2;  // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000;  // equal to RS power
+//
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1;  // no TPC
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
+//
+//    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4);
+//
+//    // This checks if the above DCI allocation is feasible in current subframe
+//    if (!nr_CCE_allocation_infeasible(module_idP, CC_idP, 0, slotP,
+//      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) {
+//      
+//      LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", frameP, slotP, ra->RA_rnti);
+//      dl_req->number_dci++;
+//      dl_req->number_pdu++;
+//
+//      dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
+//      memset((void *) dl_config_pdu, 0, sizeof(nfapi_nr_dl_config_request_pdu_t));
+//      dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
+//      dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_nr_dl_config_dlsch_pdu));
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_NR_DL_CONFIG_REQUEST_DLSCH_PDU_REL15_TAG;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4);
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
+//      //    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth);  // ignored
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
+//      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
+//      //    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ; 
+//      dl_req->number_pdu++;
+//      mac->DL_req[CC_idP].sfn_sf = frameP<<4 | slotP;
+//
+//      // Program UL processing for Msg3
+//      nr_get_Msg3alloc(&cc[CC_idP], slotP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe);
+//
+//      LOG_D(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n",
+//            frameP, slotP, ra->Msg3_frame,
+//            ra->Msg3_subframe);
+//
+//      nr_fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7);
+//      nr_add_msg3(module_idP, CC_idP, ra, frameP, slotP);
+//      ra->state = WAITMSG3;
+//      LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, slotP);
+//
+//      // DL request
+//      mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + slotP;
+//      TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
+//      TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble 
+//      TX_req->pdu_index = mac->pdu_index[CC_idP]++;
+//      TX_req->num_segments = 1;
+//      TX_req->segments[0].segment_length = 7;
+//      TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
+//      mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
+//    
+//      /*if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
+//        set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
+//      }*/  
+//    } // PDCCH CCE allocation is feasible
+//  } // Msg2 frame/subframe condition
+}
+
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
+  unsigned char i;
+  NR_RA_t *ra = (NR_RA_t *) &RC.mac[module_idP]->common_channels[CC_id].ra[0];
+  for (i = 0; i < NR_NB_RA_PROC_MAX; i++){
+    LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra[i].rnti);
+    ra[i].state = IDLE;
+    ra[i].timing_offset = 0;
+    ra[i].RRC_timer = 20;
+    ra[i].rnti = 0;
+    ra[i].msg3_round = 0;
+  }
+}
+
+unsigned short nr_fill_rar(const module_id_t mod_id,
+                           const int CC_id,
+                           NR_RA_t * ra,
+                           const frame_t frameP,
+                           uint8_t * const dlsch_buffer,
+                           const uint16_t N_RB_UL,
+                           const uint8_t input_buffer_length){
+
+    RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
+    uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
+
+    /* E/T/RAPID subheader 
+    - E = 0, one only RAR, first and last
+    - T = 1, E/T/RAPID subheader  */
+    rarh->E = 0;
+    rarh->T = 1;
+    rarh->RAPID = ra->preamble_index; // TBR Respond to Preamble 0 only for the moment
+    /* TBR handle MAC RAR BI subheader*/
+
+    /* TC-RNTI */
+    // TBR double check
+    rar[5] = (uint8_t) (ra->rnti >> 8);
+    rar[6] = (uint8_t) (ra->rnti & 0xff);
+    // TBR double check
 
-    for (i = 0; i < NB_RA_PROC_MAX; i++) {
+    /* Timing Advance Command */
+    // TBR double check
+    //ra->timing_offset = 0;
+    //printf("ra->timing_offset %d\n", ra->timing_offset); // TBR remove
 
-	    ra = (RA_t *) & cc[CC_id].ra[i];
-      //LOG_D(MAC,"RA[state:%d]\n",ra->state);
+    ra->timing_offset /= 16;    //T_A = N_TA/16, where N_TA should be on a 30.72Msps
+    rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4));  // 7 MSBs of timing advance + divide by 4
+    rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0;   // 4 LSBs of timing advance + divide by 4
+    // TBR double check
 
-	    if (ra->state == MSG2)
-        generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
-	    else if (ra->state == MSG4)
-        generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
-	    else if (ra->state == WAITMSG4ACK)
-        check_Msg4_retransmission(module_idP, CC_id, frameP, subframeP, ra);
+    // TBR double check
+    COMMON_channels_t *cc = &RC.mac[mod_id]->common_channels[CC_id];
+    if(N_RB_UL == 25){
+      ra->msg3_first_rb = 1;
+    }else{
+      // if (cc->tdd_Config && N_RB_UL == 100) {  // TBR missing tdd_Config
+      //   ra->msg3_first_rb = 3;
+      // } else {
+      //   ra->msg3_first_rb = 2;
+      // }
+    }
+    ra->msg3_nb_rb = 1;
+    // TBR double check
 
-	}			// for i=0 .. N_RA_PROC-1
-    }				// CC_id
+    /* UL Grant */
+    // TBR fix this
+    uint16_t rballoc = nr_mac_compute_RIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb);  // first PRB only for UL Grant
+    rar[1] |= (rballoc >> 7) & 7;   // Hopping = 0 (bit 3), 3 MSBs of rballoc
+    rar[2] = ((uint8_t) (rballoc & 0xff)) << 1; // 7 LSBs of rballoc
+    ra->msg3_mcs = 10;
+    ra->msg3_TPC = 3;
+    ra->msg3_ULdelay = 0;
+    ra->msg3_cqireq = 0;
+    ra->msg3_round = 0;
+    rar[2] |= ((ra->msg3_mcs & 0x8) >> 3);  // mcs 10
+    rar[3] = (((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) | ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1);
+    // TBR double check
 
-    stop_meas(&mac->schedule_ra);
+    return ra->rnti;
 }
+
+void nr_add_msg3(module_id_t module_idP, int CC_id, NR_RA_t *ra, frame_t frameP, sub_frame_t subframeP){
+
+  #if 0
+  eNB_MAC_INST *mac = RC.mac[module_idP];
+  COMMON_channels_t *cc = &mac->common_channels[CC_id];
+  uint8_t j;
+  nfapi_ul_config_request_t *ul_req;
+  nfapi_ul_config_request_body_t *ul_req_body;
+  nfapi_ul_config_request_pdu_t *ul_config_pdu;
+  nfapi_hi_dci0_request_t        *hi_dci0_req;
+  nfapi_hi_dci0_request_body_t   *hi_dci0_req_body;
+  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
+  uint8_t sf_ahead_dl;
+  uint8_t rvseq[4] = {0, 2, 3, 1};
+  ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe];
+  ul_req_body = &ul_req->ul_config_request_body;
+  AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n",
+              ra->rnti);
+#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+
+  if (ra->rach_resource_type > 0) {
+    LOG_D (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n",
+           module_idP, frameP, subframeP, CC_id, ra->rach_resource_type - 1, ra->Msg3_frame, ra->Msg3_subframe);
+    LOG_D (MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n",
+           frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, ra->msg3_nb_rb, ra->msg3_round);
+    ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
+    memset ((void *) ul_config_pdu, 0, sizeof (nfapi_ul_config_request_pdu_t));
+    ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
+    ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_ulsch_pdu));
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb (cc, ra->msg34_narrowband) + ra->msg3_first_rb;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round];
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb);
+    // Re13 fields
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
+    ul_req_body->number_of_pdus++;
+  }                             //  if (ra->rach_resource_type>0) {
+  else
+#endif
+  {
+    LOG_D(MAC,
+          "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n",
+          module_idP, frameP, subframeP, CC_id, ra->Msg3_frame,
+          ra->Msg3_subframe);
+    LOG_D(MAC,
+          "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
+          frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe,
+          ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti);
+    ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
+    memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t));
+    ul_config_pdu->pdu_type                                                = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
+    ul_config_pdu->pdu_size                                                = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu));
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                         = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                         = mac->ul_handle++;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                           = ra->rnti;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start           = ra->msg3_first_rb;
+    AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n");
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks      = ra->msg3_nb_rb;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type                = 2;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms        = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits         = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication            = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version             = rvseq[ra->msg3_round];
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number            = subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe);
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                     = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                  = 0;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                          = 1;
+    ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                           = get_TBS_UL(10, ra->msg3_nb_rb);
+    ul_req_body->number_of_pdus++;
+    ul_req_body->tl.tag                                                    = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
+    ul_req->sfn_sf                                                         = ra->Msg3_frame<<4|ra->Msg3_subframe;
+    ul_req->header.message_id                                              = NFAPI_UL_CONFIG_REQUEST;
+
+    // save UL scheduling information for preprocessor
+    for (j = 0; j < ra->msg3_nb_rb; j++)
+      cc->vrb_map_UL[ra->msg3_first_rb + j] = 1;
+
+    LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round);
+
+    if (ra->msg3_round != 0) {  // program HI too
+      sf_ahead_dl = ul_subframe2_k_phich(cc, subframeP);
+      hi_dci0_req = &mac->HI_DCI0_req[CC_id][(subframeP+sf_ahead_dl)%10];
+      hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
+      hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
+      memset((void *) hi_dci0_pdu, 0,
+             sizeof(nfapi_hi_dci0_request_pdu_t));
+      hi_dci0_pdu->pdu_type                                   = NFAPI_HI_DCI0_HI_PDU_TYPE;
+      hi_dci0_pdu->pdu_size                                   = 2 + sizeof(nfapi_hi_dci0_hi_pdu);
+      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag                  = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
+      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start    = ra->msg3_first_rb;
+      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
+      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                = 0;
+      hi_dci0_req_body->number_of_hi++;
+      hi_dci0_req_body->sfnsf                                 = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0);
+      hi_dci0_req_body->tl.tag                                = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
+      hi_dci0_req->sfn_sf                                     = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl);
+      hi_dci0_req->header.message_id                          = NFAPI_HI_DCI0_REQUEST;
+
+      if (NFAPI_MODE != NFAPI_MONOLITHIC) {
+        oai_nfapi_hi_dci0_req(hi_dci0_req);
+        hi_dci0_req_body->number_of_hi=0;
+      }
+
+      LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi);
+
+      // save UL scheduling information for preprocessor
+      for (j = 0; j < ra->msg3_nb_rb; j++)
+        cc->vrb_map_UL[ra->msg3_first_rb + j] = 1;
+
+      LOG_D(MAC,
+            "[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA (mcs %d, first rb %d, nb_rb %d,round %d)\n",
+            module_idP, ra->rnti, CC_id, frameP, subframeP, 10, 1, 1,
+            ra->msg3_round - 1);
+    }     //       if (ra->msg3_round != 0) { // program HI too
+  }       // non-BL/CE UE case
+  #endif
+}
\ No newline at end of file
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
index 9555e1d046abf25ead70053a7eb6fc11d24f0e29..024496c3d07410ad6e04f0a9ba105ee248921e6c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c
@@ -31,9 +31,9 @@
  */
 
 #include "assertions.h"
-#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_gNB/nr_mac_gNB.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "UTIL/OPT/opt.h"
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 52332701499d2868dc5c7c5cd13298439eb634d4..2999f4d8eeb6d4136c2be2fa36d570f18c4395ee 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -34,9 +34,9 @@
 #include "PHY/defs_nr_common.h"
 #include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
 /*MAC*/
-#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
-#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_COMMON/nr_mac.h"
+#include "NR_MAC_gNB/nr_mac_gNB.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 #include "LAYER2/MAC/mac.h"
 
 /*NFAPI*/
@@ -97,6 +97,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
     }
 
     LOG_D(MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id);
+
     mac_ce_size = sizeof(NR_MAC_CE_TA);
 
     // Copying  bytes for MAC CEs to the mac pdu pointer
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index 55a73851438876408e184ec048871dbd00758c67..68f1021c68160ce07ef5f2a602fda2c03630bd72 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -30,8 +30,8 @@
 
 #include "nr_mac_gNB.h"
 #include "SCHED_NR/sched_nr.h"
-#include "mac_proto.h"
-#include "nr_mac_common.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
 #include "PHY/NR_TRANSPORT/nr_dlsch.h"
 #include "PHY/NR_TRANSPORT/nr_dci.h"
 #include "executables/nr-softmodem.h"
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 9a9bfa0164c21d787c79008459e9ad0ac121f8fb..a94934c4329bfb4cc042963eb361fc43d2c472da 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -33,10 +33,10 @@
 #include "assertions.h"
 
 #include "LAYER2/MAC/mac.h"
-#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_gNB/nr_mac_gNB.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
 #include "common/utils/LOG/log.h"
 #include "common/utils/LOG/vcd_signal_dumper.h"
 #include "common/utils/nr/nr_common.h"
@@ -1363,4 +1363,177 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
     }
   }
 }
-*/
\ No newline at end of file
+*/
+
+/* TBR fix this
+boolean_t nr_CCE_allocation_infeasible(int module_idP, int CC_idP, int format_flag, int slot, int aggregation, int rnti){
+  
+  nfapi_dl_config_request_body_t *DL_req = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body;
+  nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
+  nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][slot].hi_dci0_request_body;
+  nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi];
+  
+  int ret;
+  boolean_t res = FALSE;
+
+  if (format_flag != 2) { // DL DCI
+    if (DL_req->number_pdu == MAX_NUM_DL_PDU) {
+      LOG_W(MAC,
+      "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n",
+      slot, rnti);
+    } else {
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
+      dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0) ? 2 : 1;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation;
+      DL_req->number_pdu++;
+
+      LOG_D(MAC, "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n",
+        slot, format_flag, rnti, aggregation,
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
+        aggregation_level,
+        dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type);
+      
+      // ret = nr_allocate_CCEs(module_idP, CC_idP, 0, slot, 0); // TBR
+      
+      if (ret == -1) res = TRUE;
+      
+      DL_req->number_pdu--;
+    }
+  } else {      // ue-specific UL DCI
+    if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == MAX_NUM_HI_DCI0_PDU) {
+      LOG_W(MAC, "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", slot, rnti);
+    } else {
+      hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
+      HI_DCI0_req->number_of_dci++;
+      // ret = nr_allocate_CCEs(module_idP, CC_idP, 0, slot, 0); // TBR
+      if (ret == -1) res = TRUE;
+      HI_DCI0_req->number_of_dci--;
+    }
+  }
+
+  return res;
+}*/
+
+/* // TBR fix this
+void nr_get_Msg3alloc(NR_COMMON_channels_t *cc,
+                      sub_frame_t current_subframe, // TBR sub_frame_t
+                      frame_t current_frame, 
+                      frame_t *frame,
+                      sub_frame_t *subframe){
+  // Fill in other TDD Configuration!!!!
+
+  // TBR missing ‘tdd_Config’ in NR_COMMON_channels_t
+  if (cc->tdd_Config == NULL) { // FDD
+    *subframe = current_subframe + 6;
+    if (*subframe > 9) {
+      *subframe = *subframe - 10;
+      *frame = (current_frame + 1) & 1023;
+    } else {
+      *frame = current_frame;
+    }
+  } else { // TDD
+    if (cc->tdd_Config->subframeAssignment == 1) {
+    switch (current_subframe) {  
+    
+      case 0:
+      *subframe = 7;
+      *frame = current_frame;
+      break;
+
+      case 4:
+      *subframe = 2;
+      *frame = (current_frame + 1) & 1023;
+      break;
+
+      case 5:
+      *subframe = 2;
+      *frame = (current_frame + 1) & 1023;
+      break;
+
+      case 9:
+      *subframe = 7;
+      *frame = (current_frame + 1) & 1023;
+      break;
+      }
+  } else if (cc->tdd_Config->subframeAssignment == 3) {
+    switch (current_subframe) {
+
+      case 0:
+      case 5:
+      case 6:
+        *subframe = 2;
+        *frame = (current_frame + 1) & 1023;
+        break;
+
+      case 7:
+        *subframe = 3;
+        *frame = (current_frame + 1) & 1023;
+        break;
+
+      case 8:
+        *subframe = 4;
+        *frame = (current_frame + 1) & 1023;
+        break;
+
+      case 9:
+        *subframe = 2;
+        *frame = (current_frame + 2) & 1023;
+        break;
+      }
+  } else if (cc->tdd_Config->subframeAssignment == 4) {
+    switch (current_subframe) {
+
+      case 0:
+      case 4:
+      case 5:
+      case 6:
+        *subframe = 2;
+        *frame = (current_frame + 1) & 1023;
+        break;
+
+      case 7:
+        *subframe = 3;
+        *frame = (current_frame + 1) & 1023;
+        break;
+
+      case 8:
+      case 9:
+        *subframe = 2;
+        *frame = (current_frame + 2) & 1023;
+        break;
+      }
+  } else if (cc->tdd_Config->subframeAssignment == 5) {
+    switch (current_subframe){
+      case 0:
+      case 4:
+      case 5:
+      case 6:
+        *subframe = 2;
+        *frame = (current_frame + 1) & 1023;
+        break;
+    
+      case 7:
+      case 8:
+      case 9:
+        *subframe = 2;
+        *frame = (current_frame + 2) & 1023;
+        break;
+      }
+    } 
+  } // else TDD
+}*/
+
+uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs){ // TBR this is outdated
+  uint16_t RIV;
+
+  if (Lcrbs <= (1 + (N_RB_DL >> 1))) RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart;
+  else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart);
+
+  return RIV;
+}
\ No newline at end of file
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index 4ae679b8f564173e3954d29e2aa09d921731345b..604664f3efd1aa6a7be6bd515309970a1b092ee9 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -28,7 +28,7 @@
  * @ingroup _mac
  */
 
-#include "LAYER2/NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_gNB/mac_proto.h"
 
 /*
 * When data are received on PHY and transmitted to MAC
diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
index e0932e28e1bbfa69aa9cdbd4057dbcbf4fef8c68..c2ca2dc1fe914c6b847c1ce520c9ba4224ca3a5d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h
@@ -31,8 +31,9 @@
 #ifndef __LAYER2_NR_MAC_PROTO_H__
 #define __LAYER2_NR_MAC_PROTO_H__
 
-#include "nr_mac_gNB.h"
 #include "PHY/defs_gNB.h"
+
+#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
 #include "NR_TAG-Id.h"
 
 void set_cset_offset(uint16_t);
@@ -76,6 +77,61 @@ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slo
 
 void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
 
+/////// Random Access MAC-PHY interface functions and primitives ///////
+
+void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
+
+/* \brief Function to indicate a received preamble on PRACH.  It initiates the RA procedure.
+@param module_idP Instance ID of gNB
+@param preamble_index index of the received RA request
+@param slotP Slot number on which to act
+@param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to
+@param rnti RA rnti corresponding to this PRACH preamble
+@param rach_resource type (0=non BL/CE,1 CE level 0,2 CE level 1, 3 CE level 2,4 CE level 3)
+*/
+void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, 
+  uint16_t preamble_index, int16_t timing_offset, uint16_t rnti
+  #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+  , uint8_t rach_resource_type
+  #endif
+  );
+
+void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
+
+boolean_t nr_CCE_allocation_infeasible(int module_idP,
+                                       int CC_idP,
+                                       int common_flag,
+                                       int slot,
+                                       int aggregation,
+                                       int rnti);
+
+int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
+
+void nr_get_Msg3alloc(NR_COMMON_channels_t *cc,
+                      sub_frame_t current_subframe,
+                      frame_t current_frame, 
+                      frame_t *frame,
+                      sub_frame_t *subframe);
+
+/* \brief Function in gNB to fill RAR pdu when requested by PHY. This provides a single RAR SDU for the moment and returns the t-CRNTI.
+@param Mod_id Instance ID of gNB
+@param dlsch_buffer Pointer to DLSCH input buffer
+@param N_RB_UL Number of UL resource blocks
+@returns t_CRNTI
+*/
+unsigned short nr_fill_rar(const module_id_t module_idP,
+                           const int CC_id,
+                           NR_RA_t *ra,
+                           const frame_t frameP,
+                           uint8_t * const dlsch_buffer,
+                           const uint16_t N_RB_UL,
+                           const uint8_t input_buffer_length);
+
+
+uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
+
+/////// Phy test scheduler ///////
+
 void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
                                    frame_t       frameP,
                                    sub_frame_t   subframeP);
@@ -215,4 +271,42 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
                const uint16_t sdu_lenP,
                const uint16_t timing_advance, const uint8_t ul_cqi);
 
+/* Random Access */ 
+
+/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. 
+If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC 
+attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB 
+index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for 
+andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
+@param mod_id Index of UE instance
+@param CC_id Component Carrier Index
+@param frame
+@param gNB_id gNB index
+@param nr_tti_tx slot for PRACH transmission
+@returns A pointer to a PRACH_RESOURCES_t */
+NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id,
+                                     int CC_id,
+                                     UE_MODE_t UE_mode,
+                                     frame_t frame,
+                                     uint8_t gNB_id,
+                                     int nr_tti_tx);
+
+/* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321).
+@param module_idP Index of UE instance
+@param CC_id Component Carrier Index
+@param gNB_index gNB index
+@param t_id 
+@param rach_ConfigDedicated 
+@returns A pointer to a PRACH_RESOURCES_t */
+void nr_get_prach_resources(module_id_t mod_id, 
+                            int CC_id,
+                            uint8_t gNB_id,
+                            uint8_t t_id,
+                            uint8_t first_Msg3,
+                            NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
+
+void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
+
+void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
+
 #endif /*__LAYER2_NR_MAC_PROTO_H__*/
diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c
index ff552d0bfd597a96b02f4fd3eeb0518857be5bd5..775116faf684188e785736296851fc3346bdff34 100644
--- a/openair2/LAYER2/NR_MAC_gNB/main.c
+++ b/openair2/LAYER2/NR_MAC_gNB/main.c
@@ -30,8 +30,8 @@
 
  */
 
-#include "mac_proto.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
+#include "NR_MAC_gNB/mac_proto.h"
+#include "NR_MAC_COMMON/nr_mac_extern.h"
 #include "assertions.h"
 
 #include "LAYER2/PDCP_v10.1.0/pdcp.h"
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 5bc320d5e2ee67ec8d0e76e12fb5f07d3b4b716f..ad92fdb979a8359d0ce8969b24771bf38a6dfaa7 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -42,30 +42,95 @@
 #include <stdlib.h>
 #include <string.h>
 
+/* Commmon */
+#include "targets/ARCH/COMMON/common_lib.h"
+#include "COMMON/platform_constants.h"
+#include "common/ran_context.h"
+
+/* RRC */
 #include "NR_BCCH-BCH-Message.h"
 #include "NR_CellGroupConfig.h"
 #include "NR_ServingCellConfigCommon.h"
 #include "NR_MeasConfig.h"
 
+/* PHY */
+#include "PHY/defs_gNB.h"
+#include "PHY/TOOLS/time_meas.h"
+
+/* Interface */
 #include "nfapi_nr_interface_scf.h"
 #include "NR_PHY_INTERFACE/NR_IF_Module.h"
 
-#include "COMMON/platform_constants.h"
-#include "common/ran_context.h"
+/* MAC */
 #include "LAYER2/MAC/mac.h"
 #include "LAYER2/MAC/mac_proto.h"
 #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
-#include "PHY/defs_gNB.h"
-#include "PHY/TOOLS/time_meas.h"
-#include "targets/ARCH/COMMON/common_lib.h"
-
-#include "nr_mac_common.h"
+#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
+#include "NR_TAG.h"
 
+/* Defs */
 #define MAX_NUM_BWP 2
 #define MAX_NUM_CORESET 2
 #define MAX_NUM_CCE 90
+/*!\brief Maximum number of random access process */
+#define NR_NB_RA_PROC_MAX 4
 
-#include "NR_TAG.h"
+/*! \brief gNB template for the Random access information */
+typedef struct {
+    /// Flag to indicate this process is active
+    RA_state_t state;
+    /// Subframe where preamble was received
+    uint8_t preamble_subframe;
+    /// Subframe where Msg2 is to be sent
+    uint8_t Msg2_subframe;
+    /// Frame where Msg2 is to be sent
+    frame_t Msg2_frame;
+    /// Subframe where Msg3 is to be sent
+    sub_frame_t Msg3_subframe;
+    /// Frame where Msg3 is to be sent
+    frame_t Msg3_frame;
+    /// Subframe where Msg4 is to be sent
+    sub_frame_t Msg4_subframe;
+    /// Frame where Msg4 is to be sent
+    frame_t Msg4_frame;
+    /// harq_pid used for Msg4 transmission
+    uint8_t harq_pid;
+    /// UE RNTI allocated during RAR
+    rnti_t rnti;
+    /// RA RNTI allocated from received PRACH
+    uint16_t RA_rnti;
+    /// Received preamble_index
+    uint8_t preamble_index;
+    /// Received UE Contention Resolution Identifier
+    uint8_t cont_res_id[6];
+    /// Timing offset indicated by PHY
+    int16_t timing_offset;
+    /// Timeout for RRC connection
+    int16_t RRC_timer;
+    /// Msg3 first RB
+    uint8_t msg3_first_rb;
+    /// Msg3 number of RB
+    uint8_t msg3_nb_rb;
+    /// Msg3 MCS
+    uint8_t msg3_mcs;
+    /// Msg3 TPC command
+    uint8_t msg3_TPC;
+    /// Msg3 ULdelay command
+    uint8_t msg3_ULdelay;
+    /// Msg3 cqireq command
+    uint8_t msg3_cqireq;
+    /// Round of Msg3 HARQ
+    uint8_t msg3_round;
+    /// TBS used for Msg4
+    int msg4_TBsize;
+    /// MCS used for Msg4
+    int msg4_mcs;
+    ///
+    int32_t  crnti_rrc_mui; // TBR
+    ///
+    int8_t   crnti_harq_pid; // TBR
+
+} NR_RA_t;
 
 /*! \brief gNB common channels */
 typedef struct {
@@ -93,7 +158,7 @@ typedef struct {
   /// Outgoing RAR pdu for PHY
   RAR_PDU RAR_pdu;
   /// Template for RA computations
-  RA_t ra[NB_RA_PROC_MAX];
+  NR_RA_t ra[NR_NB_RA_PROC_MAX];
   /// VRB map for common channels
   uint8_t vrb_map[100];
   /// VRB map for common channels and retransmissions by PHICH
@@ -107,9 +172,8 @@ typedef struct {
   int dummy;
 } NR_UE_sched_ctrl_t;
 
-/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
+/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
 typedef struct {
-
   DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
   /// scheduling control info
   UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
@@ -192,66 +256,63 @@ typedef struct gNB_MAC_INST_s {
 
 typedef struct {
 
-
-uint8_t format_indicator; //1 bit
-uint16_t frequency_domain_assignment; //up to 16 bits
-uint8_t time_domain_assignment; // 4 bits
-uint8_t frequency_hopping_flag; //1 bit
-
-uint8_t ra_preamble_index; //6 bits
-uint8_t ss_pbch_index; //6 bits
-uint8_t prach_mask_index; //4 bits
-
-uint8_t vrb_to_prb_mapping; //0 or 1 bit
-uint8_t mcs; //5 bits
-uint8_t ndi; //1 bit
-uint8_t rv; //2 bits
-uint8_t harq_pid; //4 bits
-uint8_t dai; //0, 2 or 4 bits
-uint8_t dai1; //1 or 2 bits
-uint8_t dai2; //0 or 2 bits
-uint8_t tpc; //2 bits
-uint8_t pucch_resource_indicator; //3 bits
-uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
-
-uint8_t short_messages_indicator; //2 bits
-uint8_t short_messages; //8 bits
-uint8_t tb_scaling; //2 bits
-
-uint8_t carrier_indicator; //0 or 3 bits
-uint8_t bwp_indicator; //0, 1 or 2 bits
-uint8_t prb_bundling_size_indicator; //0 or 1 bits
-uint8_t rate_matching_indicator; //0, 1 or 2 bits
-uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
-uint8_t transmission_configuration_indication; //0 or 3 bits
-uint8_t srs_request; //2 bits
-uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
-uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
-uint8_t dmrs_sequence_initialization; //0 or 1 bit
-
-uint8_t srs_resource_indicator;
-uint8_t precoding_information;
-uint8_t csi_request;
-uint8_t ptrs_dmrs_association;
-uint8_t beta_offset_indicator; //0 or 2 bits
-
-uint8_t slot_format_indicator_count;
-uint8_t *slot_format_indicators;
-
-uint8_t pre_emption_indication_count;
-uint16_t *pre_emption_indications; //14 bit
-
-uint8_t block_number_count;
-uint8_t *block_numbers;
-
-uint8_t ul_sul_indicator; //0 or 1 bit
-uint8_t antenna_ports;
-
-uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
-uint16_t padding;
+  uint8_t format_indicator; //1 bit
+  uint16_t frequency_domain_assignment; //up to 16 bits
+  uint8_t time_domain_assignment; // 4 bits
+  uint8_t frequency_hopping_flag; //1 bit
+
+  uint8_t ra_preamble_index; //6 bits
+  uint8_t ss_pbch_index; //6 bits
+  uint8_t prach_mask_index; //4 bits
+
+  uint8_t vrb_to_prb_mapping; //0 or 1 bit
+  uint8_t mcs; //5 bits
+  uint8_t ndi; //1 bit
+  uint8_t rv; //2 bits
+  uint8_t harq_pid; //4 bits
+  uint8_t dai; //0, 2 or 4 bits
+  uint8_t dai1; //1 or 2 bits
+  uint8_t dai2; //0 or 2 bits
+  uint8_t tpc; //2 bits
+  uint8_t pucch_resource_indicator; //3 bits
+  uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
+
+  uint8_t short_messages_indicator; //2 bits
+  uint8_t short_messages; //8 bits
+  uint8_t tb_scaling; //2 bits
+
+  uint8_t carrier_indicator; //0 or 3 bits
+  uint8_t bwp_indicator; //0, 1 or 2 bits
+  uint8_t prb_bundling_size_indicator; //0 or 1 bits
+  uint8_t rate_matching_indicator; //0, 1 or 2 bits
+  uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
+  uint8_t transmission_configuration_indication; //0 or 3 bits
+  uint8_t srs_request; //2 bits
+  uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
+  uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
+  uint8_t dmrs_sequence_initialization; //0 or 1 bit
+
+  uint8_t srs_resource_indicator;
+  uint8_t precoding_information;
+  uint8_t csi_request;
+  uint8_t ptrs_dmrs_association;
+  uint8_t beta_offset_indicator; //0 or 2 bits
+
+  uint8_t slot_format_indicator_count;
+  uint8_t *slot_format_indicators;
+
+  uint8_t pre_emption_indication_count;
+  uint16_t *pre_emption_indications; //14 bit
+
+  uint8_t block_number_count;
+  uint8_t *block_numbers;
+
+  uint8_t ul_sul_indicator; //0 or 1 bit
+  uint8_t antenna_ports;
+
+  uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
+  uint16_t padding;
 
 } dci_pdu_rel15_t;
 
-
-
 #endif /*__LAYER2_NR_MAC_GNB_H__ */
diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
index 770e27dd608b5c4063c514e0f20400e3e332c2c6..60629958415e8e5d914ccb883dac392eb50e416b 100644
--- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c
@@ -57,24 +57,19 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
     AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n");
     UL_info->rach_ind.rach_indication_body.number_of_preambles=0;
     LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->slot, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf));
-    /*
-    initiate_ra_proc(UL_info->module_id,
-
-    		         UL_info->CC_id,
-					 NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf),
-					 NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf),
-					 UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble,
-					 UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
-					 UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti
-#if (NR_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) || (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-//#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
-                    ,0
-#endif
 
-         );
-    */
+    nr_initiate_ra_proc(UL_info->module_id,
+                        UL_info->CC_id,
+                        NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf),
+                        NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf),
+                        UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble,
+                        UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
+                        UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti
+                        #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // TBR
+                           ,0
+                        #endif
+    );
   }
-
 }
 
 void handle_nr_sr(NR_UL_IND_t *UL_info) {
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 4e6c0d8979b2980604f692967bfd4672807d6491..3ac9a8a43ffc7ff805f67124b0e938da148e902b 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -32,9 +32,9 @@
 
 #include "PHY/defs_nr_UE.h"
 #include "NR_IF_Module.h"
-#include "mac_proto.h"
+#include "NR_MAC_UE/mac_proto.h"
 #include "assertions.h"
-#include "LAYER2/NR_MAC_UE/mac_extern.h"
+#include "NR_MAC_UE/mac_extern.h"
 #include "SCHED_NR_UE/fapi_nr_ue_l1.h"
 #include "executables/nr-softmodem.h"
 
@@ -93,6 +93,14 @@ int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_n
   */
 }
 
+int8_t handle_rar (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, uint8_t *pduP, uint32_t pdu_len, frame_t frame, int slot, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){
+
+  if (IS_SOFTMODEM_NOS1 || IS_SOFTMODEM_RFSIM)
+    //nr_process_rar(ue,proc, gNB_index, mode); TBR
+
+  return 0;
+}
+
 int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
 
   NR_UE_L2_STATE_t ret;
@@ -231,11 +239,11 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
 					     dl_info->rx_ind->rx_indication_body[i].mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;*/
 	break;
       case FAPI_NR_RX_PDU_TYPE_SIB:
-	ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
-				       (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
-				       (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
-				       (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length )) << FAPI_NR_RX_PDU_TYPE_SIB;
-	break;
+      ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index,
+                  (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask,
+                  (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu,
+                  (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length )) << FAPI_NR_RX_PDU_TYPE_SIB;
+      break;
       case FAPI_NR_RX_PDU_TYPE_DLSCH:
 	//                    ret_mask |= (0) << FAPI_NR_RX_PDU_TYPE_DLSCH;
 	ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
@@ -249,17 +257,17 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
 	  dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
 	  dl_config->number_pdus = dl_config->number_pdus + 1;
 	  */
+      break;
 
-	/*ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
-					  dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu,
-					  dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
+      case FAPI_NR_RX_PDU_TYPE_RAR:
+      /*ret_mask |= (handle_rar(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
+                  (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
+                  (dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length,
+                  dl_info->frame, dl_info->slot,ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_RAR;*/ //TODO TBR
+      break;
 
-	*/
-	break;
       default:
-
-	break;
-
+	    break;
       }
     }
   }
diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c
index fb1ed160cb8b674e46a0656da07080c2dcbec59f..8b2966e0c5059d8b815f1262b58bd7aae72cc7ef 100644
--- a/openair2/RRC/NR/L2_nr_interface.c
+++ b/openair2/RRC/NR/L2_nr_interface.c
@@ -53,9 +53,8 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
                            uint8_t *const    buffer_pP ){
 
   asn_enc_rval_t enc_rval;
-  //SRB_INFO *Srb_info;
-  //uint8_t Sdu_size                = 0;
-  uint8_t sfn_msb                     = (uint8_t)((frameP>>4)&0x3f);
+  uint8_t Sdu_size = 0;
+  uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
   
 #ifdef DEBUG_RRC
   LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id);
@@ -64,11 +63,15 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
   gNB_RRC_INST *rrc;
   rrc_gNB_carrier_data_t *carrier;
   NR_BCCH_BCH_Message_t *mib;
+  NR_SRB_INFO * srb_info;
+  char payload_size, payload_pP;
   
   rrc     = RC.nrrrc[Mod_idP];
   carrier = &rrc->carrier;
   mib     = &carrier->mib;
+  srb_info = &carrier->Srb0;
 
+  /* MIBCH */
   if( (Srb_id & RAB_OFFSET ) == MIBCH) {
     mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2;
     enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message,
@@ -86,10 +89,31 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
     return(3);
   }
 
-//BCCH SIB1 SIBs
+  /* TODO BCCH SIB1 SIBs */
 
-//CCCH
+  /* CCCH */  // TBR lte code
+  if( (Srb_id & RAB_OFFSET ) == CCCH) {
+    //struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
+    //if (ue_context_p == NULL) return(0);
+    //eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
+    LOG_D(RRC,"[gNB %d] Frame %d CCCH request (Srb_id %d)\n", Mod_idP, frameP, Srb_id);
+
+    // srb_info=&ue_p->Srb0;
+
+    payload_size = srb_info->Tx_buffer.payload_size;
+
+    // check if data is there for MAC
+    if (payload_size > 0) {
+      payload_pP = srb_info->Tx_buffer.Payload;
+      LOG_D(RRC,"[gNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n", Mod_idP, srb_info, payload_size, buffer_pP, payload_pP);
+      // Fill buffer
+      memcpy(buffer_pP, payload_pP, payload_size);
+      Sdu_size = payload_size;
+      srb_info->Tx_buffer.payload_size = 0;
+    }
+    return Sdu_size;
+  }
 
   return(0);
 
-}
+}
\ No newline at end of file
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index 38163a68b81512457931c755f6f22ab978fdd2b4..862cf48cec6259a8fa635fc15dde7b3005d4aab6 100755
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -42,7 +42,7 @@
 #include "rrc_defs.h"
 #include "rrc_proto.h"
 #include "rrc_vars.h"
-#include "mac_proto.h"
+#include "LAYER2/NR_MAC_UE/mac_proto.h"
 
 
 extern int phy_test;
diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h
index cb1207757dc5618ebc14779a8d6bfd62c18bd026..6481fb0cea266492f0d35ef86f40f0e7769feb05 100644
--- a/openair2/RRC/NR_UE/rrc_defs.h
+++ b/openair2/RRC/NR_UE/rrc_defs.h
@@ -39,8 +39,8 @@
 
 #include "platform_types.h"
 
-#include "LAYER2/NR_MAC_UE/mac.h"
-#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
+#include "NR_MAC_UE/mac.h"
+#include "NR_MAC_COMMON/nr_mac.h"
 #include "rrc_list.h"
 #include "NR_asn_constant.h"
 #include "NR_MeasConfig.h"