diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index a39cf35f6a8bdbf1fcae472ed430c418b0e1c0c2..56ff74b8d3e85cd60838a1b4baa4ac21f72ef1c1 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1736,6 +1736,9 @@ add_executable(oaisim
   ${s1ap_h}
   ${x2ap_h}
   ${OPENAIR_BIN_DIR}/messages_xml.h
+  ${OPENAIR_TARGETS}/RT/USER/lte-ue.c
+  ${OPENAIR_TARGETS}/RT/USER/lte-enb.c
+  ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
   ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
   ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
   ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c
@@ -1779,6 +1782,9 @@ add_executable(oaisim_nos1
   ${s1ap_h}
   ${x2ap_h}
   ${OPENAIR_BIN_DIR}/messages_xml.h
+  ${OPENAIR_TARGETS}/RT/USER/lte-ue.c
+  ${OPENAIR_TARGETS}/RT/USER/lte-enb.c
+  ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
   ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
   ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
   ${OPENAIR_TARGETS}/SIMU/USER/oaisim_config.c
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 4c46674ecb1be7a2f522a51f5a2fd600beb1dcd0..e4386c8fdfe479d8044b1b0dd31ea2bbc5eb826d 100755
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -171,6 +171,7 @@ typedef enum {
 } eNB_timing_t;
 
 
+
 typedef struct UE_SCAN_INFO_s {
   /// 10 best amplitudes (linear) for each pss signals
   int32_t amp[3][10];
@@ -310,10 +311,16 @@ typedef struct {
   uint8_t              CC_id;
   /// Last RX timestamp
   openair0_timestamp timestamp_rx;
+  /// pthread attributes for main UE thread
+  pthread_attr_t attr_ue;
+  /// scheduling parameters for main UE thread
+  struct sched_param sched_param_ue;
+  /// pthread descriptor main UE thread
+  pthread_t pthread_ue;
   /// \brief Instance count for synch thread.
   /// \internal This variable is protected by \ref mutex_synch.
   int instance_cnt_synch;
-  /// pthread attributes for prach processing thread
+  /// pthread attributes for synch processing thread
   pthread_attr_t attr_synch;
   /// scheduling parameters for synch thread
   struct sched_param sched_param_synch;
@@ -770,6 +777,9 @@ typedef struct {
   time_stats_t dlsch_tc_intl2_stats;
   time_stats_t tx_prach;
 
+  /// RF and Interface devices per CC
+  openair0_device rfdevice; 
+
 #if ENABLE_RAL
   hash_table_t    *ral_thresholds_timed;
   SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
diff --git a/openair1/PHY/extern.h b/openair1/PHY/extern.h
index 4c9e2706c78a6055a72546c6c7d102bf87399b98..2144c4f01d93b80225c1760f4b1020135964e7bc 100755
--- a/openair1/PHY/extern.h
+++ b/openair1/PHY/extern.h
@@ -111,6 +111,9 @@ extern double p_qam64[8];
 extern double beta1_dlsch[6][MCS_COUNT];
 extern double beta2_dlsch[6][MCS_COUNT];
 
+extern char eNB_functions[5][20];
+extern char eNB_timing[2][20];
+
 
 #endif /*__PHY_EXTERN_H__ */
 
diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h
index 3d940d4a94a2b58b52af104f884783f3fa0beacd..85bfe7a2a65b41b88e6da9c0af695f4106da2667 100755
--- a/openair1/PHY/vars.h
+++ b/openair1/PHY/vars.h
@@ -139,6 +139,9 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682
 
 */
 
+char eNB_functions[5][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RRU_IF5","NGFI_RRU_IF4","NGFI_RCC_IF4"};
+char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
+
 
 
 #endif /*__PHY_VARS_H__ */
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index ecaeb20fa8d36bd75876a59538b29c7760881852..43edfa807d4a6505643e4d83066b2ed8f2c524d0 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -3236,99 +3236,3 @@ int phy_procedures_RN_eNB_TX(unsigned char last_slot, unsigned char next_slot, r
   return do_proc;
 }
 #endif
-/*
-void phy_procedures_eNB_lte(unsigned char subframe,PHY_VARS_eNB **eNB,uint8_t abstraction_flag,
-                            relaying_type_t r_type, PHY_VARS_RN *rn)
-{
-#if defined(ENABLE_ITTI)
-  MessageDef   *msg_p;
-  const char   *msg_name;
-  instance_t    instance;
-  unsigned int  Mod_id;
-  int           result;
-#endif
-
-
-  int CC_id=0;
-
-
-  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB, eNB[0]->proc[subframe].frame_tx);
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,1);
-  start_meas(&eNB[0]->phy_proc);
-
-#if defined(ENABLE_ITTI)
-
-  do {
-    // Checks if a message has been sent to PHY sub-task
-    itti_poll_msg (TASK_PHY_ENB, &msg_p);
-
-    if (msg_p != NULL) {
-      msg_name = ITTI_MSG_NAME (msg_p);
-      instance = ITTI_MSG_INSTANCE (msg_p);
-      Mod_id = instance;
-
-      switch (ITTI_MSG_ID(msg_p)) {
-
-        // Messages from eNB app
-      case PHY_CONFIGURATION_REQ:
-        LOG_I(PHY, "[eNB %d] Received %s\n", instance, msg_name);
-        // TODO
-
-        break;
-
-      default:
-        LOG_E(PHY, "[ENB %d] Received unexpected message %s\n", Mod_id, msg_name);
-        break;
-      }
-
-      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
-      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
-    }
-  } while(msg_p != NULL);
-
-#endif
-
-
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    if ((((eNB[CC_id]->frame_parms.frame_type == TDD)&&
-          (subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_tx)==SF_DL))||
-         (eNB[CC_id]->frame_parms.frame_type == FDD))) {
-#ifdef Rel10
-
-      if (phy_procedures_RN_eNB_TX(eNB[CC_id]->proc[0].subframe_rx, eNB[CC_id]->proc[0].subframe_tx, r_type) != 0 )
-#endif
-        phy_procedures_eNB_TX(subframe,eNB[CC_id],abstraction_flag,r_type,rn);
-    }
-
-    if ((((eNB[CC_id]->frame_parms.frame_type == TDD )&&
-          (subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_rx)==SF_UL)) ||
-         (eNB[CC_id]->frame_parms.frame_type == FDD))) {
-      phy_procedures_eNB_RX(subframe,eNB[CC_id],abstraction_flag,r_type);
-    }
-
-    if (subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_tx)==SF_S) {
-#ifdef Rel10
-
-      if (phy_procedures_RN_eNB_TX(subframe, subframe, r_type) != 0 )
-#endif
-        phy_procedures_eNB_TX(subframe,eNB[CC_id],abstraction_flag,r_type,rn);
-    }
-
-    if ((subframe_select(&eNB[CC_id]->frame_parms,eNB[CC_id]->proc[0].subframe_rx)==SF_S)) {
-      phy_procedures_eNB_S_RX(subframe,eNB[CC_id],abstraction_flag,r_type);
-    }
-
-    eNB[CC_id]->proc[0].frame_tx++;
-    eNB[CC_id]->proc[0].frame_rx++;
-
-    if (eNB[CC_id]->proc[0].frame_tx>=MAX_FRAME_NUMBER) // defined in impl_defs_top.h
-      eNB[CC_id]->proc[0].frame_tx-=MAX_FRAME_NUMBER;
-
-    if (eNB[CC_id]->proc[0].frame_rx>=MAX_FRAME_NUMBER)
-      eNB[CC_id]->proc[0].frame_rx-=MAX_FRAME_NUMBER;
-  }
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_LTE,0);
-  stop_meas(&eNB[0]->phy_proc);
-}
-*/
diff --git a/openair2/UTIL/OCG/OCG.h b/openair2/UTIL/OCG/OCG.h
index cf96de7963dab64806482a743426538288d9fbd3..c47cc8e8c7a3dde20ba2a7edc5b960471024b410 100644
--- a/openair2/UTIL/OCG/OCG.h
+++ b/openair2/UTIL/OCG/OCG.h
@@ -707,6 +707,8 @@ typedef struct {
   // phy related params
   unsigned int n_frames;
   unsigned int n_frames_flag; // if set, then let the emulation goes to infinity
+  node_function_t node_function[MAX_NUM_CCs];
+  node_timing_t node_timing[MAX_NUM_CCS];
   unsigned char frame_type[MAX_NUM_CCs]; //! LTE frame type (TDD=1, FDD=0). \note this should be converted to \ref lte_frame_type_t (header file reorganization needed)
   char * frame_type_name[MAX_NUM_CCs];
   unsigned char tdd_config[MAX_NUM_CCs];
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf
index 50cb6747acba76737f576a55e8a36a2aa67a931a..3ec8ea01da7c99e050b0340706a181ad6db6683e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf
@@ -23,6 +23,8 @@ eNBs =
 
     component_carriers = (
       {
+        node_function                                         = "eNodeB_3GPP";
+        node_timing                                           = "SYNCH_TO_OTHER";
         frame_type					      = "FDD";
         tdd_config 					      = 3;
         tdd_config_s            			      = 0;
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 3317d289e06512b53e4b6e15597460c043bcefc1..ba7921e4082d678a05c12140b852eb814d25f1ee 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -157,7 +157,7 @@ static struct {
 
 void exit_fun(const char* s);
 
-void init_eNB(eNB_func_t node_function);
+void init_eNB(eNB_func_t node_function,int nb_inst);
 void stop_eNB(void);
 
 
@@ -350,7 +350,7 @@ static void* eNB_thread_rxtx( void* param ) {
 
   /* Set affinity mask to include CPUs 1 to MAX_CPUS */
   /* CPU 0 is reserved for UHD threads */
-  /* CPU 1 is reserved for all TX threads */
+  /* CPU 1 is reserved for all RX_TX threads */
   /* Enable CPU Affinity only if number of CPUs >2 */
   CPU_ZERO(&cpuset);
 
@@ -398,7 +398,7 @@ static void* eNB_thread_rxtx( void* param ) {
     exit_fun("Error getting thread priority");
   }
 
-  LOG_I(HW, "[SCHED][eNB] TX thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(),
+  LOG_I(HW, "[SCHED][eNB] RXn_TXnp4 thread started on CPU %d TID %ld, sched_policy = %s , priority = %d, CPU Affinity=%s \n",sched_getcpu(),gettid(),
                    (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
                    (policy == SCHED_RR)    ? "SCHED_RR" :
                    (policy == SCHED_OTHER) ? "SCHED_OTHER" :
@@ -644,12 +644,103 @@ static void* eNB_thread_asynch_rx( void* param ) {
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   openair0_timestamp timestamp_rx;
   int frame_rx,subframe_rx;
-  int first_rx = 1;
+  static int first_rx = 1;
   uint16_t packet_type;
   uint32_t symbol_number=0;
   uint32_t symbol_mask, symbol_mask_full;
   int prach_rx;
 
+#ifdef DEADLINE_SCHEDULER
+  struct sched_attr attr;
+  unsigned int flags = 0;
+  uint64_t runtime  = 870000 ;
+  uint64_t deadline = 1   *  1000000;
+  uint64_t period   = 1   * 10000000; // each rx thread has a period of 10ms from the starting point
+ 
+  attr.size = sizeof(attr);
+  attr.sched_flags = 0;
+  attr.sched_nice = 0;
+  attr.sched_priority = 0;
+
+  attr.sched_policy = SCHED_DEADLINE;
+  attr.sched_runtime  = runtime;
+  attr.sched_deadline = deadline;
+  attr.sched_period   = period; 
+
+  if (sched_setattr(0, &attr, flags) < 0 ) {
+    perror("[SCHED] eNB FH sched_setattr failed\n");
+    return &eNB_thread_FH_status;
+  }
+
+  LOG_I( HW, "[SCHED] eNB asynch RX deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() );
+#else // LOW_LATENCY
+  int policy, s, j;
+  struct sched_param sparam;
+  char cpu_affinity[1024];
+  cpu_set_t cpuset;
+
+  /* Set affinity mask to include CPUs 1 to MAX_CPUS */
+  /* CPU 0 is reserved for UHD */
+  /* CPU 1 is reserved for all TX threads */
+  /* CPU 2..MAX_CPUS is reserved for all RX threads */
+  /* Set CPU Affinity only if number of CPUs >2 */
+  CPU_ZERO(&cpuset);
+#ifdef CPU_AFFINITY
+  if (get_nprocs() >2) {
+    for (j = 1; j < get_nprocs(); j++)
+      CPU_SET(j, &cpuset);
+  
+    s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
+    if (s != 0) {
+      perror( "pthread_setaffinity_np");  
+      exit_fun (" Error setting processor affinity :");
+    }
+  }
+#endif //CPU_AFFINITY
+  /* Check the actual affinity mask assigned to the thread */
+
+  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
+  if (s != 0) {
+    perror ("pthread_getaffinity_np");
+    exit_fun (" Error getting processor affinity :");
+  }
+  memset(cpu_affinity,0, sizeof(cpu_affinity));
+
+  for (j = 0; j < CPU_SETSIZE; j++)
+    if (CPU_ISSET(j, &cpuset)) {  
+      char temp[1024];
+      sprintf (temp, " CPU_%d", j);
+      strcat(cpu_affinity, temp);
+    }
+
+  memset(&sparam, 0 , sizeof (sparam)); 
+  sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
+
+  policy = SCHED_FIFO ; 
+  s = pthread_setschedparam(pthread_self(), policy, &sparam);
+  if (s != 0) {
+    perror("pthread_setschedparam : ");
+    exit_fun("Error setting thread priority");     
+  }
+
+  memset(&sparam, 0 , sizeof (sparam));
+
+  s = pthread_getschedparam(pthread_self(), &policy, &sparam);
+  if (s != 0) {
+    perror("pthread_getschedparam");
+    exit_fun("Error getting thread priority");
+  }
+
+  LOG_I(HW, "[SCHED][eNB] eNB asynch RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(),
+	 (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
+	 (policy == SCHED_RR)    ? "SCHED_RR" :
+	 (policy == SCHED_OTHER) ? "SCHED_OTHER" :
+	 "???",
+	 sparam.sched_priority, cpu_affinity);
+  
+  
+#endif // DEADLINE_SCHEDULER
+
   if (eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF
       /// **** recv_IF5 of rxdata from RRH **** ///       
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF5, 1 );  
@@ -772,11 +863,11 @@ static void* eNB_thread_FH( void* param ) {
   attr.sched_period   = period; 
 
   if (sched_setattr(0, &attr, flags) < 0 ) {
-    perror("[SCHED] eNB RX sched_setattr failed\n");
+    perror("[SCHED] eNB FH sched_setattr failed\n");
     return &eNB_thread_FH_status;
   }
 
-  LOG_I( HW, "[SCHED] eNB RX deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() );
+  LOG_I( HW, "[SCHED] eNB FH deadline thread (TID %ld) started on CPU %d\n", gettid(), sched_getcpu() );
 #else // LOW_LATENCY
   int policy, s, j;
   struct sched_param sparam;
@@ -835,7 +926,7 @@ static void* eNB_thread_FH( void* param ) {
     exit_fun("Error getting thread priority");
   }
 
-  LOG_I(HW, "[SCHED][eNB] RX thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(),
+  LOG_I(HW, "[SCHED][eNB] FH thread started on CPU %d TID %ld, sched_policy = %s, priority = %d, CPU Affinity = %s\n", sched_getcpu(),gettid(),
 	 (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
 	 (policy == SCHED_RR)    ? "SCHED_RR" :
 	 (policy == SCHED_OTHER) ? "SCHED_OTHER" :
@@ -848,8 +939,8 @@ static void* eNB_thread_FH( void* param ) {
 
   mlockall(MCL_CURRENT | MCL_FUTURE);
 
-  // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe of TX and RX threads
-  printf( "waiting for sync (eNB_thread_rx_common)\n");
+  // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
+  printf( "waiting for sync (eNB_thread_FH)\n");
   pthread_mutex_lock( &sync_mutex );
 
   while (sync_var<0)
@@ -1080,8 +1171,8 @@ static void* eNB_thread_FH( void* param ) {
 	  break;
 	}
       } else {
-	LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_rxtx %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave);
-	exit_fun( "TX thread busy" );
+	LOG_W( PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_FH %i)\n",slave_proc->frame_rx,slave_proc->CC_id, cnt_slave);
+	exit_fun( "FH thread busy" );
 	break;
       }             
     }
@@ -1324,91 +1415,94 @@ static void* eNB_thread_prach( void* param ) {
 }
 
 
-void init_eNB_proc(void) {
+void init_eNB_proc(int nb_inst) {
   
   int i;
   int CC_id;
   PHY_VARS_eNB *eNB;
   eNB_proc_t *proc;
   eNB_rxtx_proc_t *proc_rxtx;
-
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    eNB = PHY_vars_eNB_g[0][CC_id];
-
-    proc = &eNB->proc;
-    proc_rxtx = proc->proc_rxtx;
+  int inst;
+
+  for (inst = 0; inst < nb_inst; inst++) {
+    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+      eNB = PHY_vars_eNB_g[inst][CC_id];
+      LOG_I(PHY,"Initializing eNB %d CC_id %d (%s,%s),\n",inst,CC_id,eNB_functions[eNB->node_function],eNB_timing[eNB->node_timing]);
+      proc = &eNB->proc;
+      proc_rxtx = proc->proc_rxtx;
 #ifndef DEADLINE_SCHEDULER 
-    /*  
-	pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] );
-	if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], 64 *PTHREAD_STACK_MIN ) != 0)
-        perror("[ENB_PROC_TX] setting thread stack size failed\n");
-	
-	pthread_attr_init( &attr_eNB_proc_rx[CC_id][i] );
-	if (pthread_attr_setstacksize( &attr_eNB_proc_rx[CC_id][i], 64 * PTHREAD_STACK_MIN ) != 0)
-        perror("[ENB_PROC_RX] setting thread stack size failed\n");
-    */
-    // set the kernel scheduling policy and priority
-    proc_rxtx[0].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
-    pthread_attr_setschedparam  (&proc_rxtx[0].attr_rxtx, &proc_rxtx[0].sched_param_rxtx);
-    pthread_attr_setschedpolicy (&proc_rxtx[0].attr_rxtx, SCHED_FIFO);
-    proc_rxtx[1].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
-    pthread_attr_setschedparam  (&proc_rxtx[1].attr_rxtx, &proc_rxtx[1].sched_param_rxtx);
-    pthread_attr_setschedpolicy (&proc_rxtx[1].attr_rxtx, SCHED_FIFO);
-    
-    proc->sched_param_FH.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
-    pthread_attr_setschedparam  (&proc->attr_FH, &proc->sched_param_FH);
-    pthread_attr_setschedpolicy (&proc->attr_FH, SCHED_FIFO);
-    
-    proc->sched_param_prach.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
-    pthread_attr_setschedparam  (&proc->attr_prach, &proc->sched_param_prach);
-    pthread_attr_setschedpolicy (&proc->attr_prach, SCHED_FIFO);
-    
-    printf("Setting OS scheduler to SCHED_FIFO for eNB [cc%d][thread%d] \n",CC_id, i);
+      /*  
+	  pthread_attr_init( &attr_eNB_proc_tx[CC_id][i] );
+	  if (pthread_attr_setstacksize( &attr_eNB_proc_tx[CC_id][i], 64 *PTHREAD_STACK_MIN ) != 0)
+	  perror("[ENB_PROC_TX] setting thread stack size failed\n");
+	  
+	  pthread_attr_init( &attr_eNB_proc_rx[CC_id][i] );
+	  if (pthread_attr_setstacksize( &attr_eNB_proc_rx[CC_id][i], 64 * PTHREAD_STACK_MIN ) != 0)
+	  perror("[ENB_PROC_RX] setting thread stack size failed\n");
+      */
+      // set the kernel scheduling policy and priority
+      proc_rxtx[0].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
+      pthread_attr_setschedparam  (&proc_rxtx[0].attr_rxtx, &proc_rxtx[0].sched_param_rxtx);
+      pthread_attr_setschedpolicy (&proc_rxtx[0].attr_rxtx, SCHED_FIFO);
+      proc_rxtx[1].sched_param_rxtx.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
+      pthread_attr_setschedparam  (&proc_rxtx[1].attr_rxtx, &proc_rxtx[1].sched_param_rxtx);
+      pthread_attr_setschedpolicy (&proc_rxtx[1].attr_rxtx, SCHED_FIFO);
+      
+      proc->sched_param_FH.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
+      pthread_attr_setschedparam  (&proc->attr_FH, &proc->sched_param_FH);
+      pthread_attr_setschedpolicy (&proc->attr_FH, SCHED_FIFO);
+      
+      proc->sched_param_prach.sched_priority = sched_get_priority_max(SCHED_FIFO)-1; //OPENAIR_THREAD_PRIORITY;
+      pthread_attr_setschedparam  (&proc->attr_prach, &proc->sched_param_prach);
+      pthread_attr_setschedpolicy (&proc->attr_prach, SCHED_FIFO);
+      
+      printf("Setting OS scheduler to SCHED_FIFO for eNB [cc%d][thread%d] \n",CC_id, i);
 #endif
-    proc_rxtx[0].instance_cnt_rxtx = -1;
-    proc_rxtx[1].instance_cnt_rxtx = -1;
-    proc->instance_cnt_prach = -1;
-    proc->instance_cnt_FH = -1;
-    proc->CC_id = CC_id;
-
-    proc->first_rx=4;
-
-    pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
-    pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
-    pthread_mutex_init( &proc->mutex_prach, NULL);
-    pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
-    pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
-    pthread_cond_init( &proc->cond_prach, NULL);
-    pthread_cond_init( &proc->cond_FH, NULL);
+      proc_rxtx[0].instance_cnt_rxtx = -1;
+      proc_rxtx[1].instance_cnt_rxtx = -1;
+      proc->instance_cnt_prach = -1;
+      proc->instance_cnt_FH = -1;
+      proc->CC_id = CC_id;
+      
+      proc->first_rx=4;
+      
+      pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL);
+      pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL);
+      pthread_mutex_init( &proc->mutex_prach, NULL);
+      pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL);
+      pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL);
+      pthread_cond_init( &proc->cond_prach, NULL);
+      pthread_cond_init( &proc->cond_FH, NULL);
 #ifndef DEADLINE_SCHEDULER
-    pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] );
-    pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] );
-    pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc );
-    pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc );
-    if (eNB->node_timing == synch_to_other) 
-      pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc );
+      pthread_create( &proc_rxtx[0].pthread_rxtx, &proc_rxtx[0].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[0] );
+      pthread_create( &proc_rxtx[1].pthread_rxtx, &proc_rxtx[1].attr_rxtx, eNB_thread_rxtx, &proc_rxtx[1] );
+      pthread_create( &proc->pthread_FH, &proc->attr_FH, eNB_thread_FH, &eNB->proc );
+      pthread_create( &proc->pthread_prach, &proc->attr_prach, eNB_thread_prach, &eNB->proc );
+      if (eNB->node_timing == synch_to_other) 
+	pthread_create( &proc->pthread_asynch_rx, &proc->attr_asynch_rx, eNB_thread_asynch_rx, &eNB->proc );
 #else 
-    pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] );
-    pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] );
-    pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc );
-    pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc );
-    if (eNB->node_timing == synch_to_other) 
-      pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc );
-
+      pthread_create( &proc_rxtx[0].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[0] );
+      pthread_create( &proc_rxtx[1].pthread_rxtx, NULL, eNB_thread_rxtx, &eNB->proc_rxtx[1] );
+      pthread_create( &proc->pthread_FH, NULL, eNB_thread_FH, &eNB->proc );
+      pthread_create( &proc->pthread_prach, NULL, eNB_thread_prach, &eNB->proc );
+      if (eNB->node_timing == synch_to_other) 
+	pthread_create( &proc->pthread_asynch_rx, NULL, eNB_thread_asynch_rx, &eNB->proc );
+      
 #endif
-    char name[16];
-    snprintf( name, sizeof(name), "RXTX0 %d", i );
-    pthread_setname_np( proc_rxtx[0].pthread_rxtx, name );
-    snprintf( name, sizeof(name), "RXTX1 %d", i );
-    pthread_setname_np( proc_rxtx[1].pthread_rxtx, name );
-    snprintf( name, sizeof(name), "FH %d", i );
-    pthread_setname_np( proc->pthread_FH, name );
+      char name[16];
+      snprintf( name, sizeof(name), "RXTX0 %d", i );
+      pthread_setname_np( proc_rxtx[0].pthread_rxtx, name );
+      snprintf( name, sizeof(name), "RXTX1 %d", i );
+      pthread_setname_np( proc_rxtx[1].pthread_rxtx, name );
+      snprintf( name, sizeof(name), "FH %d", i );
+      pthread_setname_np( proc->pthread_FH, name );
+    }
+    
+    /* setup PHY proc TX sync mechanism */
+    pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
+    pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
+    sync_phy_proc.phy_proc_CC_id = 0;
   }
-  
-  /* setup PHY proc TX sync mechanism */
-  pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL);
-  pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL);
-  sync_phy_proc.phy_proc_CC_id = 0;
 }
 
 
