diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index b1bf32b7904ab7fa165f04bf4ab51143304a1110..ce056b5aa5d7d46a71eb924401ae9c99c1e2ece7 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -213,7 +213,7 @@ uint8_t nr_generate_pdsch(PHY_VARS_gNB *gNB,
       nr_pdsch_codeword_scrambling_optim(harq->f,
 					 encoded_length,
 					 q,
-					 rel15->dlDmrsScramblingId,
+					 rel15->dataScramblingId,
 					 rel15->rnti,
 					 scrambled_output[q]);
     
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
index c98a685ed8cff01d8aaa8344154fc2f3396cd2ae..68006f853b8cc15766cc5ab8dcf89515d5c21085 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c
@@ -155,7 +155,7 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint
       if (dlsch->harq_processes[i]) {
         memset(dlsch->harq_processes[i],0,sizeof(NR_DL_UE_HARQ_t));
         init_downlink_harq_status(dlsch->harq_processes[i]);
-        dlsch->harq_processes[i]->first_tx=1;
+        dlsch->harq_processes[i]->first_rx=1;
         dlsch->harq_processes[i]->b = (uint8_t *)malloc16(dlsch_bytes);
 
         if (dlsch->harq_processes[i]->b)
@@ -358,7 +358,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
     }
   }
 
-  if (harq_process->round == 0) {
+  if (harq_process->first_rx == 1) {
     // This is a new packet, so compute quantities regarding segmentation
     if (A > NR_MAX_PDSCH_TBS)
       harq_process->B = A+24;
@@ -448,7 +448,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue,
                                  harq_process->w[r],
                                  harq_process->C,
                                  harq_process->rvidx,
-                                 (harq_process->round==0)?1:0,
+                                 (harq_process->first_rx==1)?1:0,
                                  E,
                                  harq_process->F,
                                  Kr-harq_process->F-2*(p_decParams->Z))==-1) {
@@ -771,7 +771,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
     }
   }
 
-  if (harq_process->round == 0) {
+  if (harq_process->first_rx == 1) {
     // This is a new packet, so compute quantities regarding segmentation
     if (A > NR_MAX_PDSCH_TBS)
       harq_process->B = A+24;
@@ -909,7 +909,7 @@ uint32_t  nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue,
                                harq_process->w[r],
                                harq_process->C,
                                harq_process->rvidx,
-                               (harq_process->round==0)?1:0,
+                               (harq_process->first_rx==1)?1:0,
                                E,
                                harq_process->F,
                                Kr-harq_process->F-2*(p_decParams->Z))==-1) {
@@ -1229,25 +1229,23 @@ void nr_dlsch_decoding_process(void *arg) {
     }
   }
 
-  harq_process->round  =0;
+  if (harq_process->first_rx == 1) {
+    // This is a new packet, so compute quantities regarding segmentation
+    if (A > NR_MAX_PDSCH_TBS)
+      harq_process->B = A+24;
+    else
+      harq_process->B = A+16;
 
-  // if (harq_process->round == 0) {
-  // This is a new packet, so compute quantities regarding segmentation
-  if (A > NR_MAX_PDSCH_TBS)
-    harq_process->B = A+24;
-  else
-    harq_process->B = A+16;
-
-  nr_segmentation(NULL,
-                  NULL,
-                  harq_process->B,
-                  &harq_process->C,
-                  &harq_process->K,
-                  &harq_process->Z,
-                  &harq_process->F,
-                  p_decParams->BG);
-  p_decParams->Z = harq_process->Z;
-  // }
+    nr_segmentation(NULL,
+                    NULL,
+                    harq_process->B,
+                    &harq_process->C,
+                    &harq_process->K,
+                    &harq_process->Z,
+                    &harq_process->F,
+                    p_decParams->BG);
+    p_decParams->Z = harq_process->Z;
+  }
   LOG_D(PHY,"round %d Z %d K %d BG %d\n", harq_process->round, p_decParams->Z, harq_process->K, p_decParams->BG);
   p_decParams->numMaxIter = dlsch->max_ldpc_iterations;
   p_decParams->outMode= 0;
