diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index dcf1bcf82342ec64a21bfe567ef7835cb0cb5715..7c39c77508710eace05eb93f4ae941c1d29851b3 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -46,6 +46,9 @@
 #include "NR_MIB.h"
 #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
 
+/* Softmodem params */
+#include "executables/softmodem-common.h"
+
 extern RAN_CONTEXT_t RC;
 //extern int l2_init_gNB(void);
 extern void mac_top_init_gNB(void);
@@ -360,22 +363,33 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
   
   if (secondaryCellGroup) {
 
-    NR_UE_list_t *UE_list = &RC.nrmac[Mod_idP]->UE_list;
-    int UE_id;
-    if (add_ue == 1) {
-      UE_id = add_new_nr_ue(Mod_idP,rnti);
-      UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup;
-      uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count;
-      UE_list->preambles[UE_id].num_preambles = num_preamble;
-      UE_list->preambles[UE_id].preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
-      for (int i=0; i<num_preamble; i++) {
-        UE_list->preambles[UE_id].preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
-      }
+    NR_UE_info_t *UE_info = &RC.nrmac[Mod_idP]->UE_info;
+    if (add_ue == 1 && get_softmodem_params()->phy_test) {
+      const int UE_id = add_new_nr_ue(Mod_idP,rnti);
+      UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
+      struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
+          secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
+      AssertFatal(bwpList->list.count == 1,
+                  "downlinkBWP_ToAddModList has %d BWP!\n",
+                  bwpList->list.count);
+      const int bwp_id = 1;
+      UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
       LOG_I(PHY,"Added new UE_id %d/%x with initial secondaryCellGroup\n",UE_id,rnti);
-    }
-    else { // secondaryCellGroup has been updated
-      UE_id = find_nr_UE_id(Mod_idP,rnti);
-      UE_list->secondaryCellGroup[UE_id] = secondaryCellGroup;
+    } else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
+      const int CC_id = 0;
+      NR_RA_t *ra = &RC.nrmac[Mod_idP]->common_channels[CC_id].ra[0];
+      ra->state = RA_IDLE;
+      ra->secondaryCellGroup = secondaryCellGroup;
+      ra->crnti = rnti;
+      uint8_t num_preamble = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.count;
+      ra->preambles.num_preambles = num_preamble;
+      ra->preambles.preamble_list = (uint8_t *) malloc(num_preamble*sizeof(uint8_t));
+      for (int i = 0; i < num_preamble; i++)
+        ra->preambles.preamble_list[i] = secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list.array[i]->ra_PreambleIndex;
+      LOG_I(PHY,"Added new RA process for UE RNTI %04x with initial secondaryCellGroup\n", rnti);
+    } else { // secondaryCellGroup has been updated
+      const int UE_id = find_nr_UE_id(Mod_idP,rnti);
+      UE_info->secondaryCellGroup[UE_id] = secondaryCellGroup;
       LOG_I(PHY,"Modified UE_id %d/%x with secondaryCellGroup\n",UE_id,rnti);
     }
   }
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 2bb283d60de66eda959efc3592d5468d362ae12c..72dd1f09801cb55594ff8dca9442bfbe5b760fb5 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -57,7 +57,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
 			     uint8_t symbol) {
   
   gNB_MAC_INST *gNB = RC.nrmac[module_idP];
-  NR_COMMON_channels_t *cc = gNB->common_channels;
+  NR_COMMON_channels_t *cc = &gNB->common_channels[0];
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
   nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
 
@@ -134,7 +134,7 @@ int16_t ssb_index_from_prach(module_id_t module_idP,
 void find_SSB_and_RO_available(module_id_t module_idP) {
 
 	gNB_MAC_INST *gNB = RC.nrmac[module_idP];
-  NR_COMMON_channels_t *cc = gNB->common_channels;
+  NR_COMMON_channels_t *cc = &gNB->common_channels[0];
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
   nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
 
@@ -169,7 +169,7 @@ void find_SSB_and_RO_available(module_id_t module_idP) {
 
 	for(int i = 0;i < 64;i++) {
     if ((L_ssb >> (63-i)) & 0x01) { // only if the bit of L_ssb at current ssb index is 1
-    gNB->SSB_list[num_active_ssb].ssb_index = i; 
+      cc->ssb_index[num_active_ssb] = i; 
 		  num_active_ssb++;
     }
 	}	
@@ -421,38 +421,31 @@ void nr_initiate_ra_proc(module_id_t module_idP,
 
   uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL
   NR_SearchSpace_t *ss;
-  int UE_id = 0;
   // ra_rnti from 5.1.3 in 38.321
   uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8);
 
   uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset;
   gNB_MAC_INST *nr_mac = RC.nrmac[module_idP];
-  NR_UE_list_t *UE_list = &nr_mac->UE_list;
-  NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
   NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id];
   NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
-	NR_RA_t *ra = &cc->ra[0];
-
+  NR_RA_t *ra = &cc->ra[0];
   // if the preamble received correspond to one of the listed
   // the UE sent a RACH either for starting RA procedure or RA procedure failed and UE retries
   int pr_found=0;
-  for (int i=0;i<UE_list->preambles[UE_id].num_preambles;i++) {
-    if (preamble_index == UE_list->preambles[UE_id].preamble_list[i]) {
+  for (int i = 0; i < ra->preambles.num_preambles; i++) {
+    if (preamble_index == ra->preambles.preamble_list[i]) {
       pr_found=1;
       break;
     }
   }
-  if (pr_found)
-    UE_list->fiveG_connected[UE_id] = false;
-  else {
-    LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated for UE_id %d\n",
-          module_idP, preamble_index, UE_id);
+  if (!pr_found) {
+    LOG_E(MAC, "[gNB %d][RAPROC] FAILURE: preamble %d does not correspond to any of the ones in rach_ConfigDedicated\n",
+          module_idP, preamble_index);
     return; // if the PRACH preamble does not correspond to any of the ones sent through RRC abort RA proc
   }
-
   // This should be handled differently when we use the initialBWP for RA
   ra->bwp_id=1;
-  NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+  NR_BWP_Downlink_t *bwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1];
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
 
@@ -460,14 +453,12 @@ void nr_initiate_ra_proc(module_id_t module_idP,
 
   if (ra->state == RA_IDLE) {
 
-    uint8_t index = ssb_index_from_prach(module_idP,
-					 frameP,
-					 slotP,
-					 preamble_index,
-					 freq_index,
-					 symbol);
-
-    NR_SSB_list_t *SSB_list = &nr_mac->SSB_list[index];
+    uint8_t beam_index = ssb_index_from_prach(module_idP,
+		                              frameP,
+					      slotP,
+					      preamble_index,
+					      freq_index,
+					      symbol);
     int loop = 0;
     LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP);
     ra->state = Msg2;
@@ -489,13 +480,13 @@ void nr_initiate_ra_proc(module_id_t module_idP,
                                               &monitoring_slot_period,
                                               &monitoring_offset);
 
-    nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,index,cc->num_active_ssb);
+    nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset,beam_index,cc->num_active_ssb);
 
     ra->Msg2_frame = msg2_frame;
     ra->Msg2_slot = msg2_slot;
 
     LOG_I(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP);
-
+    if(pr_found)
     do {
       ra->rnti = (taus() % 65518) + 1;
       loop++;
@@ -508,21 +499,16 @@ void nr_initiate_ra_proc(module_id_t module_idP,
 
     ra->RA_rnti = ra_rnti;
     ra->preamble_index = preamble_index;
-    UE_list->tc_rnti[UE_id] = ra->rnti;
-    UE_list->UE_ssb_index[UE_id] = SSB_list->ssb_index;
-    SSB_list->SSB_UE_list[UE_id].tc_rnti = ra->rnti;
-    SSB_list->SSB_UE_list[UE_id].active = true;
-    SSB_list->num_UEs += 1;
+    ra->beam_id = beam_index;
 
-    LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u UE_id %u\n",
+    LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x SSB index %u\n",
       module_idP,
       CC_id,
       frameP,
       ra->Msg2_frame,
       ra->Msg2_slot,
       ra->RA_rnti,
-			SSB_list->ssb_index,
-			UE_id);
+      cc->ssb_index[beam_index]);
 
     return;
   }
@@ -618,7 +604,6 @@ void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frame
       ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t);
       ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu;
       ul_req->n_pdus+=1;
-      ra->state = RA_IDLE;
     }
   }
 }