@@ -1577,14 +1671,15 @@ void print_opp_meas(void) {
 }
  
 
-void init_eNB(eNB_func_t node_function) {
+ void init_eNB(eNB_func_t node_function,int nb_inst) {
 
   int CC_id;
-
-  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
-    PHY_vars_eNB_g[0][CC_id]->node_function = node_function;
-
-  init_eNB_proc();
+  int inst;
+  for (inst=0;inst<nb_inst;inst++)
+    for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
+      PHY_vars_eNB_g[0][CC_id]->node_function = node_function;
+  
+  init_eNB_proc(nb_inst);
   sleep(1);
   LOG_D(HW,"[lte-softmodem.c] eNB threads created\n");
   
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index eedc6415747fa4054077a43f02f81f430cc48d29..d17f7b859941fcdbc2ccd6af19e56771e1c71ca8 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -119,14 +119,14 @@ unsigned short config_frames[4] = {2,9,11,13};
 
 // In lte-enb.c
 extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
-extern void init_eNB(eNB_func_t);
+extern void init_eNB(eNB_func_t,int);
 extern void stop_eNB(void);
 extern void kill_eNB_proc(void);
 
 // In lte-ue.c
 extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
 extern void fill_ue_band_info(void);
-extern void init_UE(void);
+extern void init_UE(int);
 
 #ifdef XFORMS
 // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
@@ -284,9 +284,6 @@ eth_params_t *eth_params;
 
 openair0_config_t openair0_cfg[MAX_CARDS];
 
-// Change to openair_global to handle UE
-openair0_device openair0;
-
 double cpuf;
 
 char uecap_xer[1024],uecap_xer_in=0;
@@ -1677,40 +1674,15 @@ int main( int argc, char **argv )
       }
     }
   }