@@ -1314,7 +1312,7 @@ void nr_dlsch_decoding_process(void *arg) {
                                harq_process->w[r],
                                harq_process->C,
                                harq_process->rvidx,
-                               (harq_process->round==0)?1:0,
+                               (harq_process->first_rx==1)?1:0,
                                E,
                                harq_process->F,
                                Kr-harq_process->F-2*(p_decParams->Z))==-1) {
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
index e8a96062556b6ebd9015a809489699c999be1aa2..b4ee4f5b41d047483cdd90afa7491a225072d478 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h
@@ -206,8 +206,8 @@ typedef struct {
 } NR_UE_ULSCH_t;
 
 typedef struct {
-  /// Indicator of first transmission
-  uint8_t first_tx;
+  /// Indicator of first reception
+  uint8_t first_rx;
   /// Last Ndi received for this process on DCI (used for C-RNTI only)
   uint8_t DCINdi;
   /// DLSCH status flag indicating
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 4a17cb98b9bc7cb576a389c297d632fa0c4a17ed..db9c7da56c023a0c72ba51956c9fd64c074f6c8c 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -127,7 +127,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
             }
             dlsch0_harq->Nl = Nl;
             dlsch0_harq->mcs_table=dlsch_config_pdu->mcs_table;
-            downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch0->rnti_type);
+            downlink_harq_process(dlsch0_harq, dlsch0->current_harq_pid, dlsch_config_pdu->ndi, dlsch_config_pdu->rv, dlsch0->rnti_type);
             if (dlsch0_harq->status != ACTIVE) {
               // dlsch0_harq->status not ACTIVE may be due to false retransmission. Reset the 
               // following flag to skip PDSCH procedures in that case.
diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c
index 3f528f02d4693d47711d251ea16ec09df1aff423..7bc1f3053bafec50360e2ac01517ca87d6b757ef 100644
--- a/openair1/SCHED_NR_UE/harq_nr.c
+++ b/openair1/SCHED_NR_UE/harq_nr.c
@@ -306,8 +306,9 @@ harq_result_t uplink_harq_process(NR_UE_ULSCH_t *ulsch, int harq_pid, int ndi, u
 void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
 {
   dl_harq->status = SCH_IDLE;
-  dl_harq->first_tx = 1;
+  dl_harq->first_rx = 1;
   dl_harq->round  = 0;
+  dl_harq->DCINdi = 1;
   dl_harq->ack = DL_ACKNACK_NO_SET;
 }
 
@@ -328,39 +329,66 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq)
 *
 *********************************************************************/
 
-void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, uint8_t rnti_type) {
+void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int rv, uint8_t rnti_type) {
 
-  if (rnti_type == _CS_RNTI_) {
-    LOG_E(PHY, "Fatal error in HARQ entity due to not supported CS_RNTI at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__);
-    return;
-  }
-  else if ((rnti_type != _C_RNTI_) && (rnti_type != _TC_RNTI_)) {
-    /* harq mechanism is not relevant for other rnti */
-    return;
-  }
 
-  if (dl_harq->first_tx == 1) {
+  if (rnti_type == _SI_RNTI_ ||
+      rnti_type == _P_RNTI_ ||
+      rnti_type == _RA_RNTI_) {
     dl_harq->round = 0;
     dl_harq->status = ACTIVE;
-    dl_harq->DCINdi = ndi;
-    dl_harq->first_tx = 0;
-
-    LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] first new reception \n", harq_pid);
+    dl_harq->first_rx = 1;
   }
-  else if (dl_harq->DCINdi != ndi) {
-    dl_harq->round = 0;
-    dl_harq->status = ACTIVE;
-    dl_harq->DCINdi = ndi;
-
-    LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] new reception due to toogle of ndi \n", harq_pid);
+  else{
+    switch(rv){
+      case 0:
+        dl_harq->round = 0;
+        dl_harq->status = ACTIVE;
+        dl_harq->first_rx = 1;
+        if (dl_harq->DCINdi == ndi)
+          LOG_E(PHY,"Warning! rv %d indicates new transmission but new ndi %d is the same as old ndi %d\n",rv,ndi,dl_harq->DCINdi);
+        dl_harq->DCINdi = ndi;
+        break;
+      case 1:
+        dl_harq->round = 2;
+        dl_harq->first_rx = 0;
+        if (dl_harq->DCINdi != ndi) {
+          LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
+          dl_harq->status = ACTIVE;
+          dl_harq->first_rx = 1;
+          dl_harq->DCINdi = ndi;
+        }
+        else if (dl_harq->ack)
+          dl_harq->status = SCH_IDLE;
+        break;
+      case 2:
+        dl_harq->round = 1;
+        dl_harq->first_rx = 0;
+        if (dl_harq->DCINdi != ndi) {
+          LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
+          dl_harq->status = ACTIVE;
+          dl_harq->first_rx = 1;
+          dl_harq->DCINdi = ndi;
+        }
+        else if (dl_harq->ack)
+          dl_harq->status = SCH_IDLE;
+        break;
+      case 3:
+        dl_harq->round = 3;
+        dl_harq->first_rx = 0;
+        if (dl_harq->DCINdi != ndi) {
+          LOG_E(PHY,"Missed previous DCI detections. NDI toggled but rv %d does not correspond to first reception\n",rv);
+          dl_harq->status = ACTIVE;
+          dl_harq->first_rx = 1;
+          dl_harq->DCINdi = ndi;
+        }
+        else if (dl_harq->ack)
+          dl_harq->status = SCH_IDLE;
+        break;
+      default:
+        AssertFatal(1==0,"Invalid value for rv %d\n",rv);
+    }
   }
-  else {
 
-    dl_harq->round++;
-
-    if (dl_harq->ack) dl_harq->status = SCH_IDLE;
-
-    LOG_D(PHY, "[HARQ-DL-PDSCH harqId : %d] reception of a retransmission \n", harq_pid);
-  }
 }
 
diff --git a/openair1/SCHED_NR_UE/harq_nr.h b/openair1/SCHED_NR_UE/harq_nr.h
index 47d1de8a1155fc6e1d052e1c34cfd53000385bfb..5586518d7c7646e598b89b7369c74cf82edf3e8c 100644
--- a/openair1/SCHED_NR_UE/harq_nr.h
+++ b/openair1/SCHED_NR_UE/harq_nr.h
@@ -120,7 +120,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq);
     @param rnti_type type of rnti
     @returns retransmission or new transmission */
 