@@ -629,8 +614,6 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
   NR_COMMON_channels_t                            *cc = &mac->common_channels[CC_id];
   NR_ServingCellConfigCommon_t                   *scc = cc->ServingCellConfigCommon;
   NR_RA_t                                         *ra = &cc->ra[0];
-  NR_UE_list_t                               *UE_list = &mac->UE_list;
-  int UE_id = 0;
 
   if (ra->state == RA_IDLE) {
     LOG_W(MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti);
@@ -642,14 +625,13 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t
   nfapi_nr_pusch_pdu_t  *pusch_pdu = &ra->pusch_pdu;
   memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t));
 
-
-  AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n", UE_id);
-
-  NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
-  AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
-    "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
-  NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
-  LOG_I(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
+  AssertFatal(ra->secondaryCellGroup,
+              "no secondaryCellGroup for RNTI %04x\n",
+              ra->crnti);
+  AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
+    "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
+  NR_BWP_Uplink_t *ubwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
+  LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
     frameP,
     slotP,
     ra->Msg3_frame,
@@ -738,17 +720,14 @@ void nr_generate_Msg2(module_id_t module_idP,
                       sub_frame_t slotP,
 											NR_RA_t *ra){
 
-  int UE_id = 0, dci_formats[2], rnti_types[2], mcsIndex;
+  int dci_formats[2], rnti_types[2], mcsIndex;
   int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment = 0;
   gNB_MAC_INST                      *nr_mac = RC.nrmac[module_idP];
   NR_COMMON_channels_t                  *cc = &nr_mac->common_channels[CC_id];
-//  NR_RA_t                               *ra = &cc->ra[0];
-  NR_UE_list_t                     *UE_list = &nr_mac->UE_list;
   NR_SearchSpace_t *ss = ra->ra_ss;
 
   uint16_t RA_rnti = ra->RA_rnti;
   long locationAndBandwidth;
-  // uint8_t *vrb_map = cc[CC_id].vrb_map, CC_id;
 
   // check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD
   // get the BW of the PDCCH for PDCCH size and RAR PDSCH size
@@ -793,11 +772,13 @@ void nr_generate_Msg2(module_id_t module_idP,
     // This code from this point on will not work on initialBWP or CORESET0
     AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n");
 
-    NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id];
-    AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
-      "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
-    NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
-    NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
+    AssertFatal(ra->secondaryCellGroup,
+                "no secondaryCellGroup for RNTI %04x\n",
+                ra->crnti);
+    AssertFatal(ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1,
+      "downlinkBWP_ToAddModList has %d BWP!\n", ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count);
+    NR_BWP_Downlink_t *bwp = ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1];
+    NR_BWP_Uplink_t *ubwp=ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1];
 
     LOG_I(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw);
 
