From c5196908d51f9e02e4a6517d670dd5cadbde6ad1 Mon Sep 17 00:00:00 2001
From: Navid Nikaein <navid.nikaein@eurecom.fr>
Date: Tue, 17 Sep 2013 05:45:21 +0000
Subject: [PATCH] * Update the relay node (RN) procedure when multicast
 relaying is enabled * Fix the non-continous indexing of the PDCP array
 (replace rb_id by lc_id) * Add a new test case 03 for Rel10 and eMBMS

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4149 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 openair1/PHY/impl_defs_top.h             |   2 +-
 openair1/SCHED/defs.h                    |  52 +++++---
 openair1/SCHED/phy_procedures_lte_eNb.c  |  69 +++++++---
 openair1/SCHED/phy_procedures_lte_ue.c   |  52 ++++++--
 openair2/LAYER2/MAC/eNB_scheduler.c      |  12 +-
 openair2/LAYER2/PDCP_v10.1.0/pdcp.c      | 163 +++++++++++------------
 openair2/LAYER2/PDCP_v10.1.0/pdcp.h      |   2 +-
 openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c |   8 +-
 openair2/RRC/LITE/rrc_UE.c               |   2 +-
 openair2/RRC/LITE/rrc_eNB.c              |   2 +-
 openair2/UTIL/OTG/otg_rx.c               |   4 +-
 targets/SIMU/USER/oaisim.c               |  42 +++---
 targets/SIMU/USER/oaisim_functions.c     |   2 +-
 targets/TEST/OAI/README                  |  17 ++-
 targets/TEST/OAI/case01.py               |   8 +-
 targets/TEST/OAI/case02.py               |  23 +---
 targets/TEST/OAI/case03.py               | 156 ++++++++++++++++++++++
 targets/TEST/OAI/log.py                  |   2 +-
 targets/TEST/OAI/test01.py               |  18 ++-
 19 files changed, 437 insertions(+), 199 deletions(-)
 create mode 100644 targets/TEST/OAI/case03.py

diff --git a/openair1/PHY/impl_defs_top.h b/openair1/PHY/impl_defs_top.h
index 21ac73763a..d56fc1df92 100755
--- a/openair1/PHY/impl_defs_top.h
+++ b/openair1/PHY/impl_defs_top.h
@@ -336,7 +336,7 @@ typedef struct {
 
 #define NUMBER_OF_RN_MAX 3
 
-typedef enum {no_relay=0,unicast_relay=1,multicast_relay=2} relaying_mode_t;
+typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_relay} relaying_type_t;
 
 typedef struct
 {
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 39dc3e7789..797f92c7fd 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -125,9 +125,9 @@ void cleanup_dlsch_threads(void);
   @param next_slot Index of next_slot (0-19)
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param abstraction_flag Indicator of PHY abstraction
-  @param r_mode indicates the relaying operation: 0: no_relaying, 1: unicast relaying, 2: multicast relaying
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_eNB_lte(u8 last_slot, u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, relaying_mode_t r_mode);
+void phy_procedures_eNB_lte(u8 last_slot, u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, relaying_type_t r_type);
 /*!
   \brief Top-level entry routine for UE procedures.  Called every slot by process scheduler. In even slots, it performs RX functions from previous subframe (if required).  On odd slots, it generate TX waveform for the following subframe.
   @param last_slot Index of last slot (0-19)
@@ -136,9 +136,26 @@ void phy_procedures_eNB_lte(u8 last_slot, u8 next_slot,PHY_VARS_eNB *phy_vars_eN
   @param eNB_id ID of eNB on which to act
   @param abstraction_flag Indicator of PHY abstraction
   @param mode calibration/debug mode
-  @param relaying_mode indicates the relaying operation: 0: no_relaying, 1: unicast relaying, 2: multicast relaying
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_UE_lte(u8 last_slot, u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, relaying_mode_t r_mode);
+void phy_procedures_UE_lte(u8 last_slot, u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, relaying_type_t r_type);
+
+#ifdef Rel10  
+/*!
+  \brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs. 
+  @param last_slot Index of last slot (0-19)
+  @param next_slot Index of next_slot (0-19)
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+*/
+int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type);
+/*!
+  \brief Top-level entry routine for relay node procedures actinf as UE. This proc will make us of the existing UE procs. 
+  @param last_slot Index of last slot (0-19)
+  @param next_slot Index of next_slot (0-19)
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
+*/
+int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type);
+#endif
 
 /*!
   \brief Scheduling for UE TX procedures in normal subframes.  
@@ -147,8 +164,9 @@ void phy_procedures_UE_lte(u8 last_slot, u8 next_slot,PHY_VARS_UE *phy_vars_ue,u
   @param eNB_id Local id of eNB on which to act
   @param abstraction_flag Indicator of PHY abstraction
   @param mode calib/normal mode
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_mode_t r_mode);
+void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type);
 /*!
   \brief Scheduling for UE RX procedures in normal subframes.  
   @param last_slot Index of last slot (0-19)
@@ -156,9 +174,9 @@ void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs
   @param eNB_id Local id of eNB on which to act
   @param abstraction_flag Indicator of PHY abstraction
   @param mode calibration/debug mode
-  @param r_mode instruct PHY to operate as normal (0), unicast relay (1), or multicast relay (2)
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-int phy_procedures_UE_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_mode_t r_mode);
+int phy_procedures_UE_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type);
 
 /*!
   \brief Scheduling for UE TX procedures in TDD S-subframes.  
@@ -166,8 +184,9 @@ int phy_procedures_UE_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abst
   @param phy_vars_ue Pointer to UE variables on which to act
   @param eNB_id Local id of eNB on which to act
   @param abstraction_flag Indicator of PHY abstraction
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_UE_S_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,relaying_mode_t r_mode);
+void phy_procedures_UE_S_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,relaying_type_t r_type);
 
 /*!
   \brief Scheduling for UE RX procedures in TDD S-subframes.  
@@ -175,42 +194,45 @@ void phy_procedures_UE_S_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 a
   @param phy_vars_ue Pointer to UE variables on which to act
   @param eNB_id Local id of eNB on which to act
   @param abstraction_flag Indicator of PHY abstraction
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_UE_S_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag, relaying_mode_t r_mode);
+void phy_procedures_UE_S_RX(u8 last_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag, relaying_type_t r_type);
 
 /*!
   \brief Scheduling for eNB TX procedures in normal subframes.  
   @param next_slot Index of next slot (0-19)
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param abstraction_flag Indicator of PHY abstraction
-  @param r_mode instruct PHY to operate as normal (0), unicast relay (1), or multicast relay (2), 
-  @note: r_mode could be extended to support other values to indicate the type of relaying AF,DF,QF, and QMF  
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_eNB_TX(u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_mode_t r_mode);
+void phy_procedures_eNB_TX(u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type);
 
 /*!
   \brief Scheduling for eNB RX procedures in normal subframes.  
   @param last_slot Index of last slot (0-19)
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param abstraction_flag Indicator of PHY abstraction
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_eNB_RX(u8 last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_mode_t r_mode);
+void phy_procedures_eNB_RX(u8 last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type);
 
 /*!
   \brief Scheduling for eNB TX procedures in TDD S-subframes.  
   @param next_slot Index of next slot (0-19)
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param abstraction_flag Indicator of PHY abstraction
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_eNB_S_TX(u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_mode_t r_mode);
+void phy_procedures_eNB_S_TX(u8 next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type);
 
 /*!
   \brief Scheduling for eNB RX procedures in TDD S-subframes.  
   @param last_slot Index of next slot (0-19)
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param abstraction_flag Indicator of PHY abstraction
+  @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_eNB_S_RX(u8 last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_mode_t r_mode);
+void phy_procedures_eNB_S_RX(u8 last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type);
 
 /*!
   \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 09e359dc63..98bd21a546 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -410,10 +410,13 @@ void phy_procedures_emos_eNB_TX(unsigned char next_slot, PHY_VARS_eNB *phy_vars_
   }
 */ 
 
