From f09ee3e5269083b57611a27b4f8997326717c4fc Mon Sep 17 00:00:00 2001
From: cig <guido.casati@iis.fraunhofer.de>
Date: Sat, 9 Jan 2021 22:53:08 +0100
Subject: [PATCH] Cleanup and review of RA procedure after Msg3 transmission

- related to section 5 of 3GPP TS 38.321 specs
- handling of RA failure
- handling of RA completion
- first implementation of contention-based RA procedures
- minor fixes related to ue_get_rach and init_ra functions
---
 openair1/SCHED_NR_UE/phy_procedures_nr_ue.c   |  37 ++-
 openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h |   3 +-
 openair2/LAYER2/NR_MAC_UE/mac_defs.h          |   2 +
 openair2/LAYER2/NR_MAC_UE/mac_proto.h         |   7 +-
 openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c  | 167 +++++++++----
 openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c  | 219 ++++++++----------
 6 files changed, 236 insertions(+), 199 deletions(-)

diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 68ec0ccd28..a42c3088a8 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -899,27 +899,6 @@ int nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_
   return 0;
 }
 
-// if contention resolution fails, go back to UE mode PRACH
-void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index) {
-
-  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-  ue->UE_mode[gNB_index] = PRACH;
-
-  for (int i=0; i <RX_NB_TH_MAX; i++ ) {
-    ue->pdcch_vars[i][gNB_index]->pdcch_config[0].rnti = 0;
-  }
-  LOG_E(PHY,"[UE %d] [RAPROC] Random-access procedure fails, going back to PRACH\n", Mod_id);
-}
-
-void nr_ra_succeeded(uint8_t Mod_id,
-                     uint8_t CC_id,
-                     uint8_t gNB_index){
-  LOG_I(PHY,"[UE %d][RAPROC] RA procedure succeeded. UE set to PUSCH mode\n", Mod_id);
-  PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
-  ue->ulsch_Msg3_active[gNB_index] = 0;
-  ue->UE_mode[gNB_index] = PUSCH;
-}
-
 void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
        UE_nr_rxtx_proc_t *proc,
        int eNB_id,
@@ -2159,7 +2138,7 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
     }
   }
 
-  nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_slot_tx);
+  nr_prach = nr_ue_get_rach(ue->prach_resources[gNB_id], &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx);
 
   if (ue->prach_resources[gNB_id] != NULL && nr_prach == 1 && prach_resources->init_msg1) {
 
@@ -2210,8 +2189,20 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
     if (ue->prach_cnt == 3)
       ue->prach_cnt = 0;
   } else if (nr_prach == 2) {
-    nr_ra_succeeded(mod_id, ue->CC_id, gNB_id);
+
+    LOG_D(PHY, "In %s: [UE %d] RA completed, setting UE mode to PUSCH\n", __FUNCTION__, mod_id);
+
+    ue->ulsch_Msg3_active[gNB_id] = 0;
+    ue->UE_mode[gNB_id] = PUSCH;
+
+  } else if(nr_prach == 3){
+
+    LOG_D(PHY, "In %s: [UE %d] RA failed, setting UE mode to PRACH\n", __FUNCTION__, mod_id);
+
+    ue->UE_mode[gNB_id] = PRACH;
+
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
+
 }
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
index 237b8d225d..0e6d110e71 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h
@@ -36,7 +36,6 @@
 #include "NR_CellGroupConfig.h"
 #include "nr_mac.h"
 
-
 // ===============================================
 // SSB to RO mapping public defines and structures
 // ===============================================
@@ -47,6 +46,8 @@
 // Definitions for MAC control and data
 #define MAX_BWP_SIZE    275
 
+extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
+
 typedef enum frequency_range_e {
     FR1 = 0, 
     FR2
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
index cb1a597f78..d2302f405d 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h
@@ -198,6 +198,8 @@ typedef struct {
   /* Random Access parameters */
   /// state of RA procedure
   RA_state_t ra_state;
+  /// RA contention type
+  uint8_t cfra;
   /// RA rx frame offset: compensate RA rx offset introduced by OAI gNB.
   uint8_t RA_offset;
   /// RA-rnti
diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
index 2182d6d173..57d7f9a509 100755
--- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h
+++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h
@@ -233,11 +233,11 @@ void nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
 
 void nr_process_rar(nr_downlink_indication_t *dl_info);
 
-void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame);
+void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources);
 
-void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
+void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot);
 