@@ -877,7 +858,30 @@ void nr_generate_Msg2(module_id_t module_idP,
 	  dci_pdu_rel15[0].mcs,
 	  dci_pdu_rel15[0].tb_scaling);
 
-    nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, RA_rnti, 0, ss, scc, bwp);
+    uint8_t nr_of_candidates, aggregation_level;
+    find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss);
+    NR_ControlResourceSet_t *coreset = get_coreset(bwp, ss, 0 /* common */);
+    int CCEIndex = allocate_nr_CCEs(
+        nr_mac,
+        bwp,
+        coreset,
+        aggregation_level,
+        0, /* n_RNTI 0: common search space */
+        0); // m
+
+    if (CCEIndex < 0) {
+      LOG_E(MAC, "%s(): cannot find free CCE for RA RNTI %04x!\n", __func__, ra->rnti);
+      return;
+    }
+    nr_configure_pdcch(nr_mac,
+                       pdcch_pdu_rel15,
+                       RA_rnti,
+                       ss,
+                       coreset,
+                       scc,
+                       bwp,
+                       aggregation_level,
+                       CCEIndex);
 
     LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti);
 
@@ -892,7 +896,7 @@ void nr_generate_Msg2(module_id_t module_idP,
       pdcch_pdu_rel15->StartSymbolIndex,
       pdcch_pdu_rel15->DurationSymbols);
 
-    fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id);
+    fill_dci_pdu_rel15(scc,ra->secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id);
 
     dl_req->nPDUs+=2;
 