-  /* device host type is set*/
-  openair0.host_type = BBU_HOST;
-  /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */
-  openair0.type = NONE_DEV;
-  /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */
-  openair0.transp_type = NONE_TP;
-  
-  // Legacy BBU - RRH init  
-  //int returns=-1;
-  ///* BBU can have either a local or a remote radio head */  
-  //if (local_remote_radio == BBU_LOCAL_RADIO_HEAD) { //local radio head active  - load library of radio head and initiate it
-  //if (mode!=loop_through_memory) {
-  //returns=openair0_device_load(&openair0, &openair0_cfg[0]);
-  //printf("openair0_device_init returns %d\n",returns);
-  //if (returns<0) {
-  //printf("Exiting, cannot initialize device\n");
-  //exit(-1);
-  //}
-  //}
-  //else if (mode==loop_through_memory) {    
-  //}
-  //}  else { //remote radio head active - load library of transport protocol and initiate it 
-  //if (mode!=loop_through_memory) {
-  //returns=openair0_transport_load(&openair0, &openair0_cfg[0], eth_params);
-  //printf("openair0_transport_init returns %d\n",returns);
-  //if (returns<0) { 
-  //printf("Exiting, cannot initialize transport protocol\n");
-  //exit(-1);
-  //}
-  //}
-  //else if (mode==loop_through_memory) {    
-  //}
-  //}   
-    
+  else {
+    /* device host type is set*/
+    PHY_vars_UE_g[0][0]->rfdevice.host_type = BBU_HOST;
+    /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */
+    PHY_vars_UE_g[0][0]->rfdevice.type = NONE_DEV;
+    /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */
+    PHY_vars_UE_g[0][0]->rfdevice.transp_type = NONE_TP;
+  }
+
   int returns=-1;
     
   // Handle spatially distributed MIMO antenna ports   