-void nr_ra_succeeded(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
+void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot);
 
 /* \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
@@ -254,7 +254,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
                        fapi_nr_ul_config_prach_pdu *prach_pdu,
                        module_id_t mod_id,
                        int CC_id,
-                       UE_MODE_t UE_mode,
                        frame_t frame,
                        uint8_t gNB_id,
                        int nr_slot_tx);
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
index f7dac8e9d9..4138b3b435 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c
@@ -49,9 +49,6 @@
 #include "NR_MAC_COMMON/nr_mac.h"
 #include "LAYER2/NR_MAC_UE/mac_proto.h"
 
-extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
-
-//extern uint8_t  nfapi_mode;
 static uint8_t first_Msg3 = 0;
 static int starting_preamble_nb = 0;
 static long cb_preambles_per_ssb; // Nb of preambles per SSB
@@ -74,6 +71,10 @@ void init_RA(module_id_t mod_id,
              NR_RACH_ConfigGeneric_t *rach_ConfigGeneric,
              NR_RACH_ConfigDedicated_t *rach_ConfigDedicated) {
 
+  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+  mac->RA_active = 1;
+  mac->RA_RAPID_found = 0;
+
   prach_resources->RA_PREAMBLE_BACKOFF = 0;
   prach_resources->RA_PCMAX = nr_get_Pcmax(mod_id);
   prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
@@ -85,6 +86,7 @@ void init_RA(module_id_t mod_id,
     if (rach_ConfigDedicated->cfra){
       LOG_I(MAC, "Initialization of 4-step contention-free random access procedure\n");
       prach_resources->RA_TYPE = RA_4STEP;
+      mac->cfra = 1;
     }
   } else if (rach_ConfigDedicated->ext1){
     if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){
@@ -449,11 +451,16 @@ void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint
 }
 
 void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
-  LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
+
   NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
+
+  LOG_D(MAC,"In %s: [UE %d] Frame %d, CB-RA: starting contention resolution timer\n", __FUNCTION__, mod_id, frameP);
+
   // start contention resolution timer
-  mac->RA_contention_resolution_cnt = 0;
+  mac->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8;
   mac->RA_contention_resolution_timer_active = 1;
+
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -476,7 +483,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
                        fapi_nr_ul_config_prach_pdu *prach_pdu,
                        module_id_t mod_id,
                        int CC_id,
-                       UE_MODE_t UE_mode,
                        frame_t frame,
                        uint8_t gNB_id,
                        int nr_slot_tx){
@@ -538,9 +544,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
 
         LOG_D(MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
 
-        mac->RA_active = 1;
-        mac->RA_RAPID_found = 0;
-        first_Msg3 = 0;
+        first_Msg3 = 1;
         RA_backoff_cnt = 0;
         Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
 
@@ -584,46 +588,15 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
       if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
         // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
         // TbD Msg3 Retransmissions to be scheduled by DCI 0_0
-        if (rach_ConfigDedicated) {
-          if (rach_ConfigDedicated->cfra){
-
-            // CFRA
-            mac->RA_active = 0;
-            mac->RA_window_cnt = -1;
-            mac->ra_state = RA_SUCCEEDED;
-            mac->generate_nr_prach = 2;
 
-            LOG_I(MAC, "[UE %d][%d.%d] RAR successfully received\n", mod_id, frame, nr_slot_tx);
+        nr_ra_succeeded(mod_id, frame, nr_slot_tx);
 
-          }
-        } else {
-
-          LOG_E(MAC, "[%s:%d][UE %d] todo: handling of received contention-based RA praemble...\n", __FUNCTION__, __LINE__, mod_id);
-
-        }
       } else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
 
         LOG_I(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx);
 
-        mac->ra_state = RA_UE_IDLE;
-        prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
-
-        if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
-
-          LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax);
-
-          RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
-
-          prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
-          prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
-          prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
-
-        } else {
-
-          // Resetting RA window
-          nr_get_RA_window(mac);
+        nr_ra_failed(mod_id, CC_id, prach_resources, frame, nr_slot_tx);
 
-        }
       } else if (mac->RA_window_cnt > 0) {
 
         LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA window count %d) \n", mod_id, frame, nr_slot_tx, mac->RA_window_cnt);
@@ -644,10 +617,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
 
       }
     }
-  } else if (UE_mode == PUSCH) {
-
-    AssertFatal(1 == 0, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet...", mod_id);
+  }
 
+  if (mac->RA_contention_resolution_timer_active){
+    nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources);
   }
 
   return mac->generate_nr_prach;
@@ -698,3 +671,107 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
       break;
   }
 }
+
+////////////////////////////////////////////////////////////////////////////
+/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
+////////////////////////////////////////////////////////////////////////////
+// Handling contention resolution timer
+// WIP todo:
+// - beam failure recovery
+// - RA completed
+void nr_ue_contention_resolution(module_id_t module_id, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources){
+  
+  NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
+
+  if (mac->RA_contention_resolution_timer_active == 1) {
+
+      mac->RA_contention_resolution_cnt--;
+
+      LOG_D(MAC, "In %s: [%d.%d] RA contention resolution timer %d\n", __FUNCTION__, frame, slot, mac->RA_contention_resolution_cnt);
+
+      if (mac->RA_contention_resolution_cnt == 0) {
+        mac->t_crnti = 0;
+        mac->RA_active = 0;
+        mac->RA_contention_resolution_timer_active = 0;
+        // Signal PHY to quit RA procedure
+        LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id);
+        nr_ra_failed(module_id, cc_id, prach_resources, frame, slot);
+      }
+    
+  }
+}
+
+// Handlig successful RA completion @ MAC layer
+// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
+// todo:
+// - complete handling of received contention-based RA preamble
+void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){
+
+  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+
+  if (mac->cfra) {
+
+    LOG_I(MAC, "[UE %d][%d.%d] CF-RA: RAR successfully received, RA procedure is completed\n", mod_id, frame, slot);
+
+    mac->RA_window_cnt = -1;
+
+  } else {
+
+    LOG_I(MAC, "[UE %d][%d.%d] CB-RA: Contention Resolution is successful, RA is completed\n", mod_id, frame, slot);
+
+    mac->RA_contention_resolution_cnt = -1;
+    mac->RA_contention_resolution_timer_active = 0;
+    mac->t_crnti = 0;
+
+    LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot);
+
+  }
+
+  LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id);
+  ra->RA_active = 0;
+  ra->generate_nr_prach = 2;
+  ra->ra_state = RA_SUCCEEDED;
+
+}
+
+// Handlig failure of RA procedure @ MAC layer
+// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
+// todo:
+// - complete handling of received contention-based RA preamble
+// - 2-step RA implementation
+void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) {
+
+  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
+
+  first_Msg3 = 0;
+  mac->generate_nr_prach = 3;
+  mac->ra_state = RA_UE_IDLE;
+
+  prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;
+
+  if(prach_resources->RA_TYPE == RA_4STEP){
+
+    if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
+
+      LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n", __FUNCTION__, mod_id, frame, slot, preambleTransMax);
+
+      RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
+
+      prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
+      prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
+      prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
+
+    } else {
+
+      // Resetting RA window
+      nr_get_RA_window(mac);
+
+    }
+
+  } else if (prach_resources->RA_TYPE == RA_2STEP){
+
+    LOG_E(MAC, "Missing implementation of RA failure handling for 2-step RA...\n");
+
+  }
+
+}
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index f49782875c..95769cc103 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -1368,7 +1368,72 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
     module_id_t mod_id    = ul_info->module_id;
     NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
 
-    if (mac->ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test) {
+    if (mac->ra_state == WAIT_RAR){
+
+      if (mac->RA_active && ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){
+
+        uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
+        nr_scheduled_response_t scheduled_response;
+        fapi_nr_tx_request_t tx_req;
+        //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx);
+        fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
+        fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus];
+        uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size;
+
+        //if (IS_SOFTMODEM_NOS1){
+        //  // Getting IP traffic to be transmitted
+        //  data_existing = nr_ue_get_sdu(mod_id,
+        //                                cc_id,
+        //                                frame_tx,
+        //                                slot_tx,
+        //                                0,
+        //                                ulsch_input_buffer,
+        //                                TBS_bytes,
+        //                                &access_mode);
+        //}
+
+        //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
+        //if (!IS_SOFTMODEM_NOS1 || !data_existing) {
+          //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
+          //and block this traffic from being forwarded to the upper layers at the gNB
+          LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes);
+          //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
+          //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
+          //have a valid LCID (nr_process_mac_pdu function)
+          ulsch_input_buffer[0] = 0x31;
+          for (int i = 1; i < TBS_bytes; i++) {
+            ulsch_input_buffer[i] = (unsigned char) rand();
+            //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
+          }
+        //}
+
+        LOG_D(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n",
+          ul_info->module_id,
+          ul_info->frame_tx,
+          ul_info->slot_tx,
+          mac->t_crnti);
+
+        // Config UL TX PDU
+        tx_req.slot = ul_info->slot_tx;
+        tx_req.sfn = ul_info->frame_tx;
+        tx_req.number_of_pdus = 1;
+        tx_req.tx_request_body[0].pdu_length = TBS_bytes;
+        tx_req.tx_request_body[0].pdu_index = 0;
+        tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
+        ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
+        ul_config->number_pdus++;
+        // scheduled_response
+        fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx, ul_info->thread_id);
+        if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
+          mac->if_module->scheduled_response(&scheduled_response);
+        }
+
+        if (!mac->cfra){
+          nr_Msg3_transmitted(ul_info->module_id, ul_info->cc_id, ul_info->frame_tx, ul_info->gNB_index);
+        }
+
+      }
+    } else if (mac->ra_state == RA_SUCCEEDED || get_softmodem_params()->phy_test) {
 
       uint8_t nb_dmrs_re_per_rb;
       uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
@@ -1512,75 +1577,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
         if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
           mac->if_module->scheduled_response(&scheduled_response);
         }
-
-        // TODO: expand
-        // Note: Contention resolution is currently not active
-        if (mac->RA_contention_resolution_timer_active == 1)
-          ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx);
-
-      }
-
-    } else if (get_softmodem_params()->do_ra){
-
-      NR_UE_MAC_INST_t *mac = get_mac_inst(ul_info->module_id);
-
-      if (mac->RA_active && ul_info->slot_tx == mac->msg3_slot && ul_info->frame_tx == mac->msg3_frame){
-
-        uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES];
-        nr_scheduled_response_t scheduled_response;
-        fapi_nr_tx_request_t tx_req;
-        //fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx);
-        fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request[0];
-        fapi_nr_ul_config_request_pdu_t *ul_config_list = &ul_config->ul_config_list[ul_config->number_pdus];
-        uint16_t TBS_bytes = ul_config_list->pusch_config_pdu.pusch_data.tb_size;
-
-        //if (IS_SOFTMODEM_NOS1){
-        //  // Getting IP traffic to be transmitted
-        //  data_existing = nr_ue_get_sdu(mod_id,
-        //                                cc_id,
-        //                                frame_tx,
-        //                                slot_tx,
-        //                                0,
-        //                                ulsch_input_buffer,
-        //                                TBS_bytes,
-        //                                &access_mode);
-        //}
-
-        //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity
-        //if (!IS_SOFTMODEM_NOS1 || !data_existing) {
-          //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid
-          //and block this traffic from being forwarded to the upper layers at the gNB
-          LOG_D(MAC, "Random data to be tranmsitted (TBS_bytes %d): \n", TBS_bytes);
-          //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2)
-          //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should
-          //have a valid LCID (nr_process_mac_pdu function)
-          ulsch_input_buffer[0] = 0x31;
-          for (int i = 1; i < TBS_bytes; i++) {
-            ulsch_input_buffer[i] = (unsigned char) rand();
-            //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]);
-          }
-        //}
-
-        LOG_D(MAC, "[UE %d] Frame %d, Subframe %d Adding Msg3 UL Config Request for rnti: %x\n",
-          ul_info->module_id,
-          ul_info->frame_tx,
-          ul_info->slot_tx,
-          mac->t_crnti);
-
-        // Config UL TX PDU
-        tx_req.slot = ul_info->slot_tx;
-        tx_req.sfn = ul_info->frame_tx;
-        tx_req.number_of_pdus = 1;
-        tx_req.tx_request_body[0].pdu_length = TBS_bytes;
-        tx_req.tx_request_body[0].pdu_index = 0;
-        tx_req.tx_request_body[0].pdu = ulsch_input_buffer;
-        ul_config_list->pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
-        ul_config->number_pdus++;
-        // scheduled_response
-        fill_scheduled_response(&scheduled_response, NULL, ul_config, &tx_req, ul_info->module_id, ul_info->cc_id, ul_info->frame_rx, ul_info->slot_rx, ul_info->thread_id);
-        if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){
-          mac->if_module->scheduled_response(&scheduled_response);
-        }
       }
     }
   }
@@ -1766,40 +1762,6 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
   } // if is_nr_UL_slot
 }
 
-////////////////////////////////////////////////////////////////////////////
-/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
-////////////////////////////////////////////////////////////////////////////
-// Handling contention resolution timer
-// WIP todo:
-// - beam failure recovery
-// - RA completed
-
-void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame){
-  
-  NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
-  NR_ServingCellConfigCommon_t *scc = mac->scc;
-  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
-
-  if (mac->RA_contention_resolution_timer_active == 1) {
-    if (nr_rach_ConfigCommon){
-      LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n",
-        tx_frame,
-        mac->RA_contention_resolution_cnt,
-        ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3));
-        mac->RA_contention_resolution_cnt++;
-
-      if (mac->RA_contention_resolution_cnt == ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) {
-        mac->t_crnti = 0;
-        mac->RA_active = 0;
-        mac->RA_contention_resolution_timer_active = 0;
-        // Signal PHY to quit RA procedure
-        LOG_E(MAC, "[UE %u] [RAPROC] Contention resolution timer expired, RA failed, discarded TC-RNTI\n", module_id);
-        nr_ra_failed(module_id, cc_id, gNB_index);
-      }
-    }
-  }
-}
-
 /*
  * This code contains all the functions needed to process all dci fields.
  * These tables and functions are going to be called by function nr_ue_process_dci
@@ -2505,6 +2467,18 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     /* TIME_DOM_RESOURCE_ASSIGNMENT */
     if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_0,NULL,dci->time_domain_assignment.val) < 0)
       return -1;