-void phy_procedures_eNB_S_RX(unsigned char last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_mode_t r_mode) {
+void phy_procedures_eNB_S_RX(unsigned char last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type) {
 
   unsigned char sect_id=0; 
 
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->frame, last_slot);
+#endif    
 
   if (last_slot%2 == 0) {
     for (sect_id=0;sect_id<number_of_cards;sect_id++) {
@@ -885,7 +888,7 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, u8 subframe, PHY_VARS_eNB *phy_vars_eNB) {
 int QPSK[4]={AMP_OVER_SQRT2|(AMP_OVER_SQRT2<<16),AMP_OVER_SQRT2|((65536-AMP_OVER_SQRT2)<<16),((65536-AMP_OVER_SQRT2)<<16)|AMP_OVER_SQRT2,((65536-AMP_OVER_SQRT2)<<16)|(65536-AMP_OVER_SQRT2)};
 int QPSK2[4]={AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),((65536-AMP_OVER_2)<<16)|AMP_OVER_2,((65536-AMP_OVER_2)<<16)|(65536-AMP_OVER_2)};
 
-void phy_procedures_eNB_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_mode_t r_mode) {
+void phy_procedures_eNB_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type) {
   u8 *pbch_pdu=&phy_vars_eNB->pbch_pdu[0];
   //  unsigned int nb_dci_ue_spec = 0, nb_dci_common = 0;
   u16 input_buffer_length, re_allocated=0;
@@ -918,6 +921,11 @@ void phy_procedures_eNB_TX(unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8
 
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,1);
 
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[%s %d] Frame %d subframe %d : Doing phy_procedures_eNB_TX(%d)\n", 
+	(r_type == multicast_relay) ? "RN/eNB" : "eNB",
+	phy_vars_eNB->Mod_id,phy_vars_eNB->frame, next_slot>>1, next_slot);
+#endif
 #ifdef OPENAIR2
   // Get scheduling info for next subframe during odd slot of previous subframe (next_slot is even)
   if (next_slot%2 == 0) 
@@ -2397,7 +2405,7 @@ void ulsch_decoding_procedures(unsigned char last_slot, unsigned int i, PHY_VARS
 }
 
 
-void phy_procedures_eNB_RX(unsigned char last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_mode_t r_mode) {
+void phy_procedures_eNB_RX(unsigned char last_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag,relaying_type_t r_type) {
   //RX processing
   u32 l, ret,i,j;
   u32 sect_id=0;
@@ -2419,6 +2427,9 @@ void phy_procedures_eNB_RX(unsigned char last_slot,PHY_VARS_eNB *phy_vars_eNB,u8
   int frame = ((last_slot>>1)>=8 ? -1 : 0 )+ phy_vars_eNB->frame;
 
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1);
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_RX(%d)\n",phy_vars_eNB->Mod_id,phy_vars_eNB->frame, last_slot);
+#endif
 
   if (abstraction_flag == 0) {
     remove_7_5_kHz(phy_vars_eNB,last_slot);
@@ -3357,44 +3368,58 @@ void phy_procedures_eNB_RX(unsigned char last_slot,PHY_VARS_eNB *phy_vars_eNB,u8
 
 #undef DEBUG_PHY_PROC
 
-void phy_procedures_eNB_lte(unsigned char last_slot, unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, relaying_mode_t r_mode) {
+#ifdef Rel10  
+int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, relaying_type_t r_type){
+  
+  int do_proc=0;// do nothing
+  switch(r_type){
+  case no_relay:
+    do_proc= no_relay; // perform the normal eNB operation 
+    break;
+  case multicast_relay:
+    if ( ((next_slot >>1) < 6) || ((next_slot >>1) > 8))
+      do_proc = 0; // do nothing
+    else // SF#6, SF#7 and SF#8 
+      do_proc = multicast_relay; // do PHY procedures eNB TX 
+    break;
+  default: // should'not be here
+    LOG_W(PHY,"Not supported relay type %d, do nothing\n", r_type);
+    do_proc=0; 
+    break;
+  }
+  return do_proc;
+}
+#endif 
+void phy_procedures_eNB_lte(unsigned char last_slot, unsigned char next_slot,PHY_VARS_eNB *phy_vars_eNB,u8 abstraction_flag, relaying_type_t r_type) {
   /*
     if (phy_vars_eNB->frame >= 1000)
     mac_xface->macphy_exit("Exiting after 1000 Frames\n");
   */
   vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER, (last_slot + 1) % 20);
   vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER, phy_vars_eNB->frame);
-
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,1);
   
   if (((phy_vars_eNB->lte_frame_parms.frame_type == 1)&&(subframe_select(&phy_vars_eNB->lte_frame_parms,next_slot>>1)==SF_DL))||
       (phy_vars_eNB->lte_frame_parms.frame_type == 0)){
-#ifdef DEBUG_PHY_PROC
-    LOG_D(PHY,"[eNB %d] Frame %d: Calling phy_procedures_eNB_TX(%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->frame, next_slot);
-#endif
-
-    phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_mode);
+#ifdef Rel10 
+    if (phy_procedures_RN_eNB_TX(last_slot, next_slot, r_type) != 0 ) 
+#endif 
+      phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_type);
   }
   if (((phy_vars_eNB->lte_frame_parms.frame_type == 1 )&&(subframe_select(&phy_vars_eNB->lte_frame_parms,last_slot>>1)==SF_UL))||
       (phy_vars_eNB->lte_frame_parms.frame_type == 0)){
-#ifdef DEBUG_PHY_PROC
-    LOG_D(PHY,"[eNB %d] Frame %d: Calling phy_procedures_eNB_RX(%d)\n",phy_vars_eNB->Mod_id,phy_vars_eNB->frame, last_slot);
-#endif
-    phy_procedures_eNB_RX(last_slot,phy_vars_eNB,abstraction_flag,r_mode);
+    phy_procedures_eNB_RX(last_slot,phy_vars_eNB,abstraction_flag,r_type);
   }
   if ((subframe_select(&phy_vars_eNB->lte_frame_parms,next_slot>>1)==SF_S) &&
       ((next_slot&1)==0)) {
-#ifdef DEBUG_PHY_PROC
-    LOG_D(PHY,"[eNB %d] Frame %d: Calling phy_procedures_eNB_S_TX(%d)\n",phy_vars_eNB->Mod_id,phy_vars_eNB->frame, next_slot);
-#endif
-    phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_mode);
+#ifdef Rel10 
+    if (phy_procedures_RN_eNB_TX(last_slot, next_slot, r_type) != 0 )
+#endif 
+      phy_procedures_eNB_TX(next_slot,phy_vars_eNB,abstraction_flag,r_type);
   }
   if ((subframe_select(&phy_vars_eNB->lte_frame_parms,last_slot>>1)==SF_S) &&
       ((last_slot&1)==0)){
-#ifdef DEBUG_PHY_PROC
-    LOG_D(PHY,"[eNB %d] Frame %d: Calling phy_procedures_eNB_S_RX(%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->frame, last_slot);
-#endif    
-    phy_procedures_eNB_S_RX(last_slot,phy_vars_eNB,abstraction_flag,r_mode);
+    phy_procedures_eNB_S_RX(last_slot,phy_vars_eNB,abstraction_flag,r_type);
   }
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0);
 
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 314fc76561..60bb9af50e 100755
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -557,7 +557,7 @@ int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
   PRACH_RESOURCES_t prach_resources_local;
 #endif
 
-void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_mode_t r_mode) {
+void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type) {
   
   //  int i_d;
   u16 first_rb, nb_rb;
@@ -1292,7 +1292,7 @@ void phy_procedures_UE_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
 }
 