@@ -1720,7 +1692,7 @@ int main( int argc, char **argv )
       if (mode!=loop_through_memory) {
         returns= (UE_flag == 0) ? 
 	  openair0_device_load(&(PHY_vars_eNB_g[0][CC_id]->rfdevice), &openair0_cfg[0]) :
-	  openair0_device_load(&openair0, &openair0_cfg[0]);
+	  openair0_device_load(&(PHY_vars_UE_g[0][CC_id]->rfdevice), &openair0_cfg[0]);
 
         printf("openair0_device_init returns %d for CC_id %d\n",returns,CC_id);
         if (returns<0) {
@@ -1904,8 +1876,8 @@ int main( int argc, char **argv )
 
 
   // start the main thread
-  if (UE_flag == 1) init_UE();
-  else init_eNB(node_function);
+  if (UE_flag == 1) init_UE(1);
+  else init_eNB(node_function,1);
 
   // Sleep to allow all threads to setup
   sleep(3);
@@ -1978,16 +1950,18 @@ int main( int argc, char **argv )
   pthread_mutex_destroy(&sync_mutex);
 
   // *** Handle per CC_id openair0
-  if (UE_flag==1)
-    openair0.trx_end_func(&openair0);
-
-  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func)
-      PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);  
-    if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func)
-      PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);  
+  if (UE_flag==1) {
+    if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func)
+      PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice);
+  }
+  else {
+    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+      if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func)
+	PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);  
+      if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func)
+	PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);  
+    }
   }
-
   if (ouput_vcd)
     VCD_SIGNAL_DUMPER_CLOSE();
 
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index 4fa06f1bc81b4e65b6ca98c2185277ae131a30ff..73e919758837d45ba92de12ac285b574047f4fee 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -92,9 +92,9 @@ typedef enum {
   si=2
 } sync_mode_t;
 
-void init_UE_threads(void);
+void init_UE_threads(int nb_inst);
 void *UE_thread(void *arg);
-void init_UE(void);
+void init_UE(int nb_inst);
 
 extern pthread_cond_t sync_cond;
 extern pthread_mutex_t sync_mutex;
@@ -105,8 +105,6 @@ extern openair0_config_t openair0_cfg[MAX_CARDS];
 extern uint32_t          downlink_frequency[MAX_NUM_CCs][4];
 extern int32_t           uplink_frequency_offset[MAX_NUM_CCs][4];
 extern openair0_rf_map rf_map[MAX_NUM_CCs];
-
-extern openair0_device openair0;
 extern int oai_exit;
 
 extern int32_t **rxdata;
@@ -176,21 +174,26 @@ pthread_t                       main_ue_thread;
 pthread_attr_t                  attr_UE_thread;
 struct sched_param              sched_param_UE_thread;
 
