diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index ac9819cfe283a1510505a5b99da6813dcbe7ce36..e99c15ffe3f74704949feb9ec86cf38abdaf9819 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -939,7 +939,17 @@ typedef struct {
 
   uint16_t priority[MAX_NUM_LCID];
 
+  /// number of active DL LCs
+  uint8_t dl_lc_num;
+  /// order in which DLSCH scheduler should allocate LCs
+  uint8_t dl_lc_ids[NB_RB_MAX];
+  /// number of bytes to schedule for each LC
+  uint32_t dl_lc_bytes[NB_RB_MAX];
+  /// Total number of bytes to schedule
+  uint32_t dl_buffer_total;
+
   // resource scheduling information
+  int dlsch_mcs;
 
   /// Current DL harq round per harq_pid on each CC
   uint8_t round[NFAPI_CC_MAX][10];
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 170f9e356cde468e04804eeb7ebcc8282d4547ee..84699c4346010a614bf67907e58018df32211f94 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -188,25 +188,89 @@ uint16_t getBWPsize(module_id_t Mod_id, int UE_id, int bwp_id, int N_RB) {
   return NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth, N_RB);
 }
 
-void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
+void nr_dlsch_buffer_update(module_id_t Mod_id, frame_t frame, sub_frame_t slot) {
+  NR_UE_list_t *UE_list = &RC.nrmac[Mod_id]->UE_list;
+
+  for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
+    const rnti_t rnti = UE_list->rnti[UE_id];
+    UE_sched_ctrl_t *sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
+    sched_ctrl->dl_buffer_total = 0;
+
+    for (int i = 0; i < sched_ctrl->dl_lc_num; i++) {
+      const uint8_t lcid = sched_ctrl->dl_lc_ids[i];
+      mac_rlc_status_resp_t resp = mac_rlc_status_ind(Mod_id,
+                                                      rnti,
+                                                      Mod_id,
+                                                      frame,
+                                                      slot,
+                                                      ENB_FLAG_YES,
+                                                      MBMS_FLAG_NO,
+                                                      lcid,
+                                                      0,
+                                                      0);
+      sched_ctrl->dl_buffer_total += resp.bytes_in_buffer;
+      sched_ctrl->dl_lc_bytes[lcid] = resp.bytes_in_buffer;
+
+      LOG_D(MAC,
+            "[gNB %d] %d.%d, UE %d RNTI %04x, LC %d, total buffer %d\n",
+            Mod_id,
+            frame,
+            slot,
+            UE_id,
+            rnti,
+            lcid,
+            sched_ctrl->dl_buffer_total);
+    }
+  }
+}
+
+void nr_dlsch_pre_processor(module_id_t Mod_id, frame_t f, sub_frame_t s) {
+  NR_UE_list_t *UE_list = &RC.nrmac[Mod_id]->UE_list;
+  AssertFatal(UE_list->num_UEs == 1,
+              "the scheduler handles only one UE at the moment, but found %d\n",
+              UE_list->num_UEs);
+
+  const int N_RB = 275;
   const int UE_id = 0;
-  const int bwp_id = 1;
   const int CC_id = 0;
+  const int bwp_id = 1;
+  UE_sched_ctrl_t *sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
 
-  gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
+  sched_ctrl->pre_nb_available_rbs[CC_id] = 0;
+  if (sched_ctrl->dl_buffer_total == 0)
+    return;
 
-  NR_UE_list_t *UE_list = &gNB_mac->UE_list;
+  // give all available RBs to this UE, start is implicit (0)
+  const uint16_t rbSize = getBWPsize(Mod_id, UE_id, bwp_id, N_RB);
+  sched_ctrl->pre_nb_available_rbs[CC_id] = rbSize;
+  sched_ctrl->dlsch_mcs = 9;
+}
 
-  if (UE_list->num_UEs ==0) return;
+void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
+  NR_UE_list_t *UE_list = &RC.nrmac[module_idP]->UE_list;
+  if (UE_list->num_UEs == 0)
+    return;
 
-  unsigned char sdu_lcids[NB_RB_MAX] = {0};
-  uint16_t sdu_lengths[NB_RB_MAX] = {0};
-  uint16_t rnti = UE_list->rnti[UE_id];
+  nr_dlsch_buffer_update(module_idP, frameP, slotP);
 