-void phy_procedures_UE_S_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,relaying_mode_t r_mode) {
+void phy_procedures_UE_S_TX(u8 next_slot,PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,relaying_type_t r_type) {
   int aa;//i,aa;
   LTE_DL_FRAME_PARMS *frame_parms=&phy_vars_ue->lte_frame_parms;
 
@@ -2163,7 +2163,7 @@ int lte_ue_pdcch_procedures(u8 eNB_id,u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8
 }
 
  
-int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_mode_t r_mode) {
+int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode,relaying_type_t r_type) {
 
   u16 l,m,n_symb;
   //  int eNB_id = 0, 
@@ -2184,7 +2184,11 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs
 
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
   //msg("UE_RX 1 last_slot %d \n",last_slot);
-
+#ifdef DEBUG_PHY_PROC
+  LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX(%d)\n", 
+	(r_type == multicast_relay) ? "RN/UE" : "UE",
+	phy_vars_ue->Mod_id,phy_vars_ue->frame, last_slot>>1, last_slot);
+#endif
   if (phy_vars_ue->lte_frame_parms.Ncp == 0) {  // normal prefix
     pilot1 = 4;
     pilot2 = 7;
@@ -3015,8 +3019,30 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs
   vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
   return (0);
 }
-  
- void phy_procedures_UE_lte(u8 last_slot, u8 next_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, relaying_mode_t r_mode) {
+
+#ifdef Rel10
+int phy_procedures_RN_UE_RX(u8 last_slot, u8 next_slot, relaying_type_t r_type) {
+
+  int do_proc =0; // do nothing by default 
+  switch(r_type){
+  case no_relay:
+    do_proc=no_relay; // perform the normal UE operation 
+    break;
+  case multicast_relay:
+    if (last_slot > 12)
+      do_proc = 0; // do nothing
+    else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12)
+      do_proc =multicast_relay ; // do PHY procedures UE RX 
+    break;
+  default: // should'not be here
+    LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type);
+    do_proc= 0;
+    break;
+  }
+  return do_proc;
+}
+#endif   
+ void phy_procedures_UE_lte(u8 last_slot, u8 next_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abstraction_flag,runmode_t mode, relaying_type_t r_type) {
 
 #undef DEBUG_PHY_PROC
 
@@ -3040,22 +3066,28 @@ int phy_procedures_UE_RX(u8 last_slot, PHY_VARS_UE *phy_vars_ue,u8 eNB_id,u8 abs
 
   if ((subframe_select(&phy_vars_ue->lte_frame_parms,next_slot>>1)==SF_UL)||
       (phy_vars_ue->lte_frame_parms.frame_type == 0)){
-    phy_procedures_UE_TX(next_slot,phy_vars_ue,eNB_id,abstraction_flag,mode,r_mode);
+    phy_procedures_UE_TX(next_slot,phy_vars_ue,eNB_id,abstraction_flag,mode,r_type);
   }
   if ((subframe_select(&phy_vars_ue->lte_frame_parms,last_slot>>1)==SF_DL) ||
       (phy_vars_ue->lte_frame_parms.frame_type == 0)){
-    phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode,r_mode);
+#ifdef Rel10 
+    if (phy_procedures_RN_UE_RX(last_slot, next_slot, r_type) != 0 )
+#endif 
+    phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode,r_type);
 #ifdef EMOS
     phy_procedures_emos_UE_RX(phy_vars_ue,last_slot,eNB_id);
 #endif
   }
   if ((subframe_select(&phy_vars_ue->lte_frame_parms,next_slot>>1)==SF_S) &&
       ((next_slot&1)==1)) {
-    phy_procedures_UE_S_TX(next_slot,phy_vars_ue,eNB_id,abstraction_flag,r_mode);
+    phy_procedures_UE_S_TX(next_slot,phy_vars_ue,eNB_id,abstraction_flag,r_type);
   }
   if ((subframe_select(&phy_vars_ue->lte_frame_parms,last_slot>>1)==SF_S) &&
       ((last_slot&1)==0)) {
-    phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode, r_mode);
+ #ifdef Rel10 
+    if (phy_procedures_RN_UE_RX(last_slot, next_slot, r_type) != 0 )
+#endif 
+   phy_procedures_UE_RX(last_slot,phy_vars_ue,eNB_id,abstraction_flag,mode, r_type);
   }
 
 #ifdef OPENAIR2
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 1c5b929e4e..a9e0c185e3 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -1325,7 +1325,7 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) {
 
   // there is MCCH
   if (mcch_flag == 1) {
-    LOG_D(MAC,"Scheduler: MCCH MESSAGE is transmitted in this subframe \n" );
+    LOG_D(MAC,"Scheduler: MCCH MESSAGE is transmitted in this subframe %d \n",  subframe);
     
     mcch_sdu_length = mac_rrc_data_req(Mod_id,
 				       frame,
@@ -1334,20 +1334,20 @@ int schedule_MBMS(unsigned char Mod_id,u32 frame, u8 subframe) {
 				       1,// this is eNB
 				       Mod_id);
     if (mcch_sdu_length > 0) {
-      LOG_D(MAC,"[eNB %d] Frame %d : MCCH->MCH, Received %d bytes from RRC \n",Mod_id,frame,mcch_sdu_length);
+      LOG_D(MAC,"[eNB %d] Frame %d subframe %d : MCCH->MCH, Received %d bytes from RRC \n",Mod_id,frame,subframe,mcch_sdu_length);
       
       header_len_mcch = 2; 
       if (mac_xface->lte_frame_parms->frame_type == TDD) {
-	LOG_D(MAC,"[eNB %d] Frame %d : Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", 
+	LOG_D(MAC,"[eNB %d] Frame %d subframe %d: Scheduling MCCH->MCH (TDD) for MCCH message %d bytes (mcs %d )\n", 
 	      Mod_id,
-	      frame,
+	      frame,subframe, 
 	      mcch_sdu_length,
 	      mcch_mcs);
       }
       else {
-	LOG_I(MAC,"[eNB %d] Frame %d : Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
+	LOG_I(MAC,"[eNB %d] Frame %d subframe %d: Scheduling MCCH->MCH (FDD) for MCCH message %d bytes (mcs %d)\n",
 	      Mod_id,
-	      frame,
+	      frame, subframe,
 	      mcch_sdu_length,
 	      mcch_mcs); 
       }
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index 611c923153..29f5d9f773 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -86,7 +86,7 @@ BOOL pdcp_data_req(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb
 #ifdef PDCP_UNIT_TEST
   pdcp_t* pdcp = test_pdcp_entity;
 #else
-  pdcp_t* pdcp = &pdcp_array[module_id][rb_id];
+  pdcp_t* pdcp = &pdcp_array[module_id][rb_id%NB_RB_MAX];
 #endif
   u8 i;
   u8 pdcp_header_len=0, pdcp_tailer_len=0;
@@ -266,7 +266,7 @@ BOOL pdcp_data_ind(module_id_t module_id, u32_t frame, u8_t eNB_flag, rb_id_t rb
   pdcp_t* pdcp = pdcp_test_entity;
   list_t* sdu_list = test_list;
 #else
-  pdcp_t* pdcp = &pdcp_array[module_id][rb_id];
+  pdcp_t* pdcp = &pdcp_array[module_id][rb_id%NB_RB_MAX];
   list_t* sdu_list = &pdcp_sdu_list;
 #endif
   mem_block_t *new_sdu = NULL;
@@ -541,8 +541,9 @@ BOOL rrc_pdcp_config_asn1_req (module_id_t module_id, u32_t frame, u8_t eNB_flag
   if (srb2add_list != NULL) {
     for (cnt=0;cnt<srb2add_list->list.count;cnt++) {
       srb_id = srb2add_list->list.array[cnt]->srb_Identity;
+      lc_id = srb_id; 
       rb_id = (index * NB_RB_MAX) + srb_id;
-      if (pdcp_array[module_id][rb_id].instanciated_instance == module_id + 1)
+      if (pdcp_array[module_id][lc_id].instanciated_instance == module_id + 1)
         action = ACTION_MODIFY;
       else
         action = ACTION_ADD;
@@ -596,7 +597,7 @@ BOOL rrc_pdcp_config_asn1_req (module_id_t module_id, u32_t frame, u8_t eNB_flag
         lc_id = -1;
       }
       rb_id =  (index * NB_RB_MAX) + lc_id;
-      if (pdcp_array[module_id][rb_id].instanciated_instance == module_id + 1)
+      if (pdcp_array[module_id][lc_id].instanciated_instance == module_id + 1)
         action = ACTION_MODIFY;
       else
         action = ACTION_ADD;
@@ -733,93 +734,93 @@ BOOL pdcp_config_req_asn1 (module_id_t module_id, u32 frame, u8_t eNB_flag, u16
                            u8 security_mode){
   switch (action) {
   case ACTION_ADD:
-    pdcp_array[module_id][rb_id].instanciated_instance = module_id + 1;
-    pdcp_array[module_id][rb_id].lcid = lc_id;
-    pdcp_array[module_id][rb_id].header_compression_profile=header_compression_profile;
-    pdcp_array[module_id][rb_id].cipheringAlgorithm=security_mode & 0x0f;
-    pdcp_array[module_id][rb_id].integrityProtAlgorithm=(security_mode>>4) & 0xf;
-    pdcp_array[module_id][rb_id].status_report = rb_report;
+    pdcp_array[module_id][lc_id].instanciated_instance = module_id + 1;
+    pdcp_array[module_id][lc_id].lcid = lc_id;
+    pdcp_array[module_id][lc_id].header_compression_profile=header_compression_profile;
+    pdcp_array[module_id][lc_id].cipheringAlgorithm=security_mode & 0x0f;
+    pdcp_array[module_id][lc_id].integrityProtAlgorithm=(security_mode>>4) & 0xf;
+    pdcp_array[module_id][lc_id].status_report = rb_report;
     if (rb_sn == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits)
-      pdcp_array[module_id][rb_id].seq_num_size = 7;
+      pdcp_array[module_id][lc_id].seq_num_size = 7;
     else if (rb_sn == PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits)
-      pdcp_array[module_id][rb_id].seq_num_size=12;
+      pdcp_array[module_id][lc_id].seq_num_size=12;
     else
-      pdcp_array[module_id][rb_id].seq_num_size=5;
+      pdcp_array[module_id][lc_id].seq_num_size=5;
 
-    pdcp_array[module_id][rb_id].rlc_mode = rlc_mode;
-    pdcp_array[module_id][rb_id].next_pdcp_tx_sn = 0;
-    pdcp_array[module_id][rb_id].next_pdcp_rx_sn = 0;
-    pdcp_array[module_id][rb_id].tx_hfn = 0;
-    pdcp_array[module_id][rb_id].rx_hfn = 0;
-    pdcp_array[module_id][rb_id].last_submitted_pdcp_rx_sn = 4095;
-    pdcp_array[module_id][rb_id].first_missing_pdu = -1;
+    pdcp_array[module_id][lc_id].rlc_mode = rlc_mode;
+    pdcp_array[module_id][lc_id].next_pdcp_tx_sn = 0;
+    pdcp_array[module_id][lc_id].next_pdcp_rx_sn = 0;
+    pdcp_array[module_id][lc_id].tx_hfn = 0;
+    pdcp_array[module_id][lc_id].rx_hfn = 0;
+    pdcp_array[module_id][lc_id].last_submitted_pdcp_rx_sn = 4095;
+    pdcp_array[module_id][lc_id].first_missing_pdu = -1;
 
-    LOG_I(PDCP,"[%s %d] Config request : Action ADD for %s %d: Frame %d radio bearer id %d configured with SN size %d bits and RLC %s\n",
+    LOG_I(PDCP,"[%s %d] Config request : Action ADD for %s %d: Frame %d LCID %d (rb id %d) configured with SN size %d bits and RLC %s\n",
           (eNB_flag) ? "eNB" : "UE", module_id,
           (eNB_flag) ? "UE" : "eNB", index,
-          frame, rb_id, pdcp_array[module_id][rb_id].seq_num_size,
+          frame, lc_id, rb_id, pdcp_array[module_id][lc_id].seq_num_size,
           (rlc_mode == 1) ? "AM" : (rlc_mode == 2) ? "TM" : "UM");
 
     LOG_D(PDCP,  "[MSC_NEW][FRAME %05d][PDCP][MOD %02d][RB %02d]\n", frame, module_id,rb_id);
 
     break;
     case ACTION_MODIFY:
-    pdcp_array[module_id][rb_id].header_compression_profile=header_compression_profile;
-    pdcp_array[module_id][rb_id].cipheringAlgorithm=security_mode & 0x0f;
-    pdcp_array[module_id][rb_id].integrityProtAlgorithm=(security_mode>>4) & 0xf;
-    pdcp_array[module_id][rb_id].status_report = rb_report;
-    pdcp_array[module_id][rb_id].rlc_mode = rlc_mode;
+    pdcp_array[module_id][lc_id].header_compression_profile=header_compression_profile;
+    pdcp_array[module_id][lc_id].cipheringAlgorithm=security_mode & 0x0f;
+    pdcp_array[module_id][lc_id].integrityProtAlgorithm=(security_mode>>4) & 0xf;
+    pdcp_array[module_id][lc_id].status_report = rb_report;
+    pdcp_array[module_id][lc_id].rlc_mode = rlc_mode;
 
     if (rb_sn == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits)
-      pdcp_array[module_id][rb_id].seq_num_size = 7;
+      pdcp_array[module_id][lc_id].seq_num_size = 7;
     else if (rb_sn == PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits)
-      pdcp_array[module_id][rb_id].seq_num_size=12;
+      pdcp_array[module_id][lc_id].seq_num_size=12;
     else
-      pdcp_array[module_id][rb_id].seq_num_size=5;
+      pdcp_array[module_id][lc_id].seq_num_size=5;
 
-    LOG_I(PDCP,"[%s %d] Config request : Action MODIFY for %s %d: Frame %d radio bearer id %d configured with SN size %d and RLC %s \n",
+    LOG_I(PDCP,"[%s %d] Config request : Action MODIFY for %s %d: Frame %d LCID %d RB id %d configured with SN size %d and RLC %s \n",
           (eNB_flag) ? "eNB" : "UE", module_id,
           (eNB_flag) ? "UE" : "eNB", index,
-          frame, rb_id, rb_sn,
+          frame, lc_id, rb_id, rb_sn,
           (rlc_mode == 1) ? "AM" : (rlc_mode == 2) ? "TM" : "UM");
 
     break;
     case ACTION_REMOVE:
-    pdcp_array[module_id][rb_id].instanciated_instance = 0;
-    pdcp_array[module_id][rb_id].lcid= 0;
-    pdcp_array[module_id][rb_id].header_compression_profile=0x0;
-    pdcp_array[module_id][rb_id].cipheringAlgorithm=0xff;
-    pdcp_array[module_id][rb_id].integrityProtAlgorithm=0xff;
-    pdcp_array[module_id][rb_id].status_report = 0;
-    pdcp_array[module_id][rb_id].rlc_mode = RLC_NONE;
-    pdcp_array[module_id][rb_id].next_pdcp_tx_sn = 0;
-    pdcp_array[module_id][rb_id].next_pdcp_rx_sn = 0;
-    pdcp_array[module_id][rb_id].tx_hfn = 0;
-    pdcp_array[module_id][rb_id].rx_hfn = 0;
-    pdcp_array[module_id][rb_id].last_submitted_pdcp_rx_sn = 4095;
-    pdcp_array[module_id][rb_id].seq_num_size = 0;
-    pdcp_array[module_id][rb_id].first_missing_pdu = -1;
-    LOG_I(PDCP,"[%s %d] Config request : ACTION_REMOVE: Frame %d radio bearer id %d configured\n",
-          (eNB_flag) ? "eNB" : "UE", module_id, frame, rb_id);
+    pdcp_array[module_id][lc_id].instanciated_instance = 0;
+    pdcp_array[module_id][lc_id].lcid= 0;
+    pdcp_array[module_id][lc_id].header_compression_profile=0x0;
+    pdcp_array[module_id][lc_id].cipheringAlgorithm=0xff;
+    pdcp_array[module_id][lc_id].integrityProtAlgorithm=0xff;
+    pdcp_array[module_id][lc_id].status_report = 0;
+    pdcp_array[module_id][lc_id].rlc_mode = RLC_NONE;
+    pdcp_array[module_id][lc_id].next_pdcp_tx_sn = 0;
+    pdcp_array[module_id][lc_id].next_pdcp_rx_sn = 0;
+    pdcp_array[module_id][lc_id].tx_hfn = 0;
+    pdcp_array[module_id][lc_id].rx_hfn = 0;
+    pdcp_array[module_id][lc_id].last_submitted_pdcp_rx_sn = 4095;
+    pdcp_array[module_id][lc_id].seq_num_size = 0;
+    pdcp_array[module_id][lc_id].first_missing_pdu = -1;
+    LOG_I(PDCP,"[%s %d] Config request : ACTION_REMOVE: Frame %d LCID %d RBID %d configured\n",
+          (eNB_flag) ? "eNB" : "UE", module_id, frame, lc_id,rb_id);
 
     break;
     case ACTION_MBMS_ADD:
     case ACTION_MBMS_MODIFY:
-    pdcp_mbms_array[module_id][rb_id].instanciated_instance = module_id + 1 ;
-    pdcp_mbms_array[module_id][rb_id].service_id = mch_id;
-    pdcp_mbms_array[module_id][rb_id].session_id = lc_id;
-    pdcp_mbms_array[module_id][rb_id].rb_id = rb_id;
+    pdcp_mbms_array[module_id][lc_id].instanciated_instance = module_id + 1 ;
+    pdcp_mbms_array[module_id][lc_id].service_id = mch_id;
+    pdcp_mbms_array[module_id][lc_id].session_id = lc_id;
+    pdcp_mbms_array[module_id][lc_id].rb_id = rb_id;
     LOG_I(PDCP,"[%s %d] Config request : ACTION_MBMS_ADD: Frame %d service_id/mch index %d, session_id/lcid %d, rbid %d configured\n",
           (eNB_flag == 1) ? "eNB" : "UE", module_id, frame, mch_id, lc_id, rb_id);
     break;
     case ACTION_SET_SECURITY_MODE:
     if ((security_mode >= 0 ) && (security_mode <=0x77)) {
-      pdcp_array[module_id][rb_id].cipheringAlgorithm= security_mode & 0x0f;
-      pdcp_array[module_id][rb_id].integrityProtAlgorithm = (security_mode>>4) & 0xf;
+      pdcp_array[module_id][lc_id].cipheringAlgorithm= security_mode & 0x0f;
+      pdcp_array[module_id][lc_id].integrityProtAlgorithm = (security_mode>>4) & 0xf;
       LOG_D(PDCP,"[%s %d] Set security mode : ACTION_SET_SECURITY_MODE: Frame %d  cipheringAlgorithm %d integrityProtAlgorithm %d\n",
             (eNB_flag) ? "eNB" : "UE", module_id, frame,
-            pdcp_array[module_id][rb_id].cipheringAlgorithm,
-            pdcp_array[module_id][rb_id].integrityProtAlgorithm );
+            pdcp_array[module_id][lc_id].cipheringAlgorithm,
+            pdcp_array[module_id][lc_id].integrityProtAlgorithm );
     }else
       LOG_D(PDCP,"[%s %d] bad security mode %d", security_mode);
     break;
@@ -829,30 +830,28 @@ BOOL pdcp_config_req_asn1 (module_id_t module_id, u32 frame, u8_t eNB_flag, u16
   }
   return 0;
 }
-
-
-void
-    rrc_pdcp_config_req (module_id_t module_id, u32 frame, u8_t eNB_flag, u32  action, rb_id_t rb_id, u8 security_mode){
+ 
+void rrc_pdcp_config_req (module_id_t module_id, u32 frame, u8_t eNB_flag, u32  action, rb_id_t rb_id, u8 security_mode){
 
   /*
      * Initialize sequence number state variables of relevant PDCP entity
      */
   switch (action) {
   case ACTION_ADD:
-    pdcp_array[module_id][rb_id].instanciated_instance = module_id + 1;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].instanciated_instance = module_id + 1;
     
-    pdcp_array[module_id][rb_id].next_pdcp_tx_sn = 0;
-    pdcp_array[module_id][rb_id].next_pdcp_rx_sn = 0;
-    pdcp_array[module_id][rb_id].tx_hfn = 0;
-    pdcp_array[module_id][rb_id].rx_hfn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].next_pdcp_tx_sn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].next_pdcp_rx_sn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].tx_hfn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].rx_hfn = 0;
     /* SN of the last PDCP SDU delivered to upper layers */
-    pdcp_array[module_id][rb_id].last_submitted_pdcp_rx_sn = 4095;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].last_submitted_pdcp_rx_sn = 4095;
 
     if ( (rb_id % NB_RB_MAX) < DTCH) // SRB
-      pdcp_array[module_id][rb_id].seq_num_size = 5;
+      pdcp_array[module_id][rb_id%NB_RB_MAX].seq_num_size = 5;
     else // DRB
-      pdcp_array[module_id][rb_id].seq_num_size = 12;
-    pdcp_array[module_id][rb_id].first_missing_pdu = -1;
+      pdcp_array[module_id][rb_id%NB_RB_MAX].seq_num_size = 12;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].first_missing_pdu = -1;
     LOG_D(PDCP,"[%s %d] Config request : Action ADD: Frame %d radio bearer id %d configured\n",
           (eNB_flag) ? "eNB" : "UE", module_id, frame, rb_id);
     LOG_D(PDCP,  "[MSC_NEW][FRAME %05d][PDCP][MOD %02d][RB %02d]\n", frame, module_id,rb_id);
@@ -860,26 +859,26 @@ void
     case ACTION_MODIFY:
     break;
     case ACTION_REMOVE:
-    pdcp_array[module_id][rb_id].instanciated_instance = 0;
-    pdcp_array[module_id][rb_id].next_pdcp_tx_sn = 0;
-    pdcp_array[module_id][rb_id].next_pdcp_rx_sn = 0;
-    pdcp_array[module_id][rb_id].tx_hfn = 0;
-    pdcp_array[module_id][rb_id].rx_hfn = 0;
-    pdcp_array[module_id][rb_id].last_submitted_pdcp_rx_sn = 4095;
-    pdcp_array[module_id][rb_id].seq_num_size = 0;
-    pdcp_array[module_id][rb_id].first_missing_pdu = -1;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].instanciated_instance = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].next_pdcp_tx_sn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].next_pdcp_rx_sn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].tx_hfn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].rx_hfn = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].last_submitted_pdcp_rx_sn = 4095;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].seq_num_size = 0;
+    pdcp_array[module_id][rb_id%NB_RB_MAX].first_missing_pdu = -1;
     LOG_D(PDCP,"[%s %d] Config request : ACTION_REMOVE: Frame %d radio bearer id %d configured\n",
           (eNB_flag) ? "eNB" : "UE", module_id, frame, rb_id);
 
     break;
     case ACTION_SET_SECURITY_MODE:
     if ((security_mode >= 0 ) && (security_mode <=0x77)) {
-      pdcp_array[module_id][rb_id].cipheringAlgorithm= security_mode & 0x0f;
-      pdcp_array[module_id][rb_id].integrityProtAlgorithm = (security_mode>>4) & 0xf;
+      pdcp_array[module_id][rb_id%NB_RB_MAX].cipheringAlgorithm= security_mode & 0x0f;
+      pdcp_array[module_id][rb_id%NB_RB_MAX].integrityProtAlgorithm = (security_mode>>4) & 0xf;
       LOG_D(PDCP,"[%s %d] Set security mode : ACTION_SET_SECURITY_MODE: Frame %d  cipheringAlgorithm %d integrityProtAlgorithm %d\n",
             (eNB_flag) ? "eNB" : "UE", module_id, frame,
-            pdcp_array[module_id][rb_id].cipheringAlgorithm,
-            pdcp_array[module_id][rb_id].integrityProtAlgorithm );
+            pdcp_array[module_id][rb_id%NB_RB_MAX].cipheringAlgorithm,
+            pdcp_array[module_id][rb_id%NB_RB_MAX].integrityProtAlgorithm );
     }else
       LOG_D(PDCP,"[%s %d] bad security mode %d", security_mode);
     break;
@@ -951,7 +950,7 @@ void
     */
   list_init(&pdcp_sdu_list, NULL);
   for (i=0; i < MAX_MODULES; i++) {
-    for (j=0; j < MAX_RB; j++) {
+    for (j=0; j < NB_RB_MAX; j++) {
       memset((void*)&pdcp_array[i][j], 0, sizeof(pdcp_t));
     }
 
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index 6ec0d67bc5..d24ed4f4f3 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -351,7 +351,7 @@ typedef struct pdcp_missing_pdu_info_t {
 #define PDCP_MAX_SN_12BIT 4095 // 2^12-1
 
 protected_pdcp(signed int             pdcp_2_nas_irq;)
-protected_pdcp(pdcp_t                 pdcp_array[MAX_MODULES][MAX_RB];)
+protected_pdcp(pdcp_t                 pdcp_array[MAX_MODULES][NB_RB_MAX];)
 public_pdcp(pdcp_mbms_t               pdcp_mbms_array[MAX_MODULES][16*29];) // MAX_SERVICEx MAX_SESSION
 protected_pdcp(sdu_size_t             pdcp_output_sdu_bytes_to_write;)
 protected_pdcp(sdu_size_t             pdcp_output_header_bytes_to_write;)
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index a0d535907f..09d187082d 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -300,7 +300,7 @@ int
           LOG_D(PDCP, "[MSC_MSG][FRAME %05d][IP][MOD %02d][][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %02d][RB %02d]\n",
                 frame, pdcp_read_header.inst,  pdcp_read_header.data_size, pdcp_read_header.inst, pdcp_read_header.rb_id);
 
-            if (pdcp_array[pdcp_read_header.inst][pdcp_read_header.rb_id].instanciated_instance) {
+            if (pdcp_array[pdcp_read_header.inst][pdcp_read_header.rb_id%NB_RB_MAX].instanciated_instance) {
                 pdcp_data_req (pdcp_input_header.inst,
                          frame, eNB_flag,
                          pdcp_input_header.rb_id,
@@ -316,7 +316,7 @@ int
 #warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
             for (rab_id = DEFAULT_RAB_ID; rab_id < MAX_RB; rab_id = rab_id + NB_RB_MAX) {
                 LOG_D(PDCP, "Checking if could sent on default rab id %d\n", rab_id);
-                if (pdcp_array[pdcp_input_header.inst][rab_id].instanciated_instance == (pdcp_input_header.inst + 1)) {
+                if (pdcp_array[pdcp_input_header.inst][rab_id%NB_RB_MAX].instanciated_instance == (pdcp_input_header.inst + 1)) {
                     pdcp_data_req (pdcp_input_header.inst,
                                 frame, eNB_flag,
                                 rab_id,
@@ -576,7 +576,7 @@ int
                       #endif
 
                       if (pdcp_read_header.rb_id != 0) {
-                          if (pdcp_array[pdcp_read_header.inst][pdcp_read_header.rb_id].instanciated_instance) {
+                          if (pdcp_array[pdcp_read_header.inst][pdcp_read_header.rb_id%NB_RB_MAX].instanciated_instance) {
 #ifdef PDCP_DEBUG
                               LOG_I(PDCP, "[PDCP][NETLINK][IP->PDCP] TTI %d, INST %d: Received socket with length %d (nlmsg_len = %d) on Rab %d \n",
                                   frame, pdcp_read_header.inst, len, nas_nlh_rx->nlmsg_len-sizeof(struct nlmsghdr), pdcp_read_header.rb_id);
@@ -601,7 +601,7 @@ int
                           // is a broadcast packet, we have to send this packet on all default RABS of all connected UEs
         #warning CODE TO BE REVIEWED, ONLY WORK FOR SIMPLE TOPOLOGY CASES
                           for (rab_id = DEFAULT_RAB_ID; rab_id < MAX_RB; rab_id = rab_id + NB_RB_MAX) {
-                              if (pdcp_array[pdcp_input_header.inst][rab_id].instanciated_instance == (pdcp_input_header.inst + 1)) {
+                              if (pdcp_array[pdcp_input_header.inst][rab_id%NB_RB_MAX].instanciated_instance == (pdcp_input_header.inst + 1)) {
                                   pdcp_data_req (pdcp_read_header.inst, frame, eNB_flag, rab_id, RLC_MUI_UNDEFINED,RLC_SDU_CONFIRM_NO,
                                             pdcp_read_header.data_size,
                                             (unsigned char *)NLMSG_DATA(nas_nlh_rx),
diff --git a/openair2/RRC/LITE/rrc_UE.c b/openair2/RRC/LITE/rrc_UE.c
index 4b94f7d2ab..9488196283 100644
--- a/openair2/RRC/LITE/rrc_UE.c
+++ b/openair2/RRC/LITE/rrc_UE.c
@@ -1605,7 +1605,7 @@ int decode_MCCH_Message(u8 Mod_id, u32 frame, u8 eNB_index, u8 *Sdu, u8 Sdu_len)
 	       (void*)&mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9,
 	       sizeof(MBSFNAreaConfiguration_r9_t)); */
 	*mcch_message = &mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9;
-	LOG_I(RRC,"[UE %d] Frame %d : Found MBSFNAreaConfiguration from eNB \n",Mod_id, frame, eNB_index);
+	LOG_I(RRC,"[UE %d] Frame %d : Found MBSFNAreaConfiguration from eNB %d \n",Mod_id, frame, eNB_index);
 	decode_MBSFNAreaConfiguration(Mod_id,eNB_index,frame);
 
       }
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index ff054c143e..8a83409c86 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -454,7 +454,7 @@ openair_rrc_lite_eNB_init (u8 Mod_id)
   LOG_I (RRC, "Checking release \n");
 #ifdef Rel10
 
-  // This has to come from some top-level configuration
+  // Thishas to come from some top-level configuration
   printf ("Rel10 RRC detected, MBMS flag %d\n",
           eNB_rrc_inst[Mod_id].MBMS_flag);
 
diff --git a/openair2/UTIL/OTG/otg_rx.c b/openair2/UTIL/OTG/otg_rx.c
index a3a7f44ada..8a44a796f0 100644
--- a/openair2/UTIL/OTG/otg_rx.c
+++ b/openair2/UTIL/OTG/otg_rx.c
@@ -173,8 +173,8 @@ float owd_const_application_v=owd_const_application()/2;
       }
 
       if (otg_hdr_info_rx->flag == 0x1000){
-	LOG_I(OTG,"received a multicast packet at time %d with size %d, seq num %d, ran owd %d number loss packet %d\n",
-	      ctime,otg_hdr_info_rx->size, otg_hdr_rx->seq_num, ctime - otg_hdr_rx->time, nb_loss_pkts);
+	LOG_I(OTG,"[SRC%d -> DST %d] Received a multicast packet at time %d with size %d, seq num %d, ran owd %d number loss packet %d\n",
+	      dst, src, ctime,otg_hdr_info_rx->size, otg_hdr_rx->seq_num, ctime - otg_hdr_rx->time, nb_loss_pkts);
 	
 	LOG_I(OTG,"INFO LATENCY :: [SRC %d][DST %d] radio access %.2f (tx time %d, ctime %d), OWD:%.2f (ms):\n", 
 	      src, dst, otg_multicast_info->radio_access_delay[src][dst], otg_hdr_rx->time, ctime , otg_multicast_info->rx_pkt_owd[src][dst]);
diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c
index bf01b8eaf5..728868633c 100644
--- a/targets/SIMU/USER/oaisim.c
+++ b/targets/SIMU/USER/oaisim.c
@@ -201,7 +201,7 @@ help (void) {
   printf ("    - wireshark: Enable tracing of layers above PHY using an UDP socket\n");
   printf ("    - pcap:      Enable tracing of layers above PHY to a pcap file\n");
   printf ("    - tshark:    Not implemented yet\n");
-  printf ("-Q Activate and set the MBMS service: 0 : not used (default eMBMS disabled), 1: eMBMS and RRC enabled, 2: eMBMS relaying and RRC enabled, 3: eMBMS enabled, RRC disabled, 4: eMBMS relaying enabled, RRC disabled\n");
+  printf ("-Q Activate and set the MBMS service: 0 : not used (default eMBMS disabled), 1: eMBMS and RRC Connection enabled, 2: eMBMS relaying and RRC Connection enabled, 3: eMBMS enabled, RRC Connection disabled, 4: eMBMS relaying enabled, RRC Connection disabled\n");
   printf ("-R [6,15,25,50,75,100] Sets N_RB_DL\n");
   printf ("-r Activates rate adaptation (DL for now)\n");
   printf ("-s snr_dB set a fixed (average) SNR, this deactivates the openair channel model generator (OCM)\n");
@@ -368,7 +368,7 @@ int
 
   s32 UE_id=0, eNB_id=0, RN_id=0;
   
-  relaying_mode_t r_mode=no_relay; // no relaying 
+  relaying_type_t r_type=no_relay; // no relaying 
   // time calibration for soft realtime mode  
 
   lte_subframe_t direction;
@@ -631,7 +631,6 @@ int
       
       direction = subframe_select(frame_parms,next_slot>>1);
 
-      r_mode = no_relay;
 #ifdef PROC      
       if(Channel_Flag==1)
         Channel_Func(s_re2,s_im2,r_re2,r_im2,r_re02,r_im02,r_re0_d,r_im0_d,r_re0_u,r_im0_u,eNB2UE,UE2eNB,enb_data,ue_data,abstraction_flag,frame_parms,slot);
@@ -647,8 +646,8 @@ int
              eNB_id++) {
           //printf ("debug: Nid_cell %d\n", PHY_vars_eNB_g[eNB_id]->lte_frame_parms.Nid_cell);
           //printf ("debug: frame_type %d,tdd_config %d\n", PHY_vars_eNB_g[eNB_id]->lte_frame_parms.frame_type,PHY_vars_eNB_g[eNB_id]->lte_frame_parms.tdd_config);
-          LOG_D(EMU,"PHY procedures eNB %d mode %s for frame %d, slot %d (subframe TX %d, RX %d) TDD %d/%d Nid_cell %d\n",
-                eNB_id, (r_mode == 0)?"Normal":"Relaying", frame, slot, next_slot >> 1,last_slot>>1,
+          LOG_D(EMU,"PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d) TDD %d/%d Nid_cell %d\n",
+                eNB_id, frame, slot, next_slot >> 1,last_slot>>1,
                 PHY_vars_eNB_g[eNB_id]->lte_frame_parms.frame_type,
                 PHY_vars_eNB_g[eNB_id]->lte_frame_parms.tdd_config,PHY_vars_eNB_g[eNB_id]->lte_frame_parms.Nid_cell);
 
@@ -659,7 +658,7 @@ int
           pdcp_run(frame, 1, 0, eNB_id);//PHY_vars_eNB_g[eNB_id]->Mod_id
 	  
 	  // PHY_vars_eNB_g[eNB_id]->frame = frame;
-          phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, r_mode);
+          phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, no_relay);
 
 #ifdef PRINT_STATS
       	if(last_slot==9 && frame%10==0)
@@ -692,8 +691,8 @@ int
              UE_id++){
           if (frame >= (UE_id * 20)) {    // activate UE only after 20*UE_id frames so that different UEs turn on separately
 	    
-	    LOG_D(EMU,"PHY procedures UE %d mode %s for frame %d, slot %d (subframe TX %d, RX %d)\n",
-		  UE_id, (r_mode == 0)?"Normal":"Relaying", frame, slot, next_slot >> 1,last_slot>>1);
+	    LOG_D(EMU,"PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
+		  UE_id, frame, slot, next_slot >> 1,last_slot>>1);
 
 	    if (PHY_vars_UE_g[UE_id]->UE_mode[0] != NOT_SYNCHED) {
 	      if (frame>0) {
@@ -705,7 +704,7 @@ int
 		//Access layer
 		pdcp_run(frame, 0, UE_id, 0);
 		
-		phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, r_mode);
+		phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, no_relay);
 		ue_data[UE_id]->tx_power_dBm = PHY_vars_UE_g[UE_id]->tx_power_dBm;
 	      }
 	    }
@@ -754,34 +753,33 @@ int
 	  eNB_id= oai_emulation.info.first_enb_local+oai_emulation.info.nb_enb_local + RN_id; // NB_eNB_INST + RN_id
 	  // currently only works in FDD
 	  if (oai_emulation.info.eMBMS_active_state == 4){
-	    r_mode = multicast_relay;
-	    LOG_I(EMU,"Activating the multicast relaying\n");
+	    r_type = multicast_relay;
+	    //LOG_I(EMU,"Activating the multicast relaying\n");
 	  }else {
-	    LOG_E(EMU,"Not supported option when relaying is enabled %d\n", r_mode);
+	    LOG_E(EMU,"Not supported eMBMS option when relaying is enabled %d\n", r_type);
 	    exit(-1);
 	  }
 	  if ( oai_emulation.info.frame_type  == 0) {
-	    // RN == UE, do RX as in UE for SF0-SF5
-	    // we could add another arg, such as operation, to call the top func  phy_procedures_UE_lte
+	    // RN == UE
 	    if (frame>0) {
 	      if (PHY_vars_UE_g[UE_id]->UE_mode[0] != NOT_SYNCHED) {
-		LOG_D(EMU,"PHY procedures UE %d mode %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
-		      UE_id, (r_mode == 0)?"Normal":"Relaying", frame, slot, next_slot >> 1,last_slot>>1);
+		LOG_D(EMU,"[RN %d] PHY procedures UE %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
+		      RN_id, UE_id, frame, slot, next_slot >> 1,last_slot>>1);
 		PHY_vars_UE_g[UE_id]->frame = frame;
-		phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, r_mode);
+		phy_procedures_UE_lte (last_slot, next_slot, PHY_vars_UE_g[UE_id], 0, abstraction_flag,normal_txrx, r_type);
 	      } else if (last_slot == (LTE_SLOTS_PER_FRAME-2)) {
 		initial_sync(PHY_vars_UE_g[UE_id],normal_txrx);
 	      }
 	    }
 	    
-	    // RN == eNB, do Tx as in eNB  for SF6-SF9
-	    LOG_D(EMU,"PHY procedures eNB %d mode %s for frame %d, slot %d (subframe TX %d, RX %d)\n",
-		  eNB_id, (r_mode == 0)?"Normal":"Relaying", frame, slot, next_slot >> 1,last_slot>>1);
-	    phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, r_mode);
+	    // RN == eNB
+	    LOG_D(EMU,"[RN %d] PHY procedures eNB %d for frame %d, slot %d (subframe TX %d, RX %d)\n",
+	    	  RN_id, eNB_id, frame, slot, next_slot >> 1,last_slot>>1);
+	    phy_procedures_eNB_lte (last_slot, next_slot, PHY_vars_eNB_g[eNB_id], abstraction_flag, r_type);
 
 	  }
 	  else{
-	    LOG_E(EMU,"TDD is not supported for multicast relaying %d\n", r_mode);
+	    LOG_E(EMU,"TDD is not supported for multicast relaying %d\n", r_type);
 	    exit(-1);
 	  }
 	}
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index 63f6091b55..5b11575a01 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -141,7 +141,7 @@ void get_simulation_options(int argc, char *argv[]) {
       break;
     case 'Q':
       //eMBMS_active=1;
-      // 0 : not used (default), 1: eMBMS and RRC enabled, 2: eMBMS relaying and RRC enabled, 3: eMBMS enabled, RRC disabled, 3: eMBMS relaying enabled, RRC disabled 
+      // 0 : not used (default), 1: eMBMS and RRC enabled, 2: eMBMS relaying and RRC enabled, 3: eMBMS enabled, RRC disabled, 4: eMBMS relaying enabled, RRC disabled 
       oai_emulation.info.eMBMS_active_state = atoi (optarg); 
       break;
     case 'R':
diff --git a/targets/TEST/OAI/README b/targets/TEST/OAI/README
index 77506d792e..c3362b2510 100644
--- a/targets/TEST/OAI/README
+++ b/targets/TEST/OAI/README
@@ -10,15 +10,26 @@ Obj.#	Case#	Test#	Description
 01	01	04	Build dlsim  Rel8 	
 01	01	05	Build ulsim  Rel8 	
 01	01	06	Build oaisim Rel10
+01      01      07      Build oaisim Rel8 with cellular RRC for eNB
+01      01      08      Build oaisim Rel8 with cellular RRC for UE
 
-01	02		Run OAI, and check the operation
+01	02		Run OAI Rel8, and check the operation
 01	02	00	Run OAI Rel8, and search for segmentation fault or exit
 01	02	01	Run OAI Rel8, and search for execution errors
 01	02	02	Run OAI Rel8 in abstraction mode and check that RRC proc is finished completely for the configured number of eNB and UE
 01	02	03	Run OAI Rel8 in abstraction mode, send ping from from one eNB to each UE, and check that there is no packet losses
 01	02	04	Run OAI Rel8 with full PHY, and check that the RRC proc for eNBsxUEs
-01 	02	05	Run OAI Rel10 in abstraction mode, and check the RRC proc for eNBsxUEs	
-01	02	05	Run OAI Rel10 in full phy mode, and check the RRC proc for eNBsxUEs
+01	02	05	Run OAI Rel8 with full PHY in FDD mode, and check that the RRC proc for eNBsxUEs
+
+01	03		Run OAI Rel10, and check the operation
+01	03	00	Run OAI Rel10, and search for segmentation fault or exit
+01	03	01	Run OAI Rel10, and search for execution errors
+01 	03	02	Run OAI Rel10 in abstraction mode, and check the RRC proc for eNBsxUEs	
+01	03	03	Run OAI Rel10 in full phy mode, and check the RRC proc for eNBsxUEs
+01	03	04	Run OAI Rel10 in full phy mode in FDD mode, and check the RRC proc for eNBsxUEs
+01      03      05      Run OAI Rel10 with eMBMS enabled, and check the SIB13 and MCCH
+01      03      06      Run OAI Rel10 with eMBMS enabled, and check the MTCH
+01      03      07      Run OAI Rel10 with eMBMS enabled and FDD mode, and check the MTCH
 
 02			Functional test case
 
diff --git a/targets/TEST/OAI/case01.py b/targets/TEST/OAI/case01.py
index 3152cc640f..bd8e2c74f5 100644
--- a/targets/TEST/OAI/case01.py
+++ b/targets/TEST/OAI/case01.py
@@ -172,9 +172,9 @@ def execute(oai, user, pw, logfile):
 
     try:
         test = '07'
-        name = 'Compile oai.rel8.cellular.rg.make'
+        name = 'Compile oai.rel8.cellular.eNB.make'
         conf = 'make rrc_cellular=1 eNB_flag=1'
-        diag = 'check the compilation errors for RRC Cellular (node RG)'
+        diag = 'check the compilation errors for eNB/RG RRC Cellular'
         oai.send('make clean;')
         oai.send('make cleanall;')
         oai.send('make cleanasn1;')
@@ -188,9 +188,9 @@ def execute(oai, user, pw, logfile):
 
     try:
         test = '08'
-        name = 'Compile oai.rel8.cellular.mt.make'
+        name = 'Compile oai.rel8.cellular.UE.make'
         conf = 'make rrc_cellular=1 UE_flag=1'
-        diag = 'check the compilation errors for RRC Cellular (node MT)'
+        diag = 'check the compilation errors for UE/MT RRC Cellular'
         oai.send('make clean;')
         oai.send('make cleanall;')
         oai.send('make cleanasn1;')
diff --git a/targets/TEST/OAI/case02.py b/targets/TEST/OAI/case02.py
index bf04744f0b..b0bf4a3f25 100644
--- a/targets/TEST/OAI/case02.py
+++ b/targets/TEST/OAI/case02.py
@@ -130,26 +130,15 @@ def execute(oai, user, pw, logfile):
 
     try:
         test = '05'
-        name = 'Run oai.rel10.abs.rrc'
-        diag = 'RRC procedure is not finished completely, check the execution logs and trace BCCH, CCCH, and DCCH channels'
+        name = 'Run oai.rel8.phy.rrc.fdd'
+        diag = 'RRC procedure is not finished completely in FDD mode, check the execution logs and trace BCCH, CCCH, and DCCH channels'
         for i in range(NUM_UE) :
             for j in range(NUM_eNB) :
-                conf = '-a -A AWGN -n' + str((i+1+j) * 50) + ' -u' + str(i+1) +' -b'+ str(j+1)
-                oai.send_expect('./oaisim.rel10 ' + conf, ' Received RRCConnectionReconfigurationComplete from UE ' + str(i),  (i+1) * 100)
+                conf = '-A AWGN -F -n' + str((i+1+j) * 50) + ' -u' + str(i+1) +' -b'+ str(j+1) + ' -s15 -x1'
+                oai.send_expect('./oaisim.rel8 ' + conf, ' Received RRCConnectionReconfigurationComplete from UE ' + str(i),  (i+1) * 100)
     except log.err, e:
         log.fail(case, test, name, conf, e.value, diag, logfile)
     else:
-        log.ok(case, test, name, conf, '', logfile)    
+        log.ok(case, test, name, conf, '', logfile)
+
 
-    try:
-        test = '06'
-        name = 'Run oai.rel10.phy.rrc'
-        diag = 'RRC procedure is not finished completely, check the execution logs and trace BCCH, CCCH, and DCCH channels'
-        for i in range(NUM_UE) :
-            for j in range(NUM_eNB) :
-                conf = '-A AWGN -s 15 -x 1 -n' + str((i+1+j) * 50) + ' -u' + str(i+1) +' -b'+ str(j+1)
-                oai.send_expect('./oaisim.rel10 ' + conf, ' Received RRCConnectionReconfigurationComplete from UE ' + str(i),  (i+1) * 100)
-    except log.err, e:
-        log.fail(case, test, name, conf, e.value, diag, logfile)
-    else:
-        log.ok(case, test, name, conf, '', logfile)    
diff --git a/targets/TEST/OAI/case03.py b/targets/TEST/OAI/case03.py
new file mode 100644
index 0000000000..4dbc719ea4
--- /dev/null
+++ b/targets/TEST/OAI/case03.py
@@ -0,0 +1,156 @@
+#******************************************************************************
+
+#  Eurecom OpenAirInterface
+#  Copyright(c) 1999 - 2013 Eurecom
+
+#  This program is free software; you can redistribute it and/or modify it
+#  under the terms and conditions of the GNU General Public License,
+#  version 2, as published by the Free Software Foundation.
+
+#  This program is distributed in the hope it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+#  more details.
+
+#  You should have received a copy of the GNU General Public License along with
+#  this program; if not, write to the Free Software Foundation, Inc.,
+#  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+#  The full GNU General Public License is included in this distribution in
+#  the file called "COPYING".
+
+#  Contact Information
+#  Openair Admin: openair_admin@eurecom.fr
+#  Openair Tech : openair_tech@eurecom.fr
+#  Forums       : http://forums.eurecom.fsr/openairinterface
+#  Address      : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France
+
+#*****************************************************************************
+
+# \file case03.py
+# \brief test case 03 for OAI: executions
+# \author Navid Nikaein
+# \date 2013
+# \version 0.1
+# @ingroup _test
+
+import time
+import random
+import log
+import openair 
+import core
+
+NUM_UE=2
+NUM_eNB=1
+NUM_TRIALS=3
+
+def execute(oai, user, pw, logfile):
+    
+    case = '03'
+    oai.send('cd $OPENAIR_TARGETS;')
+    oai.send('cd SIMU/USER;')
+    
+    try:
+        test = '00'
+        name = 'Run oai.rel10.sf'
+        conf = '-a -A AWGN -n 100'
+        diag = 'OAI is not running normally (Segmentation fault / Exiting / FATAL), debugging might be needed'
+        oai.send_expect_false('./oaisim.rel10 ' + conf, 'Segmentation fault', 30)
+        oai.send_expect_false('./oaisim.rel10 ' + conf, 'Exiting', 30)
+        oai.send_expect_false('./oaisim.rel10 ' + conf, 'FATAL', 30)
+
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, '', logfile)
+
+    try:
+        test = '01'
+        name = 'Run oai.rel10.err'
+        conf = '-a -A AWGN -n 100'
+        diag = 'Error(s) found in the execution, check the execution logs'
+        oai.send_expect_false('./oaisim.rel10 ' + conf, '[E]', 30)
+        
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, '', logfile)
+        
+    try:
+        test = '02'
+        name = 'Run oai.rel10.abs.rrc'
+        diag = 'RRC procedure is not finished completely, check the execution logs and trace BCCH, CCCH, and DCCH channels'
+        for i in range(NUM_UE) :
+            for j in range(NUM_eNB) :
+                conf = '-a -A AWGN -n' + str((i+1+j) * 50) + ' -u' + str(i+1) +' -b'+ str(j+1)
+                oai.send_expect('./oaisim.rel10 ' + conf, ' Received RRCConnectionReconfigurationComplete from UE ' + str(i),  (i+1) * 100)
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, '', logfile)    
+
+    try:
+        test = '03'
+        name = 'Run oai.rel10.phy.rrc'
+        diag = 'RRC procedure is not finished completely, check the execution logs and trace BCCH, CCCH, and DCCH channels'
+        for i in range(NUM_UE) :
+            for j in range(NUM_eNB) :
+                conf = '-A AWGN -s 15 -x 1 -n' + str((i+1+j) * 50) + ' -u' + str(i+1) +' -b'+ str(j+1)
+                oai.send_expect('./oaisim.rel10 ' + conf, ' Received RRCConnectionReconfigurationComplete from UE ' + str(i),  (i+1) * 100)
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, '', logfile)  
+
+    try:
+        test = '04'
+        name = 'Run oai.rel10.phy.rrc.fdd'
+        diag = 'RRC procedure is not finished completely in FDD mode, check the execution logs and trace BCCH, CCCH, and DCCH channels'
+        for i in range(NUM_UE) :
+            for j in range(NUM_eNB) :
+                conf = '-A AWGN -F -s 15 -x 1 -n' + str((i+1+j) * 50) + ' -u' + str(i+1) +' -b'+ str(j+1)
+                oai.send_expect('./oaisim.rel10 ' + conf, ' Received RRCConnectionReconfigurationComplete from UE ' + str(i),  (i+1) * 100)
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, '', logfile)  
+
+    try:
+        test = '05'
+        name = 'Run oai.rel10.phy.eMBMS.MCCH'
+        diag = 'eMBMS procedure is not finished completely, make sure that the SIB13/MCCH have been correclty received by UEs'
+        for i in range(NUM_UE) :
+            for j in range(NUM_eNB) :
+                conf = '-A AWGN -s 15 -x 1 -Q3 -n' + str((i+1+j) * 50) + ' -u' + str(i+1) +' -b'+ str(j+1)
+                oai.send_expect('./oaisim.rel10 ' + conf, ' Found MBSFNAreaConfiguration from eNB ' + str(j),  (i+1) * 100)
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, '', logfile)  
+        
+    try:
+        test = '06'
+        name = 'Run oai.rel10.phy.eMBMS.OTG'
+        diag = 'eMBMS multicast/broadcast data is not received, make sure that the SIB13/MCCH/MTCH have been correclty received by UEs'
+        for i in range(NUM_UE) :
+            for j in range(NUM_eNB) :
+                conf = '-A AWGN -s 15 -x 1 -T mscbr -Q3 -n' + str((i+1+j) * 100) + ' -u' + str(i+1) +' -b'+ str(j+1)
+                oai.send_expect('./oaisim.rel10 ' + conf, ' Received a multicast packet',  (i+1) * 100)
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, 'Note: check the packet loss from the OTG stats', logfile)   
+
+    try:
+        test = '07'
+        name = 'Run oai.rel10.phy.eMBMS.OTG.fdd'
+        diag = 'eMBMS multicast/broadcast data is not received in fdd mode, make sure that the SIB13/MCCH/MTCH have been correclty received by UEs'
+        for i in range(NUM_UE) :
+            for j in range(NUM_eNB) :
+                conf = '-A AWGN -F -s 15 -x 1 -T mscbr -Q3 -n' + str((i+1+j) * 100) + ' -u' + str(i+1) +' -b'+ str(j+1)
+                oai.send_expect('./oaisim.rel10 ' + conf, ' Received a multicast packet',  (i+1) * 100)
+    except log.err, e:
+        log.fail(case, test, name, conf, e.value, diag, logfile)
+    else:
+        log.ok(case, test, name, conf, 'Note: check the packet loss from the OTG stats', logfile)   
+
diff --git a/targets/TEST/OAI/log.py b/targets/TEST/OAI/log.py
index e5756b7728..20b01fd2fa 100644
--- a/targets/TEST/OAI/log.py
+++ b/targets/TEST/OAI/log.py
@@ -144,7 +144,7 @@ def ok(case, testnum, testname, conf, message, output):
     report(case, testnum, testname, conf, 'passed', output)
     log_record('passed', case + testnum + ' : ' + testname + ' ('+ conf+')')
     if message :
-        log_record('passed', "Output follows:\n" + message )
+        print bcolors.okgreen + message + bcolors.normal 
     stats['passed'] += 1
     
         
diff --git a/targets/TEST/OAI/test01.py b/targets/TEST/OAI/test01.py
index 52bd38bb0d..841e3133b9 100644
--- a/targets/TEST/OAI/test01.py
+++ b/targets/TEST/OAI/test01.py
@@ -41,10 +41,13 @@ import os
 import time
 import datetime
 import getpass
+import math #from time import clock 
 
 import log
 import case01
 import case02
+import case03
+
 from  openair import *
 
 debug = 0
@@ -70,11 +73,11 @@ for arg in sys.argv:
 
 # get the oai object
 oai = openair('localdomain','localhost')
-
+#start_time = time.time()  # datetime.datetime.now()
 try: 
     user = getpass.getuser()
-    print '\n*******Note that the user <'+user+'> should be a sudoer *******\n'
-    print '*******Connecting to the localhost to perform the test *******\n'
+    print '\n******* Note that the user <'+user+'> should be a sudoer *******\n'
+    print '******* Connecting to the localhost to perform the test *******\n'
    
     if not pw :
         print "username: " + user 
@@ -95,14 +98,15 @@ test = 'test01'
 ctime=datetime.datetime.utcnow().strftime("%Y-%m-%d.%Hh%M")
 logfile = user+'.'+test+'.'+ctime+'.txt'  
 #print '=================start the ' + test + ' at ' + ctime + '=================\n'
-print 'Results will be reported in log file : ' + logfile
+#print 'Results will be reported in log file : ' + logfile
 log.writefile(logfile,'====================start'+test+' at ' + ctime + '=======================\n')
 log.set_debug_level(debug)
 
 oai.kill(user, pw)   
 # start te test cases 
-case01.execute(oai, user, pw, logfile)
-case02.execute(oai, user, pw, logfile)
+#case01.execute(oai, user, pw, logfile)
+#case02.execute(oai, user, pw, logfile)
+#case03.execute(oai, user, pw, logfile)
 
 oai.kill(user, pw) 
 
@@ -115,4 +119,6 @@ oai.disconnect()
 ctime=datetime.datetime.utcnow().strftime("%Y-%m-%d_%Hh%M")
 log.writefile(logfile,'====================end the '+ test + ' at ' + ctime +'====================')
 print 'Test results can be found in : ' + logfile 
+#print '\nThis test took %f minutes\n' % math.ceil((time.time() - start_time)/60) 
+
 #print '\n=====================end the '+ test + ' at ' + ctime + '====================='
-- 
GitLab