-void init_UE() {
+void init_UE(int nb_inst) {
 
   int error_code;
-  
-  printf("Intializing UE Threads ...\n");
-  init_UE_threads();
-  sleep(1);
-  error_code = pthread_create(&main_ue_thread, &attr_UE_thread, UE_thread, NULL);
-  
-  if (error_code!= 0) {
-    LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code);
-    return;
-  } else {
-    LOG_D( HW, "[lte-softmodem.c] Allocate UE_thread successful\n" );
-    pthread_setname_np( main_ue_thread, "main UE" );
+  int inst;
+  PHY_VARS_UE *UE;
+
+  for (inst=0;inst<nb_inst;inst++) {
+    printf("Intializing UE Threads for instance %d ...\n",inst);
+    init_UE_threads(inst);
+    sleep(1);
+    UE = PHY_vars_UE_g[inst][0];
+    error_code = pthread_create(&UE->proc.pthread_ue, &UE->proc.attr_ue, UE_thread, NULL);
+    
+    if (error_code!= 0) {
+      LOG_D(HW,"[lte-softmodem.c] Could not allocate UE_thread, error %d\n",error_code);
+      return;
+    } else {
+      LOG_D(HW, "[lte-softmodem.c] Allocate UE_thread successful\n" );
+      pthread_setname_np( UE->proc.pthread_ue, "main UE" );
+    }
   }
 
   printf("UE threads created\n");
@@ -362,7 +365,7 @@ static void *UE_thread_synch(void *arg)
 
   }
 
-  if (openair0.trx_start_func(&openair0) != 0 ) { 
+  if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { 
     LOG_E(HW,"Could not start the device\n");
     oai_exit=1;
   }
@@ -484,12 +487,12 @@ static void *UE_thread_synch(void *arg)
 	    break;
 	  }
 
-	  //openair0.trx_set_freq_func(&openair0,&openair0_cfg[0],0);
-	  //openair0.trx_set_gains_func(&openair0,&openair0_cfg[0]);
-	  openair0.trx_stop_func(&openair0);	  
+	  //UE->rfdevice.trx_set_freq_func(&openair0,&openair0_cfg[0],0);
+	  //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
+	  UE->rfdevice.trx_stop_func(&UE->rfdevice);	  
 	  sleep(1);
 	  init_frame_parms(&UE->frame_parms,1);
-	  if (openair0.trx_start_func(&openair0) != 0 ) { 
+	  if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) { 
 	    LOG_E(HW,"Could not start the device\n");
 	    oai_exit=1;
 	  }
@@ -568,7 +571,7 @@ static void *UE_thread_synch(void *arg)
 	    
           }
         }
