From 6bb69e1964d28b700eff9ff72530b2aa417ae8ac Mon Sep 17 00:00:00 2001
From: Cedric Roux <cedric.roux@eurecom.fr>
Date: Tue, 22 Nov 2016 10:38:18 +0100
Subject: [PATCH] hotfix: correct Msg3 ressource blocks reservation

The Msg3 ressource blocks used by random access procedure
were not correctly handled. The MAC scheduler could wrongly
allocate a ressource block for both random access Msg3 and
a regular UE.

This hotfix hopefully fixes the problem.

A new function "set_msg3_subframe" has been added in the
interface between PHY and MAC.
---
 openair1/SCHED/phy_procedures_lte_eNb.c   |  6 +++++
 openair2/LAYER2/MAC/eNB_scheduler_RA.c    |  3 ++-
 openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 28 ++++++++++++++++++++++-
 openair2/LAYER2/MAC/main.c                |  1 +
 openair2/LAYER2/MAC/proto.h               | 19 +++++++++++++++
 openair2/PHY_INTERFACE/defs.h             | 10 ++++++++
 6 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 5d84853930..82e6b0dc1f 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -969,6 +969,9 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *d
 		eNB->ulsch[(uint32_t)UE_id]->Msg3_frame,
 		eNB->ulsch[(uint32_t)UE_id]->Msg3_subframe);
 
+          mac_xface->set_msg3_subframe(eNB->Mod_id, eNB->CC_id, frame, subframe, (uint16_t)crnti,
+                                       eNB->ulsch[UE_id]->Msg3_frame, eNB->ulsch[UE_id]->Msg3_subframe);
+
           T(T_ENB_PHY_MSG3_ALLOCATION, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
             T_INT(UE_id), T_INT((uint16_t)crnti), T_INT(1 /* 1 is for initial transmission*/),
             T_INT(eNB->ulsch[UE_id]->Msg3_frame), T_INT(eNB->ulsch[UE_id]->Msg3_subframe));
@@ -3067,6 +3070,9 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
                                &eNB->ulsch[i]->Msg3_frame,
                                &eNB->ulsch[i]->Msg3_subframe);
 
+            mac_xface->set_msg3_subframe(eNB->Mod_id, eNB->CC_id, frame, subframe, eNB->ulsch[i]->rnti,
+                                         eNB->ulsch[i]->Msg3_frame, eNB->ulsch[i]->Msg3_subframe);
+
             T(T_ENB_PHY_MSG3_ALLOCATION, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
               T_INT(i), T_INT(eNB->ulsch[i]->rnti), T_INT(0 /* 0 is for retransmission*/),
               T_INT(eNB->ulsch[i]->Msg3_frame), T_INT(eNB->ulsch[i]->Msg3_subframe));
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 0da90652c0..23ba001d4c 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -259,7 +259,8 @@ void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,un
 			   RA_template->RA_dci_fmt1,
 			   1);
 
-	    RA_template->Msg3_subframe=Msg3_subframe;
+            /* this will be updated when PHY calls set_msg3_subframe */
+	    RA_template->Msg3_subframe = -1;
 	  }
         } else if (RA_template->generate_Msg4 == 1) {
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index a65ec917de..77eb36c4d8 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -601,6 +601,29 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
   return(mac_header_ptr);
 }
 