-void downlink_harq_process(NR_DL_UE_HARQ_t *dlsch, int harq_pid, int ndi, uint8_t rnti_type);
+void downlink_harq_process(NR_DL_UE_HARQ_t *dlsch, int harq_pid, int ndi, int rv, uint8_t rnti_type);
 
 #undef EXTERN
 #undef INIT_VARIABLES_HARQ_NR_H
diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c
index 1196bbd70b47369774ae3b20e03187baae815bc3..97658cb657ad01bbd1d93525eb1b6d8d9ae83108 100644
--- a/openair1/SIMULATION/NR_PHY/dlsim.c
+++ b/openair1/SIMULATION/NR_PHY/dlsim.c
@@ -1009,9 +1009,10 @@ int main(int argc, char **argv)
       UE_harq_process->ack = 0;
       round = 0;
       UE_harq_process->round = round;
-      UE_harq_process->first_tx = 1;
+      UE_harq_process->first_rx = 1;
         
       while ((round<num_rounds) && (UE_harq_process->ack==0)) {
+
         memset(RC.nrmac[0]->cce_list[1][0],0,MAX_NUM_CCE*sizeof(int));
         memset(RC.nrmac[0]->cce_list[1][1],0,MAX_NUM_CCE*sizeof(int));
         clear_nr_nfapi_information(RC.nrmac[0], 0, frame, slot);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 811ff018a6e489fda6c3694d07f9841bbfa5875b..d692d6e0f04386bfec4cea057b7987d2530393be 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -516,7 +516,9 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in
     dci->dci_format = NR_UL_DCI_FORMAT_0_0;
     def_dci_pdu_rel15 = &mac->def_dci_pdu_rel15[dci->dci_format];
   }