-	//	openair0.trx_set_freq_func(&openair0,&openair0_cfg[0],0);
+	//	UE->rfdevice.trx_set_freq_func(&openair0,&openair0_cfg[0],0);
 
 	if (UE->UE_scan_carrier==1) {
 	  for (i=0;i<openair0_cfg[0].rx_num_channels;i++) {
@@ -606,192 +609,6 @@ static void *UE_thread_synch(void *arg)
   return &UE_thread_synch_retval;
 }
 
-/*!
- * \brief This is the UE transmit thread.
- * This thread performs the phy_procedures_UE_TX() on every transmit slot.
- * \param arg is a pointer to a \ref PHY_VARS_UE structure.
- * \returns a pointer to an int. The storage is not on the heap and must not be freed.
- */
-/*
-static void *UE_thread_tx(void *arg)
-{
-  static int UE_thread_tx_retval;
-  //int ret;
-
-  PHY_VARS_UE *UE = (PHY_VARS_UE*)arg;
-
-  UE->instance_cnt_tx=-1;
-
-#ifdef DEADLINE_SCHEDULER
-
-  struct sched_attr attr;
-  unsigned int flags = 0;
-
-  attr.size = sizeof(attr);
-  attr.sched_flags = 0;
-  attr.sched_nice = 0;
-  attr.sched_priority = 0;
-
-  // This creates a 1ms reservation every 10ms period
-  attr.sched_policy   = SCHED_DEADLINE;
-  attr.sched_runtime  = 900000;  // each tx thread requires .5ms to finish its job
-  attr.sched_deadline = 1000000; // each tx thread will finish within 1ms
-  attr.sched_period   = 1000000; // each tx thread has a period of 1ms from the starting point
-
-
-  if (sched_setattr(0, &attr, flags) < 0 ) {
-    perror("[SCHED] UE_thread_tx thread: sched_setattr failed\n");
-    return &UE_thread_tx_retval;
-  }
-
-#else
-  int policy, s, j;
-  struct sched_param sparam;
-  char cpu_affinity[1024];
-  cpu_set_t cpuset;
-
-  // Set affinity mask to include CPUs 1 to MAX_CPUS 
-  // CPU 0 is reserved for UHD threads 
-  CPU_ZERO(&cpuset);
-
-  #ifdef CPU_AFFINITY
-  if (get_nprocs() >2)
-  {
-    for (j = 1; j < get_nprocs(); j++)
-      CPU_SET(j, &cpuset);
-
-    s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
-    if (s != 0)
-    {
-      perror( "pthread_setaffinity_np");
-      exit_fun("Error setting processor affinity");
-    }
-  }
-#endif
-
-  // Check the actual affinity mask assigned to the thread
-
-  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
-  if (s != 0)
-  {
-    perror( "pthread_getaffinity_np");
-    exit_fun("Error getting processor affinity ");
-  }
-  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
-  for (j = 0; j < CPU_SETSIZE; j++)
-  if (CPU_ISSET(j, &cpuset))
-  {  
-     char temp[1024];
-     sprintf(temp, " CPU_%d ", j);    
-     strcat(cpu_affinity, temp);
-  }
-
-  memset(&sparam, 0 , sizeof (sparam));
-  sparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
-  policy = SCHED_FIFO ; 
-  
-  s = pthread_setschedparam(pthread_self(), policy, &sparam);
-  if (s != 0)
-     {
-     perror("pthread_setschedparam : ");
-     exit_fun("Error setting thread priority");
-     }
-  s = pthread_getschedparam(pthread_self(), &policy, &sparam);
-  if (s != 0)
-   {
-     perror("pthread_getschedparam : ");
-     exit_fun("Error getting thread priority");
-
-   }
-
-  LOG_I( HW, "[SCHED][UE] Started UE thread TX on CPU %d TID %ld , sched_policy = %s, priority = %d, CPU Affinity = %s \n", (int)sched_getcpu(), gettid(),
-                   (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
-                   (policy == SCHED_RR)    ? "SCHED_RR" :
-                   (policy == SCHED_OTHER) ? "SCHED_OTHER" :
-                   "???",
-                   (int) sparam.sched_priority, cpu_affinity);
-
-
-#endif
-
-  printf("waiting for sync (UE_thread_tx)\n");
-
-  pthread_mutex_lock(&sync_mutex);
-  printf("Locked sync_mutex, waiting (UE_thread_tx)\n");
-
-  while (sync_var<0)
-    pthread_cond_wait(&sync_cond, &sync_mutex);
-
-  pthread_mutex_unlock(&sync_mutex);
-  printf("unlocked sync_mutex, waiting (UE_thread_tx)\n");
-
-  printf("Starting UE TX thread\n");
-
-  // Lock memory from swapping. This is a process wide call (not constraint to this thread).
-  mlockall(MCL_CURRENT | MCL_FUTURE);
-
-  while (!oai_exit) {
-
-    if (pthread_mutex_lock(&UE->mutex_tx) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX\n" );
-      exit_fun("nothing to add");
-      return &UE_thread_tx_retval;
-    }
-
-    while (UE->instance_cnt_tx < 0) {
-      // most of the time, the thread is waiting here
-      pthread_cond_wait( &UE->cond_tx, &UE->mutex_tx );
-    }
-
-    if (pthread_mutex_unlock(&UE->mutex_tx) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX\n" );
-      exit_fun("nothing to add");
-      return &UE_thread_tx_retval;
-    }
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX, 1 );
-
-    if ((subframe_select( &UE->frame_parms, UE->slot_tx>>1 ) == SF_UL) ||
-        (UE->frame_parms.frame_type == FDD)) {
-      phy_procedures_UE_TX( UE, 0, 0, UE->mode, no_relay );
-    }
-
-    if ((subframe_select( &UE->frame_parms, UE->slot_tx>>1 ) == SF_S) &&
-        ((UE->slot_tx&1) == 1)) {
-      phy_procedures_UE_S_TX( UE, 0, 0, no_relay );
-    }
-
-    UE->slot_tx += 2;
-
-    if (UE->slot_tx >= 20) {
-      UE->slot_tx -= 20;
-      UE->frame_tx++;
-      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_UE, UE->frame_tx );
-    }
-
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_UE, UE->slot_tx>>1 );
-
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX, 0 );
-
-    if (pthread_mutex_lock(&UE->mutex_tx) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE TX thread\n" );
-      exit_fun("nothing to add");
-      return &UE_thread_tx_retval;
-    }
-
-    UE->instance_cnt_tx--;
-    VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX, UE->instance_cnt_tx);
-
-    if (pthread_mutex_unlock(&UE->mutex_tx) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE TX thread\n" );
-      exit_fun("nothing to add");
-      return &UE_thread_tx_retval;
-    }
-
-  }
-
-  return &UE_thread_tx_retval;
-}
-*/
 
 
 /*!
@@ -804,7 +621,7 @@ static void *UE_thread_tx(void *arg)
 
 static void *UE_thread_rxn_txnp4(void *arg)
 {
-  static int UE_thread_rx_retval;
+  static int UE_thread_rxtx_retval;
   UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg;
   int ret;
   PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id];
@@ -828,8 +645,8 @@ static void *UE_thread_rxn_txnp4(void *arg)
   attr.sched_period   = 1000000; // each rx thread has a period of 1ms from the starting point
 
   if (sched_setattr(0, &attr, flags) < 0 ) {
-    perror("[SCHED] UE_thread_rx : sched_setattr failed\n");
-    return &UE_thread_rx_retval;
+    perror("[SCHED] UE_thread_rxtx : sched_setattr failed\n");
+    return &UE_thread_rxtx_retval;
   }
 
 #else
@@ -914,15 +731,15 @@ static void *UE_thread_rxn_txnp4(void *arg)
     pthread_cond_wait(&sync_cond, &sync_mutex);
 
   pthread_mutex_unlock(&sync_mutex);
-  printf("unlocked sync_mutex, waiting (UE_thread_rx)\n");
+  printf("unlocked sync_mutex, waiting (UE_thread_rxtx)\n");
 
   printf("Starting UE RXN_TXNP4 thread\n");
 
   while (!oai_exit) {
     if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" );
+      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
       exit_fun("nothing to add");
-      return &UE_thread_rx_retval;
+      return &UE_thread_rxtx_retval;
     }
 
     while (proc->instance_cnt_rxtx < 0) {
@@ -933,7 +750,7 @@ static void *UE_thread_rxn_txnp4(void *arg)
     if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
       LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXn_TXnp4\n" );
       exit_fun("nothing to add");
-      return &UE_thread_rx_retval;
+      return &UE_thread_rxtx_retval;
     }
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RXTX0+(proc->subframe_rx&1), 1 );
@@ -976,23 +793,23 @@ static void *UE_thread_rxn_txnp4(void *arg)
 
     
     if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" );
+      LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
       exit_fun("noting to add");
-      return &UE_thread_rx_retval;
+      return &UE_thread_rxtx_retval;
     }
     
     proc->instance_cnt_rxtx--;
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX, proc->instance_cnt_rxtx);
     
     if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
-      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" );
+      LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RXTX\n" );
       exit_fun("noting to add");
-      return &UE_thread_rx_retval;
+      return &UE_thread_rxtx_retval;
     }
   }
   
   // thread finished
-  return &UE_thread_rx_retval;
+  return &UE_thread_rxtx_retval;
 }
 
 
@@ -1105,11 +922,11 @@ void *UE_thread(void *arg) {
 	  rxp[i] = (void*)&rxdata[i][0];
       
 	if (UE->mode != loop_through_memory) {
-	  rxs = openair0.trx_read_func(&openair0,
-				       &timestamp,
-				       rxp,
-				       UE->frame_parms.samples_per_tti*10,
-				       UE->frame_parms.nb_antennas_rx);
+	  rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
+					   &timestamp,
+					   rxp,
+					   UE->frame_parms.samples_per_tti*10,
+					   UE->frame_parms.nb_antennas_rx);
 	}
 	instance_cnt_synch = ++UE->proc.instance_cnt_synch;
 	if (instance_cnt_synch == 0) {
@@ -1132,11 +949,11 @@ void *UE_thread(void *arg) {
 	    rxp[i] = (void*)&dummy_rx[i][0];
 	  for (int sf=0;sf<10;sf++) {
 	    //	    printf("Reading dummy sf %d\n",sf);
-	    rxs = openair0.trx_read_func(&openair0,
-					 &timestamp,
-					 rxp,
-					 UE->frame_parms.samples_per_tti,
-					 UE->frame_parms.nb_antennas_rx);
+	    rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
+					     &timestamp,
+					     rxp,
+					     UE->frame_parms.samples_per_tti,
+					     UE->frame_parms.nb_antennas_rx);
 	  }
 	}
       }
@@ -1147,11 +964,11 @@ void *UE_thread(void *arg) {
 	start_rx_stream=1;
 	if (UE->mode != loop_through_memory) {
 	  LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
-	  rxs = openair0.trx_read_func(&openair0,
-				       &timestamp,
-				       (void**)rxdata,
-				       UE->rx_offset,
-				       UE->frame_parms.nb_antennas_rx);
+	  rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
+					   &timestamp,
+					   (void**)rxdata,
+					   UE->rx_offset,
+					   UE->frame_parms.nb_antennas_rx);
 	  if (rxs != UE->rx_offset) {
 	    exit_fun("problem in rx");
 	    return &UE_thread_retval;
@@ -1161,11 +978,11 @@ void *UE_thread(void *arg) {
 	  UE->proc.proc_rxtx[1].frame_rx++;
 
 	  // read in first symbol
-	  rxs = openair0.trx_read_func(&openair0,
-				       &timestamp,
-				       (void**)rxdata,
-				       UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
-				       UE->frame_parms.nb_antennas_rx);
+	  rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
+					   &timestamp,
+					   (void**)rxdata,
+					   UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0,
+					   UE->frame_parms.nb_antennas_rx);
 	  slot_fep(UE,
 		   0,
 		   0,
@@ -1192,21 +1009,21 @@ void *UE_thread(void *arg) {
 	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 );
 	  if (UE->mode != loop_through_memory) {
 	    if (sf<9) {
-	      rxs = openair0.trx_read_func(&openair0,
-					   &timestamp,
-					   rxp,
-					   UE->frame_parms.samples_per_tti,
-					   UE->frame_parms.nb_antennas_rx);
+	      rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
+					       &timestamp,
+					       rxp,
+					       UE->frame_parms.samples_per_tti,
+					       UE->frame_parms.nb_antennas_rx);
 	    }
 
 	    else {
-	      rxs = openair0.trx_read_func(&openair0,
-					   &timestamp,
-					   rxp,
-					   UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0,
-					   UE->frame_parms.nb_antennas_rx);
+	      rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
+					       &timestamp,
+					       rxp,
+					       UE->frame_parms.samples_per_tti-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0,
+					       UE->frame_parms.nb_antennas_rx);
 	      // read in first symbol of next frame and adjust for timing drift
-	      rxs = openair0.trx_read_func(&openair0,
+	      rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
 					   &timestamp1,
 					   (void**)rxdata,
 					   UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 - rx_off_diff,
@@ -1383,7 +1200,7 @@ void *UE_thread_old(void *arg)
       
     
       if (UE->mode != loop_through_memory) {
-	rxs = openair0.trx_read_func(&openair0,
+	rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
 				     &timestamp,
 				     rxp,
 				     spp - ((first_rx==1) ? rx_off_diff : 0),
@@ -1413,7 +1230,7 @@ void *UE_thread_old(void *arg)
         for (int i=0; i<UE->frame_parms.nb_antennas_tx; i++)
           txp[i] = (void*)&txdata[i][txpos];
 
-        openair0.trx_write_func(&openair0,
+        UE->rfdevice.trx_write_func(&openair0,
                                 (timestamp+openair0_cfg[0].tx_scheduling_advance-openair0_cfg[0].tx_sample_advance),
                                 txp,
 				spp - ((first_rx==1) ? rx_off_diff : 0),
@@ -1612,7 +1429,7 @@ void *UE_thread_old(void *arg)
 #ifndef USRP_DEBUG
 	    if (UE->mode != loop_through_memory) {
 	      LOG_I(PHY,"Resynchronizing RX by %d samples\n",UE->rx_offset);
-	      rxs = openair0.trx_read_func(&openair0,
+	      rxs = UE->rfdevice.trx_read_func(&UE->rfdevice,
 					   &timestamp,
 					   (void**)rxdata,
 					   UE->rx_offset,
@@ -1673,16 +1490,18 @@ void *UE_thread_old(void *arg)
  * - UE_thread_synch
  * and the locking between them.
  */
-void init_UE_threads(void)
+void init_UE_threads(int inst)
 {
-  PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
-
-  pthread_attr_init (&attr_UE_thread);
-  pthread_attr_setstacksize(&attr_UE_thread,8192);//5*PTHREAD_STACK_MIN);
+  PHY_VARS_UE *UE;
+ 
+  UE = PHY_vars_UE_g[inst][0];
 
+  pthread_attr_init (&UE->proc.attr_ue);
+  pthread_attr_setstacksize(&UE->proc.attr_ue,8192);//5*PTHREAD_STACK_MIN);
+  
 #ifndef LOWLATENCY
-  sched_param_UE_thread.sched_priority = sched_get_priority_max(SCHED_FIFO);
-  pthread_attr_setschedparam(&attr_UE_thread,&sched_param_UE_thread);
+  UE->proc.sched_param_ue.sched_priority = sched_get_priority_max(SCHED_FIFO);
+  pthread_attr_setschedparam(&UE->proc.attr_ue,&sched_param_UE_thread);
 #endif
 
   // the threads are not yet active, therefore access is allowed without locking
diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c
index 2472328c76beea3154ab10655225f4e14f6bdcb5..f59c7d7f544feee8594e51e990f49a456e307743 100644
--- a/targets/SIMU/USER/oaisim.c
+++ b/targets/SIMU/USER/oaisim.c
@@ -61,22 +61,15 @@
 #include "LAYER2/MAC/proto.h"
 #include "LAYER2/MAC/vars.h"
 #include "pdcp.h"
-#ifndef CELLULAR
 #include "RRC/LITE/vars.h"
-#endif
-#include "PHY_INTERFACE/vars.h"
-//#endif
 #include "RRC/NAS/nas_config.h"
 
-#ifdef IFFT_FPGA
-//#include "PHY/LTE_REFSIG/mod_table.h"
-#endif //IFFT_FPGA
 #include "SCHED/defs.h"
 #include "SCHED/vars.h"
 
-//#ifdef XFORMS
+
 #include "PHY/TOOLS/lte_phy_scope.h"
-//#endif
+
 
 #ifdef SMBV
 // Rohde&Schwarz SMBV100A vector signal generator
@@ -143,6 +136,28 @@ channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX][MAX_NUM_CCs];
 //Added for PHY abstraction
 node_desc_t *enb_data[NUMBER_OF_eNB_MAX];
 node_desc_t *ue_data[NUMBER_OF_UE_MAX];
+
+pthread_cond_t sync_cond;
+pthread_mutex_t sync_mutex;
+int sync_var;
+
+
+openair0_config_t openair0_cfg[MAX_CARDS];
+uint32_t          downlink_frequency[MAX_NUM_CCs][4];
+int32_t           uplink_frequency_offset[MAX_NUM_CCs][4];
+openair0_rf_map rf_map[MAX_NUM_CCs];
+
+#if defined(ENABLE_ITTI)
+volatile int             start_eNB = 0;
+volatile int             start_UE = 0;
+#endif
+volatile int                    oai_exit = 0;
+
+
+//int32_t **rxdata;
+//int32_t **txdata;
+
+
 // Added for PHY abstraction
 extern node_list* ue_node_list;
 extern node_list* enb_node_list;
@@ -164,6 +179,9 @@ extern uint16_t Nid_cell;
 
 extern LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs];
 
