diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 6fce45ab1ee720e6a67a30171d91cce395275f9a..459d321b3ee43663beb9d8a9486d8e79458a7d59 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -1071,7 +1071,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci
   }
   dlsch0_harq->ndi = rel8->new_data_indicator_1;
 
+#ifdef UE_EXPANSION
+  dlsch0->active[subframe]        = 1;
+#else
   dlsch0->active        = 1;
+#endif
   if (rel8->rnti_type == 2)
       dlsch0_harq->round    = 0;
 LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n",rel8->harq_process,dlsch0->harq_mask,dlsch0_harq->round,
@@ -1237,7 +1241,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
     dlsch0_harq->Qm              = 2;
     dlsch0_harq->TBS             = TBStable[I_mcs][NPRB-1];
     dlsch0->harq_ids[subframe]   = rel8->harq_process;
+#ifdef UE_EXPANSION
+    dlsch0->active[subframe]     = 1;
+#else
     dlsch0->active               = 1;
+#endif
     dlsch0->rnti                 = rel8->rnti;
     dlsch0->harq_ids[subframe]   = rel8->harq_process;
     if (dlsch0_harq->round == 0)
@@ -1251,7 +1259,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
   case NFAPI_DL_DCI_FORMAT_1:
 
     dci_alloc->format           = format1;
+#ifdef UE_EXPANSION
+    dlsch0->active[subframe]    = 1;
+#else
     dlsch0->active              = 1;
+#endif
 
     LOG_D(PHY,"Frame %d, Subframe %d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",proc->frame_tx,subframe,rel8->harq_process);
 
@@ -1388,7 +1400,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
 
     dlsch0_harq->dl_power_off = 1;
 
+#ifdef UE_EXPANSION
+    dlsch0->active[subframe] = 1;
+#else
     dlsch0->active = 1;
+#endif
 
 
 
@@ -1591,19 +1607,32 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
     // assume both TBs are active
     dlsch0_harq->Nl        = 1;
     dlsch1_harq->Nl        = 1;
+#ifdef UE_EXPANSION
+    dlsch0->active[subframe] = 1;
+    dlsch1->active[subframe] = 1;
+#else
     dlsch0->active = 1;
     dlsch1->active = 1;
+#endif
     dlsch0->harq_mask                         |= (1<<rel8->harq_process);
     dlsch1->harq_mask                         |= (1<<rel8->harq_process);
 
     // check if either TB is disabled (see 36-213 V11.3 Section )
     if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
+#ifdef UE_EXPANSION
+      dlsch0->active[subframe] = 0;
+#else
       dlsch0->active = 0;
+#endif
       dlsch0->harq_mask                         &= ~(1<<rel8->harq_process);
     }
 
     if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
+#ifdef UE_EXPANSION
+      dlsch1->active[subframe]= 0;
+#else
       dlsch1->active = 0;
+#endif
       dlsch1->harq_mask                         &= ~(1<<rel8->harq_process);
     }
 
@@ -1615,8 +1644,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
       dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
       dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
 