-  return (nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci));
+  int8_t ret_proc = nr_ue_process_dci(module_id, cc_id, gNB_index, frame, slot, def_dci_pdu_rel15, dci);
+  memset(def_dci_pdu_rel15, 0, sizeof(dci_pdu_rel15_t));
+  return ret_proc;
 }
 
 int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind) {
@@ -3555,6 +3557,12 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
   module_id_t mod_id       = dl_info->module_id;
   frame_t frame            = dl_info->frame;
   int slot                 = dl_info->slot;
+
+  if(dl_info->rx_ind->rx_indication_body[pdu_id].pdsch_pdu.ack_nack == 0) {
+    LOG_W(NR_MAC,"[UE %d][RAPROC][%d.%d] CRC check failed on RAR (NAK)\n", mod_id, frame, slot);
+    return 0;
+  }
+
   int cc_id                = dl_info->cc_id;
   uint8_t gNB_id           = dl_info->gNB_index;
   NR_UE_MAC_INST_t *mac    = get_mac_inst(mod_id);
@@ -3616,43 +3624,43 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
     unsigned char csi_req;
 #endif
 
-  // TA command
-  ul_time_alignment->apply_ta = 1;
-  ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5);
+    // TA command
+    ul_time_alignment->apply_ta = 1;
+    ul_time_alignment->ta_command = 31 + rar->TA2 + (rar->TA1 << 5);
 
 #ifdef DEBUG_RAR
-  // CSI
-  csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
+    // CSI
+    csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01);
 #endif
 
-  // TPC
-  tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
-  switch (tpc_command){
-    case 0:
-      ra->Msg3_TPC = -6;
-      break;
-    case 1:
-      ra->Msg3_TPC = -4;
-      break;
-    case 2:
-      ra->Msg3_TPC = -2;
-      break;
-    case 3:
-      ra->Msg3_TPC = 0;
-      break;
-    case 4:
-      ra->Msg3_TPC = 2;
-      break;
-    case 5:
-      ra->Msg3_TPC = 4;
-      break;
-    case 6:
-      ra->Msg3_TPC = 6;
-      break;
-    case 7:
-      ra->Msg3_TPC = 8;
-      break;
-  }
+    // TPC
+    tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07);
+    switch (tpc_command){
+      case 0:
+        ra->Msg3_TPC = -6;
+        break;
+      case 1:
+        ra->Msg3_TPC = -4;
+        break;
+      case 2:
+        ra->Msg3_TPC = -2;
+        break;
+      case 3:
+        ra->Msg3_TPC = 0;
+        break;
+      case 4:
+        ra->Msg3_TPC = 2;
+        break;
+      case 5:
+        ra->Msg3_TPC = 4;
+        break;
+      case 6:
+        ra->Msg3_TPC = 6;
+        break;
+      case 7:
+        ra->Msg3_TPC = 8;
+        break;
+    }
     // MCS
     rar_grant.mcs = (unsigned char) (rar->UL_GRANT_4 >> 4);
     // time alloc
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 7cd7ac2cf8bef2c322cc3f28513641c76d11c815..3a26858c491878b03caa378db8c9a9c1ce6b8f0d 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -1421,11 +1421,15 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     long BWPSize  = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
     long BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
+    /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
+    int current_harq_pid = sched_ctrl->retrans_dl_harq.head;
     // HARQ management