-  uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
+  // for every user, defines frequency allocation, MCS, etc
+  nr_dlsch_pre_processor(module_idP, frameP, slotP);
+
+  const int bwp_id = 1;
+  const int CC_id = 0;
+
+  gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
+  nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
+  nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[gNB_mac->TX_req[CC_id].Number_of_PDUs];
 
   LOG_D(MAC, "Scheduling UE specific search space DCI type 1\n");
 
+  int rbStart = 0;
+  int UE_id = 0;
+  UE_sched_ctrl_t *sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
+  if (sched_ctrl->pre_nb_available_rbs[CC_id] == 0)
+    return;
+
   int CCEIndex = allocate_nr_CCEs(gNB_mac,
                               bwp_id, // bwp_id
                               0, // coreset_id
@@ -219,51 +283,42 @@ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slo
     return;
   }
 
-  const int mcsIndex = 9;
-  const int N_RB = 275;
-  const uint16_t rbSize = getBWPsize(module_idP, UE_id, bwp_id, N_RB);
-  const uint16_t rbStart = 0;
   int TBS_bytes = configure_fapi_dl_pdu(gNB_mac,
                                         CC_id,
                                         UE_id,
                                         bwp_id,
                                         CCEIndex,
-                                        mcsIndex,
-                                        rbSize,
+                                        sched_ctrl->dlsch_mcs,
+                                        sched_ctrl->pre_nb_available_rbs[CC_id],
                                         rbStart);
 
+  unsigned char sdu_lcids[NB_RB_MAX] = {0};
+  uint16_t sdu_lengths[NB_RB_MAX] = {0};
+  uint8_t mac_sdus[MAX_NR_DLSCH_PAYLOAD_BYTES];
+  uint16_t rnti = UE_list->rnti[UE_id];
   int ta_len = gNB_mac->ta_len;
   int header_length_total = 0;
   int sdu_length_total = 0;
   int num_sdus = 0;
   int header_length_last;
-  for (int lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
-
-    // TODO: check if the lcid is active
-
-    LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n",
-      module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3);
-
-    if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 <= 0)
-      break;
-
-    mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(module_idP,
-                                                          rnti,
-                                                          module_idP,
-                                                          frameP,
-                                                          slotP,
-                                                          ENB_FLAG_YES,
-                                                          MBMS_FLAG_NO,
-                                                          lcid,
-                                                          0,
-                                                          0);
-
-    if (rlc_status.bytes_in_buffer <= 0)
+  for (int i = 0; i < sched_ctrl->dl_lc_num; i++) {
+    int lcid = sched_ctrl->dl_lc_ids[i];
+    // if nothing is allocated for this RB, continue
+    if (sched_ctrl->dl_lc_bytes[lcid] == 0)
       continue;
 
-    LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n",
-      module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
-      lcid, header_length_total, TBS_bytes);
+    int req_data =
+        min(TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
+            sched_ctrl->dl_lc_bytes[lcid]);
+    LOG_D(MAC,
+          "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting "
+          "%d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n",
+          module_idP,
+          frameP,
+          req_data,
+          lcid,
+          header_length_total,
+          TBS_bytes);
 
     sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
                                              rnti,
@@ -272,12 +327,16 @@ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slo
                                              ENB_FLAG_YES,
                                              MBMS_FLAG_NO,
                                              lcid,
-                                             TBS_bytes - ta_len - header_length_total - sdu_length_total - 3,
+                                             req_data,
                                              (char *)&mac_sdus[sdu_length_total],
                                              0,
                                              0);
 
-    LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid);
+    LOG_D(MAC,
+          "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
+          module_idP,
+          sdu_lengths[num_sdus],
+          lcid);
 
     sdu_lcids[num_sdus] = lcid;
     sdu_length_total += sdu_lengths[num_sdus];
@@ -287,6 +346,9 @@ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slo
     num_sdus++;
 
     //ue_sched_ctl->uplane_inactivity_timer = 0;
+
+    if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 <= 0)
+      break;
   }
 
   // check if there is at least one SDU or TA command
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index c33246dbc8b4e186566f836a3ca689249dcc58e1..752754afdb001cae3014ad649e9f36e2ef9779cb 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -1024,6 +1024,9 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
     memset((void *) &UE_list->UE_sched_ctrl[UE_id],
            0,
            sizeof(NR_UE_sched_ctrl_t));
+    // hard code single DL DRB 3 to check in the scheduler
+    UE_list->UE_sched_ctrl[UE_id].dl_lc_num = 1;
+    UE_list->UE_sched_ctrl[UE_id].dl_lc_ids[0] = DTCH;
     LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n",
           mod_idP,
           UE_id,