From 96f1a2d474d7def5720784187295a302a7affbf3 Mon Sep 17 00:00:00 2001
From: francescomani <email@francescomani.it>
Date: Tue, 17 Dec 2024 10:17:12 +0100
Subject: [PATCH] implementation of RAR response window timer suspension

(this is needed because it might expire while MSG2 is being decoded despite being received inside the window)
---
 common/utils/nr/nr_common.c                  | 11 +++++++++--
 common/utils/nr/nr_common.h                  |  7 +++++++
 openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c |  4 ++++
 openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c  | 12 ++++++++++--
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 1d1e683dce4..58c18bfd368 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -1380,15 +1380,22 @@ int set_default_nta_offset(frequency_range_t freq_range, uint32_t samples_per_su
 void nr_timer_start(NR_timer_t *timer)
 {
   timer->active = true;
+  timer->suspended = false;
   timer->counter = 0;
 }
 
 void nr_timer_stop(NR_timer_t *timer)
 {
   timer->active = false;
+  timer->suspended = false;
   timer->counter = 0;
 }
 
+void nr_timer_suspension(NR_timer_t *timer)
+{
+  timer->suspended = !timer->suspended;
+}
+
 bool nr_timer_is_active(const NR_timer_t *timer)
 {
   return timer->active;
@@ -1399,7 +1406,7 @@ bool nr_timer_tick(NR_timer_t *timer)
   bool expired = false;
   if (timer->active) {
     timer->counter += timer->step;
-    if (timer->target == UINT_MAX) // infinite target, never expires
+    if (timer->target == UINT_MAX || timer->suspended) // infinite target, never expires
       return false;
     expired = nr_timer_expired(timer);
     if (expired)
@@ -1410,7 +1417,7 @@ bool nr_timer_tick(NR_timer_t *timer)
 
 bool nr_timer_expired(const NR_timer_t *timer)
 {
-  if (timer->target == UINT_MAX) // infinite target, never expires
+  if (timer->target == UINT_MAX || timer->suspended) // infinite target, never expires
     return false;
   return timer->counter >= timer->target;
 }
diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h
index ce71500eb00..1dc6a1169df 100644
--- a/common/utils/nr/nr_common.h
+++ b/common/utils/nr/nr_common.h
@@ -156,6 +156,7 @@ typedef struct {
 
 typedef struct {
   bool active;
+  bool suspended;
   uint32_t counter;
   uint32_t target;
   uint32_t step;
@@ -171,6 +172,12 @@ void nr_timer_start(NR_timer_t *timer);
  * @param timer Timer to stopped
  */
 void nr_timer_stop(NR_timer_t *timer);
+/**
+ * @brief To suspend/resume a timer
+ * @param timer Timer to be stopped/suspended
+ */
+void nr_timer_suspension(NR_timer_t *timer);
+
 /**
  * @brief If active, it increases timer counter by an amout of units equal to step. It stops timer if expired
  * @param timer Timer to be handled
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index afe74389492..33ee5dd4c55 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -3896,6 +3896,8 @@ static void handle_rar_reception(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t
                                            rar_grant.Msg3_t_alloc);
   if (!tda_info.valid_tda || tda_info.nrOfSymbols == 0) {
     LOG_E(MAC, "Cannot schedule Msg3. Something wrong in TDA information\n");
+    // resume RAR response window timer if MSG2 decoding failed
+    nr_timer_suspension(&mac->ra.response_window_timer);
     return;
   }
   frame_t frame_tx = 0;
@@ -4082,6 +4084,8 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d
             slot,
             rarh->RAPID,
             preamble_index);
+      // resume RAR response window timer if MSG2 decoding failed
+      nr_timer_suspension(&mac->ra.response_window_timer);
       break;
     } else {
       rarh += sizeof(NR_MAC_RAR) + 1;
diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
index 06eb9f86507..96d1ee6d4d1 100644
--- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
+++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c
@@ -1124,6 +1124,11 @@ static nr_dci_format_t handle_dci(NR_UE_MAC_INST_t *mac,
   if (mac->ra.msg3_C_RNTI && mac->ra.ra_state == nrRA_WAIT_CONTENTION_RESOLUTION)
     nr_ra_succeeded(mac, gNB_index, frame, slot);
 
+  // suspend RAR response window timer
+  // (in RFsim running multiple slot in parallel it might expire while decoding MSG2)
+  if (mac->ra.ra_state == nrRA_WAIT_RAR)
+    nr_timer_suspension(&mac->ra.response_window_timer);
+
   return nr_ue_process_dci_indication_pdu(mac, frame, slot, dci);
 }
 
@@ -1291,10 +1296,13 @@ static uint32_t nr_ue_dl_processing(NR_UE_MAC_INST_t *mac, nr_downlink_indicatio
           ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
           break;
         case FAPI_NR_RX_PDU_TYPE_RAR:
-          if (!dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.ack_nack)
+          if (!dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.ack_nack) {
             LOG_W(PHY, "Received a RAR-Msg2 but LDPC decode failed\n");
-          else
+            // resume RAR response window timer if MSG2 decoding failed
+            nr_timer_suspension(&mac->ra.response_window_timer);
+          } else {
             LOG_I(PHY, "RAR-Msg2 decoded\n");
+          }
           ret_mask |= (handle_dlsch(mac, dl_info, i)) << FAPI_NR_RX_PDU_TYPE_RAR;
           break;
         case FAPI_NR_CSIRS_IND:
-- 
GitLab