+/* This function is called by PHY layer when it schedules some
+ * uplink for a random access message 3.
+ * The MAC scheduler has to skip the RBs used by this message 3
+ * (done below in schedule_ulsch).
+ */
+void set_msg3_subframe(module_id_t Mod_id,
+                       int CC_id,
+                       int frame,
+                       int subframe,
+                       int rnti,
+                       int Msg3_frame,
+                       int Msg3_subframe)
+{
+  eNB_MAC_INST *eNB=&eNB_mac_inst[Mod_id];
+  int i;
+  for (i=0; i<NB_RA_PROC_MAX; i++) {
+    if (eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE &&
+        eNB->common_channels[CC_id].RA_template[i].rnti == rnti) {
+      eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = Msg3_subframe;
+      break;
+    }
+  }
+}
 
 void schedule_ulsch(module_id_t module_idP, 
 		    frame_t frameP,
@@ -619,6 +642,7 @@ void schedule_ulsch(module_id_t module_idP,
 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
+    //leave out first RB for PUCCH
     first_rb[CC_id] = 1;
 
     // UE data info;
@@ -637,9 +661,11 @@ void schedule_ulsch(module_id_t module_idP,
     for (i=0; i<NB_RA_PROC_MAX; i++) {
       if ((eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE) &&
           (eNB->common_channels[CC_id].RA_template[i].generate_rar == 0) &&
+          (eNB->common_channels[CC_id].RA_template[i].generate_Msg4 == 0) &&
+          (eNB->common_channels[CC_id].RA_template[i].wait_ack_Msg4 == 0) &&
           (eNB->common_channels[CC_id].RA_template[i].Msg3_subframe == sched_subframe)) {
-	//leave out first RB for PUCCH
         first_rb[CC_id]++;
+        eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = -1;
         break;
       }
     }
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 4fee906f74..0fe9d63b6f 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -454,6 +454,7 @@ int l2_init(LTE_DL_FRAME_PARMS *frame_parms,int eMBMS_active, char *uecap_xer,ui
   mac_xface->fill_rar                  = fill_rar;
   mac_xface->initiate_ra_proc          = initiate_ra_proc;
   mac_xface->cancel_ra_proc            = cancel_ra_proc;
+  mac_xface->set_msg3_subframe         = set_msg3_subframe;
   mac_xface->SR_indication             = SR_indication;
   mac_xface->UL_failure_indication     = UL_failure_indication;
   mac_xface->rx_sdu                    = rx_sdu;
diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h
index 59d6c352fe..4df0c6fa45 100644
--- a/openair2/LAYER2/MAC/proto.h
+++ b/openair2/LAYER2/MAC/proto.h
@@ -246,6 +246,25 @@ unsigned short fill_rar(
 */
 void cancel_ra_proc(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t preamble_index);
 
+/* \brief Function used by PHY to inform MAC that an uplink is scheduled
+          for Msg3 in given subframe. This is used so that the MAC
+          scheduler marks as busy the RBs used by the Msg3.
+@param Mod_id        Instance ID of eNB
+@param CC_id         CC ID of eNB
+@param frame         current frame
+@param subframe      current subframe
+@param rnti          UE rnti concerned
+@param Msg3_frame    frame where scheduling takes place
+@param Msg3_subframe subframe where scheduling takes place
+*/
+void set_msg3_subframe(module_id_t Mod_id,
+                       int CC_id,
+                       int frame,
+                       int subframe,
+                       int rnti,
+                       int Msg3_frame,
+                       int Msg3_subframe);
+
 /* \brief Function to indicate a received SDU on ULSCH.
 @param Mod_id Instance ID of eNB
 @param rnti RNTI of UE transmitting the SR
diff --git a/openair2/PHY_INTERFACE/defs.h b/openair2/PHY_INTERFACE/defs.h
index 0892b4d0b1..8c711e971d 100644
--- a/openair2/PHY_INTERFACE/defs.h
+++ b/openair2/PHY_INTERFACE/defs.h
@@ -72,6 +72,16 @@ typedef struct {
   /// cancel an ongoing RA procedure
   void (*cancel_ra_proc)(module_id_t Mod_id,int CC_id,frame_t frameP,uint16_t preamble);
 
+  /// Inform MAC layer that an uplink is scheduled for Msg3 in given subframe.
+  /// This is used so that the MAC scheduler marks as busy the RBs used by the Msg3.
+  void (*set_msg3_subframe)(module_id_t Mod_id,
+                            int CC_id,
+                            int frame,
+                            int subframe,
+                            int rnti,
+                            int Msg3_frame,
+                            int Msg3_subframe);
+
   /// Get DCI for current subframe from MAC
   DCI_PDU* (*get_dci_sdu)(module_id_t Mod_id,int CC_id,frame_t frameP,sub_frame_t subframe);
 
-- 
GitLab