-    AssertFatal(sched_ctrl->available_dl_harq.head >= 0,
-                "UE context not initialized: no HARQ processes found\n");
-    int current_harq_pid = sched_ctrl->available_dl_harq.head;
-    remove_front_nr_list(&sched_ctrl->available_dl_harq);
+    if (current_harq_pid < 0) {
+      AssertFatal(sched_ctrl->available_dl_harq.head >= 0,
+                  "UE context not initialized: no HARQ processes found\n");
+      current_harq_pid = sched_ctrl->available_dl_harq.head;
+      remove_front_nr_list(&sched_ctrl->available_dl_harq);
+    }
     NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid];
     DevAssert(!harq->is_waiting);
     add_tail_nr_list(&sched_ctrl->feedback_dl_harq, current_harq_pid);
@@ -1458,18 +1462,19 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
     harq->feedback_slot = pucch->ul_slot;
     harq->feedback_frame = pucch->frame;
 
-    // Bytes to be transmitted
     uint8_t *buf = (uint8_t *) harq->tb;
-    uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id);
-    LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length);
-    uint16_t mac_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, CCCH, ra->rnti, 1, &buf[mac_pdu_length+2]);
-    ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->R = 0;
-    ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->F = 0;
-    ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->LCID = DL_SCH_LCID_CCCH;
-    ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->L = mac_sdu_length;
-    mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_SHORT);
-
-    LOG_D(NR_MAC,"Encoded RRCSetup Piggyback (%d + %d bytes), mac_pdu_length %d\n", mac_sdu_length, (int)sizeof(NR_MAC_SUBHEADER_SHORT), mac_pdu_length);
+    // Bytes to be transmitted
+    if (harq->round == 0) {
+      uint16_t mac_pdu_length = nr_write_ce_dlsch_pdu(module_idP, nr_mac->sched_ctrlCommon, buf, 255, ra->cont_res_id);
+      LOG_D(NR_MAC,"Encoded contention resolution mac_pdu_length %d\n",mac_pdu_length);
+      uint16_t mac_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, CCCH, ra->rnti, 1, &buf[mac_pdu_length+2]);
+      ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->R = 0;
+      ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->F = 0;
+      ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->LCID = DL_SCH_LCID_CCCH;
+      ((NR_MAC_SUBHEADER_SHORT *) &buf[mac_pdu_length])->L = mac_sdu_length;
+      ra->mac_pdu_length = mac_pdu_length + mac_sdu_length + sizeof(NR_MAC_SUBHEADER_SHORT);
+      LOG_D(NR_MAC,"Encoded RRCSetup Piggyback (%d + %d bytes), mac_pdu_length %d\n", mac_sdu_length, (int)sizeof(NR_MAC_SUBHEADER_SHORT), ra->mac_pdu_length);
+    }
 
     // Calculate number of symbols
     int startSymbolIndex, nrOfSymbols;
@@ -1530,12 +1535,15 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
       harq->tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx),
                            nr_get_code_rate_dl(mcsIndex, mcsTableIdx),
                            rbSize, nrOfSymbols, N_PRB_DMRS * N_DMRS_SLOT, 0, tb_scaling,1) >> 3;
-    } while (rbStart + rbSize < BWPSize && !vrb_map[rbStart + rbSize] && harq->tb_size < mac_pdu_length);
+    } while (rbSize < BWPSize && harq->tb_size < ra->mac_pdu_length);
 
-    for (int i = 0; (i < rbSize) && (rbStart <= (BWPSize - rbSize)); i++) {
+    int i = 0;
+    while ((i < rbSize) && (rbStart + rbSize <= BWPSize)) {
       if (vrb_map[rbStart + i]) {
-        rbStart += i;
+        rbStart += i+1;
         i = 0;
+      } else {
+        i++;
       }
     }
 
@@ -1681,11 +1689,11 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
                        bwpid);
 
     // Add padding header and zero rest out if there is space left