+extern Enb_properties_array_t enb_properties;
+
+
 //#ifdef XFORMS
 int otg_enabled;
 int xforms=0;
@@ -728,23 +746,32 @@ l2l1_task (void *args_p)
 #endif
 
 	    CC_id=0;
-	    PHY_vars_eNB_g[eNB_inst][CC_id]->proc.frame_rx                     = frame;
-	    PHY_vars_eNB_g[eNB_inst][CC_id]->proc.subframe_rx                  = sf;
-	    PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].frame_rx    = frame;
-	    PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].subframe_rx = sf;
-	    PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].subframe_tx = (sf+4)%10;
-	    PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1].frame_tx    = (sf<6) ? frame : frame+1;
-	    phy_procedures_eNB_common_RX(PHY_vars_eNB_g[eNB_inst][CC_id],
-					 abstraction_flag);
-	    phy_procedures_eNB_uespec_RX(PHY_vars_eNB_g[eNB_inst][CC_id],
-					 &PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1],
-					 abstraction_flag,
-					 no_relay);
-	    phy_procedures_eNB_TX(PHY_vars_eNB_g[eNB_inst][CC_id],
-				  &PHY_vars_eNB_g[eNB_inst][CC_id]->proc.proc_rxtx[sf&1],
-				  0,no_relay,NULL);
-
-
+	    // trigger synch event to RAN FH thread for CC_id
+	    eNB_proc_t *proc =  &PHY_vars_eNB_g[eNB_inst][CC_id]->proc;
+
+
+	    if (pthread_mutex_lock(&proc->mutex_FH) != 0) {
+	      LOG_E( PHY, "error locking mutex for FH\n");
+	      exit_fun( "error locking mutex" );
+	      break;
+	    }	    
+	    int cnt_FH       = ++proc->instance_cnt_FH;
+	    proc->frame_rx    = frame;
+            proc->subframe_rx = sf;
+	    proc->timestamp_rx += PHY_vars_eNB_g[eNB_inst][CC_id]->frame_parms.samples_per_tti;
+
+	    if (proc->instance_cnt_FH == 0) {
+	      if (pthread_cond_signal(&proc->cond_FH) != 0) {
+		LOG_E(PHY,"ERROR pthread_cond_signal for eNB FH CCid %d\n",proc->CC_id);
+		exit_fun("ERROR pthread_cond_signal");
+		break;
+	      }
+	    }
+	    else {
+	      LOG_W(PHY,"[eNB] Frame %d, FH CC_id %d thread busy!! (cnt_FH %d)\n",proc->instance_cnt_FH);
+	      exit_fun("FH thread busy");
+              break;
+	    }
 #ifdef PRINT_STATS
 
             if((sf==9) && frame%10==0)
@@ -780,109 +807,9 @@ l2l1_task (void *args_p)
         log_set_instance_type (LOG_INSTANCE_UE);
 #endif
 