+
+    LOG_D(MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) \n",
+      __FUNCTION__,
+      pusch_config_pdu_0_0->rb_start,
+      pusch_config_pdu_0_0->rb_size,
+      pusch_config_pdu_0_0->start_symbol_index,
+      pusch_config_pdu_0_0->nr_of_symbols);
+
+    if (mac->RA_active && mac->crnti){
+      nr_ra_succeeded(module_id, frame, slot);
+    }
+
     /* FREQ_HOPPING_FLAG */
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
@@ -2627,6 +2601,18 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr
     /* TIME_DOM_RESOURCE_ASSIGNMENT */
     if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL,dci->time_domain_assignment.val) < 0)
       return -1;
+
+    LOG_D(MAC, "In %s: received UL grant (rb_start %d, rb_size %d, start_symbol_index %d, nr_of_symbols %d) \n",
+      __FUNCTION__,
+      pusch_config_pdu_0_1->rb_start,
+      pusch_config_pdu_0_1->rb_size,
+      pusch_config_pdu_0_1->start_symbol_index,
+      pusch_config_pdu_0_1->nr_of_symbols);
+
+    if (mac->RA_active && mac->crnti){
+      nr_ra_succeeded(module_id, frame, slot);
+    }
+
     /* FREQ_HOPPING_FLAG */
     if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) &&
 	(mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0))