@@ -915,6 +919,11 @@ void nr_generate_Msg2(module_id_t module_idP,
     nr_mac->TX_req[CC_id].Number_of_PDUs++;
     nr_mac->TX_req[CC_id].Slot = slotP;
     memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length);
+
+    /* mark the corresponding RBs as used */
+    uint8_t *vrb_map = cc[CC_id].vrb_map;
+    for (int rb = 0; rb < pdsch_pdu_rel15->rbSize; rb++)
+      vrb_map[rb + pdsch_pdu_rel15->rbStart] = 1;
   }
 }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index d66ec9c52fb7e5f6f5858aa9fd139a7ac5913653..297f118e1666322da28d3686a9404491bcd66500 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -212,7 +212,7 @@ void nr_process_mac_pdu(
 
                 LOG_D(MAC, "[UE %d] Frame %d : ULSCH -> UL-DTCH %d (gNB %d, %d bytes)\n", module_idP, frameP, rx_lcid, module_idP, mac_sdu_len);
 		int UE_id = find_nr_UE_id(module_idP, rnti);
-		RC.nrmac[module_idP]->UE_list.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
+		RC.nrmac[module_idP]->UE_info.mac_stats[UE_id].lc_bytes_rx[rx_lcid] += mac_sdu_len;
                 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
                     LOG_T(MAC, "[UE %d] First 32 bytes of DLSCH : \n", module_idP);
 
@@ -313,19 +313,19 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
                const uint16_t rssi){
   int current_rnti = 0, UE_id = -1, harq_pid = 0;
   gNB_MAC_INST *gNB_mac = NULL;
-  NR_UE_list_t *UE_list = NULL;
+  NR_UE_info_t *UE_info = NULL;
   NR_UE_sched_ctrl_t *UE_scheduling_control = NULL;
 
   current_rnti = rntiP;
   UE_id = find_nr_UE_id(gnb_mod_idP, current_rnti);
   gNB_mac = RC.nrmac[gnb_mod_idP];
-  UE_list = &gNB_mac->UE_list;
+  UE_info = &gNB_mac->UE_info;
   int target_snrx10 = gNB_mac->pusch_target_snrx10;
 
   if (UE_id != -1) {
-    UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
+    UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]);
 
-    UE_list->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
+    UE_info->mac_stats[UE_id].ulsch_total_bytes_rx += sdu_lenP;
     LOG_D(MAC, "[gNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
           gnb_mod_idP,
           harq_pid,
@@ -366,20 +366,45 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
 
     }
   }
-  else {
+  else if (sduP != NULL) { // if the CRC passed
     // random access pusch with TC-RNTI
-    if (sduP != NULL) { // if the CRC passed
-      for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) {
-        if (UE_list->active[i] == TRUE) {
-          if (UE_list->tc_rnti[i] == current_rnti) {
-            // for now the only thing we are doing is set the UE as 5G connected
-            UE_list->fiveG_connected[i] = true;
-            LOG_I(MAC, "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly and UE_id %d is now 5G connected\n",
-                  gnb_mod_idP, current_rnti, i);
-          }
-        }
-      }
+    NR_RA_t *ra = &gNB_mac->common_channels[CC_idP].ra[0];
+    if (ra->state != WAIT_Msg3) {
+      LOG_E(MAC,
+            "expected RA state WAIT_Msg3/%d (but is %d) for RA-RNTI %04x\n",
+            WAIT_Msg3,
+            ra->state,
+            ra->rnti);
+      return;
+    }
+    if (ra->rnti != current_rnti) {
+      LOG_E(MAC,
+            "expected RA-RNTI %04x (C-RNTI %04x) to match current RNTI %04x\n",
+            ra->rnti,
+            ra->crnti,
+            current_rnti);
+      return;
     }
+    free(ra->preambles.preamble_list);
+    ra->state = RA_IDLE;
+    LOG_I(MAC, "reset RA state information for RA-RNTI %04x\n", ra->rnti);
+    const int UE_id = add_new_nr_ue(gnb_mod_idP, ra->crnti);
+    UE_info->secondaryCellGroup[UE_id] = ra->secondaryCellGroup;
+    UE_info->UE_beam_index[UE_id] = ra->beam_id;
+    struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList =
+        ra->secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
+    AssertFatal(bwpList->list.count == 1,
+                "downlinkBWP_ToAddModList has %d BWP!\n",
+                bwpList->list.count);
+    const int bwp_id = 1;
+    UE_info->UE_sched_ctrl[UE_id].active_bwp = bwpList->list.array[bwp_id - 1];
+    LOG_W(MAC,
+          "[gNB %d][RAPROC] PUSCH with TC_RNTI %x received correctly, "
+          "adding UE MAC Context UE_id %d/RNTI %04x\n",
+          gnb_mod_idP,
+          current_rnti,
+          UE_id,
+          ra->crnti);
   }
 }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index 93201a3d73a4438e5b18b9ea37f246dff4fee175..54bdacf3dc396d281dc128218e91560a8c8e743c 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -74,6 +74,7 @@
 #define MAX_NUM_CCE 90
 /*!\brief Maximum number of random access process */
 #define NR_NB_RA_PROC_MAX 4