+	/*
 	clear_UE_transport_info (oai_emulation.info.nb_ue_local);
 
-        for (UE_inst = oai_emulation.info.first_ue_local;
-             (UE_inst < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local));
-             UE_inst++) {
-          if (oai_emulation.info.cli_start_ue[UE_inst] != 0) {
-#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
-
-#else
-
-            if (frame >= (UE_inst * 20)) // activate UE only after 20*UE_id frames so that different UEs turn on separately
-#endif
-	      { // UE_PROCEDURES
-		LOG_D(EMU,
-		      "PHY procedures UE %d for frame %d, subframe %d\n",
-		      UE_inst, frame % MAX_FRAME_NUMBER, sf);
-
-		if (PHY_vars_UE_g[UE_inst][0]->UE_mode[0]
-		    != NOT_SYNCHED) {
-		  if (frame > 0) {
-		    PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].frame_rx    = frame % MAX_FRAME_NUMBER;
-		    PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].subframe_rx = sf;
-		    PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].frame_tx    = ((sf<6) ? frame : frame+1)% MAX_FRAME_NUMBER;
-		    PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1].subframe_tx = (sf+4)%10;
-
-#ifdef OPENAIR2
-		    //Application
-		    update_otg_UE (UE_inst, oai_emulation.info.time_ms);
-
-		    //Access layer
-		    PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, UE_inst, 0, ENB_FLAG_NO, NOT_A_RNTI, frame % MAX_FRAME_NUMBER, sf);
-		    pdcp_run (&ctxt);
-#endif
-
-		    for (CC_id = 0; CC_id < MAX_NUM_CCs;
-			 CC_id++) {
-		      phy_procedures_UE_RX(PHY_vars_UE_g[UE_inst][CC_id],
-					   &PHY_vars_UE_g[UE_inst][CC_id]->proc.proc_rxtx[sf&1],
-					   0, abstraction_flag,
-					   normal_txrx, no_relay,
-					   NULL);
-		      phy_procedures_UE_TX(PHY_vars_UE_g[UE_inst][CC_id],
-					   &PHY_vars_UE_g[UE_inst][CC_id]->proc.proc_rxtx[sf&1],
-					   0,
-					   abstraction_flag,
-					   normal_txrx,
-					   no_relay);
-		    }
-
-		    ue_data[UE_inst]->tx_power_dBm =
-		      PHY_vars_UE_g[UE_inst][0]->tx_power_dBm;
-		  }
-		} else {
-		  if (abstraction_flag == 1) {
-		    LOG_E(EMU,
-			  "sync not supported in abstraction mode (UE%d,mode%d)\n",
-			  UE_inst,
-			  PHY_vars_UE_g[UE_inst][0]->UE_mode[0]);
-		    exit (-1);
-		  }
-
-		  if ((frame > 0)
-		      && (sf==9)){
-
-		    initial_sync (PHY_vars_UE_g[UE_inst][0],
-				  normal_txrx);
-
-		    /*
-		      write_output("dlchan00.m","dlch00",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][0][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1);
-		      if (PHY_vars_UE_g[0]->frame_parms.nb_antennas_rx>1)
-		      write_output("dlchan01.m","dlch01",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][1][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1);
-		      write_output("dlchan10.m","dlch10",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][2][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1);
-		      if (PHY_vars_UE_g[0]->frame_parms.nb_antennas_rx>1)
-		      write_output("dlchan11.m","dlch11",&(PHY_vars_UE_g[0]->common_vars.dl_ch_estimates[0][3][0]),(6*(PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size)),1,1);
-		      write_output("rxsig.m","rxs",PHY_vars_UE_g[0]->common_vars.rxdata[0],PHY_vars_UE_g[0]->frame_parms.samples_per_tti*10,1,1);
-		      write_output("rxsigF.m","rxsF",PHY_vars_UE_g[0]->common_vars.rxdataF[0],2*PHY_vars_UE_g[0]->frame_parms.symbols_per_tti*PHY_vars_UE_g[0]->frame_parms.ofdm_symbol_size,2,1);
-		      write_output("pbch_rxF_ext0.m","pbch_ext0",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_ext[0],6*12*4,1,1);
-		      write_output("pbch_rxF_comp0.m","pbch_comp0",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->rxdataF_comp[0],6*12*4,1,1);
-		      write_output("pbch_rxF_llr.m","pbch_llr",PHY_vars_UE_g[0]->lte_ue_pbch_vars[0]->llr,(frame_parms->Ncp==0) ? 1920 : 1728,1,4);
-		    */
-		  }
-		}
-
-#ifdef PRINT_STATS
-
-		if((sf==1) && frame%10==0) {
-		  if (UE_stats_th[UE_inst]) {
-		    fprintf(UE_stats_th[UE_inst],"%d %d\n",frame % MAX_FRAME_NUMBER, PHY_vars_UE_g[UE_inst][0]->bitrate[0]/1000);
-		  }
-		}
-
-		if (UE_stats[UE_inst]) {
-		  len = dump_ue_stats (PHY_vars_UE_g[UE_inst][0], &PHY_vars_UE_g[UE_inst][0]->proc.proc_rxtx[sf&1],stats_buffer, 0, normal_txrx, 0);
-		  rewind (UE_stats[UE_inst]);
-		  fwrite (stats_buffer, 1, len, UE_stats[UE_inst]);
-		  fflush(UE_stats[UE_inst]);
-		}
-
-#endif
-	      } // UE_PROCEDURES
-          }
-        } // UE_inst
-
         emu_transport (frame % MAX_FRAME_NUMBER, sf<<1, ((sf+4)%10)<<1, subframe_select(&PHY_vars_eNB_g[0][0]->frame_parms,sf),
                        oai_emulation.info.frame_type[0], ethernet_flag);
 
@@ -942,6 +869,7 @@ l2l1_task (void *args_p)
 	
 	stop_meas (&ul_chan_stats);
 
+	*/
 
 	if ((sf == 0) && ((frame % MAX_FRAME_NUMBER) == 0) && (abstraction_flag == 0)
 	    && (oai_emulation.info.n_frames == 1)) {
@@ -1200,7 +1128,7 @@ main (int argc, char **argv)
 
   // oai performance profiler is enabled
   if (oai_emulation.info.opp_enabled == 1)
-    reset_opp_meas ();
+    reset_opp_meas_oaisim ();
 
   init_time ();
 
@@ -1242,7 +1170,7 @@ main (int argc, char **argv)
 }
 
 void
-reset_opp_meas (void)
+reset_opp_meas_oaisim (void)
 {
   uint8_t eNB_id = 0, UE_id = 0;
 
@@ -1383,7 +1311,7 @@ reset_opp_meas (void)
 }
 
 void
-print_opp_meas (void)
+print_opp_meas_oaisim (void)
 {
 
   uint8_t eNB_id = 0, UE_id = 0;
@@ -1687,7 +1615,7 @@ oai_shutdown (void)
     kpi_gen ();
   }
   if (oai_emulation.info.opp_enabled == 1)
-    print_opp_meas ();
+    print_opp_meas_oaisim ();
 
   // relase all rx state
   if (ethernet_flag == 1) {
diff --git a/targets/SIMU/USER/oaisim_functions.c b/targets/SIMU/USER/oaisim_functions.c
index 867d578ce918f335fcc5b1150e76f85651aad478..c8f42dfdd89a6bf8dc20639550b33b5a54d28386 100644
--- a/targets/SIMU/USER/oaisim_functions.c
+++ b/targets/SIMU/USER/oaisim_functions.c
@@ -772,12 +772,13 @@ void get_simulation_options(int argc, char *argv[])
     AssertFatal (oai_emulation.info.nb_enb_local <= enb_properties->number,
                  "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!",
                  conf_config_file_name, oai_emulation.info.nb_enb_local, enb_properties->number);
-
+    
     /* Update some simulation parameters */
     oai_emulation.info.frame_type[0] =           enb_properties->properties[0]->frame_type[0];
     oai_emulation.info.tdd_config[0] =           enb_properties->properties[0]->tdd_config[0];
     oai_emulation.info.tdd_config_S[0] =         enb_properties->properties[0]->tdd_config_s[0];
     oai_emulation.info.extended_prefix_flag[0] = enb_properties->properties[0]->prefix_type[0];
+
   }
 
   free(conf_config_file_name);
@@ -1016,23 +1017,26 @@ void init_openair1(void)
       } else {
         PHY_vars_eNB_g[eNB_id][CC_id]->N_TA_offset = 0;
       }
-    }
-  }
+    } // eNB_id
+  } // CC_id
 
-  for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++)
+  for (eNB_id=0; eNB_id<NB_eNB_INST; eNB_id++) {
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
       if (phy_test==1)
 	PHY_vars_eNB_g[eNB_id][CC_id]->mac_enabled=0;
       else
 	PHY_vars_eNB_g[eNB_id][CC_id]->mac_enabled=1;
     }
+  }
+
+   init_eNB(eNodeB_3GPP,NB_eNB_INST);
 
   // init_ue_status();
-  for (UE_id=0; UE_id<NB_UE_INST; UE_id++)
+  for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-
+      
       PHY_vars_UE_g[UE_id][CC_id]->tx_power_max_dBm=23;
-
+      
       PHY_vars_UE_g[UE_id][CC_id]->rx_total_gain_dB=100;
 
       // update UE_mode for each eNB_id not just 0
@@ -1065,8 +1069,10 @@ void init_openair1(void)
 
 #endif
 
+    } // CC_id
+  } // UE_id
+  init_UE(NB_UE_INST);
     }
-}
 
 void init_openair2(void)
 {