@@ -4164,35 +4150,16 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
 
                 break;
             case DL_SCH_LCID_CON_RES_ID:
-                //  38.321 Ch6.1.3.3
+                //  Clause 5.1.5 and 6.1.3.3 of 3GPP TS 38.321 version 16.2.1 Release 16
                 // WIP todo: handle CCCH_pdu
                 mac_ce_len = 6;
                 
                 LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pduP[0], pduP[1], pduP[2], pduP[3], pduP[4], pduP[5]);
 
                 if (mac->RA_active == 1) {
-                  LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP);
-                  mac->RA_active = 0;
-                   // // check if RA procedure has finished completely (no contention)
-                   // tx_sdu = &mac->CCCH_pdu.payload[3];
-                   // //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits)
-                   // // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or //  SCH_SUBHEADER_SHORT)
-                   // for (i = 0; i < 6; i++)
-                   //   if (tx_sdu[i] != payload_ptr[i]) {
-                   //     LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP);
-                   //     nr_ra_failed(module_idP, CC_id, eNB_index);
-                   //     mac->RA_contention_resolution_timer_active = 0;
-                   //     return;
-                   //   }
-                  LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Cleared contention resolution timer. Set C-RNTI to TC-RNTI\n",
-                    module_idP,
-                    frameP);
-                  mac->RA_contention_resolution_timer_active = 0;
-                  nr_ra_succeeded(module_idP, CC_id, gNB_index);
-                  mac->crnti = mac->t_crnti;
-                  mac->t_crnti = 0;
-                  mac->ra_state = RA_SUCCEEDED;
+                  nr_ra_succeeded(module_idP, frameP, slot);
                 }
+
                 break;
             case DL_SCH_LCID_PADDING:
                 done = 1;
-- 
2.26.2