-    if (mac_pdu_length < harq->tb_size) {
-      NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[mac_pdu_length];
+    if (ra->mac_pdu_length < harq->tb_size) {
+      NR_MAC_SUBHEADER_FIXED *padding = (NR_MAC_SUBHEADER_FIXED *) &buf[ra->mac_pdu_length];
       padding->R = 0;
       padding->LCID = DL_SCH_LCID_PADDING;
-      for(int k = mac_pdu_length+1; k<harq->tb_size; k++) {
+      for(int k = ra->mac_pdu_length+1; k<harq->tb_size; k++) {
         buf[k] = 0;
       }
     }
@@ -1736,24 +1744,32 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram
 
   NR_UE_info_t *UE_info = &RC.nrmac[module_id]->UE_info;
   NR_UE_harq_t *harq = &UE_info->UE_sched_ctrl[UE_id].harq_processes[current_harq_pid];
+  NR_mac_stats_t *stats = &UE_info->mac_stats[UE_id];
 
   LOG_D(NR_MAC, "ue %d, rnti %d, harq is waiting %d, round %d, frame %d %d, harq id %d\n", UE_id, ra->rnti, harq->is_waiting, harq->round, frame, slot, current_harq_pid);
 
-  if (harq->is_waiting == 0)
-  {
-    if (harq->round == 0)
-    {
-      LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
-      nr_clear_ra_proc(module_id, CC_id, frame, ra);
-      UE_info->active[UE_id] = true;
-      UE_info->Msg4_ACKed[UE_id] = true;
+  if (harq->is_waiting == 0) {
+    if (harq->round == 0) {
+      if (stats->dlsch_errors == 0) {
+        LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Ack of RA-Msg4. CBRA procedure succeeded!\n", UE_id, ra->rnti);
+        nr_clear_ra_proc(module_id, CC_id, frame, ra);
+        UE_info->active[UE_id] = true;
+        UE_info->Msg4_ACKed[UE_id] = true;
+      }
+      else {
+        LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) RA Procedure failed at Msg4!\n", UE_id, ra->rnti);
+        nr_mac_remove_ra_rnti(module_id, ra->rnti);
+        nr_clear_ra_proc(module_id, CC_id, frame, ra);
+        mac_remove_nr_ue(module_id, ra->rnti);
+      }
     }
-    else
-    {
+    else {
+      LOG_I(NR_MAC, "(ue %i, rnti 0x%04x) Received Nack of RA-Msg4. Preparing retransmission!\n", UE_id, ra->rnti);
+      ra->Msg4_frame = (frame + 1) % 1024;
+      ra->Msg4_slot = 1;
       ra->state = Msg4;
     }
   }
-
 }
 
 void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, NR_RA_t *ra){
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index c854dd7b2e4a08194ec93881ec8f61071ea9ad9f..a31965be3a37fecaa247caef13233adebdc8f812 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -793,7 +793,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
           nr_process_mac_pdu(gnb_mod_idP, UE_id, CC_idP, frameP, slotP, sduP, sdu_lenP);
 
           ra->state = Msg4;
-          ra->Msg4_frame = ( frameP +2 ) % 1024;
+          ra->Msg4_frame = (frameP + 2) % 1024;
           ra->Msg4_slot = 1;
           LOG_I(NR_MAC, "Scheduling RA-Msg4 for TC_RNTI %04x (state %d, frame %d, slot %d)\n", ra->rnti, ra->state, ra->Msg4_frame, ra->Msg4_slot);
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
index e09df09c1ec890b86c161209803bc67ec93b676d..2f137074ec7d7db6778efc8a0589d9409b69253a 100644
--- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
@@ -157,6 +157,8 @@ typedef struct {
   int msg4_TBsize;
   /// MCS used for Msg4
   int msg4_mcs;
+  /// MAC PDU length for Msg4
+  int mac_pdu_length;
   /// RA search space
   NR_SearchSpace_t *ra_ss;
   // Beam index