+#ifdef UE_EXPANSION
+      if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) {
+#else
       if ((dlsch0->active==1) && (dlsch1->active==1)) {
-
+#endif
         dlsch0_harq->mimo_mode = LARGE_CDD;
         dlsch1_harq->mimo_mode = LARGE_CDD;
         dlsch0_harq->dl_power_off = 1;
@@ -1626,7 +1658,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
         dlsch1_harq->mimo_mode   = ALAMOUTI;
       }
     } else if (fp->nb_antenna_ports_eNB == 4) { // 4 antenna case
+#ifdef UE_EXPANSION
+      if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) {
+#else
       if ((dlsch0->active==1) && (dlsch1->active==1)) {
+#endif
         switch (rel8->precoding_information) {
         case 0: // one layer per transport block
           dlsch0_harq->mimo_mode   = LARGE_CDD;
@@ -1666,7 +1702,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
           LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
           break;
         }
+#ifdef UE_EXPANSION
+      } else if (dlsch0->active[subframe] == 1) {
+#else
       } else if (dlsch0->active == 1) {
+#endif
         switch (rel8->precoding_information) {
         case 0: // one layer per transport block
           dlsch0_harq->mimo_mode   = ALAMOUTI;
@@ -1686,7 +1726,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
           LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",rel8->precoding_information);
           break;
         }
+#ifdef UE_EXPANSION
+      } else if (dlsch1->active[subframe] == 1) {
+#else
       } else if (dlsch1->active == 1) {
+#endif
         switch (rel8->precoding_information) {
         case 0: // one layer per transport block
           dlsch0_harq->mimo_mode   = ALAMOUTI;
@@ -1712,10 +1756,18 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
     }
 
     // reset HARQ process if this is the first transmission
+#ifdef UE_EXPANSION
+    if ((dlsch0->active[subframe]==1) && (dlsch0_harq->round == 0))
+#else
     if ((dlsch0->active==1) && (dlsch0_harq->round == 0))
+#endif
       dlsch0_harq->status = ACTIVE;
 
+#ifdef UE_EXPANSION
+    if ((dlsch1->active[subframe]==1) && (dlsch1_harq->round == 0))
+#else
     if ((dlsch1->active==1) && (dlsch1_harq->round == 0))
+#endif
       dlsch1_harq->status = ACTIVE;
 
     dlsch0->rnti = rel8->rnti;
@@ -1881,8 +1933,13 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
     printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rel8->redundancy_version_1, rel8->redundancy_version_2, rel8->mcs_1, rel8->mcs_2);
 #endif
     if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==0) {
+#ifdef UE_EXPANSION
+      dlsch0->active[subframe] = 1;
+      dlsch1->active[subframe] = 1;
+#else
       dlsch0->active = 1;
       dlsch1->active = 1;
+#endif
       dlsch0->harq_mask                         |= (1<<rel8->harq_process);
       dlsch1->harq_mask                         |= (1<<rel8->harq_process);
       dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
@@ -1904,8 +1961,13 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
     else if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==1) {
       dlsch0 = eNB->dlsch[UE_id][1];
       dlsch1 = eNB->dlsch[UE_id][0];
+#ifdef UE_EXPANSION
+      dlsch0->active[subframe] = 1;
+      dlsch1->active[subframe] = 1;
+#else
       dlsch0->active = 1;
       dlsch1->active = 1;
+#endif
 
       dlsch0->harq_mask                         |= (1<<rel8->harq_process);
       dlsch1->harq_mask                         |= (1<<rel8->harq_process);
@@ -1923,7 +1985,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
       dlsch1_harq->codeword=0;
     }
     else if (TB0_active && (TB1_active==0)) {
+#ifdef UE_EXPANSION
+      dlsch0->active[subframe] = 1;
+#else
       dlsch0->active = 1;
+#endif
       dlsch0->harq_mask                         |= (1<<rel8->harq_process);
       dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
       dlsch0_harq->mcs = rel8->mcs_1;
@@ -1938,7 +2004,11 @@ LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n"
 #endif
     }
     else if ((TB0_active==0) && TB1_active) {
+#ifdef UE_EXPANSION
+      dlsch1->active[subframe] = 1;
+#else
       dlsch1->active = 1;
+#endif
       dlsch1->harq_mask                         |= (1<<rel8->harq_process);
       dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
       dlsch1_harq->mcs = rel8->mcs_2;
@@ -2201,7 +2271,11 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
 
   case 10:  // Format 6-1A
     dci_alloc->format     = format6_1A;
+#ifdef UE_EXPANSION
+    dlsch0->active[subframe]       = 1;
+#else
     dlsch0->active       = 1;
+#endif
     switch (fp->N_RB_DL) {
 
     case 25:
@@ -2254,7 +2328,11 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
     break;
   case 11:  // Format 6-1B
     dci_alloc->format     = format6_1B;
+#ifdef UE_EXPANSION
+    dlsch0->active[subframe]       = 1;
+#else
     dlsch0->active       = 1;
+#endif
     switch (fp->N_RB_DL) {
 
     case 25:
@@ -2294,7 +2372,11 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
     }
   case 12: // Format 6-2
     dci_alloc->format     = format6_2;
+#ifdef UE_EXPANSION
+    dlsch0->active[subframe]       = 1;
+#else
     dlsch0->active       = 1;
+#endif
     switch (fp->N_RB_DL) {
     case 25:
       dci_alloc->dci_length                 = sizeof_DCI6_2_5MHz_t; 
@@ -2371,8 +2453,12 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
     //LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
   
   dlsch0_harq->dl_power_off = 1;
-  
+
+#ifdef UE_EXPANSION
+  dlsch0->active[subframe] = 1;
+#else
   dlsch0->active = 1;
+#endif
   dlsch0->harq_mask                         |= (1<<rel13->harq_process);  
   
   
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index f1f4be3072c86b166168fc906a061b599aa0cfc5..b293e56b87950d7a5bffc5d92f72ecd9e964730d 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -102,6 +102,12 @@ typedef enum {
   DISABLED
 } SCH_status_t;
 
+#ifdef Rel14
+typedef enum {
+  CEmodeA = 0,
+  CEmodeB = 1
+} CEmode_t;
+#endif
 
 typedef struct {
   /// Status Flag indicating for this DLSCH (idle,active,disabled)
@@ -178,6 +184,15 @@ typedef struct {
   uint8_t first_layer;
   /// codeword this transport block is mapped to
   uint8_t codeword;
+#ifdef UE_EXPANSION
+#ifdef Rel14
+  /// indicator that this DLSCH corresponds to SIB1-BR, needed for c_init for scrambling
+  uint8_t sib1_br_flag;
+  /// initial absolute subframe (see 36.211 Section 6.3.1), needed for c_init for scrambling
+  uint16_t i0;
+  CEmode_t CEmode;
+#endif
+#endif
 } LTE_DL_eNB_HARQ_t;
 
 typedef struct {
@@ -254,13 +269,6 @@ typedef struct {
   uint8_t decode_phich;
 } LTE_UL_UE_HARQ_t; 
 
-#ifdef Rel14
-typedef enum {
-  CEmodeA = 0,
-  CEmodeB = 1
-} CEmode_t;
-#endif
-
 typedef struct {
   /// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
   int32_t *txdataF[8];
@@ -271,7 +279,11 @@ typedef struct {
   /// Allocated RNTI (0 means DLSCH_t is not currently used)
   uint16_t rnti;
   /// Active flag for baseband transmitter processing
+#ifdef UE_EXPANSION
+  uint8_t active[10];
+#else
   uint8_t active;
+#endif
   /// HARQ process mask, indicates which processes are currently active
   uint16_t harq_mask;
   /// Indicator of TX activation per subframe.  Used during PUCCH detection for ACK/NAK.
@@ -302,6 +314,7 @@ typedef struct {
   int16_t sqrt_rho_a;
   /// amplitude of PDSCH (compared to RS) in symbols containing pilots
   int16_t sqrt_rho_b;
+#ifndef UE_EXPANSION
 #ifdef Rel14
   /// indicator that this DLSCH corresponds to SIB1-BR, needed for c_init for scrambling
   uint8_t sib1_br_flag;
@@ -309,6 +322,7 @@ typedef struct {
   uint16_t i0;
   CEmode_t CEmode;
 #endif
+#endif
 } LTE_eNB_DLSCH_t;
 
 #define PUSCH_x 2
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index dbfae80840c4c76fe605fa11fb8023cfb4877b13..7482524d41f7ae03cd2e35c1cf65d0cf9773e6e1 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -246,7 +246,12 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
   if (dlsch) {
     Mdlharq = dlsch->Mdlharq;
     dlsch->rnti = 0;
+#ifdef UE_EXPANSION
+    for (i=0; i<10; i++)
+      dlsch->active[i] = 0;
+#else
     dlsch->active = 0;
+#endif
 
     for (i=0; i<10; i++)
       dlsch->harq_ids[i] = Mdlharq;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
index d90f4c66d255158e35a820602f3140c55e8b69bc..83392b18a9cf3f4e4afa28856f4de0ab6992aff9 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
@@ -92,13 +92,27 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
   uint8_t Nacc=4;
   uint16_t j0,j,idelta;
   uint16_t i  = (Ns>>1) + (10*frame);
+#ifdef UE_EXPANSION
+  uint16_t i0 = dlsch->harq_processes[harq_pid]->i0;
+#else
   uint16_t i0 = dlsch->i0;
+#endif
 
+#ifdef UE_EXPANSION
+  if (dlsch->harq_processes[harq_pid]->sib1_br_flag==1)                              Nacc=1;
+#else
   if (dlsch->sib1_br_flag==1)                              Nacc=1;
+#endif
   else if (dlsch->rnti == 0xFFFF || dlsch->rnti == 0xFFFE) Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
+#ifdef UE_EXPANSION
+  // Note: above SC-RNTI will also have to be added when/if implemented
+  else if (dlsch->harq_processes[harq_pid]->CEmode == CEmodeA)                       Nacc=1;
+  else if (dlsch->harq_processes[harq_pid]->CEmode == CEmodeB)                       Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
+#else
   // Note: above SC-RNTI will also have to be added when/if implemented
   else if (dlsch->CEmode == CEmodeA)                       Nacc=1;
   else if (dlsch->CEmode == CEmodeB)                       Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
+#endif
 
   if (frame_parms->frame_type == FDD || Nacc == 1) idelta = 0;
   else                                             idelta = Nacc-2;
@@ -111,7 +125,11 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
   // x1 is set in lte_gold_generic
   if (mbsfn_flag == 0) {
 #ifdef Rel14
+#ifdef UE_EXPANSION
+    if (dlsch->harq_processes[harq_pid]->i0 != 0xFFFF) {
+#else
     if (dlsch->i0 != 0xFFFF) {
+#endif
       // rule for BL/CE UEs from Section 6.3.1 in 36.211
       x2=  (dlsch->rnti<<14) + (q<<13) + ((((j0+j)*Nacc)%10)<<9) + frame_parms->Nid_cell;
       if ((frame&1023) < 200) LOG_D(PHY,"Scrambling init for (i0 %d, i %d, j0 %d, j %d, Nacc %d) => x2 %d\n",i0,i,j0,j,Nacc,x2);
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index c1d3ba7ce63bcf8bbff80fab466cfbb3f75ace63..6f91b61375012d9eddcef884968fddaa4999469f 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -422,6 +422,34 @@ typedef struct RU_proc_t_s {
   int                  num_slaves;
   /// array of pointers to slaves
   struct RU_proc_t_s           **slave_proc;
+#ifdef UE_EXPANSION
+  /// pthread structure for PRACH thread
+  pthread_t pthread_phy_tx;
+  pthread_mutex_t mutex_phy_tx;
+  pthread_cond_t cond_phy_tx;
+  /// \internal This variable is protected by \ref mutex_phy_tx.
+  int instance_cnt_phy_tx;
+  /// frame to act upon for transmission
+  int frame_phy_tx;
+  /// subframe to act upon for transmission
+  int subframe_phy_tx;
+  /// timestamp to send to "slave rru"
+  openair0_timestamp timestamp_phy_tx;
+  /// pthread structure for RF TX thread
+  pthread_t pthread_rf_tx;
+  pthread_mutex_t mutex_rf_tx;
+  pthread_cond_t cond_rf_tx;
+  /// \internal This variable is protected by \ref mutex_rf_tx.
+  int instance_cnt_rf_tx;
+#endif
+#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
+  pthread_t pthread_pre_scd;
+  /// condition variable for time processing thread
+  pthread_cond_t cond_pre_scd;
+  /// mutex for time thread
+  pthread_mutex_t mutex_pre_scd;
+  int instance_pre_scd;
+#endif
 } RU_proc_t;
 
 /// Context data structure for eNB subframe processing
@@ -556,14 +584,6 @@ typedef struct eNB_proc_t_s {
   te_params tep;
   /// set of scheduling variables RXn-TXnp4 threads
   eNB_rxtx_proc_t proc_rxtx[2];
-#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
-  pthread_t pthread_pre_scd;
-  /// condition variable for time processing thread
-  pthread_cond_t cond_pre_scd;
-  /// mutex for time thread
-  pthread_mutex_t mutex_pre_scd;
-  int instance_pre_scd;
-#endif
 } eNB_proc_t;
 
 
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index c93934b011cb54ebf3aa3160be979247f5b5c638..dbce91776d56d8fc8ee9fd0be225502d4e026bce 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -156,11 +156,19 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   // compute DL power control parameters
   eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa;
 
+#ifdef UE_EXPANSION
+  if (dlsch0->active[proc->subframe_tx]){
+# else
   if (dlsch0->active){
+#endif
     computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
     computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off);
   }
+#ifdef UE_EXPANSION
+  if (dlsch1->active[proc->subframe_tx]){
+#else
   if (dlsch1->active){
+#endif
     computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
     computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off);
   }
@@ -183,17 +191,29 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   }
 
 #ifdef Rel14
+#ifdef UE_EXPANSION
+  dlsch0_harq->sib1_br_flag=0;
+#else
   dlsch0->sib1_br_flag=0;
+#endif
 
   if ((rel13->pdsch_payload_type <2) && (rel13->ue_type>0)) { // this is a BR/CE UE and SIB1-BR/SI-BR
     dlsch0->rnti             = 0xFFFF;
     dlsch0->Kmimo            = 1;
     dlsch0->Mdlharq          = 4;
     dlsch0->Nsoft            = 25344;
+#ifdef UE_EXPANSION
+    dlsch0_harq->i0               = rel13->initial_transmission_sf_io;
+#else
     dlsch0->i0               = rel13->initial_transmission_sf_io;
+#endif
     dlsch0_harq->pdsch_start = rel10->pdsch_start;
 
+#ifdef UE_EXPANSION
+    if (rel13->pdsch_payload_type == 0) dlsch0_harq->sib1_br_flag=1;
+#else
     if (rel13->pdsch_payload_type == 0) dlsch0->sib1_br_flag=1;
+#endif
 
     // configure PDSCH
     switch (eNB->frame_parms.N_RB_DL) {
@@ -220,7 +240,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
       dlsch0_harq->rb_alloc[3]      = localRIV2alloc_LUT100_3[rel8->resource_block_coding];
     }
 
+#ifdef UE_EXPANSION
+    dlsch0->active[proc->subframe_tx]= 1;
+#else
     dlsch0->active                  = 1;
+#endif
 
     dlsch0_harq->nb_rb              = 6;
     dlsch0_harq->vrb_type           = LOCALIZED;
@@ -235,7 +259,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
     dlsch0_harq->codeword           = 0;
   }
   else {
+#ifdef UE_EXPANSION
+    dlsch0_harq->i0               = 0xFFFF;
+#else
     dlsch0->i0               = 0xFFFF;
+#endif
   }
 #endif
 }
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 3debfee997d832b903548dab3949529cde258394..8500cd8b9b8cbf705fe9f5a344075c87a9400500 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -376,8 +376,11 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
 		   dlsch1);
   
   stop_meas(&eNB->dlsch_modulation_stats);
-
+#ifdef UE_EXPANSION
+  dlsch->active[subframe] = 0;
+#else
   dlsch->active = 0;
+#endif
   dlsch_harq->round++;
 }
 
@@ -512,7 +515,11 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
       if ((dlsch0)&&
 	  (dlsch0->rnti>0)&&
+#ifdef UE_EXPANSION
+	  (dlsch0->active[subframe] == 1)) {
+#else
 	  (dlsch0->active == 1)) {
+#endif
 
 	// get harq_pid
 	harq_pid = dlsch0->harq_ids[subframe];
@@ -532,7 +539,11 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
       else if ((dlsch0)&&
 	       (dlsch0->rnti>0)&&
-	       (dlsch0->active == 0)) {
+#ifdef UE_EXPANSION
+	       (dlsch0->active[subframe] == 0)) {
+#else
+           (dlsch0->active == 0)) {
+#endif
 
 	// clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
 	dlsch0->subframe_tx[subframe]=0;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 1b3a85e5eecc21774b3f56907a7b21f1b6533869..7ed20d55ae239be92592fc5e091cdcc8448c1f24 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -409,6 +409,10 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP,
 }
 
 
+#ifdef UE_EXPANSION
+extern volatile int16_t phy_tx_txdataF_end;
+extern int  oai_exit;
+#endif
 // changes to pre-processor for eMTC
 
 //------------------------------------------------------------------------------
@@ -546,6 +550,12 @@ schedule_ue_spec(module_id_t module_idP,
   stop_meas(&eNB->schedule_dlsch_preprocessor);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT);
 
+
+#ifdef UE_EXPANSION
+  struct timespec time_req, time_rem;
+  time_req.tv_sec = 0;
+  time_req.tv_nsec = 10000;
+#endif
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id);
 
@@ -1254,6 +1264,12 @@ schedule_ue_spec(module_id_t module_idP,
 			post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len;	// 1 is for the postpadding header
 		    }
 
+#ifdef UE_EXPANSION
+		    while((!oai_exit)&&(phy_tx_txdataF_end == 0)){
+		      nanosleep(&time_req,&time_rem);
+		        continue;
+		    }
+#endif
 
 		    offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus,	//num_sdus
 						   sdu_lengths,	//
diff --git a/openair2/LAYER2/MAC/extern.h b/openair2/LAYER2/MAC/extern.h
index 9f29af5b9bae85ef5e32bd1a4973605848f95d6a..790f89d2c724a89db86795c2d5431dea0dde3755 100644
--- a/openair2/LAYER2/MAC/extern.h
+++ b/openair2/LAYER2/MAC/extern.h
@@ -113,10 +113,6 @@ extern uint8_t dlsch_ue_select_tbl_in_use;
 extern uint8_t new_dlsch_ue_select_tbl_in_use;
 extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
 extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-/// sorted downlink component carrier for the scheduler
-extern int pre_scd_ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-/// number of downlink active component carrier
-extern int pre_scd_numactiveCCs[NUMBER_OF_UE_MAX];
 #endif
 
 #endif //DEF_H
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index bedd37165cc4697965a7178758d4f04b4e80bc0e..ffe24cae25de9aa62d7ee2f51f3f9fadef23ea4b 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -548,20 +548,33 @@ void sort_UEs(module_id_t Mod_idP, int frameP, sub_frame_t subframeP)
 }
 
 #if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
+inline uint16_t search_rbs_required(uint16_t mcs, uint16_t TBS,uint16_t NB_RB, uint16_t step_size){
+  uint16_t nb_rb,i_TBS,tmp_TBS;
+  i_TBS=get_I_TBS(mcs);
+  for(nb_rb=step_size;nb_rb<NB_RB;nb_rb+=step_size){
+    tmp_TBS = TBStable[i_TBS][nb_rb-1]>>3;
+    if(TBS<tmp_TBS)return(nb_rb);
+  }
+  return NB_RB;
+}
 void pre_scd_nb_rbs_required(    module_id_t     module_idP,
                                  frame_t         frameP,
                                  sub_frame_t     subframeP,
                                  int             min_rb_unit[MAX_NUM_CCs],
                                  uint16_t        nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX])
 {
-    int                          CC_id,UE_id, lc_id,i, j, tmp, N_RB_DL;;
+    int                          CC_id=0,UE_id, lc_id, N_RB_DL;
     UE_TEMPLATE                  UE_template;
-    eNB_UE_STATS                 *eNB_UE_stats, *eNB_UE_stats_i, *eNB_UE_stats_j;
+    eNB_UE_STATS                 *eNB_UE_stats;
     rnti_t                       rnti;
     mac_rlc_status_resp_t        rlc_status;
-    uint16_t                     TBS = 0;
-
+    uint16_t                     step_size=2;
+    
+    N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth);
+    if(N_RB_DL==50) step_size=3;
+    if(N_RB_DL==100) step_size=4;
     memset(nb_rbs_required, 0, sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
+    UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
 
     for (UE_id = 0; UE_id <NUMBER_OF_UE_MAX; UE_id++) {
         if (pre_scd_activeUE[UE_id] != TRUE)
@@ -571,132 +584,27 @@ void pre_scd_nb_rbs_required(    module_id_t     module_idP,
 
         // clear logical channel interface variables
         UE_template.dl_buffer_total = 0;
-        UE_template.dl_pdus_total = 0;
 
         rnti = UE_RNTI(module_idP, UE_id);
 
         for (lc_id = DCCH; lc_id <= DTCH; lc_id++) {
-            UE_template.dl_buffer_info[lc_id] = 0;
-            UE_template.dl_pdus_in_buffer[lc_id] = 0;
-            UE_template.dl_buffer_head_sdu_creation_time[lc_id] = 0;
-            UE_template.dl_buffer_head_sdu_remaining_size_to_send[lc_id] = 0;
             rlc_status =
                     mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP,
                             ENB_FLAG_YES, MBMS_FLAG_NO, lc_id, 0);
-            UE_template.dl_buffer_info[lc_id] = rlc_status.bytes_in_buffer;    //storing the dlsch buffer for each logical channel
-            UE_template.dl_pdus_in_buffer[lc_id] = rlc_status.pdus_in_buffer;
-            UE_template.dl_buffer_head_sdu_creation_time[lc_id] = rlc_status.head_sdu_creation_time;
-            UE_template.dl_buffer_head_sdu_creation_time_max =
-                    cmax(UE_template.dl_buffer_head_sdu_creation_time_max,
-                            rlc_status.head_sdu_creation_time);
-            UE_template.dl_buffer_head_sdu_remaining_size_to_send[lc_id] =
-                    rlc_status.head_sdu_remaining_size_to_send;
-            UE_template.dl_buffer_head_sdu_is_segmented[lc_id] = rlc_status.head_sdu_is_segmented;
-            UE_template.dl_buffer_total += UE_template.dl_buffer_info[lc_id]; //storing the total dlsch buffer
-            UE_template.dl_pdus_total += UE_template.dl_pdus_in_buffer[lc_id];
-
-#ifdef DEBUG_eNB_SCHEDULER
-            /* note for dl_buffer_head_sdu_remaining_size_to_send[i] :
-             * 0 if head SDU has not been segmented (yet), else remaining size not already segmented and sent
-             */
-            if (UE_template.dl_buffer_info[lc_id] > 0)
-                LOG_D(MAC,
-                   "[eNB %d] Frame %d Subframe %d : RLC status for UE %d %x in LCID%d: total of %d pdus and size %d, head sdu queuing time %d, remaining size %d, is segmeneted %d \n",
-                   module_idP, frameP, subframeP, UE_id, rnti,
-                   lc_id, UE_template.dl_pdus_in_buffer[lc_id],
-                   UE_template.dl_buffer_info[lc_id],
-                   UE_template.dl_buffer_head_sdu_creation_time[lc_id],
-                   UE_template.
-                   dl_buffer_head_sdu_remaining_size_to_send[lc_id],
-                   UE_template.dl_buffer_head_sdu_is_segmented[lc_id]);
-#endif
+            UE_template.dl_buffer_total += rlc_status.bytes_in_buffer; //storing the total dlsch buffer
         }
-
-        if (UE_template.dl_buffer_total > 0)
-            LOG_D(MAC,
-                 "[eNB %d] Frame %d Subframe %d : RLC status for UE %d %x: total DL buffer size %d and total number of pdu %d \n",
-                 module_idP, frameP, subframeP, UE_id,rnti,
-                 UE_template.dl_buffer_total,
-                 UE_template.dl_pdus_total);
          // end of store dlsch buffer
 
         // assgin rbs required
         // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
         //update CQI information across component carriers
-        for (i = 0; i < pre_scd_numactiveCCs[UE_id]; i++) {
-          CC_id = pre_scd_ordered_CCids[i][UE_id];
-          eNB_UE_stats = &pre_scd_eNB_UE_stats[CC_id][UE_id];
+        eNB_UE_stats = &pre_scd_eNB_UE_stats[CC_id][UE_id];
 
-          eNB_UE_stats->dlsch_mcs1 = 28;
-        }
+        eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
 
-        // provide the list of CCs sorted according to MCS
-        for (i = 0; i < pre_scd_numactiveCCs[UE_id]; i++) {
-            eNB_UE_stats_i =
-                    &pre_scd_eNB_UE_stats[pre_scd_ordered_CCids[i][UE_id]][UE_id];
-            for (j = i + 1; j < pre_scd_numactiveCCs[UE_id]; j++) {
-                DevAssert(j < MAX_NUM_CCs);
-                eNB_UE_stats_j =
-                        &pre_scd_eNB_UE_stats[pre_scd_ordered_CCids[j][UE_id]][UE_id];
-                if (eNB_UE_stats_j->dlsch_mcs1
-                        > eNB_UE_stats_i->dlsch_mcs1) {
-                    tmp = pre_scd_ordered_CCids[i][UE_id];
-                    pre_scd_ordered_CCids[i][UE_id] =
-                            pre_scd_ordered_CCids[j][UE_id];
-                    pre_scd_ordered_CCids[j][UE_id] = tmp;
-                }
-            }
-        }
 
         if (UE_template.dl_buffer_total > 0) {
-            LOG_D(MAC, "[preprocessor] assign RB for UE %d\n", UE_id);
-
-            for (i = 0; i < pre_scd_numactiveCCs[UE_id]; i++) {
-                CC_id = pre_scd_ordered_CCids[i][UE_id];
-                eNB_UE_stats = &pre_scd_eNB_UE_stats[CC_id][UE_id];
-
-                if (eNB_UE_stats->dlsch_mcs1 == 0) {
-                    nb_rbs_required[CC_id][UE_id] = 4; // don't let the TBS get too small
-                } else {
-                    nb_rbs_required[CC_id][UE_id] =
-                            min_rb_unit[CC_id];
-                }
-
-                TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
-                        nb_rbs_required[CC_id][UE_id]);
-
-                LOG_D(MAC,
-                        "[preprocessor] start RB assignement for UE %d CC_id %d dl buffer %d (RB unit %d, MCS %d, TBS %d) \n",
-                        UE_id, CC_id,
-                        UE_template.dl_buffer_total,
-                        nb_rbs_required[CC_id][UE_id],
-                        eNB_UE_stats->dlsch_mcs1, TBS);
-
-                N_RB_DL =
-                        to_prb(
-                                RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth);
-
-                /* calculating required number of RBs for each UE */
-                while (TBS
-                        < UE_template.dl_buffer_total) {
-                    nb_rbs_required[CC_id][UE_id] +=
-                            min_rb_unit[CC_id];
-                    if (nb_rbs_required[CC_id][UE_id] > N_RB_DL) {
-                        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, N_RB_DL);
-                        nb_rbs_required[CC_id][UE_id] = N_RB_DL;
-                        break;
-                    }
-
-                    TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
-                            nb_rbs_required[CC_id][UE_id]);
-                }       // end of while
-                LOG_D(MAC,
-                        "[eNB %d] Frame %d Subframe %d: UE %d on CC %d: RB unit %d,  nb_required RB %d (TBS %d, mcs %d)\n",
-                        module_idP, frameP, subframeP, UE_id, CC_id,
-                        min_rb_unit[CC_id],
-                        nb_rbs_required[CC_id][UE_id], TBS,
-                        eNB_UE_stats->dlsch_mcs1);
-            }
+          nb_rbs_required[CC_id][UE_id] = search_rbs_required(eNB_UE_stats->dlsch_mcs1, UE_template.dl_buffer_total, N_RB_DL, step_size);
         }
     }
 }
diff --git a/openair2/LAYER2/MAC/vars.h b/openair2/LAYER2/MAC/vars.h
index b6db7fe79e5b1aff6e67e6d7114034207cbea621..01ece20d482dcd087902d60f1eef7b60cb2d5be0 100644
--- a/openair2/LAYER2/MAC/vars.h
+++ b/openair2/LAYER2/MAC/vars.h
@@ -157,10 +157,6 @@ uint8_t dlsch_ue_select_tbl_in_use;
 uint8_t new_dlsch_ue_select_tbl_in_use;
 boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
 eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-/// sorted downlink component carrier for the scheduler
-int pre_scd_ordered_CCids[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
-/// number of downlink active component carrier
-int pre_scd_numactiveCCs[NUMBER_OF_UE_MAX];
 #endif
 
 #endif
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 9b46ae7f32f5a1db02b739285602a12d93207e06..39d059d3a312dd2a39107deec4a307011e3bd1f5 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -95,10 +95,6 @@ unsigned short config_frames[4] = {2,9,11,13};
 
 #include "T.h"
 
-#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
-#include "pdcp.h"
-#endif
-
 //#define DEBUG_THREADS 1
 
 //#define USRP_DEBUG 1
@@ -191,9 +187,9 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
 
   
   if (oai_exit) return(-1);
-  
+#if (!defined(UE_EXPANSION_SIM2)) &&(!defined(UE_EXPANSION))
   phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
-  
+#endif
   if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);
 
   stop_meas( &softmodem_stats_rxtx_sf );
@@ -500,61 +496,7 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
 }
 #endif
 
-#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
-void* pre_scd_thread( void* param ){
-    static int              eNB_pre_scd_status;
-    protocol_ctxt_t         ctxt;
-    int                     frame;
-    int                     subframe;
-    int                     min_rb_unit[MAX_NUM_CCs];
-    int                     CC_id;
-    int                     Mod_id;
-    PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param;
-    eNB_proc_t *proc = &eNB->proc;
-    Mod_id = eNB->Mod_id;
-
-    frame = 0;
-    subframe = 4;
-    thread_top_init("pre_scd_thread",0,870000,1000000,1000000);
-
-    while (!oai_exit) {
-        if(oai_exit){
-            break;
-        }
-        pthread_mutex_lock(&proc->mutex_pre_scd );
-        if (proc->instance_pre_scd < 0) {
-          pthread_cond_wait(&proc->cond_pre_scd, &proc->mutex_pre_scd);
-        }
-        pthread_mutex_unlock(&proc->mutex_pre_scd);
-        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_id, ENB_FLAG_YES,
-                 NOT_A_RNTI, frame, subframe,
-                 eNB->Mod_id);
-        pdcp_run(&ctxt);
-
-        for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-
-          rrc_rx_tx(&ctxt, 0,     // eNB index, unused in eNB
-              CC_id);
-          min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
-        }
-
-        pre_scd_nb_rbs_required(Mod_id, frame, subframe,min_rb_unit,pre_nb_rbs_required[new_dlsch_ue_select_tbl_in_use]);
-
-        if (subframe==9) {
-          subframe=0;
-          frame++;
-          frame&=1023;
-        } else {
-          subframe++;
-        }
-        pthread_mutex_lock(&proc->mutex_pre_scd );
-        proc->instance_pre_scd--;
-        pthread_mutex_unlock(&proc->mutex_pre_scd);
-    }
-    eNB_pre_scd_status = 0;
-    return &eNB_pre_scd_status;
-}
-#endif
+
 
 /*!
  * \brief The prach receive thread of eNB.
@@ -712,14 +654,6 @@ void init_eNB_proc(int inst) {
     //    attr_te     = &proc->attr_te; 
 #endif
 
-#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
-    proc->instance_pre_scd = -1;
-    pthread_mutex_init( &proc->mutex_pre_scd, NULL);
-    pthread_cond_init( &proc->cond_pre_scd, NULL);
-    pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, eNB);
-    pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread");
-#endif
-
     if (eNB->single_thread_flag==0) {
       pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] );
       pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] );
@@ -806,13 +740,6 @@ void kill_eNB_proc(int inst) {
     pthread_mutex_destroy( &proc->mutex_prach_br );
     pthread_cond_destroy( &proc->cond_prach_br );
 #endif         
-#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
-    proc->instance_pre_scd = 0;
-    pthread_cond_signal( &proc->cond_pre_scd );
-    pthread_join( proc->pthread_pre_scd, (void**)&status );
-    pthread_mutex_destroy( &proc->mutex_pre_scd );
-    pthread_cond_destroy( &proc->cond_pre_scd );
-#endif
     LOG_I(PHY, "Destroying UL_INFO mutex\n");
     pthread_mutex_destroy(&eNB->UL_INFO_mutex);
     int i;
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 430f1e64268ff79544df59dbb423f488fb17b3bf..18d9cd42fca12e2599281d022a26f1ef0eeac75e 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -110,6 +110,10 @@ unsigned short config_frames[4] = {2,9,11,13};
 
 #include "T.h"
 
+#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
+#include "pdcp.h"
+#endif
+
 extern volatile int                    oai_exit;
 
 
@@ -730,10 +734,16 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
   proc->subframe_rx  = (proc->timestamp_rx / fp->samples_per_tti)%10;
   // synchronize first reception to frame 0 subframe 0
 
+#ifdef UE_EXPANSION
+  proc->timestamp_phy_tx = proc->timestamp_rx+(3*fp->samples_per_tti);
+  proc->subframe_phy_tx  = (proc->subframe_rx+3)%10;
+  proc->frame_phy_tx     = (proc->subframe_rx>6) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
+#else
   proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti);
   proc->subframe_tx  = (proc->subframe_rx+4)%10;
   proc->frame_tx     = (proc->subframe_rx>5) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
-  
+#endif
+
   LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, subframe %d\n",
 	ru->idx, 
 	0, 
@@ -1383,6 +1393,11 @@ static void* ru_stats_thread(void* param) {
   return(NULL);
 }
 
+#ifdef UE_EXPANSION
+int first_phy_tx = 1;
+volatile int16_t phy_tx_txdataF_end;
+volatile int16_t phy_tx_end;
+#endif
 static void* ru_thread( void* param ) {
 
   static int ru_thread_status;
@@ -1400,6 +1415,11 @@ static void* ru_thread( void* param ) {
   dlsch_ue_select_tbl_in_use = 1;
 #endif
 
+#ifdef UE_EXPANSION
+  struct timespec time_req, time_rem;
+  time_req.tv_sec = 0;
+  time_req.tv_nsec = 10000;
+#endif
 
   // set default return value
   thread_top_init("ru_thread",0,870000,1000000,1000000);
@@ -1489,6 +1509,30 @@ static void* ru_thread( void* param ) {
 	  ru->do_prach,
 	  is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx),
 	  proc->frame_rx,proc->subframe_rx);
+
+#ifdef UE_EXPANSION
+    if(first_phy_tx == 0)
+    {
+        phy_tx_end = 0;
+        phy_tx_txdataF_end = 0;
+        if(pthread_mutex_lock(&ru->proc.mutex_phy_tx) != 0){
+          LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for phy tx thread (IC %d)\n", ru->proc.instance_cnt_phy_tx);
+          exit_fun( "error locking mutex_rxtx" );
+        }
+        if (ru->proc.instance_cnt_phy_tx==-1) {
+          ++ru->proc.instance_cnt_phy_tx;
+
+          // the thread can now be woken up
+          AssertFatal(pthread_cond_signal(&ru->proc.cond_phy_tx) == 0, "ERROR pthread_cond_signal for phy_tx thread\n");
+        }
+        else LOG_W(PHY,"phy tx thread busy, skipping\n");
+        pthread_mutex_unlock( &ru->proc.mutex_phy_tx );
+    } else {
+        phy_tx_end = 1;
+        phy_tx_txdataF_end = 1;
+    }
+    first_phy_tx = 0;
+#endif
  
     if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) wakeup_prach_ru(ru);
 #ifdef Rel14
@@ -1511,27 +1555,25 @@ static void* ru_thread( void* param ) {
     dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
     memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
     memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
-    memcpy(&pre_scd_ordered_CCids, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.ordered_CCids, sizeof(int)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
-    memcpy(&pre_scd_numactiveCCs, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.numactiveCCs, sizeof(int)*NUMBER_OF_UE_MAX);
-    if (pthread_mutex_lock(&ru->eNB_list[0]->proc.mutex_pre_scd)!= 0) {
-        LOG_E( MAC, "[eNB] error locking MAC proc mutex for eNB pre scd\n");
+    if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) {
+        LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n");
         exit_fun("error locking mutex_time");
     }
 
-    ru->eNB_list[0]->proc.instance_pre_scd++;
+    ru->proc.instance_pre_scd++;
 
-    if (ru->eNB_list[0]->proc.instance_pre_scd == 0) {
-        if (pthread_cond_signal(&ru->eNB_list[0]->proc.cond_pre_scd) != 0) {
-            LOG_E( MAC, "[eNB] ERROR pthread_cond_signal for eNB time sync\n" );
+    if (ru->proc.instance_pre_scd == 0) {
+        if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) {
+            LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" );
             exit_fun( "ERROR pthread_cond_signal cond_pre_scd" );
         }
     }else{
-        LOG_E( MAC, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n",
-               frame,subframe,ru->eNB_list[0]->proc.instance_pre_scd );
+        LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n",
+               frame,subframe,ru->proc.instance_pre_scd );
     }
 
-    if (pthread_mutex_unlock(&ru->eNB_list[0]->proc.mutex_pre_scd)!= 0) {
-        LOG_E( MAC, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n");
+    if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) {
+        LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n");
         exit_fun("error unlocking mutex_pre_scd");
     }
 #endif
@@ -1543,6 +1585,7 @@ static void* ru_thread( void* param ) {
     wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
 
 
+#ifndef UE_EXPANSION
     // do TX front-end processing if needed (precoding and/or IDFTs)
     if (ru->feptx_prec) ru->feptx_prec(ru);
    
@@ -1552,6 +1595,12 @@ static void* ru_thread( void* param ) {
     if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
  
     if (ru->fh_north_out) ru->fh_north_out(ru);
+#else
+    while((!oai_exit)&&(phy_tx_end == 0)){
+        nanosleep(&time_req,&time_rem);
+        continue;
+    }
+#endif
 
   }
   
@@ -1643,6 +1692,161 @@ void *ru_thread_synch(void *arg) {
 
 }
 
+#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
+void* pre_scd_thread( void* param ){
+    static int              eNB_pre_scd_status;
+    protocol_ctxt_t         ctxt;
+    int                     frame;
+    int                     subframe;
+    int                     min_rb_unit[MAX_NUM_CCs];
+    int                     CC_id;
+    int                     Mod_id;
+    RU_t               *ru      = (RU_t*)param;
+    Mod_id = ru->eNB_list[0]->Mod_id;
+
+    frame = 0;
+    subframe = 4;
+    thread_top_init("pre_scd_thread",0,870000,1000000,1000000);
+
+    while (!oai_exit) {
+        if(oai_exit){
+            break;
+        }
+        pthread_mutex_lock(&ru->proc.mutex_pre_scd );
+        if (ru->proc.instance_pre_scd < 0) {
+          pthread_cond_wait(&ru->proc.cond_pre_scd, &ru->proc.mutex_pre_scd);
+        }
+        pthread_mutex_unlock(&ru->proc.mutex_pre_scd);
+        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_id, ENB_FLAG_YES,
+                 NOT_A_RNTI, frame, subframe,Mod_id);
+        pdcp_run(&ctxt);
+
+        for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+
+          rrc_rx_tx(&ctxt, 0,     // eNB index, unused in eNB
+              CC_id);
+          min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
+        }
+
+        pre_scd_nb_rbs_required(Mod_id, frame, subframe,min_rb_unit,pre_nb_rbs_required[new_dlsch_ue_select_tbl_in_use]);
+
+        if (subframe==9) {
+          subframe=0;
+          frame++;
+          frame&=1023;
+        } else {
+          subframe++;
+        }
+        pthread_mutex_lock(&ru->proc.mutex_pre_scd );
+        ru->proc.instance_pre_scd--;
+        pthread_mutex_unlock(&ru->proc.mutex_pre_scd);
+    }
+    eNB_pre_scd_status = 0;
+    return &eNB_pre_scd_status;
+}
+#endif
+
+#ifdef UE_EXPANSION
+/*!
+ * \brief The phy tx thread of eNB.
+ * \param param is a \ref eNB_proc_t structure which contains the info what to process.
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+static void* eNB_thread_phy_tx( void* param ) {
+  static int eNB_thread_phy_tx_status;
+
+
+  RU_t *ru      = (RU_t*)param;
+  RU_proc_t *proc = &ru->proc;
+  PHY_VARS_eNB **eNB_list = ru->eNB_list;
+
+  eNB_rxtx_proc_t proc_rxtx;
+
+  // set default return value
+  eNB_thread_phy_tx_status = 0;
+
+  thread_top_init("eNB_thread_phy_tx",1,500000L,1000000L,20000000L);
+
+
+  while (!oai_exit) {
+
+    if (oai_exit) break;
+
+
+    if (wait_on_condition(&proc->mutex_phy_tx,&proc->cond_phy_tx,&proc->instance_cnt_phy_tx,"eNB_phy_tx_thread") < 0) break;
+
+    LOG_D(PHY,"Running eNB phy tx procedures\n");
+    if(ru->num_eNB == 1){
+       proc_rxtx.subframe_tx = proc->subframe_phy_tx;
+       proc_rxtx.frame_tx = proc->frame_phy_tx;
+       phy_procedures_eNB_TX(eNB_list[0], &proc_rxtx, no_relay, NULL, 1);
+       ru->proc.frame_tx = proc->frame_phy_tx;
+       ru->proc.subframe_tx = proc->subframe_phy_tx;
+       ru->proc.timestamp_tx = proc->timestamp_phy_tx;
+       phy_tx_txdataF_end = 1;
+       if(pthread_mutex_lock(&ru->proc.mutex_rf_tx) != 0){
+          LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for rf tx thread (IC %d)\n", ru->proc.instance_cnt_rf_tx);
+          exit_fun( "error locking mutex_rf_tx" );
+        }
+        if (ru->proc.instance_cnt_rf_tx==-1) {
+          ++ru->proc.instance_cnt_rf_tx;
+
+          // the thread can now be woken up
+          AssertFatal(pthread_cond_signal(&ru->proc.cond_rf_tx) == 0, "ERROR pthread_cond_signal for rf_tx thread\n");
+        }
+        else LOG_W(PHY,"rf tx thread busy, skipping\n");
+        pthread_mutex_unlock( &ru->proc.mutex_rf_tx );
+    }
+    if (release_thread(&proc->mutex_phy_tx,&proc->instance_cnt_phy_tx,"eNB_thread_phy_tx") < 0) break;
+    phy_tx_end = 1;
+  }
+
+  LOG_I(PHY, "Exiting eNB thread PHY TX\n");
+
+  eNB_thread_phy_tx_status = 0;
+  return &eNB_thread_phy_tx_status;
+}
+
+
+static void* rf_tx( void* param ) {
+  static int rf_tx_status;
+
+  RU_t *ru      = (RU_t*)param;
+  RU_proc_t *proc = &ru->proc;
+
+  // set default return value
+  rf_tx_status = 0;
+
+  thread_top_init("rf_tx",1,500000L,1000000L,20000000L);
+  
+  while (!oai_exit) {
+
+    if (oai_exit) break;
+
+
+    if (wait_on_condition(&proc->mutex_rf_tx,&proc->cond_rf_tx,&proc->instance_cnt_rf_tx,"rf_tx_thread") < 0) break;
+
+    LOG_D(PHY,"Running eNB rf tx procedures\n");
+    if(ru->num_eNB == 1){
+       // do TX front-end processing if needed (precoding and/or IDFTs)
+       if (ru->feptx_prec) ru->feptx_prec(ru);
+       // do OFDM if needed
+       if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
+       // do outgoing fronthaul (south) if needed
+       if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
+
+       if (ru->fh_north_out) ru->fh_north_out(ru);
+    }
+    if (release_thread(&proc->mutex_rf_tx,&proc->instance_cnt_rf_tx,"rf_tx") < 0) break;
+  }
+
+  LOG_I(PHY, "Exiting rf TX\n");
+
+  rf_tx_status = 0;
+  return &rf_tx_status;
+}
+#endif
+
 
  
 int start_if(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB) {
@@ -1713,6 +1917,15 @@ void init_RU_proc(RU_t *ru) {
   pthread_cond_init( &proc->cond_prach_br, NULL);
   pthread_attr_init( &proc->attr_prach_br);
 #endif  
+
+#ifdef UE_EXPANSION
+  proc->instance_cnt_phy_tx       = -1;
+  pthread_mutex_init( &proc->mutex_phy_tx, NULL);
+  pthread_cond_init( &proc->cond_phy_tx, NULL);
+  proc->instance_cnt_rf_tx       = -1;
+  pthread_mutex_init( &proc->mutex_rf_tx, NULL);
+  pthread_cond_init( &proc->cond_rf_tx, NULL);
+#endif
   
 #ifndef DEADLINE_SCHEDULER
   attr_FH        = &proc->attr_FH;
@@ -1725,6 +1938,19 @@ void init_RU_proc(RU_t *ru) {
 #endif
   
   pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru );
+#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
+    proc->instance_pre_scd = -1;
+    pthread_mutex_init( &proc->mutex_pre_scd, NULL);
+    pthread_cond_init( &proc->cond_pre_scd, NULL);
+    pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void*)ru);
+    pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread");
+#endif
+
+#ifdef UE_EXPANSION
+    pthread_create( &proc->pthread_phy_tx, NULL, eNB_thread_phy_tx, (void*)ru );
+    pthread_setname_np( proc->pthread_phy_tx, "phy_tx_thread" );
+    pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void*)ru );
+#endif
 
   if (ru->function == NGFI_RRU_IF4p5) {
     pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru );
@@ -2141,8 +2367,32 @@ void init_RU(char *rf_config_file) {
 
 
 void stop_ru(RU_t *ru) {
-
+#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
+    int *status;
+#endif
   printf("Stopping RU %p processing threads\n",(void*)ru);
-  
+#if defined(UE_EXPANSION) || defined(UE_EXPANSION_SIM2)
+  if(ru){
+    ru->proc.instance_pre_scd = 0;
+    pthread_cond_signal( &ru->proc.cond_pre_scd );
+    pthread_join(ru->proc.pthread_pre_scd, (void**)&status );
+    pthread_mutex_destroy(&ru->proc.mutex_pre_scd );
+    pthread_cond_destroy(&ru->proc.cond_pre_scd );
+  }
+#endif
+#ifdef UE_EXPANSION
+  if(ru){
+      ru->proc.instance_cnt_phy_tx = 0;
+      pthread_cond_signal(&ru->proc.cond_phy_tx);
+      pthread_join( ru->proc.pthread_phy_tx, (void**)&status );
+      pthread_mutex_destroy( &ru->proc.mutex_phy_tx );
+      pthread_cond_destroy( &ru->proc.cond_phy_tx );
+      ru->proc.instance_cnt_rf_tx = 0;
+      pthread_cond_signal(&ru->proc.cond_rf_tx);
+      pthread_join( ru->proc.pthread_rf_tx, (void**)&status );
+      pthread_mutex_destroy( &ru->proc.mutex_rf_tx );
+      pthread_cond_destroy( &ru->proc.cond_rf_tx );
+  }
+#endif
 }
 
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index e90fc4335c5edd68369163e1cde3fcc9f474dc0b..e8b204a7b4a8201ee97c75aae2463aec3f202f66 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -1360,6 +1360,11 @@ int main( int argc, char **argv )
   // cleanup
   if (UE_flag == 1) {
   } else {
+#ifdef UE_EXPANSION
+      for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
+          stop_ru(RC.ru[ru_id]);
+      }
+#endif
     stop_eNB(1);
   }
 
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index 44e35c88a385319e896142e77ec05d5a62a9eb01..0e5e6b6081d352e13753acd8a9906bfeb7de02c3 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -244,6 +244,9 @@ extern void kill_eNB_proc(int inst);
 
 // In lte-ru.c
 extern void init_RU(const char*);
+#ifdef UE_EXPANSION
+extern void stop_ru(RU_t *ru);
+#endif
 
 // In lte-ue.c
 extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);