+#define MAX_NUM_OF_SSB 64
 
 typedef enum {
   RA_IDLE = 0,
@@ -83,6 +84,11 @@ typedef enum {
   WAIT_Msg4_ACK = 4
 } RA_gNB_state_t;
 
+typedef struct NR_preamble_ue {
+  uint8_t num_preambles;
+  uint8_t *preamble_list;
+} NR_preamble_ue_t;
+
 /*! \brief gNB template for the Random access information */
 typedef struct {
   /// Flag to indicate this process is active
@@ -141,8 +147,14 @@ typedef struct {
   int msg4_mcs;
   /// RA search space
   NR_SearchSpace_t *ra_ss;
-  // SSB id
-  uint8_t ssb_id;
+  // Beam index
+  uint8_t beam_id;
+  /// secondaryCellGroup for UE in NSA that is to come
+  NR_CellGroupConfig_t *secondaryCellGroup;
+  /// Preambles for contention-free access
+  NR_preamble_ue_t preambles;
+  /// NSA: the UEs C-RNTI to use
+  rnti_t crnti;
 } NR_RA_t;
 
 /*! \brief gNB common channels */
@@ -174,19 +186,21 @@ typedef struct {
   /// Template for RA computations
   NR_RA_t ra[NR_NB_RA_PROC_MAX];
   /// VRB map for common channels
-  uint8_t vrb_map[100];
+  uint8_t vrb_map[275];
   /// VRB map for common channels and retransmissions by PHICH
-  uint8_t vrb_map_UL[100];
+  uint8_t vrb_map_UL[275];
   /// number of subframe allocation pattern available for MBSFN sync area
   uint8_t num_sf_allocation_pattern;
-	///Number of active SSBs
-	uint8_t num_active_ssb;
-	//Total available prach occasions per configuration period
-	uint32_t total_prach_occasions_per_config_period;
-	//Total available prach occasions
-	uint32_t total_prach_occasions;
-	//Max Association period
-	uint8_t max_association_period;
+  ///Number of active SSBs
+  uint8_t num_active_ssb;
+  //Total available prach occasions per configuration period
+  uint32_t total_prach_occasions_per_config_period;
+  //Total available prach occasions
+  uint32_t total_prach_occasions;
+  //Max Association period
+  uint8_t max_association_period;
+  //SSB index
+  uint8_t ssb_index[MAX_NUM_OF_SSB];
 } NR_COMMON_channels_t;
 
 
@@ -278,6 +292,14 @@ typedef struct NR_UE_harq {
   uint16_t feedback_slot;
 } NR_UE_harq_t;
 
+typedef struct NR_UE_old_sched {
+  uint16_t rbSize;
+  int time_domain_allocation;
+  uint8_t mcsTableIdx;
+  uint8_t mcs;
+  uint8_t numDmrsCdmGrpsNoData;
+} NR_UE_ret_info_t;
+
 typedef enum {
   INACTIVE = 0,
   ACTIVE_NOT_SCHED,
@@ -293,10 +315,39 @@ typedef struct NR_UE_ul_harq {
 
 /*! \brief scheduling control information set through an API */
 typedef struct {
-  uint64_t dlsch_in_slot_bitmap;  // static bitmap signaling which slot in a tdd period contains dlsch
-  uint64_t ulsch_in_slot_bitmap;  // static bitmap signaling which slot in a tdd period contains ulsch
+  /// total amount of data awaiting for this UE
+  uint32_t num_total_bytes;
+  /// per-LC status data
+  mac_rlc_status_resp_t rlc_status[MAX_NUM_LCID];
+
+  /// the currently active BWP in DL
+  NR_BWP_Downlink_t *active_bwp;
   NR_sched_pucch *sched_pucch;
+  /// selected PUCCH index, if scheduled
+  int pucch_sched_idx;
   NR_sched_pusch *sched_pusch;
+
+  /// CCE index and aggregation, should be coherent with cce_list
+  NR_SearchSpace_t *search_space;
+  NR_ControlResourceSet_t *coreset;
+  int cce_index;
+  uint8_t aggregation_level;
+
+  /// RB allocation within active BWP
+  uint16_t rbSize;
+  uint16_t rbStart;
+
+  // time-domain allocation for scheduled RBs
+  int time_domain_allocation;
+
+  /// MCS-related infos
+  uint8_t mcsTableIdx;
+  uint8_t mcs;
+  uint8_t numDmrsCdmGrpsNoData;
+
+  /// Retransmission-related information
+  NR_UE_ret_info_t retInfo[NR_MAX_NB_HARQ_PROCESSES];
+
   uint16_t ta_timer;
   int16_t ta_update;
   bool ta_apply;
@@ -310,11 +361,6 @@ typedef struct {
   NR_UE_mac_ce_ctrl_t UE_mac_ce_ctrl;// MAC CE related information
 } NR_UE_sched_ctrl_t;
 
-typedef struct NR_preamble_ue {
-  uint8_t num_preambles;
-  uint8_t *preamble_list;
-} NR_preamble_ue;
-
 typedef struct {
 
   int lc_bytes_tx[64];
@@ -328,40 +374,28 @@ typedef struct {
   int ulsch_total_bytes_rx;
 } NR_mac_stats_t;
 
+
+/*! \brief UNR_E_list_t is a "list" of users within UE_info_t. Especial useful in
+ * the scheduler and to keep "classes" of users. */
+typedef struct {
+  int head;
+  int next[MAX_MOBILES_PER_GNB];
+} NR_UE_list_t;
+
 /*! \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
   NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
   NR_mac_stats_t mac_stats[MAX_MOBILES_PER_GNB];
-  int next[MAX_MOBILES_PER_GNB];
-  int head;
-  int next_ul[MAX_MOBILES_PER_GNB];
-  int head_ul;
-  int avail;
+  NR_UE_list_t list;
   int num_UEs;
-  boolean_t active[MAX_MOBILES_PER_GNB];
-  boolean_t fiveG_connected[MAX_MOBILES_PER_GNB];
+  bool active[MAX_MOBILES_PER_GNB];
   rnti_t rnti[MAX_MOBILES_PER_GNB];
-  rnti_t tc_rnti[MAX_MOBILES_PER_GNB];
-  NR_preamble_ue preambles[MAX_MOBILES_PER_GNB];
   NR_CellGroupConfig_t *secondaryCellGroup[MAX_MOBILES_PER_GNB];
-	uint8_t UE_ssb_index[MAX_MOBILES_PER_GNB];
-} NR_UE_list_t;
-
-typedef struct {
-  rnti_t rnti;
-  rnti_t tc_rnti;
-  boolean_t active;  
-} NR_SSB_UE_list_t;
-
-#define MAX_NUM_OF_SSB 64
-
-typedef struct {
-	uint8_t ssb_index;
-  int num_UEs;
-  NR_SSB_UE_list_t SSB_UE_list[MAX_MOBILES_PER_GNB];
-} NR_SSB_list_t;		
+  // UE selected beam index
+  uint8_t UE_beam_index[MAX_MOBILES_PER_GNB];
+} NR_UE_info_t;
 
 /*! \brief top level eNB MAC structure */
 typedef struct gNB_MAC_INST_s {
@@ -395,9 +429,8 @@ typedef struct gNB_MAC_INST_s {
   /// NFAPI DL PDU structure
   nfapi_nr_tx_data_request_t        TX_req[NFAPI_CC_MAX];
 
-  NR_UE_list_t UE_list;
+  NR_UE_info_t UE_info;
 
-  NR_SSB_list_t SSB_list[MAX_NUM_OF_SSB];
   /// UL handle
   uint32_t ul_handle;