diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 56759ae0e5101d75204d57e74b481a7919ce7d57..f96c63f2bb22b2f15b50e1baafdd06b9339b96d5 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -963,6 +963,7 @@ set(PHY_SRC
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/print_stats.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/initial_sync.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c
+  ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_mobipass_tools.c
   ${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
   ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
   ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index e3128d729695d8b23fd72ea5970186d74b0ec916..a453b8eb8d0171db7073d072c3b4b8c59d9b8d1d 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -259,7 +259,7 @@ void phy_config_sib2_ue(uint8_t Mod_id,int CC_id,
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_IN);
 
-  LOG_I(PHY,"[UE%d] Frame %d: Applying radioResourceConfigCommon from eNB%d\n",Mod_id,PHY_vars_UE_g[Mod_id][CC_id]->frame_rx,CH_index);
+  LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,CH_index);
 
   frame_parms->prach_config_common.rootSequenceIndex                           =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
 
@@ -369,7 +369,7 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t CH_index,int mbsfn_Are
   LTE_DL_FRAME_PARMS *frame_parms = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms;
 
 
-  LOG_I(PHY,"[UE%d] Frame %d: Applying MBSFN_Area_id %d for index %d\n",Mod_id,PHY_vars_UE_g[Mod_id][CC_id]->frame_rx,mbsfn_AreaId_r9,mbsfn_Area_idx);
+  LOG_I(PHY,"[UE%d] Applying MBSFN_Area_id %d for index %d\n",Mod_id,mbsfn_AreaId_r9,mbsfn_Area_idx);
 
   if (mbsfn_Area_idx == 0) {
     frame_parms->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9;
@@ -517,8 +517,8 @@ void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobility
     //     uint8_t prach_fmt;
     //     int u;
 
-    LOG_I(PHY,"[UE%d] Frame %d: Handover triggered: Applying radioResourceConfigCommon from eNB %d\n",
-          Mod_id,PHY_vars_UE_g[Mod_id][CC_id]->frame_rx,eNB_id);
+    LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n",
+          Mod_id,eNB_id);
 
     frame_parms->prach_config_common.rootSequenceIndex                           =radioResourceConfigCommon->prach_Config.rootSequenceIndex;
     frame_parms->prach_config_common.prach_Config_enabled=1;
@@ -752,7 +752,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t CH_index,
 
 
   if (physicalConfigDedicated) {
-    LOG_D(PHY,"[UE %d] Frame %d: Received physicalConfigDedicated from eNB %d\n",Mod_id, phy_vars_ue->frame_rx,CH_index);
+    LOG_D(PHY,"[UE %d] Received physicalConfigDedicated from eNB %d\n",Mod_id, CH_index);
     LOG_D(PHY,"------------------------------------------------------------------------\n");
 
     if (physicalConfigDedicated->pdsch_ConfigDedicated) {
@@ -843,7 +843,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t CH_index,
 
 #endif
   } else {
-    LOG_D(PHY,"[PHY][UE %d] Frame %d: Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, phy_vars_ue->frame_rx,CH_index);
+    LOG_D(PHY,"[PHY][UE %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id,CH_index);
     return;
   }
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
index 6980ca358cb55686e0c47bb10679ebe0f9ee93a8..b78a7e24fdba391e1c33e60e4d8a96eb6e94708f 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
@@ -51,7 +51,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
   ncoef = 32767 - coef;
 
 #ifdef DEBUG_PHY
-  LOG_D(PHY,"frame %d, slot %d: rx_offset (before) = %d\n",ue->frame_rx,ue->slot_rx,ue->rx_offset);
+  LOG_D(PHY,"frame %d: rx_offset (before) = %d\n",ue->proc.proc_rxtx[0].frame_rx,ue->rx_offset);
 #endif //DEBUG_PHY
 
 
@@ -95,7 +95,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
 
 #ifdef DEBUG_PHY
   LOG_D(PHY,"frame %d: rx_offset (after) = %d : max_pos = %d,max_pos_fil = %d (peak %d)\n",
-        ue->frame_rx,ue->rx_offset,max_pos,max_pos_fil,temp);
+        ue->proc.proc_rxtx[0].frame_rx,ue->rx_offset,max_pos,max_pos_fil,temp);
 #endif //DEBUG_PHY
 
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index ae484092b807f2cb50deab487bf42922f2e7efd2..7a9fd1284df331475ff74b5876aaf1f69c887bc7 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -77,7 +77,7 @@ int16_t get_PL(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
     RSoffset = 3;
   */
 
-  LOG_D(PHY,"get_PL : Frame %d : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n", ue->frame_rx,
+  LOG_D(PHY,"get_PL : Frame %d : rsrp %f dBm/RE (%f), eNB power %d dBm/RE\n", ue->proc.proc_rxtx[0].frame_rx,
         (1.0*dB_fixed_times10(ue->measurements.rsrp[eNB_index])-(10.0*ue->rx_total_gain_dB))/10.0,
         10*log10((double)ue->measurements.rsrp[eNB_index]),
         ue->frame_parms.pdsch_config_common.referenceSignalPower);
@@ -172,7 +172,7 @@ int8_t set_RSRQ_filtered(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rs
 }
 
 void ue_rrc_measurements(PHY_VARS_UE *ue,
-                         uint8_t slot,
+                         uint8_t subframe,
                          uint8_t abstraction_flag)
 {
 
@@ -192,7 +192,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 
       if (abstraction_flag == 0) {
         if ((ue->frame_parms.frame_type == FDD) &&
-            ((slot == 0) || (slot == 10))) {  // FDD PSS/SSS, compute noise in DTX REs
+            ((subframe == 0) || (subframe == 5))) {  // FDD PSS/SSS, compute noise in DTX REs
 
           if (ue->frame_parms.Ncp==NORMAL) {
             for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
@@ -240,7 +240,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 	  }
         }
 	else if ((ue->frame_parms.frame_type == TDD) &&
-		 (slot == 1)) {  // TDD SSS, compute noise in DTX REs
+		 (subframe == 0)) {  // TDD SSS, compute noise in DTX REs
 
           if (ue->frame_parms.Ncp==NORMAL) {
             for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
@@ -294,7 +294,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
       for (l=0,nu=0; l<=(4-ue->frame_parms.Ncp); l+=(4-ue->frame_parms.Ncp),nu=3) {
         k = (nu + nushift)%6;
 #ifdef DEBUG_MEAS
-        LOG_I(PHY,"[UE %d] Frame %d slot %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",ue->Mod_id,ue->frame_rx,slot,Nid_cell,nushift,
+        LOG_I(PHY,"[UE %d] Frame %d subframe %d Doing ue_rrc_measurements rsrp/rssi (Nid_cell %d, nushift %d, eNB_offset %d, k %d, l %d)\n",ue->Mod_id,ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,Nid_cell,nushift,
               eNB_offset,k,l);
 #endif
 
@@ -376,15 +376,15 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
     //    if (slot == 0) {
 
       if (eNB_offset == 0)
-        LOG_I(PHY,"[UE %d] Frame %d, slot %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",ue->Mod_id,
-              ue->frame_rx,slot,10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
+        LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements => rssi %3.1f dBm (digital: %3.1f dB, gain %d), N0 %d dBm\n",ue->Mod_id,
+              ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
               10*log10(ue->measurements.rssi),
               ue->rx_total_gain_dB,
               ue->measurements.n0_power_tot_dBm);
 
-      LOG_I(PHY,"[UE %d] Frame %d, slot %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d), rsrq: %3.1f dB\n",
+      LOG_I(PHY,"[UE %d] Frame %d, subframe %d RRC Measurements (idx %d, Cell id %d) => rsrp: %3.1f dBm/RE (%d), rsrq: %3.1f dB\n",
             ue->Mod_id,
-            ue->frame_rx,slot,eNB_offset,
+            ue->proc.proc_rxtx[subframe&1].frame_rx,subframe,eNB_offset,
             (eNB_offset>0) ? ue->measurements.adj_cell_id[eNB_offset-1] : ue->frame_parms.Nid_cell,
             10*log10(ue->measurements.rsrp[eNB_offset])-ue->rx_total_gain_dB,
             ue->measurements.rsrp[eNB_offset],
@@ -699,9 +699,9 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
 }
 
 
-void lte_ue_measurements_emul(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
+void lte_ue_measurements_emul(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id)
 {
 
-  msg("[PHY] EMUL UE lte_ue_measurements_emul last slot %d, eNB_id %d\n",last_slot,eNB_id);
+  msg("[PHY] EMUL UE lte_ue_measurements_emul subframe %d, eNB_id %d\n",subframe,eNB_id);
 }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index e14cdac1ac9df060610c1ceece5272c227e24d49..f5e0a987f70ab9d054da6ca532ec45d3f58ea3e8 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -48,7 +48,7 @@
 #include "SIMULATION/TOOLS/defs.h" // for taus 
 #include "PHY/sse_intrin.h"
 
-#include "assertions.h"
+#include "assertions.h" 
 
 //#define DEBUG_DCI_ENCODING 1
 //#define DEBUG_DCI_DECODING 1
@@ -2079,8 +2079,8 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
   }
 
   num_pdcch_symbols = get_num_pdcch_symbols(num_ue_spec_dci+num_common_dci,dci_alloc,frame_parms,subframe);
-  //   printf("subframe %d in generate_dci_top num_pdcch_symbols = %d, num_dci %d\n",
-  //       subframe,num_pdcch_symbols,num_ue_spec_dci+num_common_dci);
+  //  printf("subframe %d in generate_dci_top num_pdcch_symbols = %d, num_dci %d\n",
+  //     subframe,num_pdcch_symbols,num_ue_spec_dci+num_common_dci);
   generate_pcfich(num_pdcch_symbols,
                   amp,
                   frame_parms,
@@ -2108,7 +2108,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
       if (dci_alloc[i].L == (uint8_t)L) {
 
 #ifdef DEBUG_DCI_ENCODING
-        LOG_I(PHY,"Generating common DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",i,num_common_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,1<<dci_alloc[i].L,
+        printf("Generating common DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",i,num_common_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,1<<dci_alloc[i].L,
               *(unsigned int*)dci_alloc[i].dci_pdu);
         dump_dci(frame_parms,&dci_alloc[i]);
 #endif
@@ -2128,7 +2128,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
       if (dci_alloc[i].L == (uint8_t)L) {
 
 #ifdef DEBUG_DCI_ENCODING
-        LOG_I(PHY," Generating UE (rnti %x) specific DCI %d of length %d, aggregation %d, format %d (%x)\n",dci_alloc[i].rnti,i,dci_alloc[i].dci_length,1<<dci_alloc[i].L,dci_alloc[i].format,
+        printf(" Generating UE (rnti %x) (nCCE %d) specific DCI %d of length %d, aggregation %d, format %d (%x)\n",dci_alloc[i].rnti,dci_alloc[i].firstCCE,i,dci_alloc[i].dci_length,1<<dci_alloc[i].L,dci_alloc[i].format,
               dci_alloc[i].dci_pdu);
         dump_dci(frame_parms,&dci_alloc[i]);
 #endif
@@ -2140,6 +2140,9 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
                                 dci_alloc[i].L,
                                 dci_alloc[i].rnti);
         }
+	else {
+	  
+	}
       }
     }
   }
@@ -2153,9 +2156,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
   //72*get_nCCE(num_pdcch_symbols,frame_parms,mi));
 
 
-#ifdef DEBUG_DCI_ENCODING
-  LOG_I(PHY," PDCCH Modulation, Msymb %d\n",Msymb);
-#endif
+
 
   // Now do modulation
   if (frame_parms->mode1_flag==1)
@@ -2165,10 +2166,16 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
 
   e_ptr = e;
 
+#ifdef DEBUG_DCI_ENCODING
+  printf(" PDCCH Modulation, Msymb %d, Msymb2 %d,gain_lin_QPSK %d\n",Msymb,Msymb2,gain_lin_QPSK);
+#endif
+
+
   if (frame_parms->mode1_flag) { //SISO
 
 
     for (i=0; i<Msymb2; i++) {
+      
       //((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
       //((int16_t*)(&(y[1][i])))[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
       ((int16_t*)(&(y[0][i])))[0] = (*e_ptr == 2) ? 0 : (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
@@ -2187,7 +2194,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
     for (i=0; i<Msymb2; i+=2) {
 
 #ifdef DEBUG_DCI_ENCODING
-      LOG_I(PHY," PDCCH Modulation (TX diversity): REG %d\n",i>>2);
+      printf(" PDCCH Modulation (TX diversity): REG %d\n",i>>2);
 #endif
       // first antenna position n -> x0
       ((int16_t*)&y[0][i])[0] = (*e_ptr == 1) ? -gain_lin_QPSK : gain_lin_QPSK;
@@ -2212,7 +2219,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
 
 
 #ifdef DEBUG_DCI_ENCODING
-  LOG_I(PHY," PDCCH Interleaving\n");
+  printf(" PDCCH Interleaving\n");
 #endif
 
   //  printf("y %p (%p,%p), wbar %p (%p,%p)\n",y,y[0],y[1],wbar,wbar[0],wbar[1]);
@@ -2262,8 +2269,9 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
                   txdataF[1][tti_offset+i] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
-                LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+                printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+i,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
 #endif
+
                 mprime++;
               }
             }
@@ -2292,7 +2300,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
                 txdataF[1][tti_offset+0] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
-              LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
 #endif
               mprime++;
               txdataF[0][tti_offset+1] = wbar[0][mprime];
@@ -2301,7 +2309,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
                 txdataF[1][tti_offset+1] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
-              LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
+              printf("PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset+1,*(short*)&wbar[0][mprime],*(1+(short*)&wbar[0][mprime]));
 #endif
               mprime++;
               txdataF[0][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[0][mprime];
@@ -2310,7 +2318,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
                 txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+3] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
-              LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime],
+              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+3,*(short*)&wbar[0][mprime],
                     *(1+(short*)&wbar[0][mprime]));
 #endif
               mprime++;
@@ -2320,7 +2328,7 @@ uint8_t generate_dci_top(uint8_t num_ue_spec_dci,
                 txdataF[1][tti_offset-frame_parms->ofdm_symbol_size+4] = wbar[1][mprime];
 
 #ifdef DEBUG_DCI_ENCODING
-              LOG_I(PHY," PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime],
+              printf(" PDCCH mapping mprime %d => %d (symbol %d re %d) -> (%d,%d)\n",mprime,tti_offset,symbol_offset,re_offset-frame_parms->ofdm_symbol_size+4,*(short*)&wbar[0][mprime],
                     *(1+(short*)&wbar[0][mprime]));
 #endif
               mprime++;
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 18e232e967c1d9188c3e2710d79d429623bad891..0ea44f1caaede50842b48e9248418fafa95137f3 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -4477,9 +4477,6 @@ int generate_ue_dlsch_params_from_dci(int frame,
     LOG_D(PHY,"UE (%x/%d): Subframe %d Format1 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi,
           dlsch0_harq->first_tx,dlsch0_harq->status);
 
-    //    printf("Format2 DCI (UE, hard pid %d): ndi %d, old_ndi %d (first tx %d)\n",harq_pid,ndi,dlsch0_harq->DCINdi,
-    //    dlsch0_harq->first_tx);
-
     if ((ndi!=dlsch0_harq->DCINdi)||
         (dlsch0_harq->first_tx==1)) {
       //    printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx);
@@ -6236,6 +6233,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
                                       uint8_t subframe,
                                       DCI_format_t dci_format,
                                       PHY_VARS_UE *ue,
+				      UE_rxtx_proc_t *proc,
                                       uint16_t si_rnti,
                                       uint16_t ra_rnti,
                                       uint16_t p_rnti,
@@ -6269,12 +6267,12 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
       harq_pid = 0;
     else
       harq_pid = subframe2harq_pid(frame_parms,
-                                   pdcch_alloc2ul_frame(frame_parms,ue->frame_rx,subframe),
+                                   pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,subframe),
                                    pdcch_alloc2ul_subframe(frame_parms,subframe));
 
     if (harq_pid == 255) {
       LOG_E(PHY, "frame %d, subframe %d, rnti %x, format %d: illegal harq_pid!\n",
-            ue->frame_rx, subframe, rnti, dci_format);
+            proc->frame_rx, subframe, rnti, dci_format);
       return(-1);
     }
 
@@ -6401,7 +6399,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
     if (rballoc > RIV_max) {
       LOG_E(PHY,"frame %d, subframe %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc > RIV_max\n",
-            ue->frame_rx, subframe, rnti, dci_format);
+            proc->frame_rx, subframe, rnti, dci_format);
       return(-1);
     }
 
@@ -6416,13 +6414,13 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
     if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) {
       LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n",
-            ue->Mod_id,harq_pid,ue->frame_rx,subframe,ulsch->f_pusch,
+            ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch,
             delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC],
             ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC);
       ulsch->f_pusch += delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC];
     } else {
       LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ABS) %d, adjusting to %d (TPC %d)\n",
-            ue->Mod_id,harq_pid,ue->frame_rx,subframe,ulsch->f_pusch,
+            ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch,
             delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC],
             ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC);
       ulsch->f_pusch = delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC];
@@ -7044,7 +7042,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
     }
 
     LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d\n",
-          ue->Mod_id,harq_pid,ue->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,
+          ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,
           ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx);
 
     // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
@@ -7071,7 +7069,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
     return(0);
   } else {
     LOG_E(PHY,"frame %d, subframe %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n",
-          ue->frame_rx, subframe,dci_format);
+          proc->frame_rx, subframe,dci_format);
     return(-1);
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index a8ebb99c8aacacd1a4169cdc99685a6d97f44caf..dd7048f9c87367de8a41e7bd58cce074fd3fcec0 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -710,6 +710,8 @@ typedef struct {
   uint32_t Nsoft;
   /// Maximum number of Turbo iterations
   uint8_t max_turbo_iterations;
+  /// number of iterations used in last turbo decoding
+  uint8_t last_iteration_cnt;
   /// accumulated tx power adjustment for PUCCH
   int8_t               g_pucch;
 } LTE_UE_DLSCH_t;
@@ -735,6 +737,7 @@ typedef enum {
   SI_PDSCH=0,
   RA_PDSCH,
   PDSCH,
+  PDSCH1,
   PMCH
 } PDSCH_t;
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index 0739d772f5a2eeea0b321d6f57c84218c81dbc16..17180af613f55a9e2864e4233befe48bd75cb42a 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
@@ -670,6 +670,8 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     }
   }
 
+  dlsch->last_iteration_cnt = ret;
+
   return(ret);
 }
 
@@ -814,7 +816,7 @@ int dlsch_abstraction_MIESM(double* sinr_dB,uint8_t TM, uint32_t rb_alloc[4], ui
 
 uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
                              uint8_t subframe,
-                             uint8_t dlsch_id,
+                             PDSCH_t dlsch_id,
                              uint8_t eNB_id)
 {
 
@@ -845,7 +847,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
 
 
   switch (dlsch_id) {
-  case 0: // SI
+  case PDSCH_SI: // SI
     dlsch_ue = phy_vars_ue->dlsch_ue_SI[eNB_id];
     dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_eNB_SI;
     //    printf("Doing SI: TBS %d\n",dlsch_ue->harq_processes[0]->TBS>>3);
@@ -861,7 +863,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     return(1);
     break;
 
-  case 1: // RA
+  case PDSCH_RA: // RA
     dlsch_ue  = phy_vars_ue->dlsch_ue_ra[eNB_id];
     dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_eNB_ra;
     memcpy(dlsch_ue->harq_processes[0]->b,dlsch_eNB->harq_processes[0]->b,dlsch_ue->harq_processes[0]->TBS>>3);
@@ -876,7 +878,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     return(1);
     break;
 
-  case 2: // TB0
+  case PDSCH: // TB0
     dlsch_ue  = phy_vars_ue->dlsch_ue[eNB_id][0];
     harq_pid = dlsch_ue->current_harq_pid;
     ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->lte_ue_pdcch_vars[(uint32_t)eNB_id]->crnti,PHY_vars_eNB_g[eNB_id2][CC_id]);
@@ -916,6 +918,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
       dlsch_ue->harq_ack[subframe].ack = 0;
       dlsch_ue->harq_ack[subframe].harq_id = harq_pid;
       dlsch_ue->harq_ack[subframe].send_harq_status = 1;
+      dlsch->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
       return(1+dlsch_ue->max_turbo_iterations);
     }
 
@@ -940,7 +943,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
   }
 
-  case 5: // PMCH
+  case PMCH: // PMCH
 
     dlsch_ue  = phy_vars_ue->dlsch_ue_MCH[eNB_id];
     dlsch_eNB = PHY_vars_eNB_g[eNB_id2][CC_id]->dlsch_eNB_MCH;
@@ -965,9 +968,11 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
       memcpy(dlsch_ue->harq_processes[0]->b,
              dlsch_eNB->harq_processes[0]->b,
              dlsch_ue->harq_processes[0]->TBS>>3);
+      dlsch->last_iteration_cnt = 1;
       return(1);
     } else {
       // retransmission
+      dlsch->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
       return(1+dlsch_ue->max_turbo_iterations);
     }
 
@@ -976,6 +981,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
   default:
     dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id][0];
     LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id);
+    dlsch->last_iteration_cnt = 1+dlsch_ue->max_turbo_iterations;
     return(1+dlsch_ue->max_turbo_iterations);
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
index c41262727f37c47ca2e8da1786e05498845654b6..ab6c4703d6574aa9137ce91c3e409132e5c08818 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -123,7 +123,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
     break;
 
   default:
-    LOG_E(PHY,"[UE %d][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",ue->frame_rx,subframe,type);
+    LOG_E(PHY,"[UE %d][FATAL] Frame %d subframe %d: Unknown PDSCH format %d\n",ue->proc.proc_rxtx[0].frame_rx,subframe,type);
     return(-1);
     break;
   }
diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c
index 8ccfc72d205e293bada16ee19a33ef1002ac693a..1f8e605eaf9f0f46ffc0667f4ff7ba950e03d3de 100644
--- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c
@@ -43,6 +43,7 @@
 //#define DEBUG_DRS
 
 int generate_drs_pusch(PHY_VARS_UE *ue,
+		       UE_rxtx_proc_t *proc,
                        uint8_t eNB_id,
                        short amp,
                        unsigned int subframe,
@@ -70,7 +71,7 @@ int generate_drs_pusch(PHY_VARS_UE *ue,
   uint32_t v0=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[subframe<<1];
   uint32_t v1=frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.seqhop[1+(subframe<<1)];
   int32_t ref_re,ref_im;
-  uint8_t harq_pid = subframe2harq_pid(frame_parms,ue->frame_tx,subframe);
+  uint8_t harq_pid = subframe2harq_pid(frame_parms,proc->frame_tx,subframe);
 
   cyclic_shift0 = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
                    ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2 +
diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 4756559ac39ddad2551456fc814a50b2a3953191..b71365d6fc0970257bdf00f1976a14325b3438ee 100644
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -176,7 +176,7 @@ void send_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t packet_type,
 }
 
 
-void recv_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t *packet_type, uint32_t *symbol_number) {
+void recv_IF4(PHY_VARS_eNB *eNB, int *frame, int *subframe, uint16_t *packet_type, uint32_t *symbol_number) {
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
   int32_t **txdataF = eNB->common_vars.txdataF[0];
   int32_t **rxdataF = eNB->common_vars.rxdataF[0];
@@ -208,10 +208,13 @@ void recv_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t *packet_type,
   
   packet_header = (IF4_header_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES);
   data_block = (int16_t*) (rx_buffer+MAC_HEADER_SIZE_BYTES+sizeof_IF4_header_t);
+
+  *frame = ((packet_header->frame_status)>>6)&0xffff;
+  *subframe = ((packet_header->frame_status)>>22)&0x000f; 
   
   if (*packet_type == IF4_PDLFFT) {          
     // Calculate from received packet
-    slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
+    slotoffsetF = (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
     blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength; 
     
     // Do decompression of the two parts and generate txdataF			
@@ -228,7 +231,7 @@ void recv_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t *packet_type,
         
   } else if (*packet_type == IF4_PULFFT) {         
     // Calculate from received packet
-    slotoffsetF = (subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
+    slotoffsetF = (*subframe)*(fp->ofdm_symbol_size)*((fp->Ncp==1) ? 12 : 14) + 1;
     blockoffsetF = slotoffsetF + fp->ofdm_symbol_size - db_halflength; 
     
     // Do decompression of the two parts and generate rxdataF
@@ -246,7 +249,7 @@ void recv_IF4(PHY_VARS_eNB *eNB, int frame, int subframe, uint16_t *packet_type,
   } else if (*packet_type == IF4_PRACH) {    
     // FIX: hard coded prach samples length
     db_fulllength = 839*2;
-		    
+		
     // Generate uncompressed data blocks
     memcpy((rxsigF[0]+slotoffsetF), data_block, db_fulllength*sizeof(int16_t));
        
diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.h b/openair1/PHY/LTE_TRANSPORT/if4_tools.h
index f06072b73e66be9feceddfda86359cb0928366ed..18ff2bb8f826186cc397dc59e895d3a9a716995e 100644
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.h
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.h
@@ -70,4 +70,4 @@ void gen_IF4_prach_header(IF4_header_t*, int, int);
 
 void send_IF4(PHY_VARS_eNB*, int, int, uint16_t, int);
 
-void recv_IF4(PHY_VARS_eNB*, int, int, uint16_t*, uint32_t*);
+void recv_IF4(PHY_VARS_eNB*, int*, int*, uint16_t*, uint32_t*);
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.c
new file mode 100644
index 0000000000000000000000000000000000000000..2306fef39b41ecaa7ed3405952c278190b050c37
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.c
@@ -0,0 +1,65 @@
+
+#include <stdint.h>
+
+#include "PHY/defs.h"
+#include "PHY/LTE_TRANSPORT/if5_mobipass_tools.h"
+
+#include "targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
+
+
+uint8_t send_IF5(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, uint8_t init_seq) {      
+  
+  uint8_t seqno=init_seq;
+  void *txp[2]; 
+  void *tx_buffer=NULL;
+  __m128i *data_block=NULL,*main_data_block=NULL;
+
+  __m128i *txp128;
+  __m128i t0, t1;
+
+  uint16_t packet_id=0, i;
+  uint16_t db_fulllength = 640;
+
+  tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
+  IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)(tx_buffer + MAC_HEADER_SIZE_BYTES);
+  data_block = (__m128i *)(tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + 4);
+  main_data_block = data_block;
+  
+  header->flags = 0;
+  header->fifo_status = 0;  
+  header->ack = 0;
+  header->seqno = seqno;
+  header->rsvd = 0;  
+
+  txp[0] = (void*)&eNB->common_vars.txdata[0][0][proc->subframe_tx*eNB->frame_parms.samples_per_tti];
+  txp128 = (__m128i *) txp[0];
+    		    
+  for (packet_id=0; packet_id<(7680*2)/640; packet_id++) {
+    header->time_stamp = proc->timestamp_tx + packet_id*640; 
+    data_block = main_data_block; 
+
+    for (i=0; i<db_fulllength>>3; i+=2) {
+      t0 = _mm_srli_epi16(*txp128++, 4);
+      t1 = _mm_srli_epi16(*txp128++, 4);   
+      
+      *data_block++ = _mm_packs_epi16(t0, t1);     
+    }
+    
+    // Write the packet to the fronthaul
+    if ((eNB->ifdevice.trx_write_func(&eNB->ifdevice,
+                                      packet_id,
+                                      &tx_buffer,
+                                      db_fulllength,
+                                      1,
+                                      IF5_MOBIPASS)) < 0) {
+      perror("ETHERNET write for IF5_MOBIPASS\n");
+    }
+
+    header->seqno += 1;    
+  }
+  
+  seqno = header->seqno;
+  free(tx_buffer);
+  return(seqno);  		    
+}
+
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.h b/openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.h
new file mode 100644
index 0000000000000000000000000000000000000000..307742dc1e25d872b72cf76e811a7cecd5351370
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.h
@@ -0,0 +1,26 @@
+
+#include <stdint.h>
+#include "PHY/defs.h"
+
+#define IF5_MOBIPASS 0x0050
+
+struct IF5_mobipass_header {  
+  /// Type
+  uint16_t flags; 
+  /// Sub-Type
+  uint16_t fifo_status;
+  /// Reserved
+  uint8_t seqno;
+  
+  uint8_t ack;
+
+  uint32_t rsvd;
+  /// Frame Status
+  uint32_t time_stamp;
+
+} __attribute__ ((__packed__));
+
+typedef struct IF5_mobipass_header IF5_mobipass_header_t;
+#define sizeof_IF5_mobipass_header_t 14
+
+uint8_t send_IF5(PHY_VARS_eNB*, eNB_rxtx_proc_t*, uint8_t);
diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
index 673b7a43485f3b1383258c65134605977cf51620..bec0c424ed455e8d4ace6834cd00c30616d0e597 100644
--- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
@@ -239,20 +239,25 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
       break;
     }
 
-    ue->frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
-    ue->frame_rx += frame_mod4;
+    ue->proc.proc_rxtx[0].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
+    ue->proc.proc_rxtx[0].frame_rx += frame_mod4;
+
+    ue->proc.proc_rxtx[1].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
+    ue->proc.proc_rxtx[1].frame_rx += frame_mod4;
 
 #ifndef USER_MODE
     // one frame delay
-    ue->frame_rx ++;
+    ue->proc.proc_rxtx[0].frame_rx ++;
+    ue->proc.proc_rxtx[1].frame_rx ++;
 #endif
-    ue->frame_tx = ue->frame_rx;
+    ue->proc.proc_rxtx[0].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
+    ue->proc.proc_rxtx[1].frame_tx = ue->proc.proc_rxtx[1].frame_rx;
 #ifdef DEBUG_INITIAL_SYNCH
     LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully mode1_flag %d, tx_ant %d, frame %d, N_RB_DL %d, phich_duration %d, phich_resource %s!\n",
           ue->Mod_id,
           frame_parms->mode1_flag,
           pbch_tx_ant,
-          ue->frame_rx,
+          ue->proc.proc_rxtx[0].frame_rx,
           frame_parms->N_RB_DL,
           frame_parms->phich_config_common.phich_duration,
           phich_resource);  //frame_parms->phich_config_common.phich_resource);
@@ -467,15 +472,15 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 
   if (ret==0) {  // PBCH found so indicate sync to higher layers and configure frame parameters
 
-#ifdef DEBUG_INITIAL_SYNCH
+    //#ifdef DEBUG_INITIAL_SYNCH
     LOG_I(PHY,"[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
-#endif
+    //#endif
 
     if (ue->UE_scan_carrier == 0) {
       if (ue->mac_enabled==1) {
 	LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
 	//mac_resynch();
-	mac_xface->dl_phy_sync_success(ue->Mod_id,ue->frame_rx,0,1);//ue->common_vars.eNb_id);
+	mac_xface->dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id);
 	ue->UE_mode[0] = PRACH;
       }
       else {
@@ -491,7 +496,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
     }
 
     LOG_I(PHY,"[UE %d] Frame %d RRC Measurements => rssi %3.1f dBm (dig %3.1f dB, gain %d), N0 %d dBm,  rsrp %3.1f dBm/RE, rsrq %3.1f dB\n",ue->Mod_id,
-	  ue->frame_rx,
+	  ue->proc.proc_rxtx[0].frame_rx,
 	  10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
 	  10*log10(ue->measurements.rssi),
 	  ue->rx_total_gain_dB,
@@ -502,7 +507,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
     
     LOG_I(PHY,"[UE %d] Frame %d MIB Information => %s, %s, NidCell %d, N_RB_DL %d, PHICH DURATION %d, PHICH RESOURCE %s, TX_ANT %d\n",
 	  ue->Mod_id,
-	  ue->frame_rx,
+	  ue->proc.proc_rxtx[0].frame_rx,
 	  duplex_string[ue->frame_parms.frame_type],
 	  prefix_string[ue->frame_parms.Ncp],
 	  ue->frame_parms.Nid_cell,
@@ -513,7 +518,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 
     LOG_I(PHY,"[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
 	  ue->Mod_id,
-	  ue->frame_rx,
+	  ue->proc.proc_rxtx[0].frame_rx,
 	  openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
 	  ue->common_vars.freq_offset);
 
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index 0d0d5832cb842297a79e1629b4295aad69c2f090..e0aa5d3ee06a79ad2df523f4dc87c9e974b52654 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -1055,6 +1055,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms,
 
 
 void rx_phich(PHY_VARS_UE *ue,
+	      UE_rxtx_proc_t *proc,
               uint8_t subframe,
               uint8_t eNB_id)
 {
@@ -1064,7 +1065,7 @@ void rx_phich(PHY_VARS_UE *ue,
   LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars;
 
   //  uint8_t HI;
-  uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,ue->frame_rx,subframe);
+  uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,proc->frame_rx,subframe);
   LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id];
   int16_t phich_d[24],*phich_d_ptr,HI16;
   //  unsigned int i,aa;
@@ -1082,10 +1083,13 @@ void rx_phich(PHY_VARS_UE *ue,
   uint8_t pusch_subframe;
 
   // check if we're expecting a PHICH in this subframe
-  LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX\n",ue->Mod_id,harq_pid,ue->frame_rx,subframe);
+  LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe);
+
+  if (!ulsch)
+    return;
 
   if (ulsch->harq_processes[harq_pid]->status == ACTIVE) {
-    LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX ACTIVE\n",ue->Mod_id,harq_pid,ue->frame_rx,subframe);
+    LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH RX ACTIVE\n",ue->Mod_id,harq_pid,proc->frame_rx,subframe);
     Ngroup_PHICH = (frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)/48;
 
     if (((frame_parms->phich_config_common.phich_resource*frame_parms->N_RB_DL)%48) > 0)
@@ -1349,14 +1353,14 @@ void rx_phich(PHY_VARS_UE *ue,
     if (ue->ulsch_Msg3_active[eNB_id] == 1) {
       LOG_D(PHY,"[UE  %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received NAK (%d) nseq %d, ngroup %d\n",
             ue->Mod_id,harq_pid,
-            ue->frame_rx,
+            proc->frame_rx,
             subframe,
             HI16,
             nseq_PHICH,
             ngroup_PHICH);
       get_Msg3_alloc_ret(&ue->frame_parms,
                          subframe,
-                         ue->frame_rx,
+                         proc->frame_rx,
                          &ue->ulsch_Msg3_frame[eNB_id],
                          &ue->ulsch_Msg3_subframe[eNB_id]);
       ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
@@ -1374,7 +1378,7 @@ void rx_phich(PHY_VARS_UE *ue,
       //#ifdef DEBUG_PHICH
       LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d\n",
             ue->Mod_id,harq_pid,
-            ue->frame_rx,
+            proc->frame_rx,
             subframe,
             HI16,
             nseq_PHICH,
@@ -1394,7 +1398,7 @@ void rx_phich(PHY_VARS_UE *ue,
     if (ue->ulsch_Msg3_active[eNB_id] == 1) {
       LOG_D(PHY,"[UE  %d][PUSCH %d][RAPROC] Frame %d subframe %d Msg3 PHICH, received ACK (%d) nseq %d, ngroup %d\n\n",
             ue->Mod_id,harq_pid,
-            ue->frame_rx,
+            proc->frame_rx,
             subframe,
             HI16,
             nseq_PHICH,ngroup_PHICH);
@@ -1402,7 +1406,7 @@ void rx_phich(PHY_VARS_UE *ue,
       //#ifdef PHICH_DEBUG
       LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n",
             ue->Mod_id,harq_pid,
-            ue->frame_rx,
+            proc->frame_rx,
             subframe, HI16,
             nseq_PHICH,ngroup_PHICH);
       //#endif
diff --git a/openair1/PHY/LTE_TRANSPORT/print_stats.c b/openair1/PHY/LTE_TRANSPORT/print_stats.c
index a175f4cb8e1530edbe9e3127e4c9054fef4d53f2..1653d0e5494c3d7dbf38d7ec0f7bca33d60d51b6 100644
--- a/openair1/PHY/LTE_TRANSPORT/print_stats.c
+++ b/openair1/PHY/LTE_TRANSPORT/print_stats.c
@@ -55,7 +55,7 @@ extern int mac_get_rrc_status(uint8_t Mod_id,uint8_t eNB_flag,uint8_t index);
 extern openair0_config_t openair0_cfg[];
 #endif
 
-int dump_ue_stats(PHY_VARS_UE *ue, char* buffer, int length, runmode_t mode, int input_level_dBm)
+int dump_ue_stats(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,char* buffer, int length, runmode_t mode, int input_level_dBm)
 {
 
   uint8_t eNB=0;
@@ -78,7 +78,7 @@ int dump_ue_stats(PHY_VARS_UE *ue, char* buffer, int length, runmode_t mode, int
     /*
     len += sprintf(&buffer[len],
                    "[UE PROC] Frame count: %d\neNB0 RSSI %d dBm/RE (%d dB, %d dB)\neNB1 RSSI %d dBm/RE (%d dB, %d dB)neNB2 RSSI %d dBm/RE (%d dB, %d dB)\nN0 %d dBm/RE, %f dBm/%dPRB (%d dB, %d dB)\n",
-                   ue->frame_rx,
+                   proc->frame_rx,
                    ue->measurements.rx_rssi_dBm[0],
                    ue->measurements.rx_power_dB[0][0],
                    ue->measurements.rx_power_dB[0][1],
@@ -535,7 +535,7 @@ int dump_ue_stats(PHY_VARS_UE *ue, char* buffer, int length, runmode_t mode, int
 
   } else {
     len += sprintf(&buffer[len], "[UE PROC] Frame count: %d, RSSI %3.2f dB (%d dB, %d dB), N0 %3.2f dB (%d dB, %d dB)\n",
-                   ue->frame_rx,
+                   proc->frame_rx,
                    10*log10(ue->measurements.rssi),
                    ue->measurements.rx_power_dB[0][0],
                    ue->measurements.rx_power_dB[0][1],
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index 0afa2936bb42964a0e54e492528a3fe67bd8b2f5..547dd86a9c8fc657f5773c1c3f61cc44fc648e97 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -1328,6 +1328,7 @@ int32_t generate_srs_tx(PHY_VARS_UE *phy_vars_ue,
 */
 
 int32_t generate_drs_pusch(PHY_VARS_UE *phy_vars_ue,
+			   UE_rxtx_proc_t *proc,
                            uint8_t eNB_id,
                            int16_t amp,
                            uint32_t subframe,
@@ -1398,7 +1399,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
                                       uint8_t subframe,
                                       DCI_format_t dci_format,
                                       PHY_VARS_UE *phy_vars_ue,
-                                      uint16_t si_rnti,
+                                      UE_rxtx_proc_t *proc,
+				      uint16_t si_rnti,
                                       uint16_t ra_rnti,
                                       uint16_t p_rnti,
                                       uint16_t cba_rnti,
@@ -1406,7 +1408,8 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
                                       uint8_t use_srs);
 
 int32_t generate_ue_ulsch_params_from_rar(PHY_VARS_UE *phy_vars_ue,
-    uint8_t eNB_id);
+					  UE_rxtx_proc_t *proc,
+					  uint8_t eNB_id);
 double sinr_eff_cqi_calc(PHY_VARS_UE *phy_vars_ue,
                          uint8_t eNB_id);
 int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
@@ -1424,16 +1427,13 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
 
 void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id);
 
-void dump_dlsch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid);
-void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
-void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
 
-void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round);
+
 
 
 int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci);
 
-int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, char* buffer, int length, runmode_t mode, int input_level_dBm);
+int dump_ue_stats(PHY_VARS_UE *phy_vars_ue, UE_rxtx_proc_t *proc, char* buffer, int length, runmode_t mode, int input_level_dBm);
 int dump_eNB_stats(PHY_VARS_eNB *phy_vars_eNB, char* buffer, int length);
 
 
@@ -1550,11 +1550,13 @@ void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
 
 /* \brief  This routine demodulates the PHICH and updates PUSCH/ULSCH parameters.
    @param phy_vars_ue Pointer to UE variables
+   @param proc Pointer to RXN_TXNp4 proc
    @param subframe Subframe of received PDCCH/PHICH
    @param eNB_id Index of eNB
 */
 
 void rx_phich(PHY_VARS_UE *phy_vars_ue,
+	      UE_rxtx_proc_t *proc,
               uint8_t subframe,
               uint8_t eNB_id);
 
@@ -1653,11 +1655,12 @@ void generate_pucch(int32_t **txdataF,
                     uint8_t subframe);
 
 void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue,
+			 UE_rxtx_proc_t *proc,
                          PUCCH_FMT_t format,
                          uint8_t ncs1,
                          uint8_t *pucch_ack_payload,
-                         uint8_t sr,
-                         uint8_t subframe);
+                         uint8_t sr);
+
 
 
 uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index e2876f95e36e3dd1280171284c748ba2aa78ddb0..cb7803fbfcef247a3699a3df91c62e6a650fdabb 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -403,13 +403,16 @@ void generate_pucch(int32_t **txdataF,
 }
 
 void generate_pucch_emul(PHY_VARS_UE *ue,
+			 UE_rxtx_proc_t *proc,
                          PUCCH_FMT_t format,
                          uint8_t ncs1,
                          uint8_t *pucch_payload,
-                         uint8_t sr,
-                         uint8_t subframe)
+                         uint8_t sr)
+
 {
 
+  int subframe = proc->subframe_tx;
+
   UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_flag    = format;
   UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_Ncs1    = ncs1;
 
@@ -428,7 +431,7 @@ void generate_pucch_emul(PHY_VARS_UE *ue,
     ue->pucch_payload[0] = pucch_payload[0] + (pucch_payload[1]<<1);
     UE_transport_info[ue->Mod_id][ue->CC_id].cntl.pucch_payload = pucch_payload[0] + (pucch_payload[1]<<1);
   } else if (format == pucch_format1) {
-    LOG_D(PHY,"[UE %d] Frame %d subframe %d Generating PUCCH for SR %d\n",ue->Mod_id,ue->frame_tx,subframe,sr);
+    LOG_D(PHY,"[UE %d] Frame %d subframe %d Generating PUCCH for SR %d\n",ue->Mod_id,proc->frame_tx,subframe,sr);
   }
 
   ue->sr[subframe] = sr;
diff --git a/openair1/PHY/LTE_TRANSPORT/rar_tools.c b/openair1/PHY/LTE_TRANSPORT/rar_tools.c
index dbac1e22809ef6b049e29d59b8b1b6512054e4f8..0cdabe9b9d0e15a99c287cf3d33a904182760ac2 100644
--- a/openair1/PHY/LTE_TRANSPORT/rar_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/rar_tools.c
@@ -175,6 +175,7 @@ int generate_eNB_ulsch_params_from_rar(unsigned char *rar_pdu,
 int8_t delta_PUSCH_msg2[8] = {-6,-4,-2,0,2,4,6,8};
 
 int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue,
+				      UE_rxtx_proc_t *proc,
                                       unsigned char eNB_id )
 {
 
@@ -189,13 +190,13 @@ int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue,
   //  int current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id];
 
   uint8_t *rar = (uint8_t *)(rar_pdu+1);
-  uint8_t harq_pid = subframe2harq_pid(frame_parms,ue->frame_tx,subframe);
+  uint8_t harq_pid = subframe2harq_pid(frame_parms,proc->frame_tx,subframe);
   uint16_t rballoc;
   uint8_t cqireq;
   uint16_t *RIV2nb_rb_LUT, *RIV2first_rb_LUT;
   uint16_t RIV_max = 0;
 
-  LOG_D(PHY,"[eNB][RAPROC] Frame %d: generate_ue_ulsch_params_from_rar: subframe %d (harq_pid %d)\n",ue->frame_tx,subframe,harq_pid);
+  LOG_D(PHY,"[eNB][RAPROC] Frame %d: generate_ue_ulsch_params_from_rar: subframe %d (harq_pid %d)\n",proc->frame_tx,subframe,harq_pid);
 
   switch (frame_parms->N_RB_DL) {
   case 6:
@@ -272,7 +273,7 @@ int generate_ue_ulsch_params_from_rar(PHY_VARS_UE *ue,
     ulsch->uci_format = HLC_subband_cqi_nopmi;
     fill_CQI(ulsch,meas,eNB_id,0,ue->frame_parms.N_RB_DL,0, transmission_mode,ue->sinr_eff);
 
-    if (((ue->frame_tx % 100) == 0) || (ue->frame_tx < 10))
+    if (((proc->frame_tx % 100) == 0) || (proc->frame_tx < 10))
       print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL);
   } else {
     ulsch->O_RI                                = 0;
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index eb2296077a04c396dfbec5a71d0312bef485f21d..2cc1c337e72dc1b20867560ac07096da1b8656c3 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -119,7 +119,7 @@ int slot_fep(PHY_VARS_UE *ue,
 
 #ifdef DEBUG_FEP
     //  if (ue->frame <100)
-    printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d\n", ue->frame_rx,Ns, symbol,
+    printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
         nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset);
 #endif
 
@@ -150,7 +150,7 @@ int slot_fep(PHY_VARS_UE *ue,
 
 #ifdef DEBUG_FEP
       //  if (ue->frame <100)
-      printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d\n", ue->frame_rx,Ns, symbol,
+      printf("slot_fep: frame %d: slot %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d\n", ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx,Ns, symbol,
           nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset);
 #endif
 
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index 8af3fcf8d18acf6f7d45b2ee4f35e60abda81a3b..f3e5e7177562b2da266471c760725a277c0119c9 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -509,7 +509,7 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   float **chest_t_abs;
   float time[FRAME_LENGTH_COMPLEX_SAMPLES];
   float freq[nsymb_ce*nb_antennas_rx*nb_antennas_tx];
-  int frame = phy_vars_ue->frame_rx;
+  int frame = phy_vars_ue->proc.proc_rxtx[0].frame_rx;
   uint32_t total_dlsch_bitrate = phy_vars_ue->bitrate[eNB_id];
   int coded_bits_per_codeword = 0;
   int mcs = 0;
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 5805076611e5441f8e39649d155444b10490b95d..70a661adf0c67d636c81b418c6e79586362eb45b 100755
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -159,6 +159,7 @@ enum transmission_access_mode {
 
 typedef enum  {
   eNodeB_3GPP=0,  // classical eNodeB function
+  eNodeB_3GPP_BBU, // eNodeB with NGFI IF5
   NGFI_RRU_IF4,   // NGFI_RRU (NGFI remote radio-unit, currently split at common - ue_specific interface, IF4) 
   NGFI_RCC_IF4    // NGFI_RCC (NGFI radio cloud center, currently split at common - ue_specific interface, IF4) 
 } eNB_func_t;
@@ -540,34 +541,8 @@ typedef struct {
   int UE_scan_carrier;
   /// \brief Indicator that UE is synchronized to an eNB
   int is_synchronized;
-  /// \brief Instance count of TX processing thread (-1 means ready, 0 means busy)
-  int instance_cnt_tx;
-  /// \brief Instance count of RX processing thread (-1 means ready, 0 means busy)
-  int instance_cnt_rx;
-  /// \brief Instance count of initial synchronization thread (-1 means ready, 0 means busy).
-  /// Protected by mutex \ref mutex_synch and condition \ref cond_synch.
-  int instance_cnt_synch;
-  /// \brief Condition variable for TX processing thread
-  pthread_cond_t cond_tx;
-  /// \brief Condition variable for RX processing thread
-  pthread_cond_t cond_rx;
-  /// \brief Condition variable for initial synchronization thread.
-  /// The corresponding mutex is \ref mutex_synch.
-  pthread_cond_t cond_synch;
-  /// \brief Mutex for TX processing thread
-  pthread_mutex_t mutex_tx;
-  /// \brief Mutex for RX processing thread
-  pthread_mutex_t mutex_rx;
-  /// \brief Mutex for initial synchronization thread.
-  /// Used to protect \ref instance_cnt_synch.
-  /// \sa cond_synch
-  pthread_mutex_t mutex_synch;
-  /// \brief Pthread structure for RX processing thread
-  pthread_t       thread_rx;
-  /// \brief Pthread structure for TX processing thread
-  pthread_t       thread_tx;
-  /// \brief Pthread structure to RX processing thread
-  pthread_t       thread_synch;
+  /// Data structure for UE process scheduling
+  UE_proc_t proc;
   /// \brief Total gain of the TX chain (16-bit baseband I/Q to antenna)
   uint32_t tx_total_gain_dB;
   /// \brief Total gain of the RX chain (antenna to baseband I/Q) This is a function of rx_gain_mode (and the corresponding gain) and the rx_gain of the card.
@@ -584,10 +559,6 @@ typedef struct {
   int tx_total_RE;
   /// \brief Maximum transmit power
   int8_t tx_power_max_dBm;
-  /// \brief Frame counters for TX and RX processing
-  uint32_t frame_rx,frame_tx;
-  /// \brief Slot counters for TX and RX processing
-  uint32_t slot_tx,slot_rx;
   /// \brief Number of eNB seen by UE
   uint8_t n_connected_eNB;
   /// \brief indicator that Handover procedure has been initiated
@@ -636,10 +607,14 @@ typedef struct {
   uint32_t high_speed_flag;
   uint32_t perfect_ce;
   int16_t ch_est_alpha;
+  int generate_ul_signal[NUMBER_OF_CONNECTED_eNB_MAX];
+
   UE_SCAN_INFO_t scan_info[NB_BANDS_MAX];
 
   char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX];
 
+
+
   unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX];
   uint32_t  ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX];
   unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX];
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index 62e0a7d9ced063dd6c4fd0cc6331343630f0738c..9f0b37ca3038ff9fe303d9ba1f42ae0e3f764231 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -72,12 +72,7 @@ enum openair_ERROR {
 
 enum openair_SYNCH_STATUS {
   openair_NOT_SYNCHED=1,
-#ifdef OPENAIR_LTE
   openair_SYNCHED,
-#else
-  openair_SYNCHED_TO_CHSCH,
-  openair_SYNCHED_TO_MRSCH,
-#endif
   openair_SCHED_EXIT
 };
 
@@ -86,65 +81,6 @@ enum openair_SYNCH_STATUS {
 #define DAQ_AGC_OFF 0
 
 
-/*
-typedef struct {
-  boolean_t  is_eNB;
-  uint8_t    mode;
-  uint8_t    synch_source;
-  uint32_t   slot_count;
-  uint32_t   sched_cnt;
-  uint32_t   synch_wait_cnt;
-  uint32_t   sync_state;
-  uint32_t   scheduler_interval_ns;
-  uint32_t   last_adac_cnt;
-  uint8_t    first_sync_call;
-  int32_t    instance_cnt;
-  uint8_t    one_shot_get_frame;
-  uint8_t    do_synch;
-  uint8_t    node_configured;  // &1..basic config, &3..ue config &5..eNb config
-  uint8_t    node_running;
-  uint8_t    tx_test;
-  uint8_t    mac_registered;
-  //uint8_t freq;
-  uint32_t   freq;
-  uint32_t   rx_gain_val;
-  uint32_t   rx_gain_mode;
-  uint32_t   tcxo_dac;
-  uint32_t   auto_freq_correction;
-  int32_t    freq_offset;
-  uint32_t   tx_rx_switch_point;
-  uint32_t   manual_timing_advance;  /// 1 to override automatic timing advance
-  int32_t   timing_advance;
-  uint32_t   dual_tx;                /// 1 for dual-antenna TX, 0 for single-antenna TX
-  uint32_t   tdd;                    /// 1 for TDD mode, 0 for FDD mode
-  uint32_t   rx_rf_mode;
-  uint32_t   node_id;
-  uint32_t   rach_detection_count;
-  uint32_t   channel_vacant[4];
-  uint32_t   target_ue_dl_mcs;
-  uint32_t   target_ue_ul_mcs;
-  uint32_t   ue_ul_nb_rb;
-  uint32_t   ue_dl_rb_alloc;
-  uint32_t   dlsch_rate_adaptation;
-  uint32_t   dlsch_transmission_mode;
-  uint32_t   ulsch_allocation_mode;
-  uint32_t   rx_total_gain_dB;
-  uint32_t   hw_frame;
-  uint32_t   get_frame_done;
-  uint32_t   use_ia_receiver;
-} OPENAIR_DAQ_VARS;
-*/
-
-#ifndef USER_MODE
-int32_t openair_sched_init(void);
-void openair_sched_cleanup(void);
-void openair_sched_exit(char *);
-void openair1_restart(void);
-int32_t init_dlsch_threads(void);
-void cleanup_dlsch_threads(void);
-#endif //USER_MODE
-
-#ifdef OPENAIR_LTE
 /** @addtogroup _PHY_PROCEDURES_
  * @{
  */
@@ -168,7 +104,7 @@ void phy_procedures_eNB_lte(uint8_t subframe,PHY_VARS_eNB **phy_vars_eNB,uint8_t
   @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
   @param *phy_vars_rn pointer to RN variables
 */
-void phy_procedures_UE_lte(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
+void phy_procedures_UE_lte(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
 
 #ifdef Rel10
 /*! \brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs.
@@ -187,22 +123,24 @@ int phy_procedures_RN_UE_RX(unsigned char last_slot, unsigned char next_slot, re
 
 /*! \brief Scheduling for UE TX procedures in normal subframes.
   @param phy_vars_ue Pointer to UE variables on which to act
+  @param proc Pointer to RXn-TXnp4 proc information
   @param eNB_id Local id of eNB on which to act
   @param abstraction_flag Indicator of PHY abstraction
   @param mode calib/normal mode
   @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
 */
-void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type);
+void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type);
 /*! \brief Scheduling for UE RX procedures in normal subframes.
   @param last_slot Index of last slot (0-19)
   @param phy_vars_ue Pointer to UE variables on which to act
+  @param proc Pointer to RXn_TXnp4 proc information
   @param eNB_id Local id of eNB on which to act
   @param abstraction_flag Indicator of PHY abstraction
   @param mode calibration/debug mode
   @param r_type indicates the relaying operation: 0: no_relaying, 1: unicast relaying type 1, 2: unicast relaying type 2, 3: multicast relaying
   @param phy_vars_rn pointer to RN variables
 */
-int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
+int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
 
 /*! \brief Scheduling for UE TX procedures in TDD S-subframes.
   @param phy_vars_ue Pointer to UE variables on which to act
@@ -385,11 +323,11 @@ uint8_t ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subfram
 
 /*! \brief Indicates the SR TXOp in current subframe.  Implements Table 10.1-5 from 36.213.
   @param phy_vars_ue Pointer to UE variables
+  @param proc Pointer to RXn_TXnp4 thread context
   @param eNB_id ID of eNB which is to receive the SR
-  @param subframe index of next subframe
   @returns 1 if TXOp is active.
 */
-uint8_t is_SR_TXOp(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
+uint8_t is_SR_TXOp(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id);
 
 /*! \brief Indicates the SR TXOp in current subframe for eNB and particular UE index.  Implements Table 10.1-5 from 36.213.
   @param phy_vars_eNB Pointer to eNB variables
@@ -426,7 +364,7 @@ int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
 int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rnti);
 
 void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance);
-void process_timing_advance_rar(PHY_VARS_UE *phy_vars_ue,uint16_t timing_advance);
+void process_timing_advance_rar(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint16_t timing_advance);
 
 unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb);
 
@@ -436,15 +374,15 @@ void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
 subframe n-4 which is acknowledged in subframe n (for FDD) according to n1_pucch = Ncce + N1_pucch.  For
 TDD, this routine computes the complex procedure described in Section 10.1 of 36.213 (through tables 10.1-1,10.1-2)
 @param phy_vars_ue Pointer to UE variables
+@param proc Pointer to RXn-TXnp4 proc information
 @param eNB_id Index of eNB
-@param subframe subframe on which to act
 @param b Pointer to PUCCH payload (b[0],b[1])
 @param SR 1 means there's a positive SR in parallel to ACK/NAK
 @returns n1_pucch
 */
 uint16_t get_n1_pucch(PHY_VARS_UE *phy_vars_ue,
+		      UE_rxtx_proc_t *proc,
                       uint8_t eNB_id,
-		      uint8_t subframe,
                       uint8_t *b,
                       uint8_t SR);
 
@@ -497,21 +435,21 @@ UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
 
 /*! \brief This function implements the power control mechanism for PUCCH from 36.213.
     @param phy_vars_ue PHY variables
-    @param subframe Index of subframe
+    @param proc Pointer to proc descriptor
     @param eNB_id Index of eNB
     @param pucch_fmt Format of PUCCH that is being transmitted
     @returns Transmit power
  */
-int8_t pucch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt);
+int8_t pucch_power_cntl(PHY_VARS_UE *phy_vars_ue, UE_rxtx_proc_t *proc,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt);
 
 /*! \brief This function implements the power control mechanism for PUCCH from 36.213.
     @param phy_vars_ue PHY variables
-    @param subframe Index of subframe
+    @param proc Pointer to proc descriptor
     @param eNB_id Index of eNB
     @param j index of type of PUSCH (SPS, Normal, Msg3)
     @returns Transmit power
  */
-void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,uint8_t subframe,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag);
+void pusch_power_cntl(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag);
 
 int8_t get_PHR(uint8_t Mod_id, uint8_t CC_id, uint8_t eNB_index);
 
@@ -543,15 +481,13 @@ int16_t get_target_pucch_rx_power(module_id_t module_idP, uint8_t CC_id);
 
 int get_ue_active_harq_pid(uint8_t Mod_id,uint8_t CC_id,uint16_t rnti,int frame, uint8_t subframe,uint8_t *harq_pid,uint8_t *round,uint8_t ul_flag);
 
-void dump_dlsch(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid);
-void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
-void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t subframe);
+void dump_dlsch(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid);
+void dump_dlsch_SI(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe);
+void dump_dlsch_ra(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe);
+void dump_dlsch2(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,int round);
 
 /*@}*/
 
-#endif //OPENAIR_LTE
-
-extern int slot_irq_handler(int irq, void *cookie);
 
 #endif
 
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index ef7b70d179bd3adbe9231a59a76a7d24d7396fa5..e191a48a561402545c6ce3a222f7d648ff80fe96 100755
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -1249,7 +1249,8 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
   // clear previous allocation information for all UEs
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-    eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
+    if (eNB->dlsch[i][0])
+      eNB->dlsch[i][0]->subframe_tx[subframe] = 0;
   }
 
 
@@ -1326,9 +1327,11 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
   if (abstraction_flag == 0) {
 
-    if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0)
+    if (DCI_pdu->Num_ue_spec_dci+DCI_pdu->Num_common_dci > 0) {
       LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (common %"PRIu8",ue_spec %"PRIu8")\n",eNB->Mod_id,frame, subframe,
             DCI_pdu->Num_common_dci,DCI_pdu->Num_ue_spec_dci);
+    }
+
 
     num_pdcch_symbols = generate_dci_top(DCI_pdu->Num_ue_spec_dci,
                                          DCI_pdu->Num_common_dci,
@@ -1353,7 +1356,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
   // Check for SI activity
 
-  if (eNB->dlsch_SI->active == 1) {
+  if ((eNB->dlsch_SI) && (eNB->dlsch_SI->active == 1)) {
 
     pdsch_procedures(eNB,proc,eNB->dlsch_SI,(LTE_eNB_DLSCH_t*)NULL,(LTE_eNB_UE_stats*)NULL,0,num_pdcch_symbols,abstraction_flag);
 
@@ -1369,7 +1372,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   }
 
   // Check for RA activity
-  if (eNB->dlsch_ra->active == 1) {
+  if ((eNB->dlsch_ra) && (eNB->dlsch_ra->active == 1)) {
 
 #if defined(SMBV) 
 
@@ -2524,11 +2527,7 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
   uint16_t packet_type;
   uint32_t symbol_number=0;
   uint32_t symbol_mask, symbol_mask_full;
-  
-  struct timespec time_req, time_rem;  
-  time_req.tv_sec = 0;
-  time_req.tv_nsec = 300000;
-  
+    
   if (subframe==9) { 
     subframe=0;
     frame++;
@@ -2547,7 +2546,7 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
   if (abstraction_flag==0) { // grab signal in chunks of 500 us (1 slot)
 		
     if ((eNB->node_function == NGFI_RRU_IF4) || 
-	      (eNB->node_function == eNodeB_3GPP)) { // acquisition from RF and front-end processing
+	      (eNB->node_function == eNodeB_3GPP)) { // acquisition from RF
 
 	    for (i=0; i<fp->nb_antennas_rx; i++)
 	      rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti];
@@ -2563,13 +2562,13 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
 
       if (proc->first_rx == 0) {
         if (proc->subframe_rx != subframe){
-	  LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
-	  exit_fun("Exiting");
-	}
+          LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
+          exit_fun("Exiting");
+	      }
         if (proc->frame_rx != frame) {
-	  LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
-	  exit_fun("Exiting");
-	}
+	        LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
+          exit_fun("Exiting");
+	      }
       } else {
         proc->first_rx = 0;
 			}
@@ -2585,6 +2584,16 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
 	
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 );
 
+    } else if(eNB->node_function == eNodeB_3GPP_BBU) { // acquisition from IF
+      /// **** trx_read_func from IF device **** ///
+    
+    }
+
+
+    if ((eNB->node_function == NGFI_RRU_IF4) || 
+        (eNB->node_function == eNodeB_3GPP)  ||
+        (eNB->node_function == eNodeB_3GPP_BBU)) { // front-end processing
+
       // now do common RX processing for first slot in subframe
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,1);
       remove_7_5_kHz(eNB,proc->subframe_rx<<1);
@@ -2608,12 +2617,10 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
     	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_SLOT_FEP,0);
 
       if (eNB->node_function == NGFI_RRU_IF4 && is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)<=0) {
-
-			  /// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
+        /// **** send_IF4 of rxdataF to RCC (no prach now) **** ///
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );   
         send_IF4(eNB, frame, subframe, IF4_PULFFT, 0);
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );   
-        
       }
 
       /// **** send_IF4 of prach to RCC **** /// done in prach thread (below)
@@ -2657,20 +2664,16 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
       symbol_mask = 0;
       symbol_mask_full = (1<<fp->symbols_per_tti)-1;
       prach_rx = 0;
-
-      // Block from loop while testing
-      //symbol_mask = symbol_mask_full;
-      //nanosleep(&time_req, &time_rem);
          
       do {
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );   
-        recv_IF4(eNB, proc->frame_rx, proc->subframe_rx, &packet_type, &symbol_number);
+        recv_IF4(eNB, &proc->frame_rx, &proc->subframe_rx, &packet_type, &symbol_number);
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );   
 
         if (packet_type == IF4_PULFFT) {
           symbol_mask = symbol_mask | (1<<symbol_number);     
                        
-        } else if (is_prach_subframe(fp,frame,subframe)>0 && packet_type == PRACH) {
+        } else if (packet_type == IF4_PRACH) {
           // wake up thread for PRACH RX
           prach_rx = 1;
 
@@ -2703,6 +2706,23 @@ void phy_procedures_eNB_common_RX(PHY_VARS_eNB *eNB,const uint8_t abstraction_fl
 
       } while( (symbol_mask != symbol_mask_full) && (prach_rx == 0));    
 
+      if (proc->first_rx == 0) {
+        if (proc->subframe_rx != subframe){
+          LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,subframe);
+//          exit_fun("Exiting");
+        }
+        if (proc->frame_rx != frame) {
+          LOG_E(PHY,"Received Timestamp doesn't correspond to the time we think it is (proc->frame_rx %d frame %d)\n",proc->frame_rx,frame);
+  //        exit_fun("Exiting");
+        }
+      } else {
+        proc->first_rx = 0;
+      }
+
+      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
+      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB, proc->frame_rx );
+      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_ENB, proc->subframe_rx );
+
       // Tobi aka mr monaco: ETH
 		  
     } else { // should not get here
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index 83d081da3fed1422783013b2290db6a75b3dafdb..4f1cc56f805f7bdadbb748e3f2111accff7f1289 100755
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -25,7 +25,7 @@
 
   Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
 
- *******************************************************************************/
+*******************************************************************************/
 
 /*! \file phy_procedures_lte_ue.c
  * \brief Implementation of UE procedures from 36.213 LTE specifications
@@ -67,9 +67,6 @@ fifo_dump_emos_UE emos_dump_UE;
 
 #if defined(ENABLE_ITTI)
 # include "intertask_interface.h"
-#   if ENABLE_RAL
-#     include "timer.h"
-#   endif
 #endif
 
 
@@ -80,14 +77,7 @@ fifo_dump_emos_UE emos_dump_UE;
 
 extern int oai_exit;
 
-uint8_t ulsch_input_buffer[2700] __attribute__ ((aligned(16)));
-uint8_t access_mode;
 
-DCI_ALLOC_t dci_alloc_rx[8];
-
-#ifdef DIAG_PHY
-extern int rx_sig_fifo;
-#endif
 
 
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
@@ -96,7 +86,7 @@ extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
 
 
 
-void dump_dlsch(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid)
+void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid)
 {
   unsigned int coded_bits_per_codeword;
   uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
@@ -107,7 +97,7 @@ void dump_dlsch(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid
                                   ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm,
                                   ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl,
                                   ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  ue->frame_rx,subframe);
+                                  proc->frame_rx,subframe);
 
   write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
   write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
@@ -125,7 +115,7 @@ void dump_dlsch(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid
   write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[0]->dl_ch_magb0,300*12,1,1);
 }
 
-void dump_dlsch_SI(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
+void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
 {
   unsigned int coded_bits_per_codeword;
   uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
@@ -136,7 +126,7 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
                                   2,
                                   1,
                                   ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  ue->frame_rx,subframe);
+                                  proc->frame_rx,subframe);
   LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         ue->Mod_id,
 	ue->frame_parms.ofdm_symbol_size,
@@ -163,49 +153,50 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
 
   write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1);
   write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1);
+  sleep(1);
   exit(-1);
 }
 
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
 //unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162};
 /*
-unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
-{
+  unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL)
+  {
 
   int gain_dB = power_dBm - power_max_dBm;
   int amp_x_100;
 
   switch (N_RB_UL) {
   case 6:
-    amp_x_100 = AMP;      // PRACH is 6 PRBS so no scale
-    break;
+  amp_x_100 = AMP;      // PRACH is 6 PRBS so no scale
+  break;
   case 15:
-    amp_x_100 = 158*AMP;  // 158 = 100*sqrt(15/6)
-    break;
+  amp_x_100 = 158*AMP;  // 158 = 100*sqrt(15/6)
+  break;
   case 25:
-    amp_x_100 = 204*AMP;  // 204 = 100*sqrt(25/6)
-    break;
+  amp_x_100 = 204*AMP;  // 204 = 100*sqrt(25/6)
+  break;
   case 50:
-    amp_x_100 = 286*AMP;  // 286 = 100*sqrt(50/6)
-    break;
+  amp_x_100 = 286*AMP;  // 286 = 100*sqrt(50/6)
+  break;
   case 75:
-    amp_x_100 = 354*AMP;  // 354 = 100*sqrt(75/6)
-    break;
+  amp_x_100 = 354*AMP;  // 354 = 100*sqrt(75/6)
+  break;
   case 100:
-    amp_x_100 = 408*AMP;  // 408 = 100*sqrt(100/6)
-    break;
+  amp_x_100 = 408*AMP;  // 408 = 100*sqrt(100/6)
+  break;
   default:
-    LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL);
-    mac_xface->macphy_exit("");
-    break;
+  LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL);
+  mac_xface->macphy_exit("");
+  break;
   }
   if (gain_dB < -30) {
-    return(amp_x_100/3162);
+  return(amp_x_100/3162);
   } else if (gain_dB>0)
-    return(amp_x_100);
+  return(amp_x_100);
   else
-    return(amp_x_100/gain_table[-gain_dB]);  // 245 corresponds to the factor sqrt(25/6)
-}
+  return(amp_x_100/gain_table[-gain_dB]);  // 245 corresponds to the factor sqrt(25/6)
+  }
 */
 
 unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
@@ -230,7 +221,7 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb
 
 #endif
 
-void dump_dlsch_ra(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
+void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
 {
   unsigned int coded_bits_per_codeword;
   uint8_t nsymb = ((ue->frame_parms.Ncp == 0) ? 14 : 12);
@@ -241,7 +232,7 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
                                   2,
                                   1,
                                   ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                                  ue->frame_rx,subframe);
+                                  proc->frame_rx,subframe);
   LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n",
         ue->Mod_id,
         ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
@@ -308,7 +299,7 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 
   // if contention resolution fails, go back to PRACH
   PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH;
-  LOG_E(PHY,"[UE %d] Frame %d Random-access procedure fails, going back to PRACH, setting SIStatus = 0 and State RRC_IDLE\n",Mod_id,PHY_vars_UE_g[Mod_id][CC_id]->frame_rx);
+  LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0 and State RRC_IDLE\n",Mod_id);
   //mac_xface->macphy_exit("");
 }
 
@@ -317,7 +308,7 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 
   int i;
 
-  LOG_I(PHY,"[UE %d][RAPROC] Frame %d Random-access procedure succeeded\n",Mod_id,PHY_vars_UE_g[Mod_id][CC_id]->frame_rx);
+  LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded\n",Mod_id);
 
   PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0;
   PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH;
@@ -338,19 +329,13 @@ UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
   return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
 
 }
-void process_timing_advance_rar(PHY_VARS_UE *ue,uint16_t timing_advance)
-{
-
-  /*
-  if ((timing_advance>>10) & 1) //it is negative
-    timing_advance = timing_advance - (1<<11);
-  */
+void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t timing_advance) {
 
   ue->timing_advance = timing_advance*4;
 
 
 #ifdef DEBUG_PHY_PROC
-  LOG_I(PHY,"[UE %d] Frame %d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,ue->frame_rx, ue->timing_advance);
+  LOG_I(PHY,"[UE %d] Frame %d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, ue->timing_advance);
 #endif
 
 }
@@ -371,11 +356,13 @@ void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
 
 }
 
-uint8_t is_SR_TXOp(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
+uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id)
 {
 
+  int subframe=proc->subframe_tx;
+
   LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n",
-        ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,ue->frame_tx,subframe,
+        ue->Mod_id,ue->pdcch_vars[eNB_id]->crnti,proc->frame_tx,subframe,
         ue->scheduling_request_config[eNB_id].sr_ConfigIndex);
 
   if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
@@ -385,13 +372,13 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
     if (subframe==(ue->scheduling_request_config[eNB_id].sr_ConfigIndex-5))
       return(1);
   } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 34) { // 20 ms SR period
-    if ((10*(ue->frame_tx&1)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-15))
+    if ((10*(proc->frame_tx&1)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-15))
       return(1);
   } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 74) { // 40 ms SR period
-    if ((10*(ue->frame_tx&3)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-35))
+    if ((10*(proc->frame_tx&3)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-35))
       return(1);
   } else if (ue->scheduling_request_config[eNB_id].sr_ConfigIndex <= 154) { // 80 ms SR period
-    if ((10*(ue->frame_tx&7)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-75))
+    if ((10*(proc->frame_tx&7)+subframe) == (ue->scheduling_request_config[eNB_id].sr_ConfigIndex-75))
       return(1);
   }
 
@@ -399,8 +386,8 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe)
 }
 
 uint16_t get_n1_pucch(PHY_VARS_UE *ue,
+		      UE_rxtx_proc_t *proc,
                       uint8_t eNB_id,
-                      uint8_t subframe,
                       uint8_t *b,
                       uint8_t SR)
 {
@@ -413,6 +400,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
   int sf;
   int M;
   // clear this, important for case where n1_pucch selection is not used
+  int subframe=proc->subframe_tx;
 
   ue->pucch_sel[subframe] = 0;
 
@@ -430,10 +418,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 #ifdef DEBUG_PHY_PROC
 
     if (bundling_flag==bundling) {
-      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,ue->frame_tx,subframe,SR,
+      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
             ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
     } else {
-      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,ue->frame_tx,subframe,SR,
+      LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR,
             ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
     }
 
@@ -458,7 +446,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
         subframe_offset = 4;
       } else {
         LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal subframe %d for tdd_config %d\n",
-              ue->Mod_id,ue->frame_tx,subframe,frame_parms->tdd_config);
+              ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config);
         return(0);
       }
 
@@ -568,858 +556,852 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
     }  // switch tdd_config
   }
 
-  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n",ue->frame_tx);
+  LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, exit without proper return\n",proc->frame_tx);
   return(-1);
 }
 
 
 #ifdef EMOS
 /*
-void phy_procedures_emos_UE_TX(uint8_t next_slot,uint8_t eNB_id) {
+  void phy_procedures_emos_UE_TX(uint8_t next_slot,uint8_t eNB_id) {
   uint8_t harq_pid;
 
 
   if (next_slot%2==0) {
-    // get harq_pid from subframe relationship
-    harq_pid = subframe2harq_pid(&ue->frame_parms,ue->frame,(next_slot>>1));
-    if (harq_pid==255) {
-      LOG_E(PHY,"[UE%d] Frame %d : FATAL ERROR: illegal harq_pid, returning\n",
-    0,ue->frame);
-      return;
-    }
+  // get harq_pid from subframe relationship
+  harq_pid = subframe2harq_pid(&ue->frame_parms,ue->frame,(next_slot>>1));
+  if (harq_pid==255) {
+  LOG_E(PHY,"[UE%d] Frame %d : FATAL ERROR: illegal harq_pid, returning\n",
+  0,ue->frame);
+  return;
+  }
 
-    if (ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
-      emos_dump_UE.uci_cnt[next_slot>>1] = 1;
-      memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o,ulsch[eNB_id]->o,MAX_CQI_BITS*sizeof(char));
-      emos_dump_UE.UCI_data[0][next_slot>>1].O = ulsch[eNB_id]->O;
-      memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_RI,ulsch[eNB_id]->o_RI,2*sizeof(char));
-      emos_dump_UE.UCI_data[0][next_slot>>1].O_RI = ulsch[eNB_id]->O_RI;
-      memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_ACK,ulsch[eNB_id]->o_ACK,4*sizeof(char));
-      emos_dump_UE.UCI_data[0][next_slot>>1].O_ACK = ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK;
-    }
-    else {
-      emos_dump_UE.uci_cnt[next_slot>>1] = 0;
-    }
+  if (ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
+  emos_dump_UE.uci_cnt[next_slot>>1] = 1;
+  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o,ulsch[eNB_id]->o,MAX_CQI_BITS*sizeof(char));
+  emos_dump_UE.UCI_data[0][next_slot>>1].O = ulsch[eNB_id]->O;
+  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_RI,ulsch[eNB_id]->o_RI,2*sizeof(char));
+  emos_dump_UE.UCI_data[0][next_slot>>1].O_RI = ulsch[eNB_id]->O_RI;
+  memcpy(emos_dump_UE.UCI_data[0][next_slot>>1].o_ACK,ulsch[eNB_id]->o_ACK,4*sizeof(char));
+  emos_dump_UE.UCI_data[0][next_slot>>1].O_ACK = ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK;
+  }
+  else {
+  emos_dump_UE.uci_cnt[next_slot>>1] = 0;
+  }
+  }
   }
-}
 */
 #endif
 
-int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
-PRACH_RESOURCES_t prach_resources_local;
-
-void phy_procedures_UE_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type)
-{
+void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc) {
 
-  int i;
-  uint16_t first_rb, nb_rb;
-  uint8_t harq_pid;
-  unsigned int input_buffer_length;
-  unsigned int aa;
-  uint8_t Msg3_flag=0;
-  uint8_t pucch_ack_payload[2];
-  uint8_t n1_pucch;
-  ANFBmode_t bundling_flag;
-  PUCCH_FMT_t format;
-  uint8_t SR_payload;
-  int32_t prach_power;
-  uint8_t nsymb;
+  int aa;
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-  uint8_t generate_ul_signal = 0;
-  uint8_t ack_status=0;
-  int8_t Po_PUCCH;
-  int32_t ulsch_start=0;
+
+  int nsymb;
+  int subframe_tx = proc->subframe_tx;
+  int frame_tx = proc->frame_tx;
+  int ulsch_start;
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
   int overflow=0;
   int k,l;
+  int dummy_tx_buffer[3840*4] __attribute__((aligned(16)));
 #endif
-  int slot_tx = ue->slot_tx;
-  int subframe_tx = ue->slot_tx>>1;
-  int frame_tx = ue->frame_tx;
-  int Mod_id = ue->Mod_id;
-  int CC_id = ue->CC_id;
-  int tx_amp;
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
-
-  start_meas(&ue->phy_proc_tx);
 
-#ifdef EMOS
-  //phy_procedures_emos_UE_TX(next_slot);
+  start_meas(&ue->ofdm_mod_stats);
+  nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
+  
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
+  ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
+		 ue->hw_timing_advance-
+		 ue->timing_advance-
+		 ue->N_TA_offset+5)%(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+#else //this is the normal case
+  ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
+#endif //else EXMIMO
+  if ((frame_tx%100) == 0)
+    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
+	  ue->Mod_id,frame_tx,subframe_tx,
+	  ulsch_start,
+	  ue->rx_offset,
+	  ue->hw_timing_advance,
+	  ue->timing_advance,
+	  ue->N_TA_offset);
+  
+  
+  for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+    if (frame_parms->Ncp == 1)
+      PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+		   dummy_tx_buffer,
+#else
+		   &ue->common_vars.txdata[aa][ulsch_start],
+#endif
+		   frame_parms->ofdm_symbol_size,
+		   nsymb,
+		   frame_parms->nb_prefix_samples,
+		   CYCLIC_PREFIX);
+    else
+      normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+			dummy_tx_buffer,
+#else
+			&ue->common_vars.txdata[aa][ulsch_start],
+#endif
+			nsymb,
+			&ue->frame_parms);
+    
+    
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+    apply_7_5_kHz(ue,dummy_tx_buffer,0);
+    apply_7_5_kHz(ue,dummy_tx_buffer,1);
+#else
+    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0);
+    apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1);
+#endif
+    
+    
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+    overflow = ulsch_start - 9*frame_parms->samples_per_tti;
+    
+    
+    for (k=ulsch_start,l=0; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) {
+      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
+      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
+    }
+    
+    for (k=0; k<overflow; k++,l++) {
+      ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
+      ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
+    }
+#if defined(EXMIMO)
+    // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
+    for (k=ulsch_start - (frame_parms->samples_per_tti>>1) ; k<ulsch_start ; k++) {
+      if (k<0)
+	ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+      else if (k>(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
+	ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
+      else
+	ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
+    }
 #endif
+#endif
+    
+  } //nb_antennas_tx
+  
+  stop_meas(&ue->ofdm_mod_stats);
 
-  if ((slot_tx%2)==0) {
-    ue->tx_power_dBm=-127;
 
-    if (abstraction_flag==0) {
-      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-        memset(&ue->common_vars.txdataF[aa][subframe_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],
-               0,
-               frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
-      }
-    }
 
-    if (ue->UE_mode[eNB_id] != PRACH) {
-      /*
-      #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d] Frame %d, slot %d: Generating SRS\n",Mod_id,ue->frame,slot_tx);
-      #endif
-        if (abstraction_flag == 0) {
-      #ifdef OFDMA_ULSCH
-      generate_srs_tx(ue,eNB_id,AMP,subframe_tx);
-      #else
-      generate_srs_tx(ue,eNB_id,AMP,subframe_tx);
-      #endif
-        }
+}
 
-      #ifdef PHY_ABSTRACTION
-        else {
-      generate_srs_tx_emul(ue,subframe_tx);
-        }
-      #endif
-      */
-      // get harq_pid from subframe relationship
-      harq_pid = subframe2harq_pid(&ue->frame_parms,
-                                   frame_tx,
-                                   subframe_tx);
+void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
 
+  int frame_tx = proc->frame_tx;
+  int subframe_tx = proc->subframe_tx;
+  int prach_power;
+  PRACH_RESOURCES_t prach_resources_local;
 
-      if (ue->mac_enabled == 1) {
-      if ((ue->ulsch_Msg3_active[eNB_id] == 1) &&
-          (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) &&
-          (ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3
-
-        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
-
-        if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0)
-          generate_ue_ulsch_params_from_rar(ue,
-                                            eNB_id);
-
-        ue->ulsch[eNB_id]->power_offset = 14;
-        LOG_D(PHY,"[UE  %d][RAPROC] Frame %d: Setting Msg3_flag in subframe %d, for harq_pid %d\n",
-              Mod_id,
-              frame_tx,
-              subframe_tx,
-              harq_pid);
-        Msg3_flag = 1;
-      } else {
+  ue->generate_prach=0;
 
-        if (harq_pid==255) {
-          LOG_E(PHY,"[UE%d] Frame %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n",
-                Mod_id,frame_tx);
-          mac_xface->macphy_exit("Error in ulsch_decoding");
-          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
-          stop_meas(&ue->phy_proc_tx);
-          return;
-        }
+  if (ue->mac_enabled==0){
+    ue->prach_resources[eNB_id] = &prach_resources_local;
+    prach_resources_local.ra_RNTI = 0xbeef;
+    prach_resources_local.ra_PreambleIndex = 0;
+  }
 
-        Msg3_flag=0;
+  if (ue->mac_enabled==1){
+    // ask L2 for RACH transport
+    if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
+      ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,
+							   ue->CC_id,
+							   frame_tx,
+							   eNB_id,
+							   subframe_tx);
+      //    LOG_I(PHY,"Got prach_resources for eNB %d address %d, RRCCommon %d\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[Mod_id].radioResourceConfigCommon);
+    }
+  }
+  
+  if (ue->prach_resources[eNB_id]!=NULL) {
+    
+    ue->generate_prach=1;
+    ue->prach_cnt=0;
+#ifdef SMBV
+    ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
+#endif
+#ifdef OAI_EMU
+    ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
+#endif
+    
+    if (abstraction_flag == 0) {
+      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
+	    ue->Mod_id,
+	    frame_tx,
+	    subframe_tx,
+	    ue->prach_resources[eNB_id]->ra_PreambleIndex,
+	    ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
+	    ue->prach_resources[eNB_id]->ra_TDD_map_index,
+	    ue->prach_resources[eNB_id]->ra_RNTI);
+      
+      if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
+	ue->tx_power_dBm = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id);
       }
+      else {
+	ue->tx_power_dBm = ue->tx_power_max_dBm;
+	ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;	      
       }
+      
+      ue->tx_total_RE = 96;
+      
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
+      ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm,
+					       ue->tx_power_max_dBm,
+					       ue->frame_parms.N_RB_UL,
+					       6);
+#else
+      ue->prach_vars[eNB_id]->amp = AMP;
+#endif
+      if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
+	LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : PRACH TX power %d dBm, amp %d\n",
+	      ue->Mod_id,
+	      proc->frame_rx,
+	      proc->subframe_tx,
+	      ue->tx_power_dBm,
+	      ue->prach_vars[eNB_id]->amp);
+      
+      
+      //      start_meas(&ue->tx_prach);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
+      prach_power = generate_prach(ue,eNB_id,subframe_tx,frame_tx);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
+      //      stop_meas(&ue->tx_prach);
+      LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
+	    ue->Mod_id,
+	    get_PL(ue->Mod_id,ue->CC_id,eNB_id),
+	    ue->tx_power_dBm,
+	    dB_fixed(prach_power),
+	    ue->prach_vars[eNB_id]->amp);
+    } else {
+      UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
+      UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
+      if (ue->mac_enabled==1){
+	mac_xface->Msg1_transmitted(ue->Mod_id,
+				    ue->CC_id,
+				    frame_tx,
+				    eNB_id);
+      }
+    }
+    
+    LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
+	  ue->Mod_id,frame_tx,subframe_tx,eNB_id,
+	  ue->prach_resources[eNB_id]->ra_PreambleIndex,
+	  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id),
+	  get_PL(ue->Mod_id,ue->CC_id,eNB_id));
+    
+  }	  
+  
 
-      if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
-
-        generate_ul_signal = 1;
-
-        // deactivate service request
-        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
-
-        ack_status = get_ack(&ue->frame_parms,
-                             ue->dlsch[eNB_id][0]->harq_ack,
-                             subframe_tx,
-                             ue->ulsch[eNB_id]->o_ACK);
-
-        first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
-        nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
-
-
-        //frame_parms->pusch_config_c ommon.ul_ReferenceSignalsPUSCH.cyclicShift = 0;
-
-        //frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[20] = 0;
+  // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
+  if (mode == calib_prach_tx)
+    ue->prach_resources[eNB_id]=NULL;
+  
+  LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n",
+	ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt);
+  
+  ue->prach_cnt++;
+  
+  if (ue->prach_cnt==3)
+    ue->generate_prach=0;
+}
 
+void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
 
+  int harq_pid;
+  int frame_tx=proc->frame_tx;
+  int subframe_tx=proc->subframe_tx;
+  int Mod_id = ue->Mod_id;
+  int CC_id = ue->CC_id;
+  uint8_t Msg3_flag=0;
+  uint8_t ack_status=0;
+  uint16_t first_rb, nb_rb;
+  unsigned int input_buffer_length;
+  int i;
+  int aa;
+  int tx_amp;
+  uint8_t ulsch_input_buffer[2700] __attribute__ ((aligned(16)));
+  uint8_t access_mode;
 
+  // get harq_pid from subframe relationship
+  harq_pid = subframe2harq_pid(&ue->frame_parms,
+			       frame_tx,
+			       subframe_tx);
+  
+  
+  if (ue->mac_enabled == 1) {
+    if ((ue->ulsch_Msg3_active[eNB_id] == 1) &&
+	(ue->ulsch_Msg3_frame[eNB_id] == frame_tx) &&
+	(ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3
+      
+      ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
+      
+      if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0)
+	generate_ue_ulsch_params_from_rar(ue,
+					  proc,
+					  eNB_id);
+      
+      ue->ulsch[eNB_id]->power_offset = 14;
+      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d: Setting Msg3_flag in subframe %d, for harq_pid %d\n",
+	    Mod_id,
+	    frame_tx,
+	    subframe_tx,
+	    harq_pid);
+      Msg3_flag = 1;
+    } else {
+      
+      if (harq_pid==255) {
+	LOG_E(PHY,"[UE%d] Frame %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n",
+	      Mod_id,frame_tx);
+	mac_xface->macphy_exit("Error in ulsch_decoding");
+	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+	stop_meas(&ue->phy_proc_tx);
+	return;
+      }
+      
+      Msg3_flag=0;
+    }
+  }
+  
+  if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
+    
+    ue->generate_ul_signal[eNB_id] = 1;
+    
+    // deactivate service request
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
+    
+    ack_status = get_ack(&ue->frame_parms,
+			 ue->dlsch[eNB_id][0]->harq_ack,
+			 subframe_tx,
+			 ue->ulsch[eNB_id]->o_ACK);
+    
+    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
+    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
+    
+    
+    
+    
 #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,
-              "[UE  %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d\n",
-              Mod_id,harq_pid,frame_tx,subframe_tx,
-              first_rb,nb_rb,
-              ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
-              ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs,
-              ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
-              (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+
-               ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+
-               frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[slot_tx])%12,
-              frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
-              ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2,
-              frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[slot_tx],
-              ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
-              ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
-#endif
-
-        if (ack_status > 0) {
-          LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n",
-                Mod_id,
-                ue->ulsch[eNB_id]->rnti,
-                frame_tx,subframe_tx,
-                ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
-                ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
-        }
-
-
-
-
-
-        //#ifdef DEBUG_PHY_PROC
-        //  debug_LOG_D(PHY,"[UE  %d] Frame %d, Subframe %d ulsch harq_pid %d : O %d, O_ACK %d, O_RI %d, TBS %d\n",Mod_id,ue->frame,subframe_tx,harq_pid,ue->ulsch[eNB_id]->O,ue->ulsch[eNB_id]->O_ACK,ue->ulsch[eNB_id]->O_RI,ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS);
-        //#endif
-        if (Msg3_flag == 1) {
-          LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d next slot %d Generating (RRCConnectionRequest) Msg3 (nb_rb %d, first_rb %d, round %d, rvidx %d) Msg3: %x.%x.%x|%x.%x.%x.%x.%x.%x\n",Mod_id,frame_tx,
-                subframe_tx, slot_tx,
-                ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
-                ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
-                ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
-                ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
-                ue->prach_resources[eNB_id]->Msg3[0],
-                ue->prach_resources[eNB_id]->Msg3[1],
-                ue->prach_resources[eNB_id]->Msg3[2],
-                ue->prach_resources[eNB_id]->Msg3[3],
-                ue->prach_resources[eNB_id]->Msg3[4],
-                ue->prach_resources[eNB_id]->Msg3[5],
-                ue->prach_resources[eNB_id]->Msg3[6],
-                ue->prach_resources[eNB_id]->Msg3[7],
-                ue->prach_resources[eNB_id]->Msg3[8]);
-
-          start_meas(&ue->ulsch_encoding_stats);
-
-          if (abstraction_flag==0) {
-            if (ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
-                               ue,
-                               harq_pid,
-                               eNB_id,
-                               ue->transmission_mode[eNB_id],0,0)!=0) {
-              LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
-              mac_xface->macphy_exit("Error in ulsch_coding");
-              VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
-              stop_meas(&ue->phy_proc_tx);
-              return;
-            }
-          }
-
+    LOG_D(PHY,
+	  "[UE  %d][PUSCH %d] Frame %d subframe %d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d\n",
+	  Mod_id,harq_pid,frame_tx,subframe_tx,
+	  first_rb,nb_rb,
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs,
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
+	  (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+
+	   ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+
+	   ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1])%12,
+	  ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2,
+	  ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1],
+	  ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
+#endif
+    
+    if (ack_status > 0) {
+      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating ACK (%d,%d) for %d bits on PUSCH\n",
+	    Mod_id,
+	    ue->ulsch[eNB_id]->rnti,
+	    frame_tx,subframe_tx,
+	    ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1],
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK);
+    }
+    
+    
+    
+    
+    
+    if (Msg3_flag == 1) {
+      LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d Generating (RRCConnectionRequest) Msg3 (nb_rb %d, first_rb %d, round %d, rvidx %d) Msg3: %x.%x.%x|%x.%x.%x.%x.%x.%x\n",Mod_id,frame_tx,
+	    subframe_tx,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,
+	    ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx,
+	    ue->prach_resources[eNB_id]->Msg3[0],
+	    ue->prach_resources[eNB_id]->Msg3[1],
+	    ue->prach_resources[eNB_id]->Msg3[2],
+	    ue->prach_resources[eNB_id]->Msg3[3],
+	    ue->prach_resources[eNB_id]->Msg3[4],
+	    ue->prach_resources[eNB_id]->Msg3[5],
+	    ue->prach_resources[eNB_id]->Msg3[6],
+	    ue->prach_resources[eNB_id]->Msg3[7],
+	    ue->prach_resources[eNB_id]->Msg3[8]);
+      
+      start_meas(&ue->ulsch_encoding_stats);
+      
+      if (abstraction_flag==0) {
+	if (ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
+			   ue,
+			   harq_pid,
+			   eNB_id,
+			   ue->transmission_mode[eNB_id],0,0)!=0) {
+	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
+	  mac_xface->macphy_exit("Error in ulsch_coding");
+	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+	  stop_meas(&ue->phy_proc_tx);
+	  return;
+	}
+      }
+      
 #ifdef PHY_ABSTRACTION
-          else {
-            ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,harq_pid,0);
-          }
-
+      else {
+	ulsch_encoding_emul(ue->prach_resources[eNB_id]->Msg3,ue,eNB_id,harq_pid,0);
+      }
+      
 #endif
-          stop_meas(&ue->ulsch_encoding_stats);
-
-	  if (ue->mac_enabled == 1) {
-	    // signal MAC that Msg3 was sent
-	    mac_xface->Msg3_transmitted(Mod_id,
-					CC_id,
-					frame_tx,
-					eNB_id);
-	  }
-        } else {
-          input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
-
-	  if (ue->mac_enabled==1) {
-          //  LOG_D(PHY,"[UE  %d] ULSCH : Searching for MAC SDUs\n",Mod_id);
-          if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) {
-            //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
-            access_mode=SCHEDULED_ACCESS;
-            mac_xface->ue_get_sdu(Mod_id,
-                                  CC_id,
-                                  frame_tx,
-                                  subframe_tx,
-                                  eNB_id,
-                                  ulsch_input_buffer,
-                                  input_buffer_length,
-                                  &access_mode);
-
-            //}
-            /*
-            else {
-              // Get calibration information from TDD procedures
-              LOG_D(PHY,"[UE %d] Frame %d, subframe %d : ULSCH: Getting TDD Auto-Calibration information\n",
-              Mod_id,ue->frame,subframe_tx);
-              for (i=0;i<input_buffer_length;i++)
-            ulsch_input_buffer[i]= i;
-
-            }
-            */
-          }
-
+      
+      stop_meas(&ue->ulsch_encoding_stats);
+      
+      if (ue->mac_enabled == 1) {
+	// signal MAC that Msg3 was sent
+	mac_xface->Msg3_transmitted(Mod_id,
+				    CC_id,
+				    frame_tx,
+				    eNB_id);
+      }
+    } // Msg3_flag==1
+    else {
+      input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
+      
+      if (ue->mac_enabled==1) {
+	//  LOG_D(PHY,"[UE  %d] ULSCH : Searching for MAC SDUs\n",Mod_id);
+	if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) {
+	  //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
+	  access_mode=SCHEDULED_ACCESS;
+	  mac_xface->ue_get_sdu(Mod_id,
+				CC_id,
+				frame_tx,
+				subframe_tx,
+				eNB_id,
+				ulsch_input_buffer,
+				input_buffer_length,
+				&access_mode);
+	}
+	
 #ifdef DEBUG_PHY_PROC
 #ifdef DEBUG_ULSCH
-          LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d)  (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
-
-          for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++)
-            LOG_T(PHY,"%x.",ulsch_input_buffer[i]);
-
-          LOG_T(PHY,"\n");
+	LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d)  (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3);
+	
+	for (i=0; i<ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++)
+	  LOG_T(PHY,"%x.",ulsch_input_buffer[i]);
+	
+	LOG_T(PHY,"\n");
 #endif
 #endif
+      }
+      else {
+	unsigned int taus(void);
+	
+	for (i=0; i<input_buffer_length; i++)
+	  ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
+	
+      }
+      
+      start_meas(&ue->ulsch_encoding_stats);
+      
+      if (abstraction_flag==0) {
+	
+	if (ulsch_encoding(ulsch_input_buffer,
+			   ue,
+			   harq_pid,
+			   eNB_id,
+			   ue->transmission_mode[eNB_id],0,
+			   0)!=0) {  //  Nbundled, to be updated!!!!
+	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
+	  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+	  stop_meas(&ue->phy_proc_tx);
+	  return;
 	}
-	  else {
-          // the following lines were necessary for the calibration in CROWN
-          /*
-          if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) {
-              for (i=0;i<input_buffer_length;i++)
-                  ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
-          }
-          else {
-              // Get calibration information from TDD procedures
-          }
-          */
-
-          unsigned int taus(void);
-
-          for (i=0; i<input_buffer_length; i++)
-            ulsch_input_buffer[i]= (uint8_t)(taus()&0xff);
-
-          // the following lines were necessary for the collaborative UL in PUCCO
-          /*
-          memset(ue->ulsch[eNB_id]->o    ,0,MAX_CQI_BYTES*sizeof(uint8_t));
-          memset(ue->ulsch[eNB_id]->o_RI ,0,2*sizeof(uint8_t));
-          memset(ue->ulsch[eNB_id]->o_ACK,0,4*sizeof(uint8_t));
-          for (i=0;i<input_buffer_length;i++)
-            ulsch_input_buffer[i]= i;
-          */
-	}
-
-          start_meas(&ue->ulsch_encoding_stats);
-
-          if (abstraction_flag==0) {
-            /*
-            if (ue->frame%100==0) {
-              LOG_I(PHY,"Encoding ulsch\n");
-            }
-            */
-            if (ulsch_encoding(ulsch_input_buffer,
-                               ue,
-                               harq_pid,
-                               eNB_id,
-                               ue->transmission_mode[eNB_id],0,
-                               0)!=0) {  //  Nbundled, to be updated!!!!
-              LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
-              VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
-              stop_meas(&ue->phy_proc_tx);
-              return;
-            }
-          }
-
+      }
+      
 #ifdef PHY_ABSTRACTION
-          else {
-            ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0);
-          }
-
+      else {
+	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0);
+      }
+      
 #endif
-          stop_meas(&ue->ulsch_encoding_stats);
-        }
-
-        if (abstraction_flag == 0) {
-	  if (ue->mac_enabled==1) {
-	    pusch_power_cntl(ue,subframe_tx,eNB_id,1, abstraction_flag);
-	    ue->tx_power_dBm = ue->ulsch[eNB_id]->Po_PUSCH;
-	  }
-	  else {
-	    ue->tx_power_dBm = ue->tx_power_max_dBm;
-	  }
-          ue->tx_total_RE = nb_rb*12;
-	  
+      stop_meas(&ue->ulsch_encoding_stats);
+    }
+    
+    if (abstraction_flag == 0) {
+      if (ue->mac_enabled==1) {
+	pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
+	ue->tx_power_dBm = ue->ulsch[eNB_id]->Po_PUSCH;
+      }
+      else {
+	ue->tx_power_dBm = ue->tx_power_max_dBm;
+      }
+      ue->tx_total_RE = nb_rb*12;
+      
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-	  tx_amp = get_tx_amp(ue->tx_power_dBm,
-			      ue->tx_power_max_dBm,
-			      ue->frame_parms.N_RB_UL,
-			      nb_rb);
+      tx_amp = get_tx_amp(ue->tx_power_dBm,
+			  ue->tx_power_max_dBm,
+			  ue->frame_parms.N_RB_UL,
+			  nb_rb);
 #else
-          tx_amp = AMP;
-#endif
-	  LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
-		Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm,ue->tx_power_max_dBm, tx_amp);
-          start_meas(&ue->ulsch_modulation_stats);
-          ulsch_modulation(ue->common_vars.txdataF,
+      tx_amp = AMP;
+#endif
+      LOG_D(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
+	    Mod_id,harq_pid,frame_tx,subframe_tx,ue->tx_power_dBm,ue->tx_power_max_dBm, tx_amp);
+      start_meas(&ue->ulsch_modulation_stats);
+      ulsch_modulation(ue->common_vars.txdataF,
+		       tx_amp,
+		       frame_tx,
+		       subframe_tx,
+		       &ue->frame_parms,
+		       ue->ulsch[eNB_id]);
+      for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++)
+	generate_drs_pusch(ue,
+			   proc,
+			   eNB_id,
 			   tx_amp,
-                           frame_tx,
-                           subframe_tx,
-                           &ue->frame_parms,
-                           ue->ulsch[eNB_id]);
-          for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++)
-            generate_drs_pusch(ue,
-			       eNB_id,
-			       tx_amp,
-			       subframe_tx,
-			       first_rb,
-			       nb_rb,
-			       aa);
-
-          stop_meas(&ue->ulsch_modulation_stats);
-        }
+			   subframe_tx,
+			   first_rb,
+			   nb_rb,
+			   aa);
+      
+      stop_meas(&ue->ulsch_modulation_stats);
+    }
+    
+    if (abstraction_flag==1) {
+      // clear SR
+      ue->sr[subframe_tx]=0;
+    }
+  } // subframe_scheduling_flag==1
+}
 
-        if (abstraction_flag==1) {
-          // clear SR
-          ue->sr[subframe_tx]=0;
-        }
-      } // ULSCH is active
-
-#ifdef PUCCH
-      else if (ue->UE_mode[eNB_id] == PUSCH) { // check if we need to use PUCCH 1a/1b
-        //      debug_LOG_D(PHY,"[UE%d] Frame %d, subframe %d: Checking for PUCCH 1a/1b\n",Mod_id,frame_tx,subframe_tx);
-        bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
-
-        if ((frame_parms->frame_type==FDD) ||
-            (bundling_flag==bundling)    ||
-            ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((slot_tx!=4)||(slot_tx!=14)))) {
-          format = pucch_format1a;
-          LOG_D(PHY,"[UE] PUCCH 1a\n");
-        } else {
-          format = pucch_format1b;
-          LOG_D(PHY,"[UE] PUCCH 1b\n");
-        }
 
-        // Check for SR and do ACK/NACK accordingly
-        if (is_SR_TXOp(ue,eNB_id,subframe_tx)==1) {
-          LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d: got SR_TXOp, Checking for SR for PUSCH from MAC\n",
-                Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx);
-
-	  if (ue->mac_enabled==1) {
-	    SR_payload = mac_xface->ue_get_SR(Mod_id,
-					      CC_id,
-					      frame_tx,
-					      eNB_id,
-					      ue->pdcch_vars[eNB_id]->crnti,
-					      subframe_tx); // subframe used for meas gap
-	  }
-	  else {
-	    SR_payload = 1;
-	  }
-	  
-          if (SR_payload>0) {
-            generate_ul_signal = 1;
-            LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d got the SR for PUSCH is %d\n",
-                  Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx,SR_payload);
-          } else {
-            ue->sr[subframe_tx]=0;
-          }
-        } else {
-          SR_payload=0;
-	}
+void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) {
 
-        if (get_ack(&ue->frame_parms,
-                    ue->dlsch[eNB_id][0]->harq_ack,
-                    subframe_tx,pucch_ack_payload) > 0) {
-          // we need to transmit ACK/NAK in this subframe
 
-          generate_ul_signal = 1;
-
-          n1_pucch = get_n1_pucch(ue,
-                                  eNB_id,
-                                  subframe_tx,
-                                  pucch_ack_payload,
-                                  SR_payload);
-
-	  if (ue->mac_enabled == 1) {
-	    Po_PUCCH = pucch_power_cntl(ue,subframe_tx,eNB_id,format);
-	  } 
-	  else {
-	    Po_PUCCH = ue->tx_power_max_dBm;
-	  }
-	  ue->tx_power_dBm = Po_PUCCH;
-          ue->tx_total_RE = 12;
+  uint8_t pucch_ack_payload[2];
+  uint8_t n1_pucch;
+  ANFBmode_t bundling_flag;
+  PUCCH_FMT_t format;
+  uint8_t SR_payload;
+  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  int frame_tx=proc->frame_tx;
+  int subframe_tx=proc->subframe_tx;
+  int Mod_id = ue->Mod_id;
+  int CC_id = ue->CC_id;
+  int tx_amp;
+  int8_t Po_PUCCH;
 
+  bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
+  
+  if ((frame_parms->frame_type==FDD) ||
+      (bundling_flag==bundling)    ||
+      ((frame_parms->frame_type==TDD)&&(frame_parms->tdd_config==1)&&((subframe_tx!=2)||(subframe_tx!=7)))) {
+    format = pucch_format1a;
+    LOG_D(PHY,"[UE] PUCCH 1a\n");
+  } else {
+    format = pucch_format1b;
+    LOG_D(PHY,"[UE] PUCCH 1b\n");
+  }
+  
+  // Check for SR and do ACK/NACK accordingly
+  if (is_SR_TXOp(ue,proc,eNB_id)==1) {
+    LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d: got SR_TXOp, Checking for SR for PUSCH from MAC\n",
+	  Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx);
+    
+    if (ue->mac_enabled==1) {
+      SR_payload = mac_xface->ue_get_SR(Mod_id,
+					CC_id,
+					frame_tx,
+					eNB_id,
+					ue->pdcch_vars[eNB_id]->crnti,
+					subframe_tx); // subframe used for meas gap
+    }
+    else {
+      SR_payload = 1;
+    }
+	    
+    if (SR_payload>0) {
+      ue->generate_ul_signal[eNB_id] = 1;
+      LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d got the SR for PUSCH is %d\n",
+	    Mod_id,ue->pdcch_vars[eNB_id]->crnti,frame_tx,subframe_tx,SR_payload);
+    } else {
+      ue->sr[subframe_tx]=0;
+    }
+  } else {
+    SR_payload=0;
+  }
+        	  
+  if (get_ack(&ue->frame_parms,
+	      ue->dlsch[eNB_id][0]->harq_ack,
+	      subframe_tx,pucch_ack_payload) > 0) {
+    // we need to transmit ACK/NAK in this subframe
+	    
+    ue->generate_ul_signal[eNB_id] = 1;
+	    
+    n1_pucch = get_n1_pucch(ue,
+			    proc,
+			    eNB_id,
+			    pucch_ack_payload,
+			    SR_payload);
+	    
+    if (ue->mac_enabled == 1) {
+      Po_PUCCH = pucch_power_cntl(ue,proc,eNB_id,format);
+    } 
+    else {
+      Po_PUCCH = ue->tx_power_max_dBm;
+    }
+    ue->tx_power_dBm = Po_PUCCH;
+    ue->tx_total_RE = 12;
+	    
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-	  tx_amp = get_tx_amp(Po_PUCCH,
-			      ue->tx_power_max_dBm,
-			      ue->frame_parms.N_RB_UL,
-			      1);
+    tx_amp = get_tx_amp(Po_PUCCH,
+			ue->tx_power_max_dBm,
+			ue->frame_parms.N_RB_UL,
+			1);
 #else
-	  tx_amp = AMP;
+    tx_amp = AMP;
 #endif
-	  
-          if (SR_payload>0) {
-	     LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), n1_pucch %d, Po_PUCCH, amp %d\n",
-                  Mod_id,
-                  ue->dlsch[eNB_id][0]->rnti,
-                  frame_tx, subframe_tx,
-		  pucch_ack_payload[0],pucch_ack_payload[1],
-                  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
-	          Po_PUCCH,
-		  tx_amp);
-          } else {
-            LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
-                  Mod_id,
-                  ue->dlsch[eNB_id][0]->rnti,
+	    
+    if (SR_payload>0) {
+      LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1a/1b payload %d,%d (with SR for PUSCH), n1_pucch %d, Po_PUCCH, amp %d\n",
+	    Mod_id,
+	    ue->dlsch[eNB_id][0]->rnti,
 	    frame_tx, subframe_tx,
-		  n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload,
-                  Po_PUCCH,
-		  tx_amp);
-	  }
-
-          if (abstraction_flag == 0) {
-
-	  generate_pucch(ue->common_vars.txdataF,
-                           &ue->frame_parms,
-                           ue->ncs_cell,
-                           format,
-                           &ue->pucch_config_dedicated[eNB_id],
-                           n1_pucch,
-                           0,  // n2_pucch
-                           1,  // shortened format
-                           pucch_ack_payload,
-	                   tx_amp,
-	                   subframe_tx);
-
-          } else {
+	    pucch_ack_payload[0],pucch_ack_payload[1],
+	    ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
+	    Po_PUCCH,
+	    tx_amp);
+    } else {
+      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d Generating PUCCH 1a/1b, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
+	    Mod_id,
+	    ue->dlsch[eNB_id][0]->rnti,
+	    frame_tx, subframe_tx,
+	    n1_pucch,pucch_ack_payload[0],pucch_ack_payload[1],SR_payload,
+	    Po_PUCCH,
+	    tx_amp);
+    }
+	    
+    if (abstraction_flag == 0) {
+	      
+      generate_pucch(ue->common_vars.txdataF,
+		     &ue->frame_parms,
+		     ue->ncs_cell,
+		     format,
+		     &ue->pucch_config_dedicated[eNB_id],
+		     n1_pucch,
+		     0,  // n2_pucch
+		     1,  // shortened format
+		     pucch_ack_payload,
+		     tx_amp,
+		     subframe_tx);
+	      
+    } else {
 #ifdef PHY_ABSTRACTION
-            LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
-            generate_pucch_emul(ue,
-                                format,
-                                ue->frame_parms.pucch_config_common.nCS_AN,
-                                pucch_ack_payload,
-                                SR_payload,
-                                subframe_tx);
+      LOG_D(PHY,"Calling generate_pucch_emul ... (ACK %d %d, SR %d)\n",pucch_ack_payload[0],pucch_ack_payload[1],SR_payload);
+      generate_pucch_emul(ue,
+			  proc,
+			  format,
+			  ue->frame_parms.pucch_config_common.nCS_AN,
+			  pucch_ack_payload,
+			  SR_payload,
+			  subframe_tx);
 #endif
-          }
-        } else if (SR_payload==1) { // no ACK/NAK but SR is triggered by MAC
-
-	  if (ue->mac_enabled == 1) {
-	    Po_PUCCH = pucch_power_cntl(ue,subframe_tx,eNB_id,pucch_format1);
-	  }
-	  else {
-	    Po_PUCCH = ue->tx_power_max_dBm;
-	  }
-	  ue->tx_power_dBm = Po_PUCCH;
-          ue->tx_total_RE = 12;
-
+    }
+  } else if (SR_payload==1) { // no ACK/NAK but SR is triggered by MAC
+	    
+    if (ue->mac_enabled == 1) {
+      Po_PUCCH = pucch_power_cntl(ue,proc,eNB_id,pucch_format1);
+    }
+    else {
+      Po_PUCCH = ue->tx_power_max_dBm;
+    }
+    ue->tx_power_dBm = Po_PUCCH;
+    ue->tx_total_RE = 12;
+	    
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-          tx_amp =  get_tx_amp(Po_PUCCH,
-	                       ue->tx_power_max_dBm,
-	                       ue->frame_parms.N_RB_UL,
-	                       1);
+    tx_amp =  get_tx_amp(Po_PUCCH,
+			 ue->tx_power_max_dBm,
+			 ue->frame_parms.N_RB_UL,
+			 1);
 #else
-	  tx_amp = AMP;
-#endif
-          LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), n1_pucch %d, Po_PUCCH %d\n",
-                Mod_id,
-                ue->dlsch[eNB_id][0]->rnti,
-                frame_tx, subframe_tx,
-                ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
-                Po_PUCCH);
-
-          if (abstraction_flag == 0) {
-
-            generate_pucch(ue->common_vars.txdataF,
-                           &ue->frame_parms,
-                           ue->ncs_cell,
-                           pucch_format1,
-                           &ue->pucch_config_dedicated[eNB_id],
-                           ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
-                           0,  // n2_pucch
-                           1,  // shortened format
-                           pucch_ack_payload,  // this is ignored anyway, we just need a pointer
-	                   tx_amp,
-                           subframe_tx);
-          } else {
-            LOG_D(PHY,"Calling generate_pucch_emul ...\n");
-            generate_pucch_emul(ue,
-                                pucch_format1,
-                                ue->frame_parms.pucch_config_common.nCS_AN,
-                                pucch_ack_payload,
-                                SR_payload,
-                                subframe_tx);
-          }
-        }
-      }
-
-#endif  // PUCCH
-
-#ifdef CBA
-
-      if ((ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag >= 1) &&
-          (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == CBA_ACTIVE)) {
-        ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag=0; //-=1
-        //  ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
-        first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
-        nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
-        //cba_mcs=ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs;
-        input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
-        access_mode=CBA_ACCESS;
-
-        LOG_D(PHY,"[UE %d] Frame %d, subframe %d: CBA num dci %d\n",
-              Mod_id,frame_tx,subframe_tx,
-              ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]);
-
-        mac_xface->ue_get_sdu(Mod_id,
-                              CC_id,
-                              frame_tx,
-                              subframe_tx,
-                              eNB_id,
-                              ulsch_input_buffer,
-                              input_buffer_length,
-                              &access_mode);
-
-        ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]=0;
-
-        if (access_mode > UNKNOWN_ACCESS) {
-
-          if (abstraction_flag==0) {
-            if (ulsch_encoding(ulsch_input_buffer,
-                               ue,
-                               harq_pid,
-                               eNB_id,
-                               ue->transmission_mode[eNB_id],0,
-                               0)!=0) {  //  Nbundled, to be updated!!!!
-              LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
-              return;
-            }
-          }
-
-#ifdef PHY_ABSTRACTION
-          else {
-            ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0);
-          }
+    tx_amp = AMP;
+#endif
+    LOG_D(PHY,"[UE  %d][SR %x] Frame %d subframe %d Generating PUCCH 1 (SR for PUSCH), n1_pucch %d, Po_PUCCH %d\n",
+	  Mod_id,
+	  ue->dlsch[eNB_id][0]->rnti,
+	  frame_tx, subframe_tx,
+	  ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
+	  Po_PUCCH);
+	    
+    if (abstraction_flag == 0) {
+	      
+      generate_pucch(ue->common_vars.txdataF,
+		     &ue->frame_parms,
+		     ue->ncs_cell,
+		     pucch_format1,
+		     &ue->pucch_config_dedicated[eNB_id],
+		     ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex,
+		     0,  // n2_pucch
+		     1,  // shortened format
+		     pucch_ack_payload,  // this is ignored anyway, we just need a pointer
+		     tx_amp,
+		     subframe_tx);
+    } else {
+      LOG_D(PHY,"Calling generate_pucch_emul ...\n");
+      generate_pucch_emul(ue,
+			  proc,
+			  pucch_format1,
+			  ue->frame_parms.pucch_config_common.nCS_AN,
+			  pucch_ack_payload,
+			  SR_payload);
 
-#endif
-        } else {
-          ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
-          //reset_cba_uci(ue->ulsch[eNB_id]->o);
-          LOG_N(PHY,"[UE %d] Frame %d, subframe %d: CBA transmission cancelled or postponed\n",
-                Mod_id, frame_tx,subframe_tx);
-        }
-      }
+    }
+  } // SR_Payload==1
+}
 
-#endif // end CBA
+void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,relaying_type_t r_type) {
+  
 
-      if (abstraction_flag == 0) {
-        nsymb = (frame_parms->Ncp == 0) ? 14 : 12;
+  LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
+  int32_t ulsch_start=0;
+  int subframe_tx = proc->subframe_tx;
+  int frame_tx = proc->frame_tx;
+  unsigned int aa;
 
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
-        ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
-                       ue->hw_timing_advance-
-                       ue->timing_advance-
-                       ue->N_TA_offset+5)%(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
-#else //this is the normal case
-        ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
-#endif //else EXMIMO
-	if ((frame_tx%100) == 0)
-	  LOG_D(PHY,"[UE %d] Frame %d, subframe %d: ulsch_start = %d (rxoff %d, HW TA %d, timing advance %d, TA_offset %d\n",
-		Mod_id,frame_tx,subframe_tx,
-		ulsch_start,
-		ue->rx_offset,
-		ue->hw_timing_advance,
-		ue->timing_advance,
-		ue->N_TA_offset);
- 
 
-        if (generate_ul_signal == 1 ) {
 
 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
 
-          start_meas(&ue->ofdm_mod_stats);
+  ue->generate_ul_signal[eNB_id] = 0;
 
-          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-            if (frame_parms->Ncp == 1)
-              PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-                           dummy_tx_buffer,
-#else
-                           &ue->common_vars.txdata[aa][ulsch_start],
-#endif
-                           frame_parms->ofdm_symbol_size,
-                           nsymb,
-                           frame_parms->nb_prefix_samples,
-                           CYCLIC_PREFIX);
-            else
-              normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size],
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-                                dummy_tx_buffer,
-#else
-                                &ue->common_vars.txdata[aa][ulsch_start],
-#endif
-                                nsymb,
-                                &ue->frame_parms);
-
-            /*
-              if (subframe_tx == 8) {
-              printf("Symbol 0 %p (offset %d) base %p\n",
-              &ue->common_vars.txdataF[0][nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*subframe],
-              nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*subframe,
-              ue->common_vars.txdataF[0]);
-              write_output("txsigF8.m","txsF8", &ue->common_vars.txdataF[0][nsymb*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*subframe],
-              ue->frame_parms.ofdm_symbol_size*nsymb,1,1);
-              write_output("txsig8.m","txs8", &ue->common_vars.txdata[0][ue->frame_parms.samples_per_tti*subframe],
-              ue->frame_parms.samples_per_tti,1,1);
-              }
-            */
-#ifndef OFDMA_ULSCH
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-            apply_7_5_kHz(ue,dummy_tx_buffer,0);
-            apply_7_5_kHz(ue,dummy_tx_buffer,1);
-#else
-            apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0);
-            apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1);
-#endif
-            /*
-              if (subframe_tx == 8) {
-              write_output("txsig8_mod.m","txs8_mod", &ue->common_vars.txdata[0][ue->frame_parms.samples_per_tti*subframe],
-              ue->frame_parms.samples_per_tti,1,1);
-              }
-            */
-#endif
+  start_meas(&ue->phy_proc_tx);
 
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-            overflow = ulsch_start - 9*frame_parms->samples_per_tti;
-
-            //if ((slot_tx==4) && (aa==0)) printf("ulsch_start %d, overflow %d\n",ulsch_start,overflow);
-            for (k=ulsch_start,l=0; k<cmin(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) {
-              ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
-              ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
-            }
-
-            for (k=0; k<overflow; k++,l++) {
-              ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]<<4;
-              ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]<<4;
-            }
-#if defined(EXMIMO)
-	    // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on
-	    for (k=ulsch_start - (frame_parms->samples_per_tti>>1) ; k<ulsch_start ; k++) {
-	      if (k<0)
-		ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
-	      else if (k>(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME))
-		ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE;
-	      else
-		ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
-	    }
-#endif
+#ifdef EMOS
+  //phy_procedures_emos_UE_TX(next_slot);
 #endif
 
-          } //nb_antennas_tx
+  ue->tx_power_dBm=-127;
+      
+  if (abstraction_flag==0) {
+    for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+      memset(&ue->common_vars.txdataF[aa][subframe_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti],
+	     0,
+	     frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t));
+    }
+  }
+      
+  if (ue->UE_mode[eNB_id] != PRACH) {
 
-          stop_meas(&ue->ofdm_mod_stats);
-        } // generate_ul_signal == 1
-        else {  // no uplink so clear signal buffer instead
-          for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
-            memset(&ue->common_vars.txdata[aa][ulsch_start],0,frame_parms->samples_per_tti<<2);
-          }
-        }
-      }
-    } // mode != PRACH
-
-    //  }// slot_tx is even
-    //  else {  // slot_tx is odd, do the PRACH here
-
-    if ((ue->UE_mode[eNB_id] == PRACH) && (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
-
-      // check if we have PRACH opportunity
-      if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
-        ue->generate_prach=0;
-
-	if (ue->mac_enabled==1){
-	  // ask L2 for RACH transport
-	  if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
-	    ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(Mod_id,
-									  CC_id,
-									  frame_tx,
-									  eNB_id,
-									  subframe_tx);
-	    //    LOG_I(PHY,"Got prach_resources for eNB %d address %d, RRCCommon %d\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[Mod_id].radioResourceConfigCommon);
-	  }
-	}
+    ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
 
-        if (ue->prach_resources[eNB_id]!=NULL) {
+  }
+  	  
+  if (ue->UE_mode[eNB_id] == PUSCH) { // check if we need to use PUCCH 1a/1b
+  
 
-          ue->generate_prach=1;
-          ue->prach_cnt=0;
-#ifdef SMBV
-          ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
-#endif
-#ifdef OAI_EMU
-          ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
+  } // UE_mode==PUSCH
+	
+  	
+#ifdef CBA
+	
+  if ((ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag >= 1) &&
+      (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == CBA_ACTIVE)) {
+    ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag=0; //-=1
+    //  ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
+    first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
+    nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
+    //cba_mcs=ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs;
+    input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8;
+    access_mode=CBA_ACCESS;
+	  
+    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: CBA num dci %d\n",
+	  Mod_id,frame_tx,subframe_tx,
+	  ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]);
+	  
+    mac_xface->ue_get_sdu(Mod_id,
+			  CC_id,
+			  frame_tx,
+			  subframe_tx,
+			  eNB_id,
+			  ulsch_input_buffer,
+			  input_buffer_length,
+			  &access_mode);
+	  
+    ue->ulsch[eNB_id]->num_cba_dci[subframe_tx]=0;
+	  
+    if (access_mode > UNKNOWN_ACCESS) {
+	    
+      if (abstraction_flag==0) {
+	if (ulsch_encoding(ulsch_input_buffer,
+			   ue,
+			   harq_pid,
+			   eNB_id,
+			   ue->transmission_mode[eNB_id],0,
+			   0)!=0) {  //  Nbundled, to be updated!!!!
+	  LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n");
+	  return;
+	}
+      }
+	    
+#ifdef PHY_ABSTRACTION
+      else {
+	ulsch_encoding_emul(ulsch_input_buffer,ue,eNB_id,harq_pid,0);
+      }
+	    
 #endif
+    } else {
+      ue->ulsch[eNB_id]->harq_processes[harq_pid]->status= IDLE;
+      //reset_cba_uci(ue->ulsch[eNB_id]->o);
+      LOG_N(PHY,"[UE %d] Frame %d, subframe %d: CBA transmission cancelled or postponed\n",
+	    Mod_id, frame_tx,subframe_tx);
+    }
+  }
+	
+#endif // end CBA
 
-          if (abstraction_flag == 0) {
-            LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
-                  Mod_id,
-                  frame_tx,
-                  subframe_tx,
-                  ue->prach_resources[eNB_id]->ra_PreambleIndex,
-                  ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
-                  ue->prach_resources[eNB_id]->ra_TDD_map_index,
-                  ue->prach_resources[eNB_id]->ra_RNTI);
-
-	    if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
-	      ue->tx_power_dBm = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(Mod_id,CC_id,eNB_id);
-	    }
-	    else {
-	      ue->tx_power_dBm = ue->tx_power_max_dBm;
-	      ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;	      
-	    }
-
-            ue->tx_total_RE = 96;
-
-#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-            ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm,
-								     ue->tx_power_max_dBm,
-								     ue->frame_parms.N_RB_UL,
-								     6);
-#else
-            ue->prach_vars[eNB_id]->amp = AMP;
-#endif
-	    if ((mode == calib_prach_tx) && (((ue->frame_tx&0xfffe)%100)==0))
-	      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : PRACH TX power %d dBm, amp %d\n",Mod_id,ue->frame_rx,ue->slot_tx>>1,ue->tx_power_dBm,
-		    ue->prach_vars[eNB_id]->amp);
-
-
-            //      start_meas(&ue->tx_prach);
-            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
-            prach_power = generate_prach(ue,eNB_id,subframe_tx,frame_tx);
-            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
-            //      stop_meas(&ue->tx_prach);
-            LOG_D(PHY,"[UE  %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
-                  Mod_id,
-                  get_PL(Mod_id,CC_id,eNB_id),
-                  ue->tx_power_dBm,
-                  dB_fixed(prach_power),
-                  ue->prach_vars[eNB_id]->amp);
-          } else {
-            UE_transport_info[Mod_id][CC_id].cntl.prach_flag=1;
-            UE_transport_info[Mod_id][CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
-	    if (ue->mac_enabled==1){
-	      mac_xface->Msg1_transmitted(Mod_id,
-					  CC_id,
-					  frame_tx,
-					  eNB_id);
-	    }
-          }
-
-          LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
-                Mod_id,frame_tx,subframe_tx,eNB_id,
-                ue->prach_resources[eNB_id]->ra_PreambleIndex,
-                ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(Mod_id,CC_id,eNB_id),
-                get_PL(Mod_id,CC_id,eNB_id));
-
-	}	  
-
+  	
+  if (abstraction_flag == 0) {
+	  
+    if (ue->generate_ul_signal[eNB_id] == 1 )
+      ulsch_common_procedures(ue,proc);
+    else {  // no uplink so clear signal buffer instead
+#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case
+      ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti-
+		     ue->hw_timing_advance-
+		     ue->timing_advance-
+		     ue->N_TA_offset+5)%(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti);
+#else //this is the normal case
+      ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance;
+#endif //else EXMIMO
+      for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
+	memset(&ue->common_vars.txdata[aa][ulsch_start],0,frame_parms->samples_per_tti<<2);
       }
-      // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
-      if (mode == calib_prach_tx)
-	ue->prach_resources[eNB_id]=NULL;
-
-      LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n",
-            Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt);
+    }
 
-      ue->prach_cnt++;
+  } // mode != PRACH
+    
+      
+  if ((ue->UE_mode[eNB_id] == PRACH) && 
+      (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
+	
+    // check if we have PRACH opportunity
+    if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) {
 
-      if (ue->prach_cnt==3)
-        ue->generate_prach=0;
-    } // mode is PRACH
-    else {
-      ue->generate_prach=0;
+      ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
     }
-  } // slot_tx is even
-
+  } // mode is PRACH
+  else {
+    ue->generate_prach=0;
+  }
+    
+      
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
   stop_meas(&ue->phy_proc_tx);
 }
@@ -1428,37 +1410,31 @@ void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_f
 {
   int aa;//i,aa;
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-
+  
   if (abstraction_flag==0) {
-
+    
     for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
 #if defined(EXMIMO) //this is the EXPRESS MIMO case
       int i;
       // set the whole tx buffer to RX
       for (i=0; i<LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti; i++)
-        ue->common_vars.txdata[aa][i] = 0x00010001;
-
+	ue->common_vars.txdata[aa][i] = 0x00010001;
+      
 #else //this is the normal case
       memset(&ue->common_vars.txdata[aa][0],0,
-             (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
+	     (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t));
 #endif //else EXMIMO
-
+      
     }
   }
 }
 
-void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode)
+void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode)
 {
-
+  
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-  //  int aa;
-#if defined(EXMIMO) && defined(DRIVER2013)
-  //  exmimo_config_t *p_exmimo_config = openair0_exmimo_pci[0].exmimo_config_ptr;
-  //  int aa;
-#endif
 
-  int slot_rx = ue->slot_rx;
-  int subframe_rx = slot_rx>>1;
+  int subframe_rx = proc->subframe_rx;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN);
 
@@ -1468,25 +1444,25 @@ void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,uint8_t eNB_id,uint8_
       LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata);
 
       lte_ue_measurements(ue,
-                          (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
-                          (slot_rx == 2) ? 1 : 0,
-                          0);
+			  (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME),
+			  (subframe_rx == 1) ? 1 : 0,
+			  0);
     } else {
       lte_ue_measurements(ue,
-                          0,
-                          0,
-                          1);
+			  0,
+			  0,
+			  1);
     }
   }
 
   if (l==(6-ue->frame_parms.Ncp)) {
 	
-   // make sure we have signal from PSS/SSS for N0 measurement
+    // make sure we have signal from PSS/SSS for N0 measurement
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
     ue_rrc_measurements(ue,
-                        slot_rx,
-                        abstraction_flag);
+			subframe_rx,
+			abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
 
     if (abstraction_flag==1)
@@ -1494,7 +1470,7 @@ void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,uint8_t eNB_id,uint8_
 
   }
 
-  if ((slot_rx==1) && (l==(4-frame_parms->Ncp))) {
+  if ((subframe_rx==0) && (l==(4-frame_parms->Ncp))) {
 
     // AGC
 
@@ -1511,14 +1487,14 @@ void ue_measurement_procedures(uint16_t l, PHY_VARS_UE *ue,uint8_t eNB_id,uint8_
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN);
     eNB_id = 0;
-
+    
     if (abstraction_flag == 0)
       lte_adjust_synch(&ue->frame_parms,
-                       ue,
-                       eNB_id,
-                       0,
-                       16384);
-
+		       ue,
+		       eNB_id,
+		       0,
+		       16384);
+    
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
 
   }
@@ -1536,14 +1512,14 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
   int Mod_id = ue->Mod_id;
 
   /*
-  if (last_slot<2)
+    if (last_slot<2)
     last_slot_emos = last_slot;
-  else if (last_slot>9)
+    else if (last_slot>9)
     last_slot_emos = last_slot - 8;
-  else {
+    else {
     LOG_E(PHY,"emos rx last_slot_emos %d, last_slot %d\n", last_slot_emos,last_slot);
     mac_xface->macphy_exit("should never happen");
-  }
+    }
   */
 
 #ifdef EMOS_CHANNEL
@@ -1551,14 +1527,14 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
   if ((last_slot==10) || (last_slot==11)) {
     for (i=0; i<ue->frame_parms.nb_antennas_rx; i++)
       for (j=0; j<ue->frame_parms.nb_antennas_tx; j++) {
-        // first OFDM symbol with pilots
-        memcpy(&emos_dump_UE.channel[i][j][(last_slot%2)*2*ue->frame_parms.ofdm_symbol_size],
-               &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][0],
-               ue->frame_parms.ofdm_symbol_size*sizeof(int));
-        // second OFDM symbol with pilots
-        memcpy(&emos_dump_UE.channel[i][j][((last_slot%2)*2+1)*ue->frame_parms.ofdm_symbol_size],
-               &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][(ue->frame_parms.Ncp == 0 ? 4 : 3)*ue->frame_parms.ofdm_symbol_size],
-               ue->frame_parms.ofdm_symbol_size*sizeof(int));
+	// first OFDM symbol with pilots
+	memcpy(&emos_dump_UE.channel[i][j][(last_slot%2)*2*ue->frame_parms.ofdm_symbol_size],
+	       &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][0],
+	       ue->frame_parms.ofdm_symbol_size*sizeof(int));
+	// second OFDM symbol with pilots
+	memcpy(&emos_dump_UE.channel[i][j][((last_slot%2)*2+1)*ue->frame_parms.ofdm_symbol_size],
+	       &ue->common_vars.dl_ch_estimates[eNB_id][(j<<1) + i][(ue->frame_parms.Ncp == 0 ? 4 : 3)*ue->frame_parms.ofdm_symbol_size],
+	       ue->frame_parms.ofdm_symbol_size*sizeof(int));
       }
   }
 
@@ -1566,7 +1542,7 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
 
   if (last_slot==0) {
     emos_dump_UE.timestamp = rt_get_time_ns();
-    emos_dump_UE.frame_rx = ue->frame_rx;
+    emos_dump_UE.frame_rx = proc->frame_rx;
     emos_dump_UE.UE_mode = ue->UE_mode[eNB_id];
     emos_dump_UE.mimo_mode = ue->transmission_mode[eNB_id];
     emos_dump_UE.freq_offset = ue->common_vars.freq_offset;
@@ -1603,10 +1579,10 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
     bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_UE, sizeof(fifo_dump_emos_UE));
 
     if (bytes!=sizeof(fifo_dump_emos_UE)) {
-      LOG_W(PHY,"[UE  %d] frame %d, slot %d, Problem writing EMOS data to FIFO\n",Mod_id,ue->frame_rx, last_slot);
+      LOG_W(PHY,"[UE  %d] frame %d, slot %d, Problem writing EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot);
     } else {
-      if (ue->frame_rx%100==0) {
-        LOG_I(PHY,"[UE  %d] frame %d, slot %d, Writing %d bytes EMOS data to FIFO\n",Mod_id,ue->frame_rx, last_slot, bytes);
+      if (proc->frame_rx%100==0) {
+	LOG_I(PHY,"[UE  %d] frame %d, slot %d, Writing %d bytes EMOS data to FIFO\n",Mod_id,proc->frame_rx, last_slot, bytes);
       }
     }
   }
@@ -1615,12 +1591,12 @@ void phy_procedures_emos_UE_RX(PHY_VARS_UE *ue,uint8_t last_slot,uint8_t eNB_id)
 #endif
 
 
-void restart_phy(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag)
+void restart_phy(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,uint8_t abstraction_flag)
 {
 
   //  uint8_t last_slot;
   uint8_t i;
-  LOG_I(PHY,"[UE  %d] frame %d, slot %d, restarting PHY!\n",ue->Mod_id,ue->frame_rx,ue->slot_rx);
+  LOG_I(PHY,"[UE  %d] frame %d, slot %d, restarting PHY!\n",ue->Mod_id,proc->frame_rx,proc->subframe_rx);
   mac_xface->macphy_exit("restart_phy called");
   //   first_run = 1;
 
@@ -1631,8 +1607,8 @@ void restart_phy(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag)
     ue->prach_resources[eNB_id]=NULL;
   }
 
-  ue->frame_rx = -1;
-  ue->frame_tx = -1;
+  proc->frame_rx = -1;
+  proc->frame_tx = -1;
   //  ue->synch_wait_cnt=0;
   //  ue->sched_cnt=-1;
 
@@ -1673,7 +1649,7 @@ void restart_phy(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag)
 }
 
 
-void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
+void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag)
 {
 
   //  int i;
@@ -1684,8 +1660,9 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
   uint8_t pbch_trials = 0;
 
   DevAssert(ue);
-  int slot_rx = ue->slot_rx;
-  int frame_rx = ue->frame_rx;
+
+  int frame_rx = proc->frame_rx;
+  int subframe_rx = proc->subframe_rx;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN);
 
@@ -1699,12 +1676,12 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
     //LOG_I(PHY,"[UE  %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id);
     if (abstraction_flag == 0) {
       pbch_tx_ant = rx_pbch(&ue->common_vars,
-                            ue->pbch_vars[eNB_id],
-                            &ue->frame_parms,
-                            eNB_id,
-                            ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
-                            ue->high_speed_flag,
-                            pbch_phase);
+			    ue->pbch_vars[eNB_id],
+			    &ue->frame_parms,
+			    eNB_id,
+			    ue->frame_parms.mode1_flag==1?SISO:ALAMOUTI,
+			    ue->high_speed_flag,
+			    pbch_phase);
 
 
 
@@ -1713,8 +1690,8 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 #ifdef PHY_ABSTRACTION
     else {
       pbch_tx_ant = rx_pbch_emul(ue,
-                                 eNB_id,
-                                 pbch_phase);
+				 eNB_id,
+				 pbch_phase);
     }
 
 #endif
@@ -1757,76 +1734,74 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 
     if (first_run) {
       first_run = 0;
-      LOG_I(PHY,"[UE %d] frame %d, slot %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d).\n",
-            ue->Mod_id,
-            frame_rx,
-            slot_rx,
-            pbch_tx_ant,
-            frame_tx,
-            pbch_phase);
-      ue->frame_rx = (ue->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
-      ue->frame_tx = ue->frame_rx;
-      frame_rx = ue->frame_rx;
-    } else if (((frame_tx & 0x03FF) != (ue->frame_rx & 0x03FF))) {
+
+      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+      proc->frame_tx = proc->frame_rx;
+      ue->proc.proc_rxtx[1].frame_rx = proc->frame_rx;
+      ue->proc.proc_rxtx[1].frame_tx = proc->frame_tx;
+      LOG_I(PHY,"[UE %d] frame %d, subframe %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d, rx_offset %d) => new frame %d\n",
+	    ue->Mod_id,
+	    frame_rx,
+	    subframe_rx,
+	    pbch_tx_ant,
+	    frame_tx,
+	    pbch_phase,
+	    ue->rx_offset,
+	    proc->frame_rx);
+      frame_rx = proc->frame_rx;
+      
+    } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) {
       //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) {
-      LOG_D(PHY,"[UE %d] frame %d, slot %d: Re-adjusting frame counter (PBCH ant_tx=%d, frame_rx=%d, frame%1024=%d, phase %d).\n",
-            ue->Mod_id,
-            ue->frame_rx,
-            slot_rx,
-            pbch_tx_ant,
-            frame_tx,
-            frame_rx & 0x03FF,
-            pbch_phase);
-
-      ue->frame_rx = (ue->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
-      ue->frame_tx = ue->frame_rx;
-      frame_rx = ue->frame_rx;
-      /*
-      LOG_D(PHY,"[UE  %d] frame %d, slot %d: PBCH PDU does not match, ignoring it (PBCH ant_tx=%d, frame_tx=%d).\n",
-          ue->Mod_id,
-          ue->frame,
-          slot_rx,
-          pbch_tx_ant,
-          frame_tx);
-      */
-      //ue->pbch_vars[eNB_id]->pdu_errors_conseq = 21; // this will make it go out of sync
-      //ue->pbch_vars[eNB_id]->pdu_errors_conseq += 1; // this will make it go out of sync
+      LOG_D(PHY,"[UE %d] frame %d, subframe %d: Re-adjusting frame counter (PBCH ant_tx=%d, frame_rx=%d, frame%1024=%d, phase %d).\n",
+	    ue->Mod_id,
+	    proc->frame_rx,
+	    subframe_rx,
+	    pbch_tx_ant,
+	    frame_tx,
+	    frame_rx & 0x03FF,
+	    pbch_phase);
+
+      proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+      ue->proc.proc_rxtx[1].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+      proc->frame_tx = proc->frame_rx;
+      ue->proc.proc_rxtx[1].frame_tx = proc->frame_rx;
+      frame_rx = proc->frame_rx;
+
     }
 
 #ifdef DEBUG_PHY_PROC
-    LOG_D(PHY,"[UE %d] frame %d, slot %d, Received PBCH (MIB): mode1_flag %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
-          ue->Mod_id,
-          frame_rx,
-          slot_rx,
-          ue->frame_parms.mode1_flag,
-          pbch_tx_ant,
-          frame_tx,
-          ue->frame_parms.N_RB_DL,
-          ue->frame_parms.phich_config_common.phich_duration,
-          ue->frame_parms.phich_config_common.phich_resource);
+    LOG_D(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): mode1_flag %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
+	  ue->Mod_id,
+	  frame_rx,
+	  subframe_rx,
+	  ue->frame_parms.mode1_flag,
+	  pbch_tx_ant,
+	  frame_tx,
+	  ue->frame_parms.N_RB_DL,
+	  ue->frame_parms.phich_config_common.phich_duration,
+	  ue->frame_parms.phich_config_common.phich_resource);
+#endif
+
+  } else { 
     /*
-    if (frame_rx%100 == 0) {
-      LOG_I(PHY,"[UE %d] frame %d, slot %d, PBCH: mode1_flag %d, tx_ant %d, frame_tx %d, phase %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6,Frequency offset %d Hz (%d)\n",
-            ue->Mod_id,
-            frame_rx,
-            slot_rx,
-            ue->frame_parms.mode1_flag,
-            pbch_tx_ant,
-            frame_tx,
-            pbch_phase,
-            ue->frame_parms.N_RB_DL,
-            ue->frame_parms.phich_config_common.phich_duration,
-            ue->frame_parms.phich_config_common.phich_resource,
-            ue->common_vars.freq_offset,openair_daq_vars.freq_offset);
-      //dump_frame_parms(&ue->frame_parms);
+    LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
+	  ue->Mod_id,frame_rx, subframe_rx);
 
-    }
-      */
-#endif
+    LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);
+
+
+    write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1);
+
+    write_output("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
+    write_output("H10.m","h10",&(ue->common_vars.dl_ch_estimates[0][2][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
+
+    write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],8*ue->frame_parms.ofdm_symbol_size,1,1);
+    write_output("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1);
+    write_output("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1);
+    write_output("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4);
+    exit(-1);
+    */
 
-  } else {
-    LOG_E(PHY,"[UE %d] frame %d, slot %d, Error decoding PBCH!\n",
-          ue->Mod_id,frame_rx, slot_rx);
     ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
     ue->pbch_vars[eNB_id]->pdu_errors++;
     if (ue->mac_enabled == 1) {
@@ -1847,24 +1822,21 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 
 #ifdef DEBUG_PHY_PROC
   LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n",
-        ue->Mod_id,frame_rx, slot_rx,
-        ue->pbch_vars[eNB_id]->pdu_errors,
-        ue->pbch_vars[eNB_id]->pdu_errors_conseq);
+	ue->Mod_id,frame_rx, subframe_rx,
+	ue->pbch_vars[eNB_id]->pdu_errors,
+	ue->pbch_vars[eNB_id]->pdu_errors_conseq);
 #endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT);
 }
 
-int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
+int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag)
 {
 
   unsigned int dci_cnt=0, i;
-  //DCI_PDU *DCI_pdu;
-  //uint16_t ra_RNTI;
 
-
-  int frame_rx = ue->frame_rx;
-  int slot_rx = ue->slot_rx;
-  int subframe_rx = slot_rx>>1;
+  int frame_rx = proc->frame_rx;
+  int subframe_rx = proc->subframe_rx;
+  DCI_ALLOC_t dci_alloc_rx[8];
 
 
 #ifdef PHY_ABSTRACTION
@@ -1874,6 +1846,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 #endif
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
+  start_meas(&ue->dlsch_rx_pdcch_stats);
 
   //  if (subframe_rx != 5)
   //    return 0;
@@ -1881,29 +1854,29 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
     rx_pdcch(&ue->common_vars,
-             ue->pdcch_vars,
-             &ue->frame_parms,
-             subframe_rx,
-             eNB_id,
-             (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
-             ue->high_speed_flag,
-             ue->is_secondary_ue);
+	     ue->pdcch_vars,
+	     &ue->frame_parms,
+	     subframe_rx,
+	     eNB_id,
+	     (ue->frame_parms.mode1_flag == 1) ? SISO : ALAMOUTI,
+	     ue->high_speed_flag,
+	     ue->is_secondary_ue);
 
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN);
     dci_cnt = dci_decoding_procedure(ue,
-                                     dci_alloc_rx,
-                                     (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
-                                     // later when we need paging or RA during connection, update this ...
-                                     eNB_id,subframe_rx);
+				     dci_alloc_rx,
+				     (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0,  // if we're in PUSCH don't listen to common search space,
+				     // later when we need paging or RA during connection, update this ...
+				     eNB_id,subframe_rx);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT);
     //LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d PHICH RX\n",ue->Mod_id,frame_rx,subframe_rx);
 
     if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN);
-      rx_phich(ue,
-               subframe_rx,eNB_id);
+      rx_phich(ue,proc,
+	       subframe_rx,eNB_id);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
     }
   }
@@ -1912,11 +1885,11 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
   else {
     for (i=0; i<NB_eNB_INST; i++) {
       for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
-        if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
-          break;
+	if (PHY_vars_eNB_g[i][CC_id]->frame_parms.Nid_cell == ue->frame_parms.Nid_cell)
+	  break;
 
       if (CC_id < MAX_NUM_CCs)
-        break;
+	break;
     }
 
     if (i==NB_eNB_INST) {
@@ -1928,142 +1901,65 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 
     LOG_D(PHY,"Calling dci_decoding_proc_emul ...\n");
     dci_cnt = dci_decoding_procedure_emul(ue->pdcch_vars,
-                                          PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[subframe_rx&1],
-                                          PHY_vars_eNB_g[i][CC_id]->num_common_dci[subframe_rx&1],
-                                          PHY_vars_eNB_g[i][CC_id]->dci_alloc[subframe_rx&1],
-                                          dci_alloc_rx,
-                                          eNB_id);
+					  PHY_vars_eNB_g[i][CC_id]->num_ue_spec_dci[subframe_rx&1],
+					  PHY_vars_eNB_g[i][CC_id]->num_common_dci[subframe_rx&1],
+					  PHY_vars_eNB_g[i][CC_id]->dci_alloc[subframe_rx&1],
+					  dci_alloc_rx,
+					  eNB_id);
     //    printf("DCI: dci_cnt %d\n",dci_cnt);
     UE_id = (uint32_t)find_ue((int16_t)ue->pdcch_vars[eNB_id]->crnti,PHY_vars_eNB_g[i][CC_id]);
 
     if (UE_id>=0) {
-      //      msg("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
+      //      printf("Checking PHICH for UE  %d (eNB %d)\n",UE_id,i);
       if (is_phich_subframe(&ue->frame_parms,subframe_rx)) {
-        harq_pid = phich_subframe_to_harq_pid(&ue->frame_parms,frame_rx,subframe_rx);
-
-        if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == ACTIVE) {
-          // ue->ulsch[eNB_id]->harq_processes[harq_pid]->phich_ACK=1;
-          ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
-          ue->ulsch[eNB_id]->harq_processes[harq_pid]->status = IDLE;
-          ue->ulsch_Msg3_active[eNB_id] = 0;
-          ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
-          LOG_D(PHY,"Msg3 inactive\n");
-          /* Phich is not abstracted for the moment
-          if (PHY_vars_eNB_g[i][CC_id]->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->phich_ACK==0) { // NAK
-            if (ue->ulsch_Msg3_active[eNB_id] == 1) {
-          #ifdef DEBUG_PHY_PROC
-              LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Msg3 PHICH, received NAK\n",
-            ue->Mod_id,
-            frame_rx,
-            subframe_rx);
-          #endif
-              get_Msg3_alloc_ret(&ue->frame_parms,
-               subframe_rx,
-               frame_rx,
-                   &ue->ulsch_Msg3_frame[eNB_id],
-               &ue->ulsch_Msg3_subframe[eNB_id]);
-            }
-            //      PHY_vars_eNB_g[i][CC_id]->ulsch_eNB[UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
-            //      PHY_vars_eNB_g[i][CC_id]->ulsch_eNB[UE_id]->harq_processes[harq_pid]->Ndi = 0;
-            //      PHY_vars_eNB_g[i][CC_id]->ulsch_eNB[UE_id]->harq_processes[harq_pid]->round++;
-          }
-          else {
-          #ifdef DEBUG_PHY_PROC
-            if (ue->ulsch_Msg3_active[eNB_id] == 1)
-              LOG_D(PHY,"[UE  %d][RAPROC] Frame %d, subframe %d: Msg3 PHICH, received ACK\n",
-            ue->Mod_id,
-            frame_rx,
-            subframe_rx);
-          #endif
-                  PHY_vars_eNB_g[i][CC_id]->ulsch_eNB[UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
-                  PHY_vars_eNB_g[i][CC_id]->ulsch_eNB[UE_id]->harq_processes[harq_pid]->status = IDLE;
-            // inform MAC?
-            ue->ulsch_Msg3_active[eNB_id] = 0;
-          } //phich_ACK */
-        } // harq_pid is ACTIVE
+	harq_pid = phich_subframe_to_harq_pid(&ue->frame_parms,frame_rx,subframe_rx);
+
+	if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->status == ACTIVE) {
+	  // ue->ulsch[eNB_id]->harq_processes[harq_pid]->phich_ACK=1;
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag =0;
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->status = IDLE;
+	  ue->ulsch_Msg3_active[eNB_id] = 0;
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+	  LOG_D(PHY,"Msg3 inactive\n");
+
+	} // harq_pid is ACTIVE
       } // This is a PHICH subframe
     } // UE_id exists
   }
 
 #endif
 
-  //#ifdef DEBUG_PHY_PROC
-  LOG_D(PHY,"[UE  %d] Frame %d, slot %d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx,slot_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt);
-  //#endif
+
+  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d, Mode %s: DCI found %i\n",ue->Mod_id,frame_rx,subframe_rx,mode_string[ue->UE_mode[eNB_id]],dci_cnt);
+
+ 
 
   ue->pdcch_vars[eNB_id]->dci_received += dci_cnt;
-  /*
-  #ifdef DEBUG_PHY_PROC
-  if (slot_rx==18)
-    debug_LOG_D(PHY,"[UE  %d] Frame %d, slot %d: PDCCH: DCI errors %d, DCI received %d, DCI missed %d, DCI False Detection %d \n",
-        ue->Mod_id,frame_rx,slot_rx,
-        ue->pdcch_vars[eNB_id]->dci_errors,
-        ue->pdcch_vars[eNB_id]->dci_received,
-        ue->pdcch_vars[eNB_id]->dci_missed,
-        ue->pdcch_vars[eNB_id]->dci_false);
-  #endif
-  */
+
 #ifdef EMOS
   //emos_dump_UE.dci_cnt[subframe_rx] = dci_cnt;
 #endif
 
-  /*
-    #ifdef DIAG_PHY
-    //if (ue->UE_mode[eNB_id] == PUSCH)
-    if (dci_cnt > 1) {
-    LOG_D(PHY,"[UE  %d][DIAG] frame %d, subframe %d: received %d>1 DCI!\n",ue->Mod_id,frame_rx,subframe_rx,dci_cnt);
-    ue->pdcch_vars[eNB_id]->dci_false++;
-    }
-    else if (dci_cnt==0) {
-    LOG_D(PHY,"[UE  %d][DIAG] frame %d, subframe %d: received %d DCI!\n",ue->Mod_id,frame_rx,subframe_rx,dci_cnt);
-    ue->pdcch_vars[eNB_id]->dci_missed++;
-    }
-    #endif
-  */
-
-  // dci_cnt = 0;
-  //  ra_RNTI = (ue->prach_resources[eNB_id]) ? ue->prach_resources[eNB_id]->ra_RNTI : 0;
   for (i=0; i<dci_cnt; i++) {
 
-#ifdef DEBUG_PHY_PROC
-
-    if ( frame_rx % 100 == 0)   {
-      LOG_D(PHY,"frame %d, subframe %d, rnti %x: dci %d/%d\n",frame_rx,subframe_rx,ue->pdcch_vars[eNB_id]->crnti,i,dci_cnt);
-      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-    }
-
-#endif
 
-    //if ((ue->UE_mode[eNB_id] != PRACH) &&
-    //    (dci_alloc_rx[i].rnti != 0x1234) &&
 
     if ((ue->UE_mode[eNB_id]>PRACH) &&
 	(dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) &&
 	(dci_alloc_rx[i].format != format0)) {
       
-#ifdef DEBUG_PHY_PROC
+
       LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] frame %d, subframe %d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
-            ue->Mod_id,dci_alloc_rx[i].rnti,
-            frame_rx,subframe_rx,
-            dci_alloc_rx[i].format,
-            ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-            ue->pdcch_vars[eNB_id]->nCCE[subframe_rx],
-            get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
+	    ue->Mod_id,dci_alloc_rx[i].rnti,
+	    frame_rx,subframe_rx,
+	    dci_alloc_rx[i].format,
+	    ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
+	    ue->pdcch_vars[eNB_id]->nCCE[subframe_rx],
+	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
+
+
 
 
-#endif
-#ifdef DIAG_PHY
-      
-      if (!(((subframe_rx == 7) && (dci_alloc_rx[i].format == format1E_2A_M10PRB)) ||
-            ((subframe_rx == 7) && (dci_alloc_rx[i].format == format1)))) {
-        LOG_E(PHY,"[UE  %d][DIAG] frame %d, subframe %d: should not have received C_RNTI Format %d!\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format);
-        ue->pdcch_vars[eNB_id]->dci_errors++;
-        ue->pdcch_vars[eNB_id]->dci_false++;
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
-        return(-1);
-      }
-      
-#endif
       
       //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
       if ((ue->UE_mode[eNB_id] > PRACH) &&
@@ -2079,86 +1975,61 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 					     0,
 					     P_RNTI)==0)) {
 
-#ifdef DIAG_PHY
-	
-        if (ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->mcs != (((frame_rx%1024)%28))) {
-          LOG_E(PHY,"[UE  %d][DIAG] frame %d, subframe %d: wrong mcs!\n",ue->Mod_id,frame_rx,subframe_rx,
-                ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->mcs);
-          dump_dci(&ue->frame_parms,(void *)&dci_alloc_rx[i]);
-        }
-	
-#endif
-	
-	
-        ue->dlsch_received[eNB_id]++;
+	ue->dlsch_received[eNB_id]++;
 	
 #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format);
-        dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-        LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d (%d)=> %d\n",ue->Mod_id,subframe_rx,slot_rx,ue->dlsch[eNB_id][0]->active);
+	LOG_D(PHY,"[UE  %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format);
+	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[eNB_id][0]->active);
 #endif
 	
-        // we received a CRNTI, so we're in PUSCH
-        if (ue->UE_mode[eNB_id] != PUSCH) {
+	// we received a CRNTI, so we're in PUSCH
+	if (ue->UE_mode[eNB_id] != PUSCH) {
 #ifdef DEBUG_PHY_PROC
-          LOG_D(PHY,"[UE  %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[eNB_id]->crnti);
+	  LOG_D(PHY,"[UE  %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[eNB_id]->crnti);
 #endif
-          //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-          ue->UE_mode[eNB_id] = PUSCH;
-          //mac_xface->macphy_exit("Connected. Exiting\n");
-        }
+	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	  ue->UE_mode[eNB_id] = PUSCH;
+	  //mac_xface->macphy_exit("Connected. Exiting\n");
+	}
       } else {
-        LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx);
-        dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx);
+	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
       }
     }
 
     else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
-             ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
+	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
 
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i);
-      /*
-      if (((frame_rx%100) == 0) || (frame_rx < 20))
-      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-      */
 #endif
-#ifdef DIAG_PHY
-
-      if ((subframe_rx != 5)) {
-        LOG_E(PHY,"[UE  %d][DIAG] frame %d, subframe %d: should not have received SI_RNTI!\n",ue->Mod_id,frame_rx,subframe_rx);
-        ue->pdcch_vars[eNB_id]->dci_errors++;
-        ue->pdcch_vars[eNB_id]->dci_false++;
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
-        return(-1);
-      }
 
-#endif
 
       if (generate_ue_dlsch_params_from_dci(frame_rx,
 					    subframe_rx,
-                                            (void *)&dci_alloc_rx[i].dci_pdu,
-                                            SI_RNTI,
-                                            dci_alloc_rx[i].format,
-                                            &ue->dlsch_SI[eNB_id],
-                                            &ue->frame_parms,
-                                            ue->pdsch_config_dedicated,
-                                            SI_RNTI,
-                                            0,
-                                            P_RNTI)==0) {
-
-        ue->dlsch_SI_received[eNB_id]++;
+					    (void *)&dci_alloc_rx[i].dci_pdu,
+					    SI_RNTI,
+					    dci_alloc_rx[i].format,
+					    &ue->dlsch_SI[eNB_id],
+					    &ue->frame_parms,
+					    ue->pdsch_config_dedicated,
+					    SI_RNTI,
+					    0,
+					    P_RNTI)==0) {
+
+	ue->dlsch_SI_received[eNB_id]++;
  
 
 	LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C");
-        //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	//dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
 
       }
     }
 
     else if ((ue->prach_resources[eNB_id]) &&
-             (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
-             (dci_alloc_rx[i].format == format1A)) {
+	     (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) &&
+	     (dci_alloc_rx[i].format == format1A)) {
 
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d][RAPROC] subframe %d: Found RA rnti %x, format 1A, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,i);
@@ -2167,57 +2038,32 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
       //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
       //mac_xface->macphy_exit("so far so good...\n");
 #endif
-#ifdef DIAG_PHY
-
-      if (subframe_rx != 9) {
-        LOG_E(PHY,"[UE  %d][DIAG] frame %d, subframe %d: should not have received RA_RNTI!\n",ue->Mod_id,frame_rx,subframe_rx);
-        ue->pdcch_vars[eNB_id]->dci_errors++;
-        ue->pdcch_vars[eNB_id]->dci_false++;
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
-        return(-1);
-      }
 
-#endif
 
       if (generate_ue_dlsch_params_from_dci(frame_rx,
 					    subframe_rx,
-                                            (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
-                                            ue->prach_resources[eNB_id]->ra_RNTI,
-                                            format1A,
-                                            &ue->dlsch_ra[eNB_id],
-                                            &ue->frame_parms,
-                                            ue->pdsch_config_dedicated,
-                                            SI_RNTI,
-                                            ue->prach_resources[eNB_id]->ra_RNTI,
-                                            P_RNTI)==0) {
-
-        ue->dlsch_ra_received[eNB_id]++;
+					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
+					    ue->prach_resources[eNB_id]->ra_RNTI,
+					    format1A,
+					    &ue->dlsch_ra[eNB_id],
+					    &ue->frame_parms,
+					    ue->pdsch_config_dedicated,
+					    SI_RNTI,
+					    ue->prach_resources[eNB_id]->ra_RNTI,
+					    P_RNTI)==0) {
+
+	ue->dlsch_ra_received[eNB_id]++;
 
 #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
-              ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
+	LOG_D(PHY,"[UE  %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n",
+	      ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]);
 #endif
       }
     } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[eNB_id]->crnti) &&
-               (dci_alloc_rx[i].format == format0)) {
+	       (dci_alloc_rx[i].format == format0)) {
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n",
-            ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
-      /*
-        if (((frame_rx%100) == 0) || (frame_rx < 20))
-        dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-      */
-#endif
-#ifdef DIAG_PHY
-
-      if (subframe_rx != 9) {
-        LOG_E(PHY,"[UE  %d][DIAG] frame %d, subframe %d: should not have received C_RNTI Format 0!\n",ue->Mod_id,frame_rx,subframe_rx);
-        ue->pdcch_vars[eNB_id]->dci_errors++;
-        ue->pdcch_vars[eNB_id]->dci_false++;
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
-        return(-1);
-      }
-
+	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
 #endif
 
       ue->ulsch_no_allocation_counter[eNB_id] = 0;
@@ -2229,6 +2075,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 					     subframe_rx,
 					     format0,
 					     ue,
+					     proc,
 					     SI_RNTI,
 					     0,
 					     P_RNTI,
@@ -2237,34 +2084,22 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 					     0)==0)) {
 
 #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
+	LOG_D(PHY,"[UE  %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
 #endif
 
       }
     } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) &&
-               (dci_alloc_rx[i].format == format0)) {
+	       (dci_alloc_rx[i].format == format0)) {
       // UE could belong to more than one CBA group
       // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups]
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n",
-            ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
+	    ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i);
       /*
-        if (((frame_rx%100) == 0) || (frame_rx < 20))
-        dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+	if (((frame_rx%100) == 0) || (frame_rx < 20))
+	dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
       */
 #endif
-      /*
-      #ifdef DIAG_PHY
-      if (subframe_rx != 8) {
-        LOG_E(PHY,"[UE  %d][DIAG] frame %d, subframe %d: should not have received CBA RNTI Format 0!\n",
-        ue->Mod_id,frame_rx,subframe_rx);
-        ue->pdcch_vars[eNB_id]->dci_errors++;
-        ue->pdcch_vars[eNB_id]->dci_false++;
-              VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
-        return(-1);
-      }
-      #endif
-      */
 
       ue->ulsch_no_allocation_counter[eNB_id] = 0;
       //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
@@ -2275,6 +2110,7 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 					     subframe_rx,
 					     format0,
 					     ue,
+					     proc,
 					     SI_RNTI,
 					     0,
 					     P_RNTI,
@@ -2283,1093 +2119,792 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,uint8_t abstraction_flag)
 					     0)==0)) {
 
 #ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
+	LOG_D(PHY,"[UE  %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx);
 #endif
-        ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
+	ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++;
       }
     }
 
     else {
 #ifdef DEBUG_PHY_PROC
       LOG_D(PHY,"[UE  %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti,
-            ue->pdcch_vars[eNB_id]->crnti,
-            ue->ulsch[eNB_id]->cba_rnti[0],
-            dci_alloc_rx[i].format);
+	    ue->pdcch_vars[eNB_id]->crnti,
+	    ue->ulsch[eNB_id]->cba_rnti[0],
+	    dci_alloc_rx[i].format);
       //      dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-#endif
-#ifdef DIAG_PHY
-      ue->pdcch_vars[eNB_id]->dci_errors++;
-      ue->pdcch_vars[eNB_id]->dci_false++;
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
-      return(-1);
 #endif
     }
 
   }
-/*
-  if ((frame_rx > 1000) && ((frame_rx&1)==0) && (subframe_rx == 5)) {
-    write_output("rxsig0.m","rxs0", ue->common_vars.rxdata[0],10*ue->frame_parms.samples_per_tti,1,1);
-    write_output("rxsigF0.m","rxsF0", ue->common_vars.rxdataF[0],ue->frame_parms.ofdm_symbol_size*2*((ue->frame_parms.Ncp==0)?14:12),2,1);
-    write_output("H00.m","h00",&(ue->common_vars.dl_ch_estimates[0][0][0]),((ue->frame_parms.Ncp==0)?7:6)*(ue->frame_parms.ofdm_symbol_size),1,1);
 
-    write_output("pdcch_rxF_ext0.m","pdcch_rxF_ext0",ue->pdcch_vars[eNB_id]->rxdataF_ext[0],3*12*ue->frame_parms.N_RB_DL,1,1);
-    write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",ue->pdcch_vars[eNB_id]->rxdataF_comp[0],4*12*ue->frame_parms.N_RB_DL,1,1);
-    write_output("pdcch_rxF_llr.m","pdcch_llr",ue->pdcch_vars[eNB_id]->llr,2400,1,4);
-    mac_xface->macphy_exit("debug exit");
-  }
-*/ 
+  stop_meas(&ue->dlsch_rx_pdcch_stats);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
   return(0);
 }
 
 
-int phy_procedures_UE_RX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
-                         relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn)
-{
- 
-  uint16_t l,m,n_symb;
-  //  int eNB_id = 0,
-  int ret=0;
-  uint8_t harq_pid = -1;
-  int timing_advance;
-  uint8_t pilot1,pilot2,pilot3;
-  uint8_t i_mod = 0;
-  int eNB_id_i = 1;
-  uint8_t dual_stream_UE = 0;
+void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) {
 
-  uint8_t *rar;
-  int pmch_flag=0;
-  uint8_t sync_area=255;
+  int subframe_rx = proc->subframe_rx;
+  int frame_rx = proc->frame_rx;
   int pmch_mcs=-1;
-  uint8_t mcch_active=0;
-  int frame_rx = ue->frame_rx;
-  int slot_rx = ue->slot_rx;
-  int subframe_rx = slot_rx>>1;
-  int subframe_prev = (subframe_rx+9)%10;
   int CC_id = ue->CC_id;
+  uint8_t sync_area=255;
+  uint8_t mcch_active;
+  int l;
+  int ret=0;
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
-
-
-  start_meas(&ue->phy_proc_rx);
-#ifdef DEBUG_PHY_PROC
-  LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX(%d)\n",
-        (r_type == multicast_relay) ? "RN/UE" : "UE",
-        ue->Mod_id,frame_rx, subframe_rx, slot_rx);
+  if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
+    LOG_D(PHY,"ue calling pmch subframe ..\n ");
+    
+    LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n",
+	  ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
+#ifdef Rel10
+    pmch_mcs = mac_xface->ue_query_mch(ue->Mod_id,
+				       CC_id,
+				       frame_rx,
+				       subframe_rx,
+				       eNB_id,
+				       &sync_area,
+				       &mcch_active);
+    
+#else
+    pmch_mcs=-1;
 #endif
-#ifdef EMOS
+    
+    if (pmch_mcs>=0) {
+      LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,pmch_mcs);
+      fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0);
+      
+      if (abstraction_flag == 0 ) {
+	for (l=2; l<12; l++) {
+	  
+	  slot_fep_mbsfn(ue,
+			 l,
+			 subframe_rx,
+			 0,0);//ue->rx_offset,0);
+	}
 
-  if ((slot_rx == 0)) {
-    if (frame_rx%1024 == 0)
-      openair_daq_vars.use_ia_receiver = 0;
-    else
-      openair_daq_vars.use_ia_receiver = (openair_daq_vars.use_ia_receiver+1)%3;
+	for (l=2; l<12; l++) {
+	  rx_pmch(ue,
+		  0,
+		  subframe_rx,
+		  l);
+	}
 
-    LOG_D(PHY,"[MYEMOS] frame %d, IA receiver %d, MCS %d, bitrate %d\n",
-          frame_rx,
-          openair_daq_vars.use_ia_receiver,
-          ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->mcs,
-          ue->bitrate[eNB_id]);
-  }
 
+	ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
+						       ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
+						       ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
+						       ue->dlsch_MCH[0]->harq_processes[0]->Qm,
+						       1,
+						       2,
+						       frame_rx,subframe_rx);
+	
+	dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
+			   ue->dlsch_MCH[0]->harq_processes[0]->G,
+			   ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1);
+	
+	ret = dlsch_decoding(ue,
+			     ue->pdsch_vars_MCH[0]->llr[0],
+			     &ue->frame_parms,
+			     ue->dlsch_MCH[0],
+			     ue->dlsch_MCH[0]->harq_processes[0],
+			     subframe_rx,
+			     0,
+			     0,1);
+      } else { // abstraction
+#ifdef PHY_ABSTRACTION
+	ret = dlsch_decoding_emul(ue,
+				  subframe_rx,
+				  5, // PMCH
+				  eNB_id);
 #endif
+      }
+      
+      if (mcch_active == 1)
+	ue->dlsch_mcch_trials[sync_area][0]++;
+      else
+	ue->dlsch_mtch_trials[sync_area][0]++;
+      
+      if (ret == (1+ue->dlsch_MCH[0]->max_turbo_iterations)) {
+	if (mcch_active == 1)
+	  ue->dlsch_mcch_errors[sync_area][0]++;
+	else
+	  ue->dlsch_mtch_errors[sync_area][0]++;
+	
+	LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
+	      frame_rx,subframe_rx,
+	      ue->dlsch_mcch_errors[sync_area][0],
+	      ue->dlsch_mtch_errors[sync_area][0],
+	      ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
+	      ue->dlsch_MCH[0]->max_turbo_iterations,
+	      ue->dlsch_MCH[0]->harq_processes[0]->G);
+	dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
+#ifdef DEBUG_DLSCH
+	
+	for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
+	  LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]);
+	}
+	
+	LOG_T(PHY,"\n");
+#endif
+	
+	if (subframe_rx==9)
+	  mac_xface->macphy_exit("Why are we exiting here?");
+      } else { // decoding successful
+#ifdef Rel10
+	
+	if (mcch_active == 1) {
+	  mac_xface->ue_send_mch_sdu(ue->Mod_id,
+				     CC_id,
+				     frame_rx,
+				     ue->dlsch_MCH[0]->harq_processes[0]->b,
+				     ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
+				     eNB_id,// not relevant in eMBMS context
+				     sync_area);
+	  ue->dlsch_mcch_received[sync_area][0]++;
+	  
+	  
+	  if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
+	    ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
+	  } else {
+	    ue->dlsch_mch_received[0]+=1;
+	    ue->dlsch_mch_received_sf[subframe_rx][0]=1;
+	  }
+	  
+	  
+	}
+#endif // Rel10
+      } // decoding sucessful
+    } // pmch_mcs>=0
+  } // is_pmch_subframe=true
+}
 
-  if (ue->frame_parms.Ncp == 0) {  // normal prefix
-    pilot1 = 4;
-    pilot2 = 7;
-    pilot3 = 11;
-  } else { // extended prefix
-    pilot1 = 3;
-    pilot2 = 6;
-    pilot3 = 9;
-  }
-
-  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) {
-    if ((slot_rx%2)==0)
-      n_symb = 5;//3;
-    else
-      n_symb = 0;
-  } else {
-    /*
-    if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) {
-      if ((slot_rx%2)==0) {
-    n_symb=2;
-    pmch_flag=1;
+void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, LTE_UE_DLSCH_t *dlsch0, LTE_UE_DLSCH_t *dlsch1, int s0, int s1, int abstraction_flag) {
+
+  int subframe_rx = proc->subframe_rx;
+  int m;
+  int harq_pid;
+  int i_mod,eNB_id_i,dual_stream_UE;
+  int first_symbol_flag=0;
+
+  if (dlsch0->active == 0)
+    return;
+
+  for (m=s0;m<=s1;m++) {
+
+    if (dlsch0 && (!dlsch1))  {
+      harq_pid = dlsch0->current_harq_pid;
+      LOG_D(PHY,"[UE %d] PDSCH active in subframe %d (%d), harq_pid %d\n",ue->Mod_id,subframe_rx,harq_pid);
+	    
+      if ((pdsch==PDSCH) && 
+	  (ue->transmission_mode[eNB_id] == 5) &&
+	  (dlsch0->harq_processes[harq_pid]->dl_power_off==0) &&
+	  (ue->use_ia_receiver ==1)) {
+	dual_stream_UE = 1;
+	eNB_id_i = ue->n_connected_eNB;
+	i_mod =  dlsch0->harq_processes[harq_pid]->Qm;
+      } else {
+	dual_stream_UE = 0;
+	eNB_id_i = eNB_id+1;
+	i_mod = 0;
       }
+      
+      if ((m==s0) && (m<4))
+	first_symbol_flag = 1;
       else
-    n_symb=0;
-    }
-    else*/
-    n_symb = ue->frame_parms.symbols_per_tti/2;
+	first_symbol_flag = 0;
+
+      start_meas(&ue->dlsch_llr_stats);
+      // process DLSCH received in first slot
+      rx_pdsch(ue,
+	       pdsch,
+	       eNB_id,
+	       eNB_id_i,
+	       subframe_rx,  // subframe,
+	       m,
+	       first_symbol_flag,
+	       dual_stream_UE,
+	       i_mod,
+	       dlsch0->current_harq_pid);
+      stop_meas(&ue->dlsch_llr_stats);
+    } // CRNTI active
   }
+} 
 
-  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-  // This is normal processing (i.e. not MBSFN)
-  // RX processing of symbols in slot_rx
-
-  
-
-  for (l=0; l<n_symb; l++) {
-    if (abstraction_flag == 0) {
-      start_meas(&ue->ofdm_demod_stats);
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
 
-      slot_fep(ue,
-               l,
-               slot_rx,
-               ue->rx_offset,
-               0,
-	       0);
-      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
-      stop_meas(&ue->ofdm_demod_stats);
-    }
-
-    //if (subframe_select(&ue->frame_parms,subframe_rx) == SF_DL)
-    ue_measurement_procedures(l,ue,eNB_id,abstraction_flag,mode);
-
-
-    if ((slot_rx==1) && (l==4-ue->frame_parms.Ncp)) {
+  int frame_rx = proc->frame_rx;
+  int subframe_rx = proc->subframe_rx;
+  int timing_advance;
+  LTE_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
+  int harq_pid = 0;
+  uint8_t *rar;
 
-      /*
-      ue->ulsch_no_allocation_counter[eNB_id]++;
-
-      if (ue->ulsch_no_allocation_counter[eNB_id] == 10) {
-      #ifdef DEBUG_PHY_PROC
-      msg("[UE  %d] no_allocation : setting mode to PRACH\n",ue->Mod_id);
-      #endif
-      ue->UE_mode[eNB_id] = PRACH;
-      ue->pdcch_vars[eNB_id]->crnti = 0x1234;
+  LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Received RAR  mode %d\n",
+	ue->Mod_id,
+	frame_rx,
+	subframe_rx, ue->UE_mode[eNB_id]);
+  
+	
+  if (ue->mac_enabled == 1) {
+    if ((ue->UE_mode[eNB_id] != PUSCH) && 
+	(ue->prach_resources[eNB_id]->Msg3!=NULL)) {
+      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n",
+	    ue->Mod_id,frame_rx,
+	    subframe_rx,
+	    ue->prach_resources[eNB_id]->ra_PreambleIndex);
+      
+      timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
+						 ue->CC_id,
+						 frame_rx,
+						 dlsch0->harq_processes[0]->b,
+						 &ue->pdcch_vars[eNB_id]->crnti,
+						 ue->prach_resources[eNB_id]->ra_PreambleIndex);
+      
+	    
+      if (timing_advance!=0xffff) {
+	      
+	LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
+	      ue->Mod_id,
+	      frame_rx,
+	      subframe_rx,
+	      ue->pdcch_vars[eNB_id]->crnti,
+	      timing_advance);
+	      
+	//timing_advance = 0;
+	process_timing_advance_rar(ue,proc,timing_advance);
+	      
+	if (mode!=debug_prach) {
+	  ue->ulsch_Msg3_active[eNB_id]=1;
+	  get_Msg3_alloc(&ue->frame_parms,
+			 subframe_rx,
+			 frame_rx,
+			 &ue->ulsch_Msg3_frame[eNB_id],
+			 &ue->ulsch_Msg3_subframe[eNB_id]);
+	  
+	  LOG_D(PHY,"[UE  %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n",
+		ue->Mod_id,
+		frame_rx,
+		subframe_rx,
+		ue->ulsch_Msg3_frame[eNB_id],
+		ue->ulsch_Msg3_subframe[eNB_id]);
+	  harq_pid = subframe2harq_pid(&ue->frame_parms,
+				       ue->ulsch_Msg3_frame[eNB_id],
+				       ue->ulsch_Msg3_subframe[eNB_id]);
+	  ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
+	  
+	  ue->UE_mode[eNB_id] = RA_RESPONSE;
+	  //      ue->Msg3_timer[eNB_id] = 10;
+	  ue->ulsch[eNB_id]->power_offset = 6;
+	  ue->ulsch_no_allocation_counter[eNB_id] = 0;
+	}
+      } else { // PRACH preamble doesn't match RAR
+	LOG_W(PHY,"[UE  %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
+	      ue->Mod_id,
+	      ue->prach_resources[eNB_id]->ra_PreambleIndex);
       }
-      */
+    } // mode != PUSCH
+  }
+  else {
+    rar = dlsch0->harq_processes[0]->b+1;
+    timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
+    process_timing_advance_rar(ue,proc,timing_advance);
+  }
+  
+}
 
-      ue_pbch_procedures(eNB_id,ue,abstraction_flag);
+void ue_dlsch_procedures(PHY_VARS_UE *ue, 
+			 UE_rxtx_proc_t *proc, 
+			 int eNB_id,
+			 PDSCH_t pdsch, 
+			 LTE_UE_DLSCH_t *dlsch0, 
+			 LTE_UE_DLSCH_t *dlsch1, 
+			 int *dlsch_errors, 
+			 runmode_t mode, 
+			 int abstraction_flag) {
+
+  int harq_pid;
+  int frame_rx = proc->frame_rx;
+  int subframe_rx = proc->subframe_rx;
+  int ret=0;
+  int CC_id = ue->CC_id;
+  LTE_UE_PDSCH *pdsch_vars;
 
-      /*
-      if (ue->UE_mode[eNB_id] == RA_RESPONSE) {
-        ue->Msg3_timer[eNB_id]--;
-        msg("[UE RAR] frame %d: Msg3_timer %d\n",frame_rx,ue->Msg3_timer);
-
-        if (ue->Msg3_timer[eNB_id] == 0) {
-          LOG_D(PHY,"[UE  %d] Frame %d: Msg3_timer = 0 : setting mode to PRACH\n",ue->Mod_id,frame_rx);
-      // I guess here we also need to tell the RRC
-          ue->UE_mode[eNB_id] = PRACH;
-      ue->pdcch_vars[eNB_id]->crnti = 0x1234;
-      }
+  if (dlsch0 && (!dlsch1)) {
+    switch (pdsch) {
+    case SI_PDSCH:
+      pdsch_vars = ue->pdsch_vars_SI[eNB_id];
+      break;
+    case RA_PDSCH:
+      pdsch_vars = ue->pdsch_vars_ra[eNB_id];
+      break;
+    case PDSCH:
+      pdsch_vars = ue->pdsch_vars[eNB_id];
+      break;
+    case PMCH:
+    case PDSCH1:
+      LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch);
+      pdsch_vars = NULL;
+      return;
+      break;
+    }
+  
+    harq_pid = dlsch0->current_harq_pid;
+
+    if (frame_rx < *dlsch_errors)
+      *dlsch_errors=0;
+
+    if (pdsch==RA_PDSCH) {
+      if (ue->prach_resources[eNB_id]!=NULL)
+	dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+      else {
+	LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx);
+	mac_xface->macphy_exit("prach_resources is NULL");
+	return;
       }
-      */
     }
 
-    // process last DLSCH symbols + invoke decoding
-    if (((slot_rx%2)==0) && (l==0)) {
-      // Regular PDSCH
-      LOG_D(PHY,"[UE %d] dlsch->active in subframe %d => %d\n",ue->Mod_id,subframe_prev,ue->dlsch[eNB_id][0]->active);
-
-      if (ue->dlsch[eNB_id][0]->active == 1) {
-
-        harq_pid = ue->dlsch[eNB_id][0]->current_harq_pid;
-        LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d\n",ue->Mod_id,subframe_prev,harq_pid);
-
-        if ((ue->transmission_mode[eNB_id] == 5) &&
-            (ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->dl_power_off==0) &&
-            (ue->use_ia_receiver ==1)) {
-          dual_stream_UE = 1;
-          eNB_id_i = ue->n_connected_eNB;
-          i_mod = ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm;
-
-          if (frame_rx%100==0) {
-            LOG_I(PHY,"using IA receiver\n");
-          }
-        } else {
-          dual_stream_UE = 0;
-          eNB_id_i = eNB_id+1;
-          i_mod = 0;
-        }
-
-        // process symbols 10,11,12 and trigger DLSCH decoding
-        if (abstraction_flag == 0) {
-
-          start_meas(&ue->dlsch_llr_stats);
-
-          for (m=pilot3; m<ue->frame_parms.symbols_per_tti; m++) {
-
-            rx_pdsch(ue,
-                     PDSCH,
-                     eNB_id,
-                     eNB_id_i,
-                     subframe_prev,  // subframe
-                     m,                    // symbol
-                     0,                    // first_symbol_flag
-                     dual_stream_UE,
-                     i_mod,
-                     ue->dlsch[eNB_id][0]->current_harq_pid);
-          }
-
-          stop_meas(&ue->dlsch_llr_stats);
-        }
-
-        ue->dlsch[eNB_id][0]->active = 0;
-
-	//#ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d Scheduling DLSCH decoding\n",
-              ue->Mod_id,
-              ue->dlsch[eNB_id][0]->rnti,
-              harq_pid,
-              (subframe_prev == 9) ? (frame_rx-1) : frame_rx,subframe_prev);
-	//#endif
-
-        if (ue->dlsch[eNB_id][0]) {
-          if (abstraction_flag == 0) {
-            ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
-                ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
-                ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm,
-                ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Nl,
-                ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                frame_rx,subframe_prev);
-            start_meas(&ue->dlsch_unscrambling_stats);
-            dlsch_unscrambling(&ue->frame_parms,
-                               0,
-                               ue->dlsch[0][0],
-                               ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->G,
-                               ue->pdsch_vars[eNB_id]->llr[0],
-                               0,
-                               subframe_prev<<1);
-            stop_meas(&ue->dlsch_unscrambling_stats);
-
-            start_meas(&ue->dlsch_decoding_stats);
-            ret = dlsch_decoding(ue,
-                                 ue->pdsch_vars[eNB_id]->llr[0],
-                                 &ue->frame_parms,
-                                 ue->dlsch[eNB_id][0],
-                                 ue->dlsch[eNB_id][0]->harq_processes[harq_pid],
-                                 subframe_prev,
-                                 harq_pid,
-                                 1,ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->nb_rb>10 ? 1 : 0);
-            stop_meas(&ue->dlsch_decoding_stats);
-          }
+    if (abstraction_flag == 0) {
 
-          else {
-            LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
+      dlsch0->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
+						  dlsch0->harq_processes[harq_pid]->nb_rb,
+						  dlsch0->harq_processes[harq_pid]->rb_alloc_even,
+						  dlsch0->harq_processes[harq_pid]->Qm,
+						  dlsch0->harq_processes[harq_pid]->Nl,
+						  ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
+						  frame_rx,subframe_rx);
+      start_meas(&ue->dlsch_unscrambling_stats);
+      dlsch_unscrambling(&ue->frame_parms,
+			 0,
+			 dlsch0,
+			 dlsch0->harq_processes[harq_pid]->G,
+			 pdsch_vars->llr[0],
+			 0,
+			 subframe_rx<<1);
+      stop_meas(&ue->dlsch_unscrambling_stats);
+      
+      start_meas(&ue->dlsch_decoding_stats);
+      ret = dlsch_decoding(ue,
+			   pdsch_vars->llr[0],
+			   &ue->frame_parms,
+			   dlsch0,
+			   dlsch0->harq_processes[harq_pid],
+			   subframe_rx,
+			   harq_pid,
+			   pdsch==PDSCH?1:0,
+			   dlsch0->harq_processes[harq_pid]->nb_rb>10?1:0);
+      stop_meas(&ue->dlsch_decoding_stats);
+    }
+	
+    else {
+      LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
 #ifdef PHY_ABSTRACTION
-            ret = dlsch_decoding_emul(ue,
-                                      subframe_prev,
-                                      2,
-                                      eNB_id);
-#endif
-          }
-
-          if (ret == (1+ue->dlsch[eNB_id][0]->max_turbo_iterations)) {
-            ue->dlsch_errors[eNB_id]++;
-
-#ifdef DEBUG_PHY_PROC
-            LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d,TBS %d)\n",
-                  ue->Mod_id,ue->dlsch[eNB_id][0]->rnti,
-                  harq_pid,frame_rx,subframe_prev,
-                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rvidx,
-                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->mcs,
-                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->TBS);
-/*
-            if (abstraction_flag ==0 )
-              dump_dlsch(ue,eNB_id,subframe_prev,harq_pid);
-            mac_xface->macphy_exit("");
-*/
-#endif
-          } else {
-            LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d (slot_rx %d): Received DLSCH (rv %d,mcs %d,TBS %d)\n",
-                  ue->Mod_id,ue->dlsch[eNB_id][0]->rnti,
-                  harq_pid,frame_rx,subframe_prev,slot_rx,
-                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rvidx,
-                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->mcs,
-                  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->TBS);
-#ifdef DEBUG_PHY_PROC
-#ifdef DEBUG_DLSCH
-            int j;
-            LOG_D(PHY,"dlsch harq_pid %d (rx): \n",ue->dlsch[eNB_id][0]->current_harq_pid);
-
-            for (j=0; j<ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->TBS>>3; j++)
-              LOG_T(PHY,"%x.",ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->b[j]);
-
-            LOG_T(PHY,"\n");
+      ret = dlsch_decoding_emul(ue,
+				subframe_rx,
+				dlsch,
+				eNB_id);
 #endif
-#endif
-	    if (ue->mac_enabled == 1) {
-	      mac_xface->ue_send_sdu(ue->Mod_id,
-				     CC_id,
-				     frame_rx,
-				     ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->b,
-				     ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->TBS>>3,
-				     eNB_id);
-	    }
-            ue->total_TBS[eNB_id] =  ue->total_TBS[eNB_id] +
-                                              ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->TBS;
-            ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] +
-                ue->dlsch[eNB_id][0]->harq_processes[ue->dlsch[eNB_id][0]->current_harq_pid]->TBS;
-          }
-        }
+    }
+	
+    if (ret == (1+dlsch0->max_turbo_iterations)) {
+      *dlsch_errors=*dlsch_errors+1;
+      
 
+      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH in error (rv %d,mcs %d,TBS %d)\n",
+	    ue->Mod_id,dlsch0->rnti,
+	    harq_pid,frame_rx,subframe_rx,
+	    dlsch0->harq_processes[harq_pid]->rvidx,
+	    dlsch0->harq_processes[harq_pid]->mcs,
+	    dlsch0->harq_processes[harq_pid]->TBS);
+      
 
-#ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n",
-              ue->Mod_id,
-              ue->dlsch[eNB_id][0]->rnti,harq_pid,
-              frame_rx,subframe_prev,ret,
-              ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->mcs,
-              ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->rvidx,
-              ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->TBS);
-
-        if (frame_rx%100==0) {
-          LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n",
-                ue->Mod_id,ue->dlsch[eNB_id][0]->rnti,
-                frame_rx,subframe_prev,
-                ue->dlsch_errors[eNB_id],
-                ue->dlsch_received[eNB_id],
-                ue->dlsch_fer[eNB_id],
-                ue->measurements.wideband_cqi_tot[eNB_id]);
-        }
+    } else {
+      LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH (rv %d,mcs %d,TBS %d)\n",
+	    ue->Mod_id,dlsch0->rnti,
+	    harq_pid,frame_rx,subframe_rx,
+	    dlsch0->harq_processes[harq_pid]->rvidx,
+	    dlsch0->harq_processes[harq_pid]->mcs,
+	    dlsch0->harq_processes[harq_pid]->TBS);
 
+#ifdef DEBUG_DLSCH
+      int j;
+      LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid);
+      
+      for (j=0; j<dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3; j++)
+	LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
+      
+      LOG_T(PHY,"\n");
 #endif
 
-      } else {
-        //  printf("PDSCH inactive in subframe %d\n",subframe_rx-1);
-        ue->dlsch[eNB_id][0]->harq_ack[subframe_prev].send_harq_status = 0;
+      
+      if (ue->mac_enabled == 1) {
+	switch (pdsch) {
+	case PDSCH:
+	  mac_xface->ue_send_sdu(ue->Mod_id,
+				 CC_id,
+				 frame_rx,
+				 dlsch0->harq_processes[dlsch0->current_harq_pid]->b,
+				 dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3,
+				 eNB_id);
+	  break;
+	case SI_PDSCH:
+	  mac_xface->ue_decode_si(ue->Mod_id,
+				  CC_id,
+				  frame_rx,
+				  eNB_id,
+				  ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
+				  ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
+	  break;
+	case RA_PDSCH:
+	  process_rar(ue,proc,eNB_id,mode,abstraction_flag);
+	  break;
+	case PDSCH1:
+	  LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n");
+	  AssertFatal(1==0,"exiting");
+	  break;
+	case PMCH:
+	  LOG_E(PHY,"Shouldn't have PMCH here\n");
+	  AssertFatal(1==0,"exiting");
+	  break;
+	}
       }
-
-      // SI_DLSCH
-      if (ue->dlsch_SI[eNB_id]->active == 1) {
-#ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"SI is active in subframe %d\n",subframe_prev);
-#endif
-
-        // process symbols 10,11,12 (13) of last SF and trigger DLSCH decoding
-        if (abstraction_flag==0) {
-          start_meas(&ue->dlsch_llr_stats);
-
-          for (m=pilot3; m<ue->frame_parms.symbols_per_tti; m++) {
-#ifdef DEBUG_PHY_PROC
-
-            LOG_D(PHY,"[UE  %d] Frame %d, slot %d: DLSCH (SI) demod between pilot 3 and 4 (2nd slot), m %d\n",
-                  ue->Mod_id,frame_rx,slot_rx,m);
-
-#endif
-            rx_pdsch(ue,
-                     SI_PDSCH,
-                     eNB_id,
-                     eNB_id+1,
-                     subframe_prev,  // subframe,
-                     m,
-                     0,
-                     0,
-                     ue->is_secondary_ue,
-                     ue->dlsch_SI[eNB_id]->current_harq_pid);
-          }
-
-          stop_meas(&ue->dlsch_llr_stats);
-        }
-
-        //  write_output("dlsch_ra_llr.m","llr",pdsch_vars_ra[eNB_id]->llr[0],40,1,0);
-
-        ue->dlsch_SI[eNB_id]->active = 0;
-
-        if (frame_rx < ue->dlsch_SI_errors[eNB_id])
-          ue->dlsch_SI_errors[eNB_id]=0;
-
-        if (ue->dlsch_SI[eNB_id]) {
-
-          if (abstraction_flag==0) {
-
-            //          dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
-            ue->dlsch_SI[eNB_id]->harq_processes[0]->G =
-              get_G(&ue->frame_parms,
-                    ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
-                    ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even,
-                    2,
-		    1,
-                    ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-                    frame_rx,subframe_prev);
-
-#ifdef DEBUG_PHY_PROC
-            LOG_D(PHY,"Decoding DLSCH_SI : rb_alloc %x : nb_rb %d G %d TBS %d, num_pdcch_sym %d\n",ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[0],
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->G,
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS,
-                  ue->pdcch_vars[eNB_id]->num_pdcch_symbols);
-#endif
-
-
-            dlsch_unscrambling(&ue->frame_parms,
-                               0,
-                               ue->dlsch_SI[eNB_id],
-                               ue->dlsch_SI[eNB_id]->harq_processes[0]->G,
-                               ue->pdsch_vars_SI[eNB_id]->llr[0],
-                               0,
-                               subframe_prev<<1);
-
-            ret = dlsch_decoding(ue,
-                                 ue->pdsch_vars_SI[eNB_id]->llr[0],
-                                 &ue->frame_parms,
-                                 ue->dlsch_SI[eNB_id],
-                                 ue->dlsch_SI[eNB_id]->harq_processes[0],
-                                 subframe_prev,
-                                 ue->dlsch_SI[eNB_id]->current_harq_pid,
-                                 0,0);
-
+      ue->total_TBS[eNB_id] =  ue->total_TBS[eNB_id] +
+	dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
+      ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] +
+	dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
+    }
+  
+  
+      
 #ifdef DEBUG_PHY_PROC
-
-            for (int i=0; i<11; i++)
-              LOG_D(PHY,"dlsch_output_buffer[%d]=%x\n",i,ue->dlsch_SI[eNB_id]->harq_processes[0]->c[0][i]);
-
+    LOG_D(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n",
+	  ue->Mod_id,
+	  dlsch0->rnti,harq_pid,
+	  frame_rx,subframe_rx,ret,
+	  dlsch0->harq_processes[harq_pid]->mcs,
+	  dlsch0->harq_processes[harq_pid]->rvidx,
+	  dlsch0->harq_processes[harq_pid]->TBS);
+    
+    if (frame_rx%100==0) {
+      LOG_D(PHY,"[UE  %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n",
+	    ue->Mod_id,dlsch0->rnti,
+	    frame_rx,subframe_rx,
+	    ue->dlsch_errors[eNB_id],
+	    ue->dlsch_received[eNB_id],
+	    ue->dlsch_fer[eNB_id],
+	    ue->measurements.wideband_cqi_tot[eNB_id]);
+    }
+    
 #endif
 
-          }
-
-#ifdef PHY_ABSTRACTION
-          else {
-            LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
-            ret = dlsch_decoding_emul(ue,
-                                      subframe_prev,
-                                      0,
-                                      eNB_id);
-          }
+  }
 
-#endif
 
-          if (ret == (1+ue->dlsch_SI[eNB_id]->max_turbo_iterations)) {
-            ue->dlsch_SI_errors[eNB_id]++;
-#ifdef DEBUG_PHY_PROC
-            LOG_D(PHY,"[UE  %d] Frame %d, subframe %d, received SI in error (TBS %d, mcs %d, rvidx %d, rballoc %X.%X.%X.%X\n",
-		  ue->Mod_id,
-		  frame_rx,
-		  subframe_prev,
-		  ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS,
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs,
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rvidx,
-		  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[0],
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[1],
-		  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[2],
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[3]);
-#endif
+}
+int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
+			 relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) {
  
-	    //	      dump_dlsch_SI(ue,eNB_id,subframe_prev);
-            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
-            stop_meas(&ue->phy_proc_rx);
-	    return(-1);
-          } else {
-
+  int l,l2;
+  int pilot1;
+  int pmch_flag=0;
+  int frame_rx = proc->frame_rx;
+  int subframe_rx = proc->subframe_rx;
 
-#ifdef DEBUG_PHY_PROC
-            //if ((frame_rx % 100) == 0)
-            LOG_D(PHY,"[UE  %d] Frame %d, subframe %d, received SI for TBS %d, mcs %d, rvidx %d, rballoc %X.%X.%X.%X\n",
-                  ue->Mod_id,frame_rx,subframe_prev,
-		  ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS,
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs,
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rvidx,
-		  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[0],
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[1],
-		  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[2],
-                  ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even[3]);
-#endif
-
-	    if (ue->mac_enabled == 1) {
-	      /*
-		printf("\n\n");
-		for (i=0;i<ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3;i++)
-		printf("%02x ",ue->dlsch_SI[eNB_id]->harq_processes[0]->b[i]);
-		printf("\n");
-	      */
-	      mac_xface->ue_decode_si(ue->Mod_id,
-				      CC_id,
-				      frame_rx,
-				      eNB_id,
-				      ue->dlsch_SI[eNB_id]->harq_processes[0]->b,
-				      ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3);
-	    }
-          }
-        }
 
-        /*
-        #ifdef DEBUG_PHY_PROC
-        debug_LOG_D(PHY,"[UE  %d] Frame %d, slot %d: dlsch_decoding (SI) ret %d (%d errors)\n",
-            ue->Mod_id,frame_rx,slot_rx,ret,ue->dlsch_SI_errors[eNB_id]);
-        #endif
-        */
-      }
 
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
 
-      if (ue->dlsch_ra[eNB_id]->active == 1) {
-#ifdef DEBUG_PHY_PROC
-        LOG_D(PHY,"[UE  %d] Frame %d, slot %d: DLSCH (RA) demod symbols 10,11,12\n",ue->Mod_id,frame_rx,slot_rx);
-#endif
-
-        // process symbols 10,11,12 and trigger DLSCH decoding
-        if (abstraction_flag==0) {
-          start_meas(&ue->dlsch_llr_stats);
-
-          for (m=pilot3; m<ue->frame_parms.symbols_per_tti; m++)
-            rx_pdsch(ue,
-                     RA_PDSCH,
-                     eNB_id,
-                     eNB_id+1,
-                     subframe_prev,  // subframe,
-                     m, // symbol
-                     0, // first_symbol_flag
-                     0,
-                     ue->is_secondary_ue,
-                     ue->dlsch_ra[eNB_id]->current_harq_pid);
-        }
 
-        stop_meas(&ue->dlsch_llr_stats);
+  start_meas(&ue->phy_proc_rx);
 
-        ue->dlsch_ra[eNB_id]->active = 0;
+  pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
 
-        if (frame_rx < ue->dlsch_ra_errors[eNB_id])
-          ue->dlsch_ra_errors[eNB_id]=0;
 
-        if (ue->prach_resources[eNB_id]!=NULL)
-          ue->dlsch_ra[eNB_id]->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
-        else {
-          LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_prev);
-          mac_xface->macphy_exit("prach_resources is NULL");
-          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
-          stop_meas(&ue->phy_proc_rx);
-          return 0;
-        }
+  // deactivate reception until we scan pdcch
+  if (ue->dlsch[eNB_id][0])
+    ue->dlsch[eNB_id][0]->active = 0;
+  if (ue->dlsch[eNB_id][1])
+    ue->dlsch[eNB_id][1]->active = 0;
 
-        if (abstraction_flag==0) {
-          ue->dlsch_ra[eNB_id]->harq_processes[0]->G = get_G(&ue->frame_parms,
-									 ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
-									 ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even,
-									 2,
-									 1,
-									 ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
-              frame_rx,
-              subframe_prev);
+  if (ue->dlsch_SI[eNB_id])
+    ue->dlsch_SI[eNB_id]->active = 0;
+  if (ue->dlsch_ra[eNB_id])
+    ue->dlsch_ra[eNB_id]->active = 0;
 
+  
 #ifdef DEBUG_PHY_PROC
-          LOG_D(PHY,"[UE] decoding RA (subframe %d): G %d,rnti %x\n" ,subframe_prev,
-                ue->dlsch_ra[eNB_id]->harq_processes[0]->G,
-                ue->dlsch_ra[eNB_id]->rnti);
-#endif
-
-          dlsch_unscrambling(&ue->frame_parms,
-                             0,
-                             ue->dlsch_ra[eNB_id],
-                             ue->dlsch_ra[eNB_id]->harq_processes[0]->G,
-                             ue->pdsch_vars_ra[eNB_id]->llr[0],
-                             0,
-                             subframe_prev<<1);
-
-          ret = dlsch_decoding(ue,
-                               ue->pdsch_vars_ra[eNB_id]->llr[0],
-                               &ue->frame_parms,
-                               ue->dlsch_ra[eNB_id],
-                               ue->dlsch_ra[eNB_id]->harq_processes[0],
-                               subframe_prev,  // subframe
-			       ue->dlsch_ra[eNB_id]->current_harq_pid,
-                               0,0);
-        }
-
-#ifdef PHY_ABSTRACTION
-        else {
-          LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
-          ret = dlsch_decoding_emul(ue,
-                                    subframe_prev,
-                                    1,
-                                    eNB_id);
-        }
-
+  LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX (%d)\n",
+	(r_type == multicast_relay) ? "RN/UE" : "UE",
+	ue->Mod_id,frame_rx, subframe_rx);
 #endif
 
-        if (ret == (1+ue->dlsch_ra[eNB_id]->max_turbo_iterations)) {
-          ue->dlsch_ra_errors[eNB_id]++;
-          LOG_D(PHY,"[UE  %d] Frame %d, subframe %d, received RA in error\n",ue->Mod_id,frame_rx,subframe_prev);
-
-	  //          dump_dlsch_ra(ue,eNB_id,subframe_prev); exit(-1);
-
-          //    oai_exit=1;
-          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
-          stop_meas(&ue->phy_proc_rx);
-          return(-1);
-
-        } else {
-#ifdef DEBUG_PHY_PROC
-          LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Received RAR  mode %d\n",
-                ue->Mod_id,
-                frame_rx,
-                subframe_prev, ue->UE_mode[eNB_id]);
-#endif
-
-	  if (ue->mac_enabled == 1) {
-          if ((ue->UE_mode[eNB_id] != PUSCH) && (ue->prach_resources[eNB_id]->Msg3!=NULL)) {
-            LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n",
-                  ue->Mod_id,frame_rx-((subframe_prev==9) ? 1 : 0),
-                  subframe_prev,
-                  ue->prach_resources[eNB_id]->ra_PreambleIndex);
-
-            timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
-                             CC_id,
-                             frame_rx-((subframe_prev==0) ? 1 : 0),
-                             ue->dlsch_ra[eNB_id]->harq_processes[0]->b,
-                             &ue->pdcch_vars[eNB_id]->crnti,
-                             ue->prach_resources[eNB_id]->ra_PreambleIndex);
-
-
-            if (timing_advance!=0xffff) {
-
-              LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
-                    ue->Mod_id,
-                    frame_rx-((subframe_prev==9) ? 1 : 0),
-                    subframe_prev,
-                    ue->pdcch_vars[eNB_id]->crnti,
-                    timing_advance);
-
-              //timing_advance = 0;
-              process_timing_advance_rar(ue,timing_advance);
-
-              if (mode!=debug_prach) {
-                ue->ulsch_Msg3_active[eNB_id]=1;
-                get_Msg3_alloc(&ue->frame_parms,
-                               subframe_prev,
-                               frame_rx-((subframe_prev==9) ? 1 : 0),
-                               &ue->ulsch_Msg3_frame[eNB_id],
-                               &ue->ulsch_Msg3_subframe[eNB_id]);
-
-                LOG_D(PHY,"[UE  %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n",
-                      ue->Mod_id,
-                      frame_rx-((subframe_prev==9) ? 1 : 0),
-                      subframe_prev,
-                      ue->ulsch_Msg3_frame[eNB_id],
-                      ue->ulsch_Msg3_subframe[eNB_id]);
-                harq_pid = subframe2harq_pid(&ue->frame_parms,
-                                             ue->ulsch_Msg3_frame[eNB_id],
-                                             ue->ulsch_Msg3_subframe[eNB_id]);
-                ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
-
-                ue->UE_mode[eNB_id] = RA_RESPONSE;
-                //      ue->Msg3_timer[eNB_id] = 10;
-                ue->ulsch[eNB_id]->power_offset = 6;
-                ue->ulsch_no_allocation_counter[eNB_id] = 0;
-              }
-            } else { // PRACH preamble doesn't match RAR
-              LOG_W(PHY,"[UE  %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n",
-                    ue->Mod_id,
-                    ue->prach_resources[eNB_id]->ra_PreambleIndex);
-            }
-          } // mode != PUSCH
-	  }
-	    else {
-	      rar = ue->dlsch_ra[eNB_id]->harq_processes[0]->b+1;
-	      timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
-	      //timing_advance = ue->dlsch_ra[eNB_id]->harq_processes[0]->b[0];
-	      process_timing_advance_rar(ue,timing_advance);
-	    }
-        } //ret <= MAX_ITERATIONS
-
-        /*
-        #ifdef DEBUG_PHY_PROC
-        debug_LOG_D(PHY,"[UE  %d] Frame %d, slot %d: dlsch_decoding (RA) ret %d (%d errors)\n",
-            ue->Mod_id,frame_rx,slot_rx,ret,ue->dlsch_ra_errors[eNB_id]);
-        #endif
-        */
-      } // dlsch_ra[eNB_id]->active == 1
-
+  if (ue->frame_parms.Ncp == 0) {  // normal prefix
+    pilot1 = 4;
+  } else { // extended prefix
+    pilot1 = 3;
+  }
+  
+  
+  if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only
+    l2 = 5;
+  } else if (pmch_flag == 1) { // do first 2 symbols only
+    l2 = 1;
+  } else { // normal subframe, last symbol to be processed is the first of the second slot
+    l2 = (ue->frame_parms.symbols_per_tti/2)-1;
+  }
+  
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  
+  for (l=1; l<=l2; l++) {
+    if (abstraction_flag == 0) {
+      start_meas(&ue->ofdm_demod_stats);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+      slot_fep(ue,
+	       l,
+	       (subframe_rx<<1),
+	       ue->rx_offset,
+	       0,
+	       0);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+      stop_meas(&ue->ofdm_demod_stats);
     }
-
-
-    if ((((slot_rx%2)==0) && ((l==pilot1))) ||
-        ((pmch_flag==1)&&(l==1)))  {
-
-#ifdef DEBUG_PHY_PROC
-      LOG_D(PHY,"[UE  %d] Frame %d, slot %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,slot_rx,eNB_id);
-#endif
-
-      //      rt_printk("[PDCCH] Frame %d, slot %d, start %llu\n",frame_rx,slot_rx,rt_get_time_ns());
-      if (ue_pdcch_procedures(eNB_id,ue,abstraction_flag) == -1) {
-#ifdef DEBUG_PHY_PROC
-	  LOG_E(PHY,"[UE  %d] Frame %d, slot %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,slot_rx);
-#endif
-	  return(-1);
-      }
     
-
-      //      rt_printk("[PDCCH] Frame %d, slot %d, stop  %llu\n",frame_rx,slot_rx,rt_get_time_ns());
-#ifdef DEBUG_PHY_PROC
+    ue_measurement_procedures(l-1,ue,proc,eNB_id,abstraction_flag,mode);
+    if ((l==pilot1) ||
+	((pmch_flag==1)&(l==l2)))  {
+      LOG_D(PHY,"[UE  %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id);
+      
+      if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) {
+	LOG_E(PHY,"[UE  %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx);
+	return(-1);
+      }
       LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[eNB_id]->num_pdcch_symbols);
-#endif
     }
+    
+  } // for l=1..l2
+  
+    // If this is PMCH, call procedures and return
+  if (pmch_flag == 1) {
+    ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag);
+    return 0;
+  }
 
-    if (abstraction_flag==0) {
+  slot_fep(ue,
+	   0,
+	   1+(subframe_rx<<1),
+	   ue->rx_offset,
+	   0,
+	   0);
+  
+  // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+ 
+  // do procedures for C-RNTI
+  if (ue->dlsch[eNB_id][0]->active == 1) {
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			PDSCH,
+			ue->dlsch[eNB_id][0],
+			NULL,
+			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
+  }
+  // do procedures for SI-RNTI
+  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			SI_PDSCH,
+			ue->dlsch_SI[eNB_id],
+			NULL,
+			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
+  }
+  // do procedures for RA-RNTI
+  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			RA_PDSCH,
+			ue->dlsch_ra[eNB_id],
+			NULL,
+			ue->pdcch_vars[eNB_id]->num_pdcch_symbols,
+			ue->frame_parms.symbols_per_tti>>1,
+			abstraction_flag);
+  }    
+  
+  if (subframe_select(&ue->frame_parms,subframe_rx) != SF_S) {  // do front-end processing for second slot, and first symbol of next subframe
+    for (l=1; l<ue->frame_parms.symbols_per_tti>>1; l++) {
+      if (abstraction_flag == 0) {
+	start_meas(&ue->ofdm_demod_stats);
+	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+	slot_fep(ue,
+		 l,
+		 1+(subframe_rx<<1),
+		 ue->rx_offset,
+		 0,
+		 0);
+	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+	stop_meas(&ue->ofdm_demod_stats);
+      }
+      
+      ue_measurement_procedures(l-1,ue,proc,eNB_id,abstraction_flag,mode);
+      
+    } // for l=1..l2
+      // do first symbol of next subframe for channel estimation
+    slot_fep(ue,
+	     0,
+	     (2+(subframe_rx<<1))%20,
+	     ue->rx_offset,
+	     0,
+	     0);
+  } // not an S-subframe
+
+  // run pbch procedures if subframe is 0
+  if (subframe_rx == 0)
+    ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
+   
+  // do procedures for C-RNTI
+  if (ue->dlsch[eNB_id][0]->active == 1) {
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			PDSCH,
+			ue->dlsch[eNB_id][0],
+			NULL,
+			1+(ue->frame_parms.symbols_per_tti>>1),
+			ue->frame_parms.symbols_per_tti-1,
+			abstraction_flag);
+    ue_dlsch_procedures(ue,
+			proc,
+			eNB_id,
+			PDSCH,
+			ue->dlsch[eNB_id][0],
+			NULL,
+			&ue->dlsch_errors[eNB_id],
+			mode,
+			abstraction_flag);
+      
+
+  }
+  else {
+    //  printf("PDSCH inactive in subframe %d\n",subframe_rx-1);
+    ue->dlsch[eNB_id][0]->harq_ack[subframe_rx].send_harq_status = 0;
+  }
 
-      if (((slot_rx%2)==1) && (l==0)) {
-        start_meas(&ue->dlsch_llr_stats);
-
-        for (m=ue->pdcch_vars[eNB_id]->num_pdcch_symbols;
-             m<pilot2;
-             m++) {
-
-          if (ue->dlsch[eNB_id][0]->active == 1)  {
-            harq_pid = ue->dlsch[eNB_id][0]->current_harq_pid;
-            LOG_D(PHY,"[UE %d] PDSCH active in subframe %d (%d), harq_pid %d\n",ue->Mod_id,subframe_rx,slot_rx,harq_pid);
-
-            if ((ue->transmission_mode[eNB_id] == 5) &&
-                (ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->dl_power_off==0) &&
-                (ue->use_ia_receiver ==1)) {
-              dual_stream_UE = 1;
-              eNB_id_i = ue->n_connected_eNB;
-              i_mod =  ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm;
-            } else {
-              dual_stream_UE = 0;
-              eNB_id_i = eNB_id+1;
-              i_mod = 0;
-            }
-
-            // process DLSCH received in first slot
-
-            rx_pdsch(ue,
-                     PDSCH,
-                     eNB_id,
-                     eNB_id_i,
-                     subframe_rx,  // subframe,
-                     m,
-                     (m==ue->pdcch_vars[eNB_id]->num_pdcch_symbols)?1:0,   // first_symbol_flag
-                     dual_stream_UE,
-                     i_mod,
-                     ue->dlsch[eNB_id][0]->current_harq_pid);
-          } // CRNTI active
-
-
-
-          if (ue->dlsch_SI[eNB_id]->active == 1)  {
-            // process SI DLSCH in first slot
-            rx_pdsch(ue,
-                     SI_PDSCH,
-                     eNB_id,
-                     eNB_id+1,
-                     subframe_rx,  // subframe,
-                     m,
-                     (m==ue->pdcch_vars[eNB_id]->num_pdcch_symbols)?1:0,   // first_symbol_flag
-                     0,
-                     ue->is_secondary_ue,
-                     ue->dlsch_SI[eNB_id]->current_harq_pid);
-          } // SI active
-
-          if (ue->dlsch_ra[eNB_id]->active == 1)  {
-            rx_pdsch(ue,
-                     RA_PDSCH,
-                     eNB_id,
-                     eNB_id+1,
-                     subframe_rx,  // subframe,
-                     m,
-                     (m==ue->pdcch_vars[eNB_id]->num_pdcch_symbols)?1:0,
-                     0,
-                     ue->is_secondary_ue,
-                     ue->dlsch_ra[eNB_id]->current_harq_pid);
-          } // RA active
-        } // loop from first dlsch symbol to end of slot
-
-        stop_meas(&ue->dlsch_llr_stats);
-      } // 2nd quarter
-
-      if (((slot_rx%2)==1) && (l==pilot1)) {
-        start_meas(&ue->dlsch_llr_stats);
-
-        for (m=pilot2; m<pilot3; m++) {
-
-
-          if (ue->dlsch[eNB_id][0]->active == 1) {
-            harq_pid = ue->dlsch[eNB_id][0]->current_harq_pid;
-
-            if ((ue->transmission_mode[eNB_id] == 5) &&
-                (ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->dl_power_off==0) &&
-                (ue->use_ia_receiver ==1)) {
-              dual_stream_UE = 1;
-              eNB_id_i = ue->n_connected_eNB;
-              i_mod = ue->dlsch[eNB_id][0]->harq_processes[harq_pid]->Qm;
-            } else {
-              dual_stream_UE = 0;
-              eNB_id_i = eNB_id+1;
-              i_mod = 0;
-            }
-
-            rx_pdsch(ue,
-                     PDSCH,
-                     eNB_id,
-                     eNB_id_i,
-                     subframe_rx,  // subframe,
-                     m,
-                     0,
-                     dual_stream_UE,
-                     i_mod,
-                     ue->dlsch[eNB_id][0]->current_harq_pid);
-          } // CRNTI active
-
-
-
-          if(ue->dlsch_SI[eNB_id]->active == 1) {
-            rx_pdsch(ue,
-                     SI_PDSCH,
-                     eNB_id,
-                     eNB_id+1,
-                     subframe_rx,  // subframe,
-                     m,
-                     0,   // first_symbol_flag
-                     0,
-                     ue->is_secondary_ue,
-                     ue->dlsch_SI[eNB_id]->current_harq_pid);
-          } // SI active
-
-          if (ue->dlsch_ra[eNB_id]->active == 1) {
-            rx_pdsch(ue,
-                     RA_PDSCH,
-                     eNB_id,
-                     eNB_id+1,
-                     subframe_rx,  // subframe,
-                     m,
-                     0,   // first_symbol_flag
-                     0,
-                     ue->is_secondary_ue,
-                     ue->dlsch_ra[eNB_id]->current_harq_pid);
-          } // RA active
-
-        } // loop over 3rd quarter
-
-        stop_meas(&ue->dlsch_llr_stats);
-      } // 3rd quarter of subframe
-    } // abstraction_flag==0
-  }// l loop
-
-  // calculate some statistics
-  if (slot_rx==19) {
+  // do procedures for SI-RNTI
+  if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			SI_PDSCH,
+			ue->dlsch_SI[eNB_id],
+			NULL,
+			1+(ue->frame_parms.symbols_per_tti>>1),
+			ue->frame_parms.symbols_per_tti-1,
+			abstraction_flag);
+
+    ue_dlsch_procedures(ue,
+			proc,
+			eNB_id,
+			SI_PDSCH,
+			ue->dlsch_SI[eNB_id],
+			NULL,
+			&ue->dlsch_SI_errors[eNB_id],
+			mode,
+			abstraction_flag);
+    ue->dlsch_SI[eNB_id]->active = 0;
+  }
+  // do procedures for RA-RNTI
+  if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+    ue_pdsch_procedures(ue,
+			proc,
+			eNB_id,
+			RA_PDSCH,
+			ue->dlsch_ra[eNB_id],
+			NULL,
+			1+(ue->frame_parms.symbols_per_tti>>1),
+			ue->frame_parms.symbols_per_tti-1,
+			abstraction_flag);
+    ue_dlsch_procedures(ue,
+			proc,
+			eNB_id,
+			RA_PDSCH,
+			ue->dlsch_ra[eNB_id],
+			NULL,
+			&ue->dlsch_ra_errors[eNB_id],
+			mode,
+			abstraction_flag);
+    ue->dlsch_ra[eNB_id]->active = 0;
+  }
+
+  if (subframe_rx==9) {
     if (frame_rx % 10 == 0) {
       if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0)
-        ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
+	ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]);
 
       ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id];
       ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id];
     }
 
+
     ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100;
     ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id];
     LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n",
-          ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
-          ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
-    /*
-    if ((frame_rx % 100 == 0)) {
-      LOG_I(PHY,"Throughput %5.1f kbps\n",(float) ue->bitrate[eNB_id]/1000.0);
-    }
-    */
+	  ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
+	  ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
   }
 
-  if (is_pmch_subframe((subframe_rx==9?-1:0)+frame_rx,subframe_rx,&ue->frame_parms)) {
-    LOG_D(PHY,"ue calling pmch subframe ..\n ");
 
-    if ((slot_rx%2)==1) {
-      LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation(%d)\n",
-            ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx,slot_rx);
-#ifdef Rel10
-      pmch_mcs = mac_xface->ue_query_mch(ue->Mod_id,
-                                         CC_id,
-                                         (subframe_rx==9?-1:0)+frame_rx,
-                                         subframe_rx,
-                                         eNB_id,
-                                         &sync_area,
-                                         &mcch_active);
-
-      if (phy_vars_rn)
-        phy_vars_rn->mch_avtive[subframe_rx]=0;
-
-#else
-      pmch_mcs=-1;
-#endif
-
-      if (pmch_mcs>=0) {
-        LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Programming PMCH demodulation for mcs %d\n",ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx,pmch_mcs);
-        fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0);
-
-        if (abstraction_flag == 0 ) {
-          for (l=2; l<12; l++) {
-
-            slot_fep_mbsfn(ue,
-                           l,
-                           subframe_rx,
-                           0,0);//ue->rx_offset,0);
-          }
-
-          for (l=2; l<12; l++) {
-            rx_pmch(ue,
-                    0,
-                    subframe_rx,
-                    l);
-
-
-          }
-
-          /*  printf("PMCH decoding, Frame %d, subframe %d, G %d\n",
-               (subframe_rx==9?-1:0)+frame_rx,
-               subframe_rx,
-               ue->dlsch_MCH[0]->harq_processes[0]->G);
-          */
-          ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms,
-              ue->dlsch_MCH[0]->harq_processes[0]->nb_rb,
-              ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even,
-              ue->dlsch_MCH[0]->harq_processes[0]->Qm,
-              1,
-              2,
-              (subframe_rx==9?-1:0)+frame_rx,subframe_rx);
-
-          dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
-                             ue->dlsch_MCH[0]->harq_processes[0]->G,
-                             ue->pdsch_vars_MCH[0]->llr[0],0,subframe_prev<<1);
-
-          ret = dlsch_decoding(ue,
-                               ue->pdsch_vars_MCH[0]->llr[0],
-                               &ue->frame_parms,
-                               ue->dlsch_MCH[0],
-                               ue->dlsch_MCH[0]->harq_processes[0],
-                               subframe_prev,
-                               0,
-                               0,1);
-        } else { // abstraction
-#ifdef PHY_ABSTRACTION
-          ret = dlsch_decoding_emul(ue,
-                                    subframe_rx,
-                                    5, // PMCH
-                                    eNB_id);
-#endif
-        }
-
-        if (mcch_active == 1)
-          ue->dlsch_mcch_trials[sync_area][0]++;
-        else
-          ue->dlsch_mtch_trials[sync_area][0]++;
-
-        if (ret == (1+ue->dlsch_MCH[0]->max_turbo_iterations)) {
-          if (mcch_active == 1)
-            ue->dlsch_mcch_errors[sync_area][0]++;
-          else
-            ue->dlsch_mtch_errors[sync_area][0]++;
-
-          LOG_D(PHY,"[%s %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n",
-                (r_type == no_relay)? "UE": "RN/UE", ue->Mod_id,
-                (subframe_rx==9?-1:0)+frame_rx,subframe_rx,
-                ue->dlsch_mcch_errors[sync_area][0],
-                ue->dlsch_mtch_errors[sync_area][0],
-                ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
-                ue->dlsch_MCH[0]->max_turbo_iterations,
-                ue->dlsch_MCH[0]->harq_processes[0]->G);
-          dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx);
-#ifdef DEBUG_DLSCH
-
-          for (int i=0; i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) {
-            LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]);
-          }
-
-          LOG_T(PHY,"\n");
-#endif
-
-          if (subframe_rx==9)
-            mac_xface->macphy_exit("Why are we exiting here?");
-        } else {
-#ifdef Rel10
-
-          if ((r_type == no_relay) || (mcch_active == 1)) {
-            mac_xface->ue_send_mch_sdu(ue->Mod_id,
-                                       CC_id,
-                                       frame_rx,
-                                       ue->dlsch_MCH[0]->harq_processes[0]->b,
-                                       ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3,
-                                       eNB_id,// not relevant in eMBMS context
-                                       sync_area);
-            /*   for (i=0;i<ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3;i++)
-              msg("%2x.",ue->dlsch_MCH[0]->harq_processes[0]->b[i]);
-            msg("\n");
-            */
-
-            if (mcch_active == 1)
-              ue->dlsch_mcch_received[sync_area][0]++;
-            else
-              ue->dlsch_mtch_received[sync_area][0]++;
-
-
-            if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) {
-              ue->dlsch_mch_received_sf[subframe_rx%5][0]=0;
-            } else {
-              ue->dlsch_mch_received[0]+=1;
-              ue->dlsch_mch_received_sf[subframe_rx][0]=1;
-            }
-
-          } else if (r_type == multicast_relay) { // mcch is not active here
-            // only 1 harq process exists
-            // Fix me: this could be a pointer copy
-            memcpy (phy_vars_rn->dlsch_rn_MCH[subframe_rx]->harq_processes[0]->b,
-                    ue->dlsch_MCH[0]->harq_processes[0]->b,
-                    ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3);
-            // keep the tbs
-            phy_vars_rn->mch_avtive[subframe_rx] = 1;
-            phy_vars_rn->sync_area[subframe_rx] = sync_area; // this could also go the harq data struct
-            phy_vars_rn->dlsch_rn_MCH[subframe_rx]->harq_processes[0]->TBS = ue->dlsch_MCH[0]->harq_processes[0]->TBS;
-            phy_vars_rn->dlsch_rn_MCH[subframe_rx]->harq_processes[0]->mcs = ue->dlsch_MCH[0]->harq_processes[0]->mcs;
-            LOG_D(PHY,"[RN/UE %d] Frame %d subframe %d: store the MCH PDU for MBSFN sync area %d (MCS %d, TBS %d)\n",
-                  ue->Mod_id, frame_rx,subframe_rx,sync_area,
-                  phy_vars_rn->dlsch_rn_MCH[subframe_rx]->harq_processes[0]->mcs,
-                  phy_vars_rn->dlsch_rn_MCH[subframe_rx]->harq_processes[0]->TBS>>3);
-#ifdef DEBUG_PHY
-
-            for (int i=0; i<phy_vars_rn->dlsch_rn_MCH[subframe_rx]->harq_processes[0]->TBS>>3; i++)
-              msg("%02x ",phy_vars_rn->dlsch_rn_MCH[subframe_rx]->harq_processes[0]->b[i]);
-
-            msg("\n");
-#endif
-          } else
-            LOG_W(PHY,"[UE %d] Frame %d: not supported option\n",ue->Mod_id, frame_rx);
-
-#endif
-        }
-      }
-    }
-  }
 
 #ifdef EMOS
-  phy_procedures_emos_UE_RX(ue,slot_rx,eNB_id);
+  phy_procedures_emos_UE_RX(ue,slot,eNB_id);
 #endif
 
+     
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
   stop_meas(&ue->phy_proc_rx);
   return (0);
 }
-
+   
 #ifdef Rel10
 int phy_procedures_RN_UE_RX(uint8_t slot_rx, uint8_t next_slot, relaying_type_t r_type)
 {
-
+   
   int do_proc =0; // do nothing by default
-
+   
   switch(r_type) {
   case no_relay:
     do_proc=no_relay; // perform the normal UE operation
     break;
-
+     
   case multicast_relay:
     if (slot_rx > 12)
       do_proc = 0; // do nothing
     else // SF#1, SF#2, SF3, SF#3, SF#4, SF#5, SF#6(do rx slot 12)
       do_proc = multicast_relay ; // do PHY procedures UE RX
-
+     
     break;
-
+     
   default: // should'not be here
     LOG_W(PHY,"Not supported relay type %d, do nothing \n", r_type);
     do_proc= 0;
     break;
   }
-
+   
   return do_proc;
 }
 #endif
-
-
-void phy_procedures_UE_lte(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
-                           relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn)
+ 
+ 
+void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
+			   relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn)
 {
 #if defined(ENABLE_ITTI)
   MessageDef   *msg_p;
@@ -3378,27 +2913,21 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_fl
   unsigned int  Mod_id;
   int           result;
 #endif
-#   if ENABLE_RAL
-  int           CC_id =0;
-#endif
-  int           frame_rx = ue->frame_rx;
-  int           frame_tx = ue->frame_tx;
-  int           slot_rx  = ue->slot_rx;
-  int           slot_tx  = ue->slot_tx;
-  int           subframe_tx = slot_tx>>1;
-  int           subframe_rx = slot_rx>>1;
+   
+  int           frame_rx = proc->frame_rx;
+  int           frame_tx = proc->frame_tx;
+  int           subframe_rx = proc->subframe_rx;
+  int           subframe_tx = proc->subframe_tx;
 #undef DEBUG_PHY_PROC
-
+   
   UE_L2_STATE_t ret;
+  int slot;
 
   if (ue->mac_enabled == 0) {
     ue->UE_mode[eNB_id]=PUSCH;
-    ue->prach_resources[eNB_id] = &prach_resources_local;
-    prach_resources_local.ra_RNTI = 0xbeef;
-    prach_resources_local.ra_PreambleIndex = 0;
   }
-
-
+   
+   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
   start_meas(&ue->phy_proc);
 #if defined(ENABLE_ITTI)
@@ -3406,218 +2935,92 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_fl
   do {
     // Checks if a message has been sent to PHY sub-task
     itti_poll_msg (TASK_PHY_UE, &msg_p);
-
+     
     if (msg_p != NULL) {
       msg_name = ITTI_MSG_NAME (msg_p);
       instance = ITTI_MSG_INSTANCE (msg_p);
       Mod_id = instance - NB_eNB_INST;
-
+       
       switch (ITTI_MSG_ID(msg_p)) {
       case PHY_FIND_CELL_REQ:
-        LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
-
-        /* TODO process the message */
-#   if ENABLE_RAL
-        {
-          MessageDef *message_p;
-
-          message_p = itti_alloc_new_message(TASK_PHY_UE , PHY_FIND_CELL_IND);
-          memset(&PHY_FIND_CELL_IND(message_p), 0, sizeof(PHY_FIND_CELL_IND(message_p)));
-          PHY_FIND_CELL_IND (message_p).transaction_id   = PHY_FIND_CELL_REQ(msg_p).transaction_id;
-          PHY_FIND_CELL_IND (message_p).cell_nb          = 1;
-          PHY_FIND_CELL_IND (message_p).cells[0].earfcn  = 1;
-          PHY_FIND_CELL_IND (message_p).cells[0].cell_id = 06;
-          PHY_FIND_CELL_IND (message_p).cells[0].rsrp    = 39;
-          PHY_FIND_CELL_IND (message_p).cells[0].rsrq    = 39;
-
-          itti_send_msg_to_task(TASK_RRC_UE, instance, message_p);
-
-        }
-#   endif
-        break;
-
-#   if ENABLE_RAL
-
-      case TIMER_HAS_EXPIRED:
-        // check if it is a measurement timer
-      {
-        hashtable_rc_t       hashtable_rc;
-        hashtable_rc = hashtable_is_key_exists(ue_g[Mod_id][CC_id]->ral_thresholds_timed, (uint64_t)(TIMER_HAS_EXPIRED(msg_p).timer_id));
-        LOG_I(PHY, "[UE %d] Received TIMER HAS EXPIRED: (hash_rc %d, HASH_TABLE_OK %d)\n", Mod_id, hashtable_rc, HASH_TABLE_OK);
-
-        if (hashtable_rc == HASH_TABLE_OK) {
-          phy_UE_lte_check_measurement_thresholds(instance, (ral_threshold_phy_t*)TIMER_HAS_EXPIRED(msg_p).arg);
-        }
-      }
-      break;
-
-
-      case PHY_MEAS_THRESHOLD_REQ:
-#warning "TO DO LIST OF THRESHOLDS"
-        LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
-        {
-          ral_threshold_phy_t* threshold_phy_p  = NULL;
-          int                  index, res;
-          long                 timer_id;
-          hashtable_rc_t       hashtable_rc;
-
-          switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action) {
-
-          case RAL_TH_ACTION_CANCEL_THRESHOLD:
-            break;
-
-          case RAL_TH_ACTION_SET_NORMAL_THRESHOLD:
-          case RAL_TH_ACTION_SET_ONE_SHOT_THRESHOLD:
-            for (index = 0; index < PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.num_thresholds; index++) {
-              threshold_phy_p                  = calloc(1, sizeof(ral_threshold_phy_t));
-              threshold_phy_p->th_action       = PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action;
-              memcpy(&threshold_phy_p->link_param.link_param_type,
-                     &PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type,
-                     sizeof(ral_link_param_type_t));
-
-              memcpy(&threshold_phy_p->threshold,
-                     &PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.thresholds[index],
-                     sizeof(ral_threshold_t));
-
-              switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice) {
-
-              case RAL_LINK_CFG_PARAM_CHOICE_TIMER_NULL:
-                switch (PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice) {
-                case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
-                  SLIST_INSERT_HEAD(
-                    &ue_g[Mod_id][CC_id]->ral_thresholds_gen_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_gen],
-                    threshold_phy_p,
-                    ral_thresholds);
-                  break;
-
-                case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
-                  SLIST_INSERT_HEAD(
-                    &ue_g[Mod_id][CC_id]->ral_thresholds_lte_polled[PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type._union.link_param_lte],
-                    threshold_phy_p,
-                    ral_thresholds);
-                  //LOG_E(PHY, "[UE %d] NORMAL/ONE SHOT - TIMER NULL - type LTE in %s\n", Mod_id, msg_name);
-                  break;
-
-                default:
-                  LOG_E(PHY, "[UE %d] BAD PARAMETER cfg_param.link_param_type.choice %d in %s\n",
-                        Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.link_param_type.choice, msg_name);
-                }
-
-                break;
-
-              case RAL_LINK_CFG_PARAM_CHOICE_TIMER:
-                res = timer_setup(
-                        (uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval/1000),//uint32_t      interval_sec,
-                        (uint32_t)(PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param._union.timer_interval%1000),//uint32_t      interval_us,
-                        TASK_PHY_UE,
-                        instance,
-                        TIMER_PERIODIC,
-                        threshold_phy_p,
-                        &timer_id);
-
-                if (res == 0) {
-                  hashtable_rc = hashtable_insert(ue_g[Mod_id][CC_id]->ral_thresholds_timed, (uint64_t )timer_id, (void*)threshold_phy_p);
-
-                  if (hashtable_rc == HASH_TABLE_OK) {
-                    threshold_phy_p->timer_id = timer_id;
-                    LOG_I(PHY, "[UE %d] NORMAL/ONE SHOT - TIMER CHOICE - OK - in Hash %s\n", Mod_id, msg_name);
-                  } else {
-                    LOG_E(PHY, "[UE %d]  %s: Error in hashtable. Could not configure threshold index %d \n",
-                          Mod_id, msg_name, index);
-                  }
-
-                } else {
-                  LOG_E(PHY, "[UE %d]  %s: Could not configure threshold index %d because of timer initialization failure\n",
-                        Mod_id, msg_name, index);
-                }
-
-                break;
-
-              default: // already checked in RRC, should not happen here
-                LOG_E(PHY, "[UE %d] BAD PARAMETER cfg_param.union_choice %d in %s\n",
-                      Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.union_choice, msg_name);
-              }
-            }
-
-            break;
-
-          default:
-            LOG_E(PHY, "[UE %d] BAD PARAMETER th_action value %d in %s\n",
-                  Mod_id, PHY_MEAS_THRESHOLD_REQ(msg_p).cfg_param.th_action, msg_name);
-          }
-
-        }
-        break;
-#   endif
-
+	LOG_I(PHY, "[UE %d] Received %s\n", Mod_id, msg_name);
+	 
+	/* TODO process the message */
+	break;
+	 
       default:
-        LOG_E(PHY, "[UE %d] Received unexpected message %s\n", Mod_id, msg_name);
-        break;
+	LOG_E(PHY, "[UE %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
-
-  if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
-      (ue->frame_parms.frame_type == FDD)) {
-    phy_procedures_UE_TX(ue,eNB_id,abstraction_flag,mode,r_type);
-  }
-
-  if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) ||
-      (ue->frame_parms.frame_type == FDD)) {
+   
+#endif
+   
+  for (slot=0;slot<2;slot++) {
+     
+    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
+	(ue->frame_parms.frame_type == FDD)) {
+      phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode,r_type);
+    }
+     
+    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) ||
+	(ue->frame_parms.frame_type == FDD)) {
 #ifdef Rel10
-
-    if (phy_procedures_RN_UE_RX(slot_rx, slot_tx, r_type) != 0 )
+       
+      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
 #endif
-      phy_procedures_UE_RX(ue,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
-  }
-
-  if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
-      ((slot_tx&1)==1)) {
-    phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag,r_type);
-  }
-
-  if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) &&
-      ((slot_rx&1)==0)) {
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
+    }
+     
+    if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
+	(slot==1)) {
+      phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag,r_type);
+    }
+       
+    if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) &&
+	(slot==0)) {
 #ifdef Rel10
-
-    if (phy_procedures_RN_UE_RX(slot_rx, slot_tx, r_type) != 0 )
+	 
+      if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
 #endif
-      phy_procedures_UE_RX(ue,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
-  }
-
-  if (ue->mac_enabled==1) {
-    if (slot_rx%2==0) {
-      ret = mac_xface->ue_scheduler(ue->Mod_id,
-				    frame_tx,
-				    subframe_rx,
-				    subframe_select(&ue->frame_parms,subframe_tx),
-				    eNB_id,
-				    0/*FIXME CC_id*/);
-
-    if (ret == CONNECTION_LOST) {
-      LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
-            frame_rx,subframe_tx);
-      ue->UE_mode[eNB_id] = PRACH;
-      //      mac_xface->macphy_exit("Connection lost");
-    } else if (ret == PHY_RESYNCH) {
-      LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n",
-            ue->Mod_id,
-            frame_rx,subframe_tx);
-      ue->UE_mode[eNB_id] = RESYNCH;
-      //     mac_xface->macphy_exit("Connection lost");
-    } else if (ret == PHY_HO_PRACH) {
-      LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n",
-            ue->Mod_id,frame_rx,subframe_tx);
-      ue->UE_mode[eNB_id] = PRACH;
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
     }
-  }
-  }
-
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
-  stop_meas(&ue->phy_proc);
+       
+    if (ue->mac_enabled==1) {
+      if (slot==0) {
+	ret = mac_xface->ue_scheduler(ue->Mod_id,
+				      frame_tx,
+				      subframe_rx,
+				      subframe_select(&ue->frame_parms,subframe_tx),
+				      eNB_id,
+				      0/*FIXME CC_id*/);
+	   
+	if (ret == CONNECTION_LOST) {
+	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id,
+		frame_rx,subframe_tx);
+	  ue->UE_mode[eNB_id] = PRACH;
+	  //      mac_xface->macphy_exit("Connection lost");
+	} else if (ret == PHY_RESYNCH) {
+	  LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n",
+		ue->Mod_id,
+		frame_rx,subframe_tx);
+	  ue->UE_mode[eNB_id] = RESYNCH;
+	  //     mac_xface->macphy_exit("Connection lost");
+	} else if (ret == PHY_HO_PRACH) {
+	  LOG_I(PHY,"[UE %d] Frame %d, subframe %d, return to PRACH and perform a contention-free access\n",
+		ue->Mod_id,frame_rx,subframe_tx);
+	  ue->UE_mode[eNB_id] = PRACH;
+	}
+      }
+    }
+       
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
+    stop_meas(&ue->phy_proc);
+  } // slot
 }
+ 
+ 
diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c
index 229ae3f1a332c1443b6789accfdb743a2031ec0b..7eaf1738dc3f27b7e630392c74aa55ea2bad5696 100644
--- a/openair1/SCHED/pucch_pc.c
+++ b/openair1/SCHED/pucch_pc.c
@@ -42,7 +42,7 @@
 #include "PHY/LTE_TRANSPORT/proto.h"
 #include "PHY/extern.h"
 
-int8_t pucch_power_cntl(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt)
+int8_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,uint8_t eNB_id,PUCCH_FMT_t pucch_fmt)
 {
 
   int8_t Po_PUCCH;
@@ -98,7 +98,7 @@ int8_t pucch_power_cntl(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id,PUCCH_FM
   if (pucch_fmt!=pucch_format1) {
     LOG_I(PHY,"[UE  %d][PDSCH %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
           ue->Mod_id,
-          ue->dlsch[eNB_id][0]->rnti,ue->frame_tx,subframe,
+          ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
           Po_PUCCH,
           ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
           get_PL(ue->Mod_id,ue->CC_id,eNB_id),
@@ -106,7 +106,7 @@ int8_t pucch_power_cntl(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id,PUCCH_FM
   } else {
     LOG_I(PHY,"[UE  %d][SR %x] frame %d, subframe %d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
           ue->Mod_id,
-          ue->dlsch[eNB_id][0]->rnti,ue->frame_tx,subframe,
+          ue->dlsch[eNB_id][0]->rnti,proc->frame_tx,subframe,
           Po_PUCCH,
           ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
           get_PL(ue->Mod_id,ue->CC_id,eNB_id),
diff --git a/openair1/SCHED/pusch_pc.c b/openair1/SCHED/pusch_pc.c
index 074cd507effa79ee80712abb34f9f955bf7d69a5..6babb4fef0f8e1f6ea3ca6d2815a7dc498b1a56d 100644
--- a/openair1/SCHED/pusch_pc.c
+++ b/openair1/SCHED/pusch_pc.c
@@ -136,13 +136,13 @@ int16_t get_hundred_times_delta_IF(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t harq_p
 
 uint8_t alpha_lut[8] = {0,40,50,60,70,80,90,100};
 
-void pusch_power_cntl(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag)
+void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t j, uint8_t abstraction_flag)
 {
 
 
   uint8_t harq_pid = subframe2harq_pid(&ue->frame_parms,
-                                       ue->frame_tx,
-                                       subframe);
+                                       proc->frame_tx,
+                                       proc->subframe_tx);
 
   uint8_t nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
   int8_t PL;
@@ -164,7 +164,7 @@ void pusch_power_cntl(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id,uint8_t j,
     ue->ulsch[eNB_id]->Po_PUSCH += (mac_xface->get_Po_NOMINAL_PUSCH(ue->Mod_id,0) + PL);
 
     LOG_I(PHY,"[UE  %d][RAPROC] frame %d, subframe %d: Msg3 Po_PUSCH %d dBm (%d,%d,100*PL=%d,%d,%d)\n",
-          ue->Mod_id,ue->frame_tx,subframe,ue->ulsch[eNB_id]->Po_PUSCH,
+          ue->Mod_id,proc->frame_tx,proc->subframe_tx,ue->ulsch[eNB_id]->Po_PUSCH,
           100*mac_xface->get_Po_NOMINAL_PUSCH(ue->Mod_id,0),
           hundred_times_log10_NPRB[nb_rb-1],
           100*PL,
@@ -183,7 +183,7 @@ void pusch_power_cntl(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id,uint8_t j,
       ue->ulsch[eNB_id]->PHR = 40;
 
     LOG_D(PHY,"[UE  %d][PUSCH %d] frame %d, subframe %d: Po_PUSCH %d dBm : tx power %d, Po_NOMINAL_PUSCH %d,log10(NPRB) %f,PHR %d, PL %d, alpha*PL %f,delta_IF %f,f_pusch %d\n",
-          ue->Mod_id,harq_pid,ue->frame_tx,subframe,
+          ue->Mod_id,harq_pid,proc->frame_tx,proc->subframe_tx,
           ue->ulsch[eNB_id]->Po_PUSCH,
           ue->tx_power_max_dBm,
           ue->frame_parms.ul_power_control_config_common.p0_NominalPUSCH,
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index d757a7573c8848e056dc53eaff7dcfda164ef1c6..23a453b941d1afbd56219283f3cb80f0efcd487a 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -126,1829 +126,1997 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_
 
 
   }
-
+  
 }
 
-int main(int argc, char **argv)
-{
-
-  int c;
-  int k,i,aa,aarx,aatx;
-
-  int s,Kr,Kr_bytes;
-
-  double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1,rate;
-  double snr_step=1,input_snr_step=1, snr_int=30;
+void DL_channel(PHY_VARS_eNB *eNB,PHY_VARS_UE *UE,int subframe,int awgn_flag,double SNR, int tx_lev,int hold_channel,int abstx, int num_rounds, int trials, int round, channel_desc_t *eNB2UE[4], double **s_re,double **s_im,double **r_re,double **r_im,FILE *csv_fd) {
 
-  LTE_DL_FRAME_PARMS *frame_parms;
-  double **s_re,**s_im,**r_re,**r_im;
-  double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
+  int i,u;
+  int aa,aarx,aatx;
+  double channelx,channely;
+  double sigma2_dB,sigma2;
   double iqim=0.0;
 
-  uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx=1,n_rx=2;
-  uint16_t Nid_cell=0;
-
-  int eNB_id = 0, eNB_id_i = 1;
-  unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round,dci_flag=0;
-  unsigned char i_mod = 2;
-  unsigned short NB_RB;
-  unsigned char Ns,l,m;
-  uint16_t tdd_config=3;
-  uint16_t n_rnti=0x1234;
-  int n_users = 1;
-
-  SCM_t channel_model=Rayleigh1;
-  //  unsigned char *input_data,*decoded_output;
-
-  unsigned char *input_buffer0[2],*input_buffer1[2];
-  unsigned short input_buffer_length0,input_buffer_length1;
-  unsigned int ret;
-  unsigned int coded_bits_per_codeword=0,nsymb,dci_cnt,tbs=0;
+  //    printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag);
+  for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
+    for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
+      if (awgn_flag == 0) {
+	s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
+	s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+      } else {
+	for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) {
+	  if (aa==0) {
+	    r_re[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+	    r_im[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+	  } else {
+	    r_re[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
+	    r_im[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[0][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
+	  }
+	  
+	}
+      }
+    }
+  }
+  
+  // Multipath channel
+  if (awgn_flag == 0) {
+    multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
+		      2*UE->frame_parms.samples_per_tti,hold_channel);
+    
+    //      printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
+    if(abstx==1 && num_rounds>1)
+      if(round==0 && hold_channel==0) {
+	random_channel(eNB2UE[1],0);
+	random_channel(eNB2UE[2],0);
+	random_channel(eNB2UE[3],0);
+      }
+    
+    if (UE->perfect_ce==1) {
+      // fill in perfect channel estimates
+      freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
+      /*
+	write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8);
+	write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8);
+      */
+    }
+  }
+  
+  
+  if(abstx) {
+    if (trials==0 && round==0) {
+      // calculate freq domain representation to compute SINR
+      freq_channel(eNB2UE[0], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1);
+      // snr=pow(10.0,.1*SNR);
+      fprintf(csv_fd,"%f,",SNR);
+      
+      for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
+	for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) {
+	  for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) {
+	    channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x;
+	    channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y;
+	    fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+	  }
+	}
+      }	
+      
+      if(num_rounds>1) {
+	freq_channel(eNB2UE[1], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1);
+	
+	for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
+	  for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) {
+	    for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) {
+	      channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x;
+	      channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y;
+	      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+	    }
+	  }
+	}
+	
+	freq_channel(eNB2UE[2], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1);
+	
+	for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
+	  for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) {
+	    for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) {
+	      channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x;
+	      channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y;
+	      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+	    }
+	  }
+	}
+	
+	freq_channel(eNB2UE[3], eNB->frame_parms.N_RB_DL,2*eNB->frame_parms.N_RB_DL + 1);
+	
+	for (u=0; u<2*eNB->frame_parms.N_RB_DL; u++) {
+	  for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) {
+	    for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) {
+	      channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x;
+	      channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y;
+	      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
+	    }
+	  }
+	}
+      }
+    }
+  }
+  
+  //AWGN
+  // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A
+  sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(eNB->frame_parms.N_RB_DL*12)) - SNR - get_pa_dB(eNB->pdsch_config_dedicated);
+  sigma2 = pow(10,sigma2_dB/10);
+
+  for (i=0; i<2*UE->frame_parms.samples_per_tti; i++) {
+    for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
+      //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
+      ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] =
+	(short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+      ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
+	(short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+    }
+  }
+}
 
-  unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors=0,dlsch_active=0;//,num_layers;
-  int re_allocated;
-  char fname[32],vname[32];
-  FILE *bler_fd;
-  char bler_fname[256];
-  FILE *time_meas_fd;
-  char time_meas_fname[256];
-  //  FILE *tikz_fd;
-  //  char tikz_fname[256];
 
-  FILE *input_trch_fd=NULL;
-  unsigned char input_trch_file=0;
-  FILE *input_fd=NULL;
-  unsigned char input_file=0;
-  //  char input_val_str[50],input_val_str2[50];
+void fill_DCI(PHY_VARS_eNB *eNB,
+	      DCI_ALLOC_t *dci_alloc,
+	      int subframe, 
+	      int n_rnti,
+	      int n_users,
+	      int transmission_mode,
+	      int common_flag,
+	      int DLSCH_RB_ALLOC,
+	      int TPC,
+	      int mcs1,
+	      int mcs2,
+	      int ndi,
+	      int rv,
+	      int *num_common_dci,
+	      int *num_ue_spec_dci,
+	      int *num_dci) {
+
+  int k;
+  int dci_length,dci_length_bytes;
+
+  //  printf("Generating DCIs for %d users, TM %d, mcs1 %d\n",n_users,transmission_mode,mcs1);
+  for(k=0; k<n_users; k++) {
+    switch(transmission_mode) {
+    case 1:
 
-  char input_trch_val[16];
-  double channelx,channely;
+    case 2:
+      if (common_flag == 0) {
+	
+	if (eNB->frame_parms.frame_type == TDD) {
+	  
+	  switch (eNB->frame_parms.N_RB_DL) {
+	  case 6:
+	    dci_length = sizeof_DCI1_1_5MHz_TDD_t;
+	    dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t);
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+	    ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+	    break;
+	    
+	  case 25:
+	    dci_length = sizeof_DCI1_5MHz_TDD_t;
+	    dci_length_bytes = sizeof(DCI1_5MHz_TDD_t);
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+	    ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+	    break;
+	    
+	  case 50:
+	    dci_length = sizeof_DCI1_10MHz_TDD_t;
+	    dci_length_bytes = sizeof(DCI1_10MHz_TDD_t);
+	    ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+              break;
 
-  //  unsigned char pbch_pdu[6];
+            case 100:
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+              dci_length = sizeof_DCI1_20MHz_TDD_t;
+              dci_length_bytes = sizeof(DCI1_20MHz_TDD_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t);
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+              break;
 
-  DCI_ALLOC_t dci_alloc[8],dci_alloc_rx[8];
-  int num_common_dci=0,num_ue_spec_dci=0,num_dci=0;
+            case 25:
+              dci_length = sizeof_DCI1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_5MHz_FDD_t);
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+              break;
 
-  //  FILE *rx_frame_file;
+            case 50:
+              dci_length = sizeof_DCI1_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_10MHz_FDD_t);
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+              break;
 
-  int n_frames;
-  int n_ch_rlz = 1;
-  channel_desc_t *eNB2UE[4];
-  uint8_t num_pdcch_symbols=1,num_pdcch_symbols_2=0;
-  uint8_t pilot1,pilot2,pilot3;
-  uint8_t rx_sample_offset = 0;
-  //char stats_buffer[4096];
-  //int len;
-  uint8_t num_rounds = 4;//,fix_rounds=0;
-  uint8_t subframe=7;
-  int u;
-  int n=0;
-  int abstx=0;
-  int iii;
-  FILE *csv_fd=NULL;
-  char csv_fname[512];
-  int ch_realization;
-  int pmi_feedback=0;
-  int hold_channel=0;
+            case 100:
+              dci_length = sizeof_DCI1_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1_20MHz_FDD_t);
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = ndi;
+              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = rv;
+              break;
+            }
+          }
 
-  // void *data;
-  // int ii;
-  //  int bler;
-  double blerr[4],uncoded_ber,avg_ber;
-  short *uncoded_ber_bit=NULL;
-  uint8_t N_RB_DL=25,osf=1;
-  frame_t frame_type = FDD;
-  int xforms=0;
-  FD_lte_phy_scope_ue *form_ue = NULL;
-  char title[255];
-  uint32_t DLSCH_RB_ALLOC = 0x1fff;
-  int numCCE=0;
-  int dci_length_bytes=0,dci_length=0;
-  //double channel_bandwidth = 5.0, sampling_rate=7.68;
-  int common_flag=0,TPC=0;
+          memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[*num_dci].dci_length = dci_length;
+          dci_alloc[*num_dci].L          = 1;
+          dci_alloc[*num_dci].rnti       = n_rnti+k;
+          dci_alloc[*num_dci].format     = format1;
+          dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-  double cpu_freq_GHz;
-  //  time_stats_t ts;//,sts,usts;
-  int avg_iter,iter_trials;
-  int rballocset=0;
-  int print_perf=0;
-  int test_perf=0;
-  int dump_table=0;
-  int llr8_flag=0;
+	  //          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             n_rnti+k,
+                                             format1,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single);
 
-  double effective_rate=0.0;
-  char channel_model_input[10]="I";
+          *num_dci = *num_dci+1;
+          *num_ue_spec_dci = *num_ue_spec_dci+1;
+        } else {
+          if (eNB->frame_parms.frame_type == TDD) {
 
-  int TB0_active = 1;
-  uint32_t perfect_ce = 0;
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-  //  LTE_DL_UE_HARQ_t *dlsch0_ue_harq;
-  //  LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq;
-  uint8_t Kmimo;
-  uint8_t ue_category=4;
-  uint32_t Nsoft;
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
+            case 100:
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-  int CCE_table[800];
-
-  int threequarter_fs=0;
-
-  opp_enabled=1; // to enable the time meas
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-#if defined(__arm__)
-  FILE    *proc_fd = NULL;
-  char buf[64];
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-  proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
-  if(!proc_fd)
-     printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
-  else {
-     while(fgets(buf, 63, proc_fd))
-        printf("%s", buf);
-  }
-  fclose(proc_fd);
-  cpu_freq_GHz = ((double)atof(buf))/1e6;
-#else
-  cpu_freq_GHz = get_cpu_freq_GHz();
-#endif
-  printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
+            case 100:
+              dci_length = sizeof_DCI1A_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+            }
+          }
 
-  //signal(SIGSEGV, handler);
-  //signal(SIGABRT, handler);
+          memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[*num_dci].dci_length = dci_length;
+          dci_alloc[*num_dci].L          = 1;
+          dci_alloc[*num_dci].rnti       = SI_RNTI;
+          dci_alloc[*num_dci].format     = format1A;
+          dci_alloc[*num_dci].firstCCE       = 0;
+          dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-  logInit();
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             SI_RNTI,
+                                             format1A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single);
 
-  // default parameters
-  n_frames = 1000;
-  snr0 = 0;
-  //  num_layers = 1;
-  perfect_ce = 0;
+          *num_common_dci=*num_common_dci+1;
+          *num_dci = *num_dci + 1;
 
-  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XY")) != -1) {
-    switch (c) {
-    case 'a':
-      awgn_flag = 1;
-      channel_model = AWGN;
-      break;
+        }
 
-    case 'A':
-      abstx = 1;
-      break;
+        break;
 
-    case 'b':
-      tdd_config=atoi(optarg);
-      break;
+      case 3:
+        if (common_flag == 0) {
 
-    case 'B':
-      N_RB_DL=atoi(optarg);
-      break;
+          if (eNB->frame_parms.nb_antennas_tx == 2) {
 
-    case 'c':
-      num_pdcch_symbols=atoi(optarg);
-      break;
+            if (eNB->frame_parms.frame_type == TDD) {
 
-    case 'C':
-      Nid_cell = atoi(optarg);
-      break;
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t);
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-    case 'd':
-      dci_flag = 1;
-      break;
+              case 25:
+                dci_length = sizeof_DCI2A_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t);
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-    case 'D':
-      frame_type=TDD;
-      break;
+              case 50:
+                dci_length = sizeof_DCI2A_10MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t);
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-    case 'e':
-      num_rounds=1;
-      common_flag = 1;
-      TPC = atoi(optarg);
-      break;
-      
-    case 'E':
-      threequarter_fs=1;
-      break;
+              case 100:
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                dci_length = sizeof_DCI2A_20MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t);
+                break;
+              }
+            }
 
-    case 'f':
-      input_snr_step= atof(optarg);
-      break;
+            else {
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t);
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-    case 'F':
-      forgetting_factor = atof(optarg);
-      break;
+              case 25:
+                dci_length = sizeof_DCI2A_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t);
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-    case 'i':
-      input_fd = fopen(optarg,"r");
-      input_file=1;
-      dci_flag = 1;
-      break;
+              case 50:
+                dci_length = sizeof_DCI2A_10MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t);
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-    case 'I':
-      input_trch_fd = fopen(optarg,"r");
-      input_trch_file=1;
-      break;
+              case 100:
+                dci_length = sizeof_DCI2A_20MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t);
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
+              }
+            }
+          } else if (eNB->frame_parms.nb_antennas_tx == 4) {
 
-    case 'L':
-      llr8_flag=1;
-      break;
+          }
 
-    case 'l':
-      offset_mumimo_llr_drange_fix=atoi(optarg);
-      break;
+          memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[*num_dci].dci_length = dci_length;
+          dci_alloc[*num_dci].L          = 1;
+          dci_alloc[*num_dci].rnti       = n_rnti+k;
+          dci_alloc[*num_dci].format     = format2A;
+          dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-    case 'm':
-      mcs1 = atoi(optarg);
-      break;
+          printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             n_rnti+k,
+                                             format2A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single);
 
-    case 'M':
-      mcs2 = atoi(optarg);
-      break;
+          *num_dci = *num_dci + 1;
+          *num_ue_spec_dci = *num_ue_spec_dci + 1;
+        } else {
+          if (eNB->frame_parms.frame_type == TDD) {
 
-    case 'O':
-      test_perf=atoi(optarg);
-      //print_perf =1;
-      break;
-
-    case 't':
-      mcs_i = atoi(optarg);
-      i_mod = get_Qm(mcs_i);
-      break;
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-    case 'n':
-      n_frames = atoi(optarg);
-      break;
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-    case 'o':
-      rx_sample_offset = atoi(optarg);
-      break;
+            case 100:
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-    case 'r':
-      DLSCH_RB_ALLOC = atoi(optarg);
-      rballocset = 1;
-      break;
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-    case 's':
-      snr0 = atof(optarg);
-      break;
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-    case 'w':
-      snr_int = atof(optarg);
-      break;
+            case 100:
+              dci_length = sizeof_DCI1A_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+            }
+          }
 
+          memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[*num_dci].dci_length = dci_length;
+          dci_alloc[*num_dci].L          = 1;
+          dci_alloc[*num_dci].rnti       = SI_RNTI;
+          dci_alloc[*num_dci].format     = format1A;
+          dci_alloc[*num_dci].firstCCE       = 0;
+          dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-    case 'N':
-      n_ch_rlz= atof(optarg);
-      break;
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             SI_RNTI,
+                                             format1A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single);
 
-    case 'p':
-      extended_prefix_flag=1;
-      break;
+          *num_common_dci = *num_common_dci + 1;
+          *num_dci = *num_dci + 1;
 
-    case 'g':
-      memcpy(channel_model_input,optarg,10);
+        }
 
-      switch((char)*optarg) {
-      case 'A':
-        channel_model=SCM_A;
+        printf("Generated DCI format 2A (Transmission Mode 3)\n");
         break;
 
-      case 'B':
-        channel_model=SCM_B;
-        break;
+      case 4:
+        if (common_flag == 0) {
 
-      case 'C':
-        channel_model=SCM_C;
-        break;
+          if (eNB->frame_parms.nb_antennas_tx == 2) {
 
-      case 'D':
-        channel_model=SCM_D;
-        break;
+            if (eNB->frame_parms.frame_type == TDD) {
 
-      case 'E':
-        channel_model=EPA;
-        break;
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t);
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-      case 'F':
-        channel_model=EVA;
-        break;
+              case 25:
+                dci_length = sizeof_DCI2_5MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t);
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-      case 'G':
-        channel_model=ETU;
-        break;
+              case 50:
+                dci_length = sizeof_DCI2_10MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t);
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-      case 'H':
-        channel_model=Rayleigh8;
-        break;
+              case 100:
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                dci_length = sizeof_DCI2_20MHz_2A_TDD_t;
+                dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t);
+                break;
+              }
+            }
 
-      case 'I':
-        channel_model=Rayleigh1;
-        break;
+            else {
+              switch (eNB->frame_parms.N_RB_DL) {
+              case 6:
+                dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t);
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-      case 'J':
-        channel_model=Rayleigh1_corr;
-        break;
+              case 25:
+                dci_length = sizeof_DCI2_5MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t);
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-      case 'K':
-        channel_model=Rayleigh1_anticorr;
-        break;
+              case 50:
+                dci_length = sizeof_DCI2_10MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t);
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
 
-      case 'L':
-        channel_model=Rice8;
-        break;
+              case 100:
+                dci_length = sizeof_DCI2_20MHz_2A_FDD_t;
+                dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t);
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = ndi;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = rv;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = ndi;
+                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = rv;
+                break;
+              }
+            }
+          } else if (eNB->frame_parms.nb_antennas_tx == 4) {
 
-      case 'M':
-        channel_model=Rice1;
-        break;
+          }
 
-      case 'N':
-        channel_model=AWGN;
-        break;
-      default:
-        msg("Unsupported channel model!\n");
-        exit(-1);
-      }
+          memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[*num_dci].dci_length = dci_length;
+          dci_alloc[*num_dci].L          = 1;
+          dci_alloc[*num_dci].rnti       = n_rnti+k;
+          dci_alloc[*num_dci].format     = format2;
+          dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-      break;
-    case 'R':
-      num_rounds=atoi(optarg);
-      break;
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             n_rnti+k,
+                                             format2,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single);
 
-    case 'S':
-      subframe=atoi(optarg);
-      break;
+          *num_dci = *num_dci + 1;
+          *num_ue_spec_dci = *num_ue_spec_dci + 1;
+        } else {
+          if (eNB->frame_parms.frame_type == TDD) {
 
-    case 'T':
-      n_rnti=atoi(optarg);
-      break;
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-    case 'u':
-      dual_stream_UE=1;
-      UE->use_ia_receiver = 1;
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-      if ((n_tx!=2) || (transmission_mode!=5)) {
-        msg("IA receiver only supported for TM5!");
-        exit(-1);
-      }
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-      break;
+            case 100:
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
+              break;
+            }
+          } else {
+            switch (eNB->frame_parms.N_RB_DL) {
+            case 6:
+              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-    case 'v':
-      i_mod = atoi(optarg);
+            case 25:
+              dci_length = sizeof_DCI1A_5MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-      if (i_mod!=2 && i_mod!=4 && i_mod!=6) {
-        msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod);
-        exit(-1);
-      }
+            case 50:
+              dci_length = sizeof_DCI1A_10MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
 
-      break;
+            case 100:
+              dci_length = sizeof_DCI1A_20MHz_FDD_t;
+              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
+              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
+              break;
+            }
+          }
 
-    case 'P':
-      print_perf=1;
-      break;
+          memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
+          dci_alloc[*num_dci].dci_length = dci_length;
+          dci_alloc[*num_dci].L          = 1;
+          dci_alloc[*num_dci].rnti       = SI_RNTI;
+          dci_alloc[*num_dci].format     = format1A;
+          dci_alloc[*num_dci].firstCCE       = 0;
+          dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-    case 'x':
-      transmission_mode=atoi(optarg);
+          printf("Generating dlsch params for user %d\n",k);
+          generate_eNB_dlsch_params_from_dci(0,
+					     subframe,
+                                             &DLSCH_alloc_pdu_1[0],
+                                             SI_RNTI,
+                                             format1A,
+                                             eNB->dlsch[0],
+                                             &eNB->frame_parms,
+                                             eNB->pdsch_config_dedicated,
+                                             SI_RNTI,
+                                             0,
+                                             P_RNTI,
+                                             eNB->UE_stats[0].DL_pmi_single);
 
-      if ((transmission_mode!=1) &&
-          (transmission_mode!=2) &&
-          (transmission_mode!=3) &&
-          (transmission_mode!=4) &&
-          (transmission_mode!=5) &&
-          (transmission_mode!=6)) {
-        msg("Unsupported transmission mode %d\n",transmission_mode);
-        exit(-1);
-      }
+          *num_common_dci = *num_common_dci + 1;
+          *num_dci = *num_dci + 1;
 
-      if (transmission_mode>1) {
-        n_tx = 2;
-      }
+        }
 
-      break;
+        break;
 
-    case 'y':
-      n_tx=atoi(optarg);
+      case 5:
+      case 6:
+        memcpy(&dci_alloc[*num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
+        dci_alloc[*num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+        dci_alloc[*num_dci].L          = 1;
+        dci_alloc[*num_dci].rnti       = n_rnti+k;
+        dci_alloc[*num_dci].format     = format1E_2A_M10PRB;
+        dci_alloc[*num_dci].firstCCE       = 4*k;
+        printf("Generating dlsch params for user %d\n",k);
+        generate_eNB_dlsch_params_from_dci(0,
+					   subframe,
+                                           &DLSCH_alloc_pdu2_1E[k],
+                                           n_rnti+k,
+                                           format1E_2A_M10PRB,
+                                           eNB->dlsch[k],
+                                           &eNB->frame_parms,
+                                           eNB->pdsch_config_dedicated,
+                                           SI_RNTI,
+                                           0,
+                                           P_RNTI,
+                                           eNB->UE_stats[k].DL_pmi_single);
 
-      if ((n_tx==0) || (n_tx>2)) {
-        msg("Unsupported number of tx antennas %d\n",n_tx);
+        dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
+        *num_ue_spec_dci = *num_ue_spec_dci + 1;
+        *num_dci = *num_dci + 1;
+
+        break;
+
+      default:
+        printf("Unsupported Transmission Mode!!!");
         exit(-1);
+        break;
       }
+    }
+}
 
-      break;
+int n_users = 1;
+sub_frame_t subframe=7;
+DCI_PDU DCI_pdu;
+int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1;
 
-    case 'X':
-      xforms=1;
-      break;
 
-    case 'Y':
-      perfect_ce=1;
-      break;
+DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) {
 
-    case 'z':
-      n_rx=atoi(optarg);
+  if (subframeP == subframe) {
+    DCI_pdu.Num_ue_spec_dci   = num_ue_spec_dci;
+    DCI_pdu.Num_common_dci    = num_common_dci;
+    DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; 
+    return(&DCI_pdu);
+  } else {
+    DCI_pdu.Num_ue_spec_dci   = 0;
+    DCI_pdu.Num_common_dci    = 0;
+    DCI_pdu.num_pdcch_symbols = num_pdcch_symbols; 
+  }
+}
 
-      if ((n_rx==0) || (n_rx>2)) {
-        msg("Unsupported number of rx antennas %d\n",n_rx);
-        exit(-1);
-      }
-
-      break;
+void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) {
+  
+  return;
+}
 
-    case 'Z':
-      dump_table=1;
-      break;
+uint16_t n_rnti=0x1234;
+unsigned char *input_buffer0[2],*input_buffer1[2];
+unsigned short input_buffer_length0,input_buffer_length1;
 
+uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex) {
 
+  int k;
 
-    case 'h':
-    default:
-      printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6) -y TXant -z RXant -I trch_file\n",argv[0]);
-      printf("-h This message\n");
-      printf("-a Use AWGN channel and not multipath\n");
-      printf("-c Number of PDCCH symbols\n");
-      printf("-m MCS1 for TB 1\n");
-      printf("-M MCS2 for TB 2\n");
-      printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n");
-      printf("-p Use extended prefix mode\n");
-      printf("-n Number of frames to simulate\n");
-      printf("-o Sample offset for receiver\n");
-      printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step);
-      printf("-f step size of SNR, default value is 1.\n");
-      printf("-r ressource block allocation (see  section 7.1.6.3 in 36.213\n");
-      printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n");
-      printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n");
-      printf("-x Transmission mode (1,2,6 for the moment)\n");
-      printf("-y Number of TX antennas used in eNB\n");
-      printf("-z Number of RX antennas used in UE\n");
-      printf("-t MCS of interfering UE\n");
-      printf("-R Number of HARQ rounds (fixed)\n");
-      printf("-A Turns on calibration mode for abstraction.\n");
-      printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n");
-      printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n");
-      printf("-I Input filename for TrCH data (binary)\n");
-      printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n");
-      exit(1);
+  for (k=0;k<n_users;k++)
+    if (rnti == n_rnti+k)
       break;
-    }
+  if (k<n_users)
+    return(TBindex==0 ? input_buffer0[k] : input_buffer1[k]);
+  else {
+    printf("RNTI not found,exiting\n");
+    exit(-1);
   }
+}
 
-  if (common_flag == 0) {
-    switch (N_RB_DL) {
-    case 6:
-      if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
-      num_pdcch_symbols = 3;
-      break;
+int main(int argc, char **argv)
+{
 
-    case 25:
-      if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
-      break;
+  int c;
+  int k,i,aa;
 
-    case 50:
-      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;
-      break;
+  int s,Kr,Kr_bytes;
 
-    case 100:
-      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;
-      break;
-    }
+  double SNR,snr0=-2.0,snr1,rate;
+  double snr_step=1,input_snr_step=1, snr_int=30;
 
-    NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
-  } else
-    NB_RB = 4;
+  LTE_DL_FRAME_PARMS *frame_parms;
+  double **s_re,**s_im,**r_re,**r_im;
+  double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
 
-  if ((transmission_mode > 1) && (n_tx != 2))
-    printf("n_tx must be >1 for transmission_mode %d\n",transmission_mode);
 
-  if (xforms==1) {
-    fl_initialize (&argc, argv, NULL, 0, 0);
-    form_ue = create_lte_phy_scope_ue();
-    sprintf (title, "LTE PHY SCOPE eNB");
-    fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
-    
-    if (!dual_stream_UE==0) {
-      UE->use_ia_receiver = 1;
-      fl_set_button(form_ue->button_0,1);
-      fl_set_object_label(form_ue->button_0, "IA Receiver ON");
-      fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
-    }
-  }
+  uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx=1,n_rx=2;
+  uint16_t Nid_cell=0;
 
-  if (transmission_mode==5) {
-    n_users = 2;
-    printf("dual_stream_UE=%d\n", dual_stream_UE);
-  }
+  int eNB_id = 0;
+  unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round;
+  unsigned char i_mod = 2;
+  unsigned short NB_RB;
+  uint16_t tdd_config=3;
 
-  lte_param_init(n_tx,
-		 n_rx,
-		 transmission_mode,
-		 extended_prefix_flag,
-		 frame_type,
-		 Nid_cell,
-		 tdd_config,
-		 N_RB_DL,
-		 threequarter_fs,
-		 osf,
-		 perfect_ce);
 
 
-    
-  eNB_id_i = UE->n_connected_eNB;
+  SCM_t channel_model=Rayleigh1;
+  //  unsigned char *input_data,*decoded_output;
 
-  printf("Setting mcs1 = %d\n",mcs1);
-  printf("Setting mcs2 = %d\n",mcs2);
-  printf("NPRB = %d\n",NB_RB);
-  printf("n_frames = %d\n",n_frames);
-  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag);
+  DCI_ALLOC_t *dci_alloc = &DCI_pdu.dci_alloc[0];
 
-  snr1 = snr0+snr_int;
-  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
+  unsigned int ret;
+  unsigned int coded_bits_per_codeword=0,nsymb,tbs=0;
 
-  /*
-    txdataF    = (int **)malloc16(2*sizeof(int*));
-    txdataF[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
-    txdataF[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
+  unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[4]= {0,0,0,0},errs2[4]= {0,0,0,0},round_trials[4]= {0,0,0,0},dci_errors=0;//,num_layers;
+  int re_allocated;
+  char fname[32],vname[32];
+  FILE *bler_fd;
+  char bler_fname[256];
+  FILE *time_meas_fd;
+  char time_meas_fname[256];
+  //  FILE *tikz_fd;
+  //  char tikz_fname[256];
 
-    txdata    = (int **)malloc16(2*sizeof(int*));
-    txdata[0] = (int *)malloc16(FRAME_LENGTH_BYTES);
-    txdata[1] = (int *)malloc16(FRAME_LENGTH_BYTES);
-  */
+  FILE *input_trch_fd=NULL;
+  unsigned char input_trch_file=0;
+  FILE *input_fd=NULL;
+  unsigned char input_file=0;
+  //  char input_val_str[50],input_val_str2[50];
 
-  frame_parms = &eNB->frame_parms;
+  char input_trch_val[16];
 
-  s_re = malloc(2*sizeof(double*));
-  s_im = malloc(2*sizeof(double*));
-  r_re = malloc(2*sizeof(double*));
-  r_im = malloc(2*sizeof(double*));
-  //  r_re0 = malloc(2*sizeof(double*));
-  //  r_im0 = malloc(2*sizeof(double*));
+  //  unsigned char pbch_pdu[6];
 
-  nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
 
-  printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model);
-  printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n",
-         SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8);
 
-  if(transmission_mode==5)
-    sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,channel_model,n_rx,mcs1,mcs_i,dual_stream_UE,i_mod);
-  else
-    sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,n_rx,mcs1);
 
-  bler_fd = fopen(bler_fname,"w");
-  if (bler_fd==NULL) {
-    fprintf(stderr,"Cannot create file %s!\n",bler_fname);
-    exit(-1);
-  }
-  fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
+  //  FILE *rx_frame_file;
 
-  if (test_perf != 0) {
-    char hostname[1024];
-    hostname[1023] = '\0';
-    gethostname(hostname, 1023);
-    printf("Hostname: %s\n", hostname);
-    //char dirname[FILENAME_MAX];
-    //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname );
-    sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv",
-            N_RB_DL,mcs1,n_tx,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
-    //mkdir(dirname,0777);
-    time_meas_fd = fopen(time_meas_fname,"w");
-    if (time_meas_fd==NULL) {
-      fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
-      exit(-1);
-    }
-  }
+  int n_frames;
+  int n_ch_rlz = 1;
+  channel_desc_t *eNB2UE[4];
+  uint8_t num_pdcch_symbols_2=0;
+  uint8_t rx_sample_offset = 0;
+  //char stats_buffer[4096];
+  //int len;
+  uint8_t num_rounds = 4;//,fix_rounds=0;
 
-  if(abstx) {
-    // CSV file
-    sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds);
-    csv_fd = fopen(csv_fname,"w");
-    fprintf(csv_fd,"data_all%d=[",mcs1);
-    if (csv_fd==NULL) {
-      fprintf(stderr,"Cannot create file %s!\n",csv_fname);
-      exit(-1);
-    }
+  int u;
+  int n=0;
+  int abstx=0;
+  int iii;
+
+  int ch_realization;
+  int pmi_feedback=0;
+  int hold_channel=0;
+
+  // void *data;
+  // int ii;
+  //  int bler;
+  double blerr[4],uncoded_ber,avg_ber;
+  short *uncoded_ber_bit=NULL;
+  uint8_t N_RB_DL=25,osf=1;
+  frame_t frame_type = FDD;
+  int xforms=0;
+  FD_lte_phy_scope_ue *form_ue = NULL;
+  char title[255];
+
+  int numCCE=0;
+  int dci_length_bytes=0,dci_length=0;
+  //double channel_bandwidth = 5.0, sampling_rate=7.68;
+  int common_flag=0,TPC=0;
+
+  double cpu_freq_GHz;
+  //  time_stats_t ts;//,sts,usts;
+  int avg_iter,iter_trials;
+  int rballocset=0;
+  int print_perf=0;
+  int test_perf=0;
+  int dump_table=0;
+
+  double effective_rate=0.0;
+  char channel_model_input[10]="I";
+
+  int TB0_active = 1;
+  uint32_t perfect_ce = 0;
+
+  //  LTE_DL_UE_HARQ_t *dlsch0_ue_harq;
+  //  LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq;
+  uint8_t Kmimo;
+  uint8_t ue_category=4;
+  uint32_t Nsoft;
+
+
+
+  int CCE_table[800];
+
+  int threequarter_fs=0;
+
+  opp_enabled=1; // to enable the time meas
+
+  FILE *csv_fd=NULL;
+  char csv_fname[32];
+  int dci_flag=1;
+  int llr8_flag=1;
+  int DLSCH_RB_ALLOC;
+
+#if defined(__arm__)
+  FILE    *proc_fd = NULL;
+  char buf[64];
+
+  proc_fd = fopen("/sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq", "r");
+  if(!proc_fd)
+     printf("cannot open /sys/devices/system/cpu/cpu4/cpufreq/cpuinfo_cur_freq");
+  else {
+     while(fgets(buf, 63, proc_fd))
+        printf("%s", buf);
   }
+  fclose(proc_fd);
+  cpu_freq_GHz = ((double)atof(buf))/1e6;
+#else
+  cpu_freq_GHz = get_cpu_freq_GHz();
+#endif
+  printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz);
 
-  /*
-  //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
-  sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
-  tikz_fd = fopen(tikz_fname,"w");
-  //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
-  switch (mcs)
-    {
-    case 0:
-      fprintf(tikz_fd,"\\addplot[color=blue, mark=star] plot coordinates {");
-      break;
-    case 1:
-      fprintf(tikz_fd,"\\addplot[color=red, mark=star] plot coordinates {");
-      break;
-    case 2:
-      fprintf(tikz_fd,"\\addplot[color=green, mark=star] plot coordinates {");
+  //signal(SIGSEGV, handler);
+  //signal(SIGABRT, handler);
+
+  logInit();
+
+  // default parameters
+  n_frames = 1000;
+  snr0 = 0;
+  //  num_layers = 1;
+  perfect_ce = 0;
+
+  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:PLl:XY")) != -1) {
+    switch (c) {
+    case 'a':
+      awgn_flag = 1;
+      channel_model = AWGN;
       break;
-    case 3:
-      fprintf(tikz_fd,"\\addplot[color=yellow, mark=star] plot coordinates {");
+
+    case 'A':
+      abstx = 1;
       break;
-    case 4:
-      fprintf(tikz_fd,"\\addplot[color=black, mark=star] plot coordinates {");
+
+    case 'b':
+      tdd_config=atoi(optarg);
       break;
-    case 5:
-      fprintf(tikz_fd,"\\addplot[color=blue, mark=o] plot coordinates {");
+
+    case 'B':
+      N_RB_DL=atoi(optarg);
       break;
-    case 6:
-      fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
+
+    case 'c':
+      num_pdcch_symbols=atoi(optarg);
       break;
-    case 7:
-      fprintf(tikz_fd,"\\addplot[color=green, mark=o] plot coordinates {");
+
+    case 'C':
+      Nid_cell = atoi(optarg);
       break;
-    case 8:
-      fprintf(tikz_fd,"\\addplot[color=yellow, mark=o] plot coordinates {");
+
+    case 'd':
+      dci_flag = 1;
       break;
-    case 9:
-      fprintf(tikz_fd,"\\addplot[color=black, mark=o] plot coordinates {");
+
+    case 'D':
+      frame_type=TDD;
       break;
-    case 10:
-      fprintf(tikz_fd,"\\addplot[color=blue, mark=square] plot coordinates {");
+
+    case 'e':
+      num_rounds=1;
+      common_flag = 1;
+      TPC = atoi(optarg);
       break;
-    case 11:
-      fprintf(tikz_fd,"\\addplot[color=red, mark=square] plot coordinates {");
+      
+    case 'E':
+      threequarter_fs=1;
       break;
-    case 12:
-      fprintf(tikz_fd,"\\addplot[color=green, mark=square] plot coordinates {");
+
+    case 'f':
+      input_snr_step= atof(optarg);
       break;
-    case 13:
-      fprintf(tikz_fd,"\\addplot[color=yellow, mark=square] plot coordinates {");
+
+    case 'F':
+      forgetting_factor = atof(optarg);
       break;
-    case 14:
-      fprintf(tikz_fd,"\\addplot[color=black, mark=square] plot coordinates {");
+
+    case 'i':
+      input_fd = fopen(optarg,"r");
+      input_file=1;
+      dci_flag = 1;
       break;
-    case 15:
-      fprintf(tikz_fd,"\\addplot[color=blue, mark=diamond] plot coordinates {");
+
+    case 'I':
+      input_trch_fd = fopen(optarg,"r");
+      input_trch_file=1;
       break;
-    case 16:
-      fprintf(tikz_fd,"\\addplot[color=red, mark=diamond] plot coordinates {");
+
+    case 'L':
+      llr8_flag=1;
       break;
-    case 17:
-      fprintf(tikz_fd,"\\addplot[color=green, mark=diamond] plot coordinates {");
+
+    case 'l':
+      offset_mumimo_llr_drange_fix=atoi(optarg);
       break;
-    case 18:
-      fprintf(tikz_fd,"\\addplot[color=yellow, mark=diamond] plot coordinates {");
+
+    case 'm':
+      mcs1 = atoi(optarg);
       break;
-    case 19:
-      fprintf(tikz_fd,"\\addplot[color=black, mark=diamond] plot coordinates {");
+
+    case 'M':
+      mcs2 = atoi(optarg);
       break;
-    case 20:
-      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+
+    case 'O':
+      test_perf=atoi(optarg);
+      //print_perf =1;
       break;
-    case 21:
-      fprintf(tikz_fd,"\\addplot[color=red, mark=x] plot coordinates {");
+
+    case 't':
+      mcs_i = atoi(optarg);
+      i_mod = get_Qm(mcs_i);
       break;
-    case 22:
-      fprintf(tikz_fd,"\\addplot[color=green, mark=x] plot coordinates {");
+
+    case 'n':
+      n_frames = atoi(optarg);
       break;
-    case 23:
-      fprintf(tikz_fd,"\\addplot[color=yellow, mark=x] plot coordinates {");
+
+
+    case 'o':
+      rx_sample_offset = atoi(optarg);
       break;
-    case 24:
-      fprintf(tikz_fd,"\\addplot[color=black, mark=x] plot coordinates {");
+
+    case 'r':
+      DLSCH_RB_ALLOC = atoi(optarg);
+      rballocset = 1;
       break;
-    case 25:
-      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+
+    case 's':
+      snr0 = atof(optarg);
       break;
-    case 26:
-      fprintf(tikz_fd,"\\addplot[color=red, mark=+] plot coordinates {");
+
+    case 'w':
+      snr_int = atof(optarg);
       break;
-    case 27:
-      fprintf(tikz_fd,"\\addplot[color=green, mark=+] plot coordinates {");
+
+
+    case 'N':
+      n_ch_rlz= atof(optarg);
       break;
-    case 28:
-      fprintf(tikz_fd,"\\addplot[color=yellow, mark=+] plot coordinates {");
+
+    case 'p':
+      extended_prefix_flag=1;
       break;
-    }
-  */
 
-  for (i=0; i<2; i++) {
-    s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-    s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-    r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-    r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-    //    r_re0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-    //    bzero(r_re0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-    //    r_im0[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-    //    bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
-  }
+    case 'g':
+      memcpy(channel_model_input,optarg,10);
 
+      switch((char)*optarg) {
+      case 'A':
+        channel_model=SCM_A;
+        break;
 
-  UE->pdcch_vars[0]->crnti = n_rnti;
+      case 'B':
+        channel_model=SCM_B;
+        break;
 
-  // Fill in UL_alloc
-  UL_alloc_pdu.type    = 0;
-  UL_alloc_pdu.hopping = 0;
-  UL_alloc_pdu.rballoc = UL_RB_ALLOC;
-  UL_alloc_pdu.mcs     = 1;
-  UL_alloc_pdu.ndi     = 1;
-  UL_alloc_pdu.TPC     = 0;
-  UL_alloc_pdu.cqi_req = 1;
+      case 'C':
+        channel_model=SCM_C;
+        break;
 
-  CCCH_alloc_pdu.type               = 0;
-  CCCH_alloc_pdu.vrb_type           = 0;
-  CCCH_alloc_pdu.rballoc            = CCCH_RB_ALLOC;
-  CCCH_alloc_pdu.ndi      = 1;
-  CCCH_alloc_pdu.mcs      = 1;
-  CCCH_alloc_pdu.harq_pid = 0;
+      case 'D':
+        channel_model=SCM_D;
+        break;
 
-  DLSCH_alloc_pdu2_1E[0].rah              = 0;
-  DLSCH_alloc_pdu2_1E[0].rballoc          = DLSCH_RB_ALLOC;
-  DLSCH_alloc_pdu2_1E[0].TPC              = 0;
-  DLSCH_alloc_pdu2_1E[0].dai              = 0;
-  DLSCH_alloc_pdu2_1E[0].harq_pid         = 0;
-  //DLSCH_alloc_pdu2_1E[0].tb_swap          = 0;
-  DLSCH_alloc_pdu2_1E[0].mcs             = mcs1;
-  DLSCH_alloc_pdu2_1E[0].ndi             = 1;
-  DLSCH_alloc_pdu2_1E[0].rv              = 0;
-  // Forget second codeword
-  DLSCH_alloc_pdu2_1E[0].tpmi             = (transmission_mode>=5 ? 5 : 0);  // precoding
-  DLSCH_alloc_pdu2_1E[0].dl_power_off     = (transmission_mode==5 ? 0 : 1);
+      case 'E':
+        channel_model=EPA;
+        break;
 
-  DLSCH_alloc_pdu2_1E[1].rah              = 0;
-  DLSCH_alloc_pdu2_1E[1].rballoc          = DLSCH_RB_ALLOC;
-  DLSCH_alloc_pdu2_1E[1].TPC              = 0;
-  DLSCH_alloc_pdu2_1E[1].dai              = 0;
-  DLSCH_alloc_pdu2_1E[1].harq_pid         = 0;
-  //DLSCH_alloc_pdu2_1E[1].tb_swap          = 0;
-  DLSCH_alloc_pdu2_1E[1].mcs             = mcs_i;
-  DLSCH_alloc_pdu2_1E[1].ndi             = 1;
-  DLSCH_alloc_pdu2_1E[1].rv              = 0;
-  // Forget second codeword
-  DLSCH_alloc_pdu2_1E[1].tpmi             = (transmission_mode>=5 ? 5 : 0) ;  // precoding
-  DLSCH_alloc_pdu2_1E[1].dl_power_off     = (transmission_mode==5 ? 0 : 1);
+      case 'F':
+        channel_model=EVA;
+        break;
 
-  eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
-                                   UE->frame_parms.nb_antennas_rx,
-                                   channel_model,
-                                   N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
-				   N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
-                                   forgetting_factor,
-                                   rx_sample_offset,
-                                   0);
+      case 'G':
+        channel_model=ETU;
+        break;
 
-  if(num_rounds>1) {
-    for(n=1; n<4; n++)
-      eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
-                                       UE->frame_parms.nb_antennas_rx,
-                                       channel_model,
-				       N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
-				       N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
-				       forgetting_factor,
-                                       rx_sample_offset,
-                                       0);
-  }
+      case 'H':
+        channel_model=Rayleigh8;
+        break;
 
-  if (eNB2UE[0]==NULL) {
-    msg("Problem generating channel model. Exiting.\n");
-    exit(-1);
-  }
+      case 'I':
+        channel_model=Rayleigh1;
+        break;
 
-  if ((transmission_mode == 3) || (transmission_mode==4))
-    Kmimo=2;
-  else
-    Kmimo=1;
+      case 'J':
+        channel_model=Rayleigh1_corr;
+        break;
 
-  switch (ue_category) {
-  case 1:
-    Nsoft = 250368;
-    break;
-  case 2:
-  case 3:
-    Nsoft = 1237248;
-    break;
-  case 4:
-    Nsoft = 1827072;
-    break;
-  default:
-    printf("Unsupported UE category %d\n",ue_category);
-    exit(-1);
-    break;
-  }
+      case 'K':
+        channel_model=Rayleigh1_anticorr;
+        break;
 
-  for (k=0; k<n_users; k++) {
-    // Create transport channel structures for 2 transport blocks (MIMO)
-    for (i=0; i<2; i++) {
-      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0);
+      case 'L':
+        channel_model=Rice8;
+        break;
 
-      if (!eNB->dlsch[k][i]) {
-        printf("Can't get eNB dlsch structures\n");
+      case 'M':
+        channel_model=Rice1;
+        break;
+
+      case 'N':
+        channel_model=AWGN;
+        break;
+      default:
+        msg("Unsupported channel model!\n");
         exit(-1);
       }
 
-      eNB->dlsch[k][i]->rnti = n_rnti+k;
-    }
-  }
-
-  for (i=0; i<2; i++) {
-    UE->dlsch[0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
-
-    if (!UE->dlsch[0][i]) {
-      printf("Can't get ue dlsch structures\n");
-      exit(-1);
-    }
+      break;
+    case 'R':
+      num_rounds=atoi(optarg);
+      break;
 
-    UE->dlsch[0][i]->rnti   = n_rnti;
-  }
+    case 'S':
+      subframe=atoi(optarg);
+      break;
 
-  // structure for SIC at UE
-  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0);
+    case 'T':
+      n_rnti=atoi(optarg);
+      break;
 
-  if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
+    case 'u':
+      dual_stream_UE=1;
+      UE->use_ia_receiver = 1;
 
-    eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);
+      if ((n_tx!=2) || (transmission_mode!=5)) {
+        msg("IA receiver only supported for TM5!");
+        exit(-1);
+      }
 
-    if (n_users>1)
-      eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI
-  } else {
-    eNB->UE_stats[0].DL_pmi_single = 0;
+      break;
 
-    if (n_users>1)
-      eNB->UE_stats[1].DL_pmi_single = 0;
-  }
+    case 'v':
+      i_mod = atoi(optarg);
 
+      if (i_mod!=2 && i_mod!=4 && i_mod!=6) {
+        msg("Wrong i_mod %d, should be 2,4 or 6\n",i_mod);
+        exit(-1);
+      }
 
-  if (input_fd==NULL) {
+      break;
 
+    case 'P':
+      print_perf=1;
+      break;
 
-    /*
-    // common DCI
-    memcpy(&dci_alloc[num_dci].dci_pdu[0],&CCCH_alloc_pdu,sizeof(DCI1A_5MHz_TDD_1_6_t));
-    dci_alloc[num_dci].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-    dci_alloc[num_dci].L          = 2;
-    dci_alloc[num_dci].rnti       = SI_RNTI;
-    num_dci++;
-    num_common_dci++;
-    */
+    case 'x':
+      transmission_mode=atoi(optarg);
 
-    // UE specific DCI
-    for(k=0; k<n_users; k++) {
-      switch(transmission_mode) {
-      case 1:
-      case 2:
-        if (common_flag == 0) {
+      if ((transmission_mode!=1) &&
+          (transmission_mode!=2) &&
+          (transmission_mode!=3) &&
+          (transmission_mode!=4) &&
+          (transmission_mode!=5) &&
+          (transmission_mode!=6)) {
+        msg("Unsupported transmission mode %d\n",transmission_mode);
+        exit(-1);
+      }
 
-          if (eNB->frame_parms.frame_type == TDD) {
+      if (transmission_mode>1) {
+        n_tx = 2;
+      }
 
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1_1_5MHz_TDD_t;
-              dci_length_bytes = sizeof(DCI1_1_5MHz_TDD_t);
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+      break;
 
-            case 25:
-              dci_length = sizeof_DCI1_5MHz_TDD_t;
-              dci_length_bytes = sizeof(DCI1_5MHz_TDD_t);
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+    case 'y':
+      n_tx=atoi(optarg);
 
-            case 50:
-              dci_length = sizeof_DCI1_10MHz_TDD_t;
-              dci_length_bytes = sizeof(DCI1_10MHz_TDD_t);
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+      if ((n_tx==0) || (n_tx>2)) {
+        msg("Unsupported number of tx antennas %d\n",n_tx);
+        exit(-1);
+      }
 
-            case 100:
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              dci_length = sizeof_DCI1_20MHz_TDD_t;
-              dci_length_bytes = sizeof(DCI1_20MHz_TDD_t);
-              break;
-            }
-          } else {
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1_1_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1_1_5MHz_FDD_t);
-              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+      break;
 
-            case 25:
-              dci_length = sizeof_DCI1_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1_5MHz_FDD_t);
-              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+    case 'X':
+      xforms=1;
+      break;
 
-            case 50:
-              dci_length = sizeof_DCI1_10MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1_10MHz_FDD_t);
-              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+    case 'Y':
+      perfect_ce=1;
+      break;
 
-            case 100:
-              dci_length = sizeof_DCI1_20MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1_20MHz_FDD_t);
-              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 1;
-              ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-            }
-          }
+    case 'z':
+      n_rx=atoi(optarg);
 
-          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format1;
-          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+      if ((n_rx==0) || (n_rx>2)) {
+        msg("Unsupported number of rx antennas %d\n",n_rx);
+        exit(-1);
+      }
 
-          printf("Generating dlsch params for user %d\n",k);
-          generate_eNB_dlsch_params_from_dci(0,
-					     subframe,
-                                             &DLSCH_alloc_pdu_1[0],
-                                             n_rnti+k,
-                                             format1,
-                                             eNB->dlsch[0],
-                                             &eNB->frame_parms,
-                                             eNB->pdsch_config_dedicated,
-                                             SI_RNTI,
-                                             0,
-                                             P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+      break;
 
-          num_dci++;
-          num_ue_spec_dci++;
-        } else {
-          if (eNB->frame_parms.frame_type == TDD) {
+    case 'Z':
+      dump_table=1;
+      break;
 
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
 
-            case 25:
-              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 1;
-              break;
 
-            case 50:
-              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+    case 'h':
+    default:
+      printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6) -y TXant -z RXant -I trch_file\n",argv[0]);
+      printf("-h This message\n");
+      printf("-a Use AWGN channel and not multipath\n");
+      printf("-c Number of PDCCH symbols\n");
+      printf("-m MCS1 for TB 1\n");
+      printf("-M MCS2 for TB 2\n");
+      printf("-d Transmit the DCI and compute its error statistics and the overall throughput\n");
+      printf("-p Use extended prefix mode\n");
+      printf("-n Number of frames to simulate\n");
+      printf("-o Sample offset for receiver\n");
+      printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step);
+      printf("-f step size of SNR, default value is 1.\n");
+      printf("-r ressource block allocation (see  section 7.1.6.3 in 36.213\n");
+      printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n");
+      printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n");
+      printf("-x Transmission mode (1,2,6 for the moment)\n");
+      printf("-y Number of TX antennas used in eNB\n");
+      printf("-z Number of RX antennas used in UE\n");
+      printf("-t MCS of interfering UE\n");
+      printf("-R Number of HARQ rounds (fixed)\n");
+      printf("-A Turns on calibration mode for abstraction.\n");
+      printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n");
+      printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n");
+      printf("-I Input filename for TrCH data (binary)\n");
+      printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n");
+      exit(1);
+      break;
+    }
+  }
 
-            case 100:
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
-              break;
-            }
-          } else {
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+  if (common_flag == 0) {
+    switch (N_RB_DL) {
+    case 6:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x3f;
+      num_pdcch_symbols = 3;
+      break;
 
-            case 25:
-              dci_length = sizeof_DCI1A_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+    case 25:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff;
+      break;
 
-            case 50:
-              dci_length = sizeof_DCI1A_10MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+    case 50:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff;
+      break;
 
-            case 100:
-              dci_length = sizeof_DCI1A_20MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-            }
-          }
+    case 100:
+      if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff;
+      break;
+    }
 
-          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
-          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+    NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL);
+  } else
+    NB_RB = 4;
 
-          printf("Generating dlsch params for user %d\n",k);
-          generate_eNB_dlsch_params_from_dci(0,
-					     subframe,
-                                             &DLSCH_alloc_pdu_1[0],
-                                             SI_RNTI,
-                                             format1A,
-                                             eNB->dlsch[0],
-                                             &eNB->frame_parms,
-                                             eNB->pdsch_config_dedicated,
-                                             SI_RNTI,
-                                             0,
-                                             P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+  if ((transmission_mode > 1) && (n_tx != 2))
+    printf("n_tx must be >1 for transmission_mode %d\n",transmission_mode);
 
-          num_common_dci++;
-          num_dci++;
+  if (xforms==1) {
+    fl_initialize (&argc, argv, NULL, 0, 0);
+    form_ue = create_lte_phy_scope_ue();
+    sprintf (title, "LTE PHY SCOPE eNB");
+    fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
+    
+    if (!dual_stream_UE==0) {
+      UE->use_ia_receiver = 1;
+      fl_set_button(form_ue->button_0,1);
+      fl_set_object_label(form_ue->button_0, "IA Receiver ON");
+      fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
+    }
+  }
 
-        }
+  if (transmission_mode==5) {
+    n_users = 2;
+    printf("dual_stream_UE=%d\n", dual_stream_UE);
+  }
 
-        break;
+  lte_param_init(n_tx,
+		 n_rx,
+		 transmission_mode,
+		 extended_prefix_flag,
+		 frame_type,
+		 Nid_cell,
+		 tdd_config,
+		 N_RB_DL,
+		 threequarter_fs,
+		 osf,
+		 perfect_ce);
 
-      case 3:
-        if (common_flag == 0) {
+  eNB->mac_enabled=1;
+  // callback functions required for phy_procedures_tx 
+  mac_xface->get_dci_sdu = get_dci_sdu;
+  mac_xface->get_dlsch_sdu = get_dlsch_sdu;
+  mac_xface->eNB_dlsch_ulsch_scheduler = eNB_dlsch_ulsch_scheduler;
+   
+  //  eNB_id_i = UE->n_connected_eNB;
 
-          if (eNB->frame_parms.nb_antennas_tx == 2) {
+  printf("Setting mcs1 = %d\n",mcs1);
+  printf("Setting mcs2 = %d\n",mcs2);
+  printf("NPRB = %d\n",NB_RB);
+  printf("n_frames = %d\n",n_frames);
+  printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx,n_rx,extended_prefix_flag);
 
-            if (eNB->frame_parms.frame_type == TDD) {
+  snr1 = snr0+snr_int;
+  printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
 
-              switch (eNB->frame_parms.N_RB_DL) {
-              case 6:
-                dci_length = sizeof_DCI2A_1_5MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_TDD_t);
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
 
-              case 25:
-                dci_length = sizeof_DCI2A_5MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2A_5MHz_2A_TDD_t);
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
 
-              case 50:
-                dci_length = sizeof_DCI2A_10MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2A_10MHz_2A_TDD_t);
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  frame_parms = &eNB->frame_parms;
 
-              case 100:
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                dci_length = sizeof_DCI2A_20MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2A_20MHz_2A_TDD_t);
-                break;
-              }
-            }
+  s_re = malloc(2*sizeof(double*));
+  s_im = malloc(2*sizeof(double*));
+  r_re = malloc(2*sizeof(double*));
+  r_im = malloc(2*sizeof(double*));
+  //  r_re0 = malloc(2*sizeof(double*));
+  //  r_im0 = malloc(2*sizeof(double*));
 
-            else {
-              switch (eNB->frame_parms.N_RB_DL) {
-              case 6:
-                dci_length = sizeof_DCI2A_1_5MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2A_1_5MHz_2A_FDD_t);
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
 
-              case 25:
-                dci_length = sizeof_DCI2A_5MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2A_5MHz_2A_FDD_t);
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
-
-              case 50:
-                dci_length = sizeof_DCI2A_10MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2A_10MHz_2A_FDD_t);
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
-
-              case 100:
-                dci_length = sizeof_DCI2A_20MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2A_20MHz_2A_FDD_t);
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
-              }
-            }
-          } else if (eNB->frame_parms.nb_antennas_tx == 4) {
-
-          }
-
-          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format2A;
-          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
-
-          printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
-          generate_eNB_dlsch_params_from_dci(0,
-					     subframe,
-                                             &DLSCH_alloc_pdu_1[0],
-                                             n_rnti+k,
-                                             format2A,
-                                             eNB->dlsch[0],
-                                             &eNB->frame_parms,
-                                             eNB->pdsch_config_dedicated,
-                                             SI_RNTI,
-                                             0,
-                                             P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
-
-          num_dci++;
-          num_ue_spec_dci++;
-        } else {
-          if (eNB->frame_parms.frame_type == TDD) {
-
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-
-            case 25:
-              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 1;
-              break;
-
-            case 50:
-              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-
-            case 100:
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
-              break;
-            }
-          } else {
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-
-            case 25:
-              dci_length = sizeof_DCI1A_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-
-            case 50:
-              dci_length = sizeof_DCI1A_10MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-
-            case 100:
-              dci_length = sizeof_DCI1A_20MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-            }
-          }
-
-          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
-          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
-
-          printf("Generating dlsch params for user %d\n",k);
-          generate_eNB_dlsch_params_from_dci(0,
-					     subframe,
-                                             &DLSCH_alloc_pdu_1[0],
-                                             SI_RNTI,
-                                             format1A,
-                                             eNB->dlsch[0],
-                                             &eNB->frame_parms,
-                                             eNB->pdsch_config_dedicated,
-                                             SI_RNTI,
-                                             0,
-                                             P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
-
-          num_common_dci++;
-          num_dci++;
-
-        }
-
-        printf("Generated DCI format 2A (Transmission Mode 3)\n");
-        break;
-
-      case 4:
-        if (common_flag == 0) {
-
-          if (eNB->frame_parms.nb_antennas_tx == 2) {
-
-            if (eNB->frame_parms.frame_type == TDD) {
-
-              switch (eNB->frame_parms.N_RB_DL) {
-              case 6:
-                dci_length = sizeof_DCI2_1_5MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2_1_5MHz_2A_TDD_t);
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  printf("Channel Model= (%s,%d)\n",channel_model_input, channel_model);
+  printf("SCM-A=%d, SCM-B=%d, SCM-C=%d, SCM-D=%d, EPA=%d, EVA=%d, ETU=%d, Rayleigh8=%d, Rayleigh1=%d, Rayleigh1_corr=%d, Rayleigh1_anticorr=%d, Rice1=%d, Rice8=%d\n",
+         SCM_A, SCM_B, SCM_C, SCM_D, EPA, EVA, ETU, Rayleigh8, Rayleigh1, Rayleigh1_corr, Rayleigh1_anticorr, Rice1, Rice8);
 
-              case 25:
-                dci_length = sizeof_DCI2_5MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2_5MHz_2A_TDD_t);
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  if(transmission_mode==5)
+    sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,channel_model,n_rx,mcs1,mcs_i,dual_stream_UE,i_mod);
+  else
+    sprintf(bler_fname,"bler_tx%d_chan%d_nrx%d_mcs%d.csv",transmission_mode,channel_model,n_rx,mcs1);
 
-              case 50:
-                dci_length = sizeof_DCI2_10MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2_10MHz_2A_TDD_t);
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  bler_fd = fopen(bler_fname,"w");
+  if (bler_fd==NULL) {
+    fprintf(stderr,"Cannot create file %s!\n",bler_fname);
+    exit(-1);
+  }
+  fprintf(bler_fd,"SNR; MCS; TBS; rate; err0; trials0; err1; trials1; err2; trials2; err3; trials3; dci_err\n");
 
-              case 100:
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                dci_length = sizeof_DCI2_20MHz_2A_TDD_t;
-                dci_length_bytes = sizeof(DCI2_20MHz_2A_TDD_t);
-                break;
-              }
-            }
+  if (test_perf != 0) {
+    char hostname[1024];
+    hostname[1023] = '\0';
+    gethostname(hostname, 1023);
+    printf("Hostname: %s\n", hostname);
+    //char dirname[FILENAME_MAX];
+    //sprintf(dirname, "%s/SIMU/USER/pre-ci-logs-%s", getenv("OPENAIR_TARGETS"),hostname );
+    sprintf(time_meas_fname,"time_meas_prb%d_mcs%d_anttx%d_antrx%d_pdcch%d_channel%s_tx%d.csv",
+            N_RB_DL,mcs1,n_tx,n_rx,num_pdcch_symbols,channel_model_input,transmission_mode);
+    //mkdir(dirname,0777);
+    time_meas_fd = fopen(time_meas_fname,"w");
+    if (time_meas_fd==NULL) {
+      fprintf(stderr,"Cannot create file %s!\n",time_meas_fname);
+      exit(-1);
+    }
+  }
 
-            else {
-              switch (eNB->frame_parms.N_RB_DL) {
-              case 6:
-                dci_length = sizeof_DCI2_1_5MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2_1_5MHz_2A_FDD_t);
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  if(abstx) {
+    // CSV file
+    sprintf(csv_fname,"dataout_tx%d_u2%d_mcs%d_chan%d_nsimus%d_R%d.m",transmission_mode,dual_stream_UE,mcs1,channel_model,n_frames,num_rounds);
+    csv_fd = fopen(csv_fname,"w");
+    fprintf(csv_fd,"data_all%d=[",mcs1);
+    if (csv_fd==NULL) {
+      fprintf(stderr,"Cannot create file %s!\n",csv_fname);
+      exit(-1);
+    }
+  }
 
-              case 25:
-                dci_length = sizeof_DCI2_5MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2_5MHz_2A_FDD_t);
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  /*
+  //sprintf(tikz_fname, "second_bler_tx%d_u2=%d_mcs%d_chan%d_nsimus%d.tex",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
+  sprintf(tikz_fname, "second_bler_tx%d_u2%d_mcs%d_chan%d_nsimus%d",transmission_mode,dual_stream_UE,mcs,channel_model,n_frames);
+  tikz_fd = fopen(tikz_fname,"w");
+  //fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
+  switch (mcs)
+    {
+    case 0:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=star] plot coordinates {");
+      break;
+    case 1:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=star] plot coordinates {");
+      break;
+    case 2:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=star] plot coordinates {");
+      break;
+    case 3:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=star] plot coordinates {");
+      break;
+    case 4:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=star] plot coordinates {");
+      break;
+    case 5:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=o] plot coordinates {");
+      break;
+    case 6:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=o] plot coordinates {");
+      break;
+    case 7:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=o] plot coordinates {");
+      break;
+    case 8:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=o] plot coordinates {");
+      break;
+    case 9:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=o] plot coordinates {");
+      break;
+    case 10:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=square] plot coordinates {");
+      break;
+    case 11:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=square] plot coordinates {");
+      break;
+    case 12:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=square] plot coordinates {");
+      break;
+    case 13:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=square] plot coordinates {");
+      break;
+    case 14:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=square] plot coordinates {");
+      break;
+    case 15:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=diamond] plot coordinates {");
+      break;
+    case 16:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=diamond] plot coordinates {");
+      break;
+    case 17:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=diamond] plot coordinates {");
+      break;
+    case 18:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=diamond] plot coordinates {");
+      break;
+    case 19:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=diamond] plot coordinates {");
+      break;
+    case 20:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+      break;
+    case 21:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=x] plot coordinates {");
+      break;
+    case 22:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=x] plot coordinates {");
+      break;
+    case 23:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=x] plot coordinates {");
+      break;
+    case 24:
+      fprintf(tikz_fd,"\\addplot[color=black, mark=x] plot coordinates {");
+      break;
+    case 25:
+      fprintf(tikz_fd,"\\addplot[color=blue, mark=x] plot coordinates {");
+      break;
+    case 26:
+      fprintf(tikz_fd,"\\addplot[color=red, mark=+] plot coordinates {");
+      break;
+    case 27:
+      fprintf(tikz_fd,"\\addplot[color=green, mark=+] plot coordinates {");
+      break;
+    case 28:
+      fprintf(tikz_fd,"\\addplot[color=yellow, mark=+] plot coordinates {");
+      break;
+    }
+  */
 
-              case 50:
-                dci_length = sizeof_DCI2_10MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2_10MHz_2A_FDD_t);
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
+  for (i=0; i<2; i++) {
+    s_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    s_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    r_re[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+    r_im[i] = malloc(FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
+  }
 
-              case 100:
-                dci_length = sizeof_DCI2_20MHz_2A_FDD_t;
-                dci_length_bytes = sizeof(DCI2_20MHz_2A_FDD_t);
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rah              = 0;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = DLSCH_RB_ALLOC;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = 0;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs1             = mcs1;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi1             = 1;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv1              = 0;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs2             = mcs2;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi2             = 1;
-                ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv2              = 0;
-                break;
-              }
-            }
-          } else if (eNB->frame_parms.nb_antennas_tx == 4) {
 
-          }
+  UE->pdcch_vars[0]->crnti = n_rnti;
 
-          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = n_rnti+k;
-          dci_alloc[num_dci].format     = format2;
-          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+  // Fill in UL_alloc
+  UL_alloc_pdu.type    = 0;
+  UL_alloc_pdu.hopping = 0;
+  UL_alloc_pdu.rballoc = UL_RB_ALLOC;
+  UL_alloc_pdu.mcs     = 1;
+  UL_alloc_pdu.ndi     = 1;
+  UL_alloc_pdu.TPC     = 0;
+  UL_alloc_pdu.cqi_req = 1;
 
-          printf("Generating dlsch params for user %d\n",k);
-          generate_eNB_dlsch_params_from_dci(0,
-					     subframe,
-                                             &DLSCH_alloc_pdu_1[0],
-                                             n_rnti+k,
-                                             format2,
-                                             eNB->dlsch[0],
-                                             &eNB->frame_parms,
-                                             eNB->pdsch_config_dedicated,
-                                             SI_RNTI,
-                                             0,
-                                             P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+  CCCH_alloc_pdu.type               = 0;
+  CCCH_alloc_pdu.vrb_type           = 0;
+  CCCH_alloc_pdu.rballoc            = CCCH_RB_ALLOC;
+  CCCH_alloc_pdu.ndi      = 1;
+  CCCH_alloc_pdu.mcs      = 1;
+  CCCH_alloc_pdu.harq_pid = 0;
 
-          num_dci++;
-          num_ue_spec_dci++;
-        } else {
-          if (eNB->frame_parms.frame_type == TDD) {
+  DLSCH_alloc_pdu2_1E[0].rah              = 0;
+  DLSCH_alloc_pdu2_1E[0].rballoc          = DLSCH_RB_ALLOC;
+  DLSCH_alloc_pdu2_1E[0].TPC              = 0;
+  DLSCH_alloc_pdu2_1E[0].dai              = 0;
+  DLSCH_alloc_pdu2_1E[0].harq_pid         = 0;
+  //DLSCH_alloc_pdu2_1E[0].tb_swap          = 0;
+  DLSCH_alloc_pdu2_1E[0].mcs             = mcs1;
+  DLSCH_alloc_pdu2_1E[0].ndi             = 1;
+  DLSCH_alloc_pdu2_1E[0].rv              = 0;
+  // Forget second codeword
+  DLSCH_alloc_pdu2_1E[0].tpmi             = (transmission_mode>=5 ? 5 : 0);  // precoding
+  DLSCH_alloc_pdu2_1E[0].dl_power_off     = (transmission_mode==5 ? 0 : 1);
 
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_1_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+  DLSCH_alloc_pdu2_1E[1].rah              = 0;
+  DLSCH_alloc_pdu2_1E[1].rballoc          = DLSCH_RB_ALLOC;
+  DLSCH_alloc_pdu2_1E[1].TPC              = 0;
+  DLSCH_alloc_pdu2_1E[1].dai              = 0;
+  DLSCH_alloc_pdu2_1E[1].harq_pid         = 0;
+  //DLSCH_alloc_pdu2_1E[1].tb_swap          = 0;
+  DLSCH_alloc_pdu2_1E[1].mcs             = mcs_i;
+  DLSCH_alloc_pdu2_1E[1].ndi             = 1;
+  DLSCH_alloc_pdu2_1E[1].rv              = 0;
+  // Forget second codeword
+  DLSCH_alloc_pdu2_1E[1].tpmi             = (transmission_mode>=5 ? 5 : 0) ;  // precoding
+  DLSCH_alloc_pdu2_1E[1].dl_power_off     = (transmission_mode==5 ? 0 : 1);
 
-            case 25:
-              dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_5MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 1;
-              break;
+  eNB2UE[0] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+                                   UE->frame_parms.nb_antennas_rx,
+                                   channel_model,
+                                   N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+				   N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+                                   forgetting_factor,
+                                   rx_sample_offset,
+                                   0);
 
-            case 50:
-              dci_length = sizeof_DCI1A_10MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_10MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+  if(num_rounds>1) {
+    for(n=1; n<4; n++)
+      eNB2UE[n] = new_channel_desc_scm(eNB->frame_parms.nb_antennas_tx,
+                                       UE->frame_parms.nb_antennas_rx,
+                                       channel_model,
+				       N_RB2sampling_rate(eNB->frame_parms.N_RB_DL),
+				       N_RB2channel_bandwidth(eNB->frame_parms.N_RB_DL),
+				       forgetting_factor,
+                                       rx_sample_offset,
+                                       0);
+  }
 
-            case 100:
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->dai              = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_20MHz_TDD_1_6_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              dci_length = sizeof_DCI1A_20MHz_TDD_1_6_t;
-              dci_length_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
-              break;
-            }
-          } else {
-            switch (eNB->frame_parms.N_RB_DL) {
-            case 6:
-              dci_length = sizeof_DCI1A_1_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+  if (eNB2UE[0]==NULL) {
+    msg("Problem generating channel model. Exiting.\n");
+    exit(-1);
+  }
 
-            case 25:
-              dci_length = sizeof_DCI1A_5MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_5MHz_FDD_t);
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+  if ((transmission_mode == 3) || (transmission_mode==4))
+    Kmimo=2;
+  else
+    Kmimo=1;
 
-            case 50:
-              dci_length = sizeof_DCI1A_10MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_10MHz_FDD_t);
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
+  switch (ue_category) {
+  case 1:
+    Nsoft = 250368;
+    break;
+  case 2:
+  case 3:
+    Nsoft = 1237248;
+    break;
+  case 4:
+    Nsoft = 1827072;
+    break;
+  default:
+    printf("Unsupported UE category %d\n",ue_category);
+    exit(-1);
+    break;
+  }
 
-            case 100:
-              dci_length = sizeof_DCI1A_20MHz_FDD_t;
-              dci_length_bytes = sizeof(DCI1A_20MHz_FDD_t);
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->type             = 1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->vrb_type         = 1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rballoc          = computeRIV(eNB->frame_parms.N_RB_DL,0,9);
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->TPC              = TPC;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->harq_pid         = 0;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->mcs             = mcs1;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->ndi             = 0;
-              ((DCI1A_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[k])->rv              = 0;
-              break;
-            }
-          }
+  for (k=0; k<n_users; k++) {
+    // Create transport channel structures for 2 transport blocks (MIMO)
+    for (i=0; i<2; i++) {
+      eNB->dlsch[k][i] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0);
 
-          memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu_1[k],dci_length_bytes);
-          dci_alloc[num_dci].dci_length = dci_length;
-          dci_alloc[num_dci].L          = 1;
-          dci_alloc[num_dci].rnti       = SI_RNTI;
-          dci_alloc[num_dci].format     = format1A;
-          dci_alloc[num_dci].firstCCE       = 0;
-          dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
+      if (!eNB->dlsch[k][i]) {
+        printf("Can't get eNB dlsch structures\n");
+        exit(-1);
+      }
 
-          printf("Generating dlsch params for user %d\n",k);
-          generate_eNB_dlsch_params_from_dci(0,
-					     subframe,
-                                             &DLSCH_alloc_pdu_1[0],
-                                             SI_RNTI,
-                                             format1A,
-                                             eNB->dlsch[0],
-                                             &eNB->frame_parms,
-                                             eNB->pdsch_config_dedicated,
-                                             SI_RNTI,
-                                             0,
-                                             P_RNTI,
-                                             eNB->UE_stats[0].DL_pmi_single);
+      eNB->dlsch[k][i]->rnti = n_rnti+k;
+    }
+  }
 
-          num_common_dci++;
-          num_dci++;
+  for (i=0; i<2; i++) {
+    UE->dlsch[0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
 
-        }
+    if (!UE->dlsch[0][i]) {
+      printf("Can't get ue dlsch structures\n");
+      exit(-1);
+    }
 
-        break;
+    UE->dlsch[0][i]->rnti   = n_rnti;
+  }
 
-      case 5:
-      case 6:
-        memcpy(&dci_alloc[num_dci].dci_pdu[0],&DLSCH_alloc_pdu2_1E[k],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-        dci_alloc[num_dci].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-        dci_alloc[num_dci].L          = 1;
-        dci_alloc[num_dci].rnti       = n_rnti+k;
-        dci_alloc[num_dci].format     = format1E_2A_M10PRB;
-        dci_alloc[num_dci].firstCCE       = 4*k;
-        printf("Generating dlsch params for user %d\n",k);
-        generate_eNB_dlsch_params_from_dci(0,
-					   subframe,
-                                           &DLSCH_alloc_pdu2_1E[k],
-                                           n_rnti+k,
-                                           format1E_2A_M10PRB,
-                                           eNB->dlsch[k],
-                                           &eNB->frame_parms,
-                                           eNB->pdsch_config_dedicated,
-                                           SI_RNTI,
-                                           0,
-                                           P_RNTI,
-                                           eNB->UE_stats[k].DL_pmi_single);
+  // structure for SIC at UE
+  UE->dlsch_eNB[0] = new_eNB_dlsch(Kmimo,8,Nsoft,N_RB_DL,0);
 
-        dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
-        num_ue_spec_dci++;
-        num_dci++;
+  if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
 
-        break;
+    eNB->UE_stats[0].DL_pmi_single = (unsigned short)(taus()&0xffff);
 
-      default:
-        printf("Unsupported Transmission Mode!!!");
-        exit(-1);
-        break;
-      }
+    if (n_users>1)
+      eNB->UE_stats[1].DL_pmi_single = (eNB->UE_stats[0].DL_pmi_single ^ 0x1555); //opposite PMI
+  } else {
+    eNB->UE_stats[0].DL_pmi_single = 0;
 
+    if (n_users>1)
+      eNB->UE_stats[1].DL_pmi_single = 0;
+  }
 
 
+  if (input_fd==NULL) {
 
-      /*
-      memcpy(&dci_alloc[1].dci_pdu[0],&UL_alloc_pdu,sizeof(DCI0_5MHz_TDD0_t));
-      dci_alloc[1].dci_length = sizeof_DCI0_5MHz_TDD_0_t;
-      dci_alloc[1].L          = 2;
-      dci_alloc[1].rnti       = n_rnti;
-      */
-    }
 
-    if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d => ",num_pdcch_symbols,numCCE);
+    // UE specific DCI
+    fill_DCI(eNB,
+	     &dci_alloc[0],
+	     subframe,
+	     n_rnti,
+	     n_users,
+	     transmission_mode,
+	     common_flag,
+	     DLSCH_RB_ALLOC,
+	     TPC,
+	     mcs1,
+	     mcs2,
+	     0,
+	     0,
+	     &num_common_dci,
+	     &num_ue_spec_dci,
+	     &num_dci);
 
     numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
 
-    if (n_frames==1) printf("%d\n",numCCE);
+    if (n_frames==1) printf("num_pdcch_symbols %d, numCCE %d, num_dci %d/%d/%d\n",num_pdcch_symbols,numCCE, num_dci,num_ue_spec_dci,num_common_dci);
 
-    // apply RNTI-based nCCE allocation
-    memset(CCE_table,0,800*sizeof(int));
 
-    for (i=num_common_dci; i<num_dci; i++) {
 
-      dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table,
-						 1<<dci_alloc[i].L,
-						 numCCE,
-						 (dci_alloc[i].rnti==SI_RNTI)? 1 : 0,
-						 dci_alloc[i].rnti,
-						 subframe);
-
-      if (n_frames==1)
-        printf("dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format,
-               dci_alloc[i].firstCCE,numCCE);
-    }
 
     for (k=0; k<n_users; k++) {
 
@@ -2015,7 +2183,7 @@ int main(int argc, char **argv)
     }
 
     for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
-      UE->frame_rx=0;
+      UE->proc.proc_rxtx[subframe&1].frame_rx=0;
       errs[0]=0;
       errs[1]=0;
       errs[2]=0;
@@ -2080,18 +2248,20 @@ int main(int argc, char **argv)
       struct list time_vector_rx_dec;
       initialize(&time_vector_rx_dec);
 
+      eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[subframe&1];
+
       for (trials = 0; trials<n_frames; trials++) {
-        //  printf("Trial %d\n",trials);
+	//printf("Trial %d\n",trials);
         fflush(stdout);
         round=0;
 
         //if (trials%100==0)
         eNB2UE[0]->first_run = 1;
 
-        ret = UE->dlsch[0][0]->max_turbo_iterations+1;
+        UE->dlsch_errors[0] = 1;
 
-        while ((round < num_rounds) && (ret > UE->dlsch[0][0]->max_turbo_iterations)) {
-          //    printf("Trial %d, round %d\n",trials,round);
+        while ((round < num_rounds) && (UE->dlsch_errors[0] > 0)) {
+	  //	  printf("Trial %d, round %d\n",trials,round);
           round_trials[round]++;
 
           if(transmission_mode>=5)
@@ -2107,7 +2277,7 @@ int main(int argc, char **argv)
           } else
             hold_channel = 0;//(round==0) ? 0 : 1;
 
-PMI_FEEDBACK:
+	  //PMI_FEEDBACK:
 
           //  printf("Trial %d : Round %d, pmi_feedback %d \n",trials,round,pmi_feedback);
           for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
@@ -2119,389 +2289,47 @@ PMI_FEEDBACK:
             start_meas(&eNB->phy_proc_tx);
 
             // Simulate HARQ procedures!!!
+	    memset(CCE_table,0,800*sizeof(int));
             if (common_flag == 0) {
 
+	      num_dci=0;
+	      num_common_dci=0;
+	      num_ue_spec_dci=0;
+
               if (round == 0) {   // First round
                 TB0_active = 1;
 
                 eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
-
-                if (eNB->frame_parms.frame_type == TDD) {
-
-                  switch (transmission_mode) {
-                  case 1:
-                  case 2:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t));
-                      break;
-
-                    case 25:
-                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t));
-                      break;
-
-                    case 50:
-                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t));
-                      break;
-
-                    case 100:
-                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 3:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t));
-                      break;
-
-                    case 25:
-                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t));
-                      break;
-
-                    case 50:
-                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t));
-                      break;
-
-                    case 100:
-                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 5:
-                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
-                    DLSCH_alloc_pdu2_1E[0].rv              = 0;
-                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-                    break;
-                  }
-                } else { // FDD
-                  switch (transmission_mode) {
-                  case 1:
-                  case 2:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t));
-                      break;
-
-                    case 25:
-                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t));
-                      break;
-
-                    case 50:
-                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t));
-                      break;
-
-                    case 100:
-                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 3:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t));
-                      break;
-
-                    case 25:
-                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t));
-                      break;
-
-                    case 50:
-                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t));
-                      break;
-
-                    case 100:
-                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 5:
-                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
-                    DLSCH_alloc_pdu2_1E[0].rv              = 0;
-                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-                    break;
-                  }
-
-                }
-              } else {
-                eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
-
-                if (eNB->frame_parms.frame_type == TDD) {
-
-
-                  switch (transmission_mode) {
-                  case 1:
-                  case 2:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_TDD_t));
-                      break;
-
-                    case 25:
-                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_5MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_TDD_t));
-                      break;
-
-                    case 50:
-                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_10MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_TDD_t));
-                      break;
-
-                    case 100:
-                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_20MHz_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_TDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 3:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      if (TB0_active==1) {
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_TDD_t));
-                      break;
-
-                    case 25:
-                      if (TB0_active==1) {
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_TDD_t));
-                      break;
-
-                    case 50:
-                      if (TB0_active==1) {
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_TDD_t));
-                      break;
-
-                    case 100:
-                      if (TB0_active==1) {
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_TDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 5:
-                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
-                    DLSCH_alloc_pdu2_1E[0].rv              = round&3;
-                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-                    break;
-                  }
-                } else {
-                  switch (transmission_mode) {
-                  case 1:
-                  case 2:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_1_5MHz_FDD_t));
-                      break;
-
-                    case 25:
-                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_5MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_5MHz_FDD_t));
-                      break;
-
-                    case 50:
-                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_10MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_10MHz_FDD_t));
-                      break;
-
-                    case 100:
-                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi             = trials&1;
-                      ((DCI1_20MHz_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv              = round&3;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI1_20MHz_FDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 3:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      if (TB0_active==1) {
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_1_5MHz_2A_FDD_t));
-                      break;
-
-                    case 25:
-                      if (TB0_active==1) {
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_5MHz_2A_FDD_t));
-                      break;
-
-                    case 50:
-                      if (TB0_active==1) {
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_10MHz_2A_FDD_t));
-                      break;
-
-                    case 100:
-                      if (TB0_active==1) {
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      } else { // deactivate TB0
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2A_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2A_20MHz_2A_FDD_t));
-                      break;
-                    }
-
-                    break;
-
-                  case 5:
-                    DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
-                    DLSCH_alloc_pdu2_1E[0].rv              = round&3;
-                    memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-                    break;
-                  }
-                }
-              }
-            }
+	       
+		fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC,mcs1,mcs2,trials&1,round&3,&num_common_dci,&num_ue_spec_dci,&num_dci);
+	      }
+	      else {
+		fill_DCI(eNB,&dci_alloc[0],subframe,n_rnti,n_users,transmission_mode,common_flag,DLSCH_RB_ALLOC,TPC,
+			 (TB0_active==1)?mcs1:0,mcs2,trials&1,(TB0_active==1)?round&3:0,&num_common_dci,&num_ue_spec_dci,&num_dci);
+	      }
+	      for (i=num_common_dci; i<num_dci; i++) {
+		
+		dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table,
+							   1<<dci_alloc[i].L,
+							   numCCE,
+							   (dci_alloc[i].rnti==SI_RNTI)? 1 : 0,
+							   dci_alloc[i].rnti,
+							   subframe);
+		
+		if (dci_alloc[i].firstCCE < 0) {
+		  printf("firstCCE <0 !! dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format,
+			 dci_alloc[i].firstCCE,numCCE);
+		  exit(-1);
+		}
+		if (n_frames==1)
+		  printf("dci %d: rnti %x, format %d : nCCE %d/%d\n",i,dci_alloc[i].rnti, dci_alloc[i].format,
+			 dci_alloc[i].firstCCE,numCCE);
+	      }
+
+	    } // common_flag == 0
 	    
+
+	    /*	    
             num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci,
                                                    num_common_dci,
                                                    dci_alloc,
@@ -2511,8 +2339,10 @@ PMI_FEEDBACK:
                                                    eNB->common_vars.txdataF[eNB_id],
                                                    subframe);
 	    
+	    if (n_frames==1) printf("Generated DCI, num_pdcch_symbols %d\n",num_pdcch_symbols_2);
+
             if (num_pdcch_symbols_2 > num_pdcch_symbols) {
-              msg("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols);
+              printf("Error: given num_pdcch_symbols not big enough (%d > %d)\n",num_pdcch_symbols_2,num_pdcch_symbols);
               exit(-1);
             }
 
@@ -2526,11 +2356,7 @@ PMI_FEEDBACK:
                                                 num_pdcch_symbols,
                                                 0,subframe);
 
-#ifdef TBS_FIX   // This is for MESH operation!!!
-                tbs = (double)3*TBStable[get_I_TBS(eNB->dlsch[k][cw]->harq_processes[0]->mcs)][eNB->dlsch[k][cw]->nb_rb-1]/4;
-#else
                 tbs = eNB->dlsch[k][cw]->harq_processes[0]->TBS;
-#endif
                 rate = (double)tbs/(double)coded_bits_per_codeword;
 
                 if ((SNR==snr0) && (trials==0) && (round==0))
@@ -2550,16 +2376,10 @@ PMI_FEEDBACK:
                   if (n_users>1)
                     eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555);
 
-                  /*
-                    if ((trials<10) && (round==0)) {
-                    printf("tx PMI UE0 %x (pmi_feedback %d)\n",pmi2hex_2Ar1(eNB->dlsch[0][0]->pmi_alloc),pmi_feedback);
-                    if (transmission_mode ==5)
-                    printf("tx PMI UE1 %x\n",pmi2hex_2Ar1(eNB->dlsch[1][0]->pmi_alloc));
-                    }
-                  */
+                  
                 }
 
-
+		
                 start_meas(&eNB->dlsch_encoding_stats);
 
                 if (dlsch_encoding(((cw==0) ? input_buffer0[k] : input_buffer1[k]),
@@ -2573,20 +2393,6 @@ PMI_FEEDBACK:
                                   )<0)
                   exit(-1);
 
-                /*
-                if (transmission_mode == 3) {
-                if (dlsch_encoding(input_buffer1[k],
-                   &eNB->frame_parms,
-                   num_pdcch_symbols,
-                   eNB->dlsch[k][1],
-                   0,subframe,
-                   &eNB->dlsch_rate_matching_stats,
-                   &eNB->dlsch_turbo_encoding_stats,
-                   &eNB->dlsch_interleaving_stats
-                   )<0)
-                exit(-1);
-                }
-                */
                 stop_meas(&eNB->dlsch_encoding_stats);
 
                 eNB->dlsch[k][cw]->rnti = (common_flag==0) ? n_rnti+k : SI_RNTI;
@@ -2623,14 +2429,11 @@ PMI_FEEDBACK:
                                               num_pdcch_symbols,
                                               eNB->dlsch[k][0],
                                               (transmission_mode==3)||(transmission_mode==4) ? eNB->dlsch[k][1] : NULL);	      
-              /* avoid gcc warnings */
+              
               (void)re_allocated;
 
               stop_meas(&eNB->dlsch_modulation_stats);
-              /*
-              if (trials==0 && round==0)
-              printf("RE count %d\n",re_allocated);
-              */
+              
             } //n_users
 
 
@@ -2684,7 +2487,7 @@ PMI_FEEDBACK:
                            eNB->frame_parms.samples_per_tti,1,1);
             }
           }
-
+		*/
           /*
             else {  // Read signal from file
             i=0;
@@ -2709,164 +2512,165 @@ PMI_FEEDBACK:
             tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
             }
           */
+		
 
-          //    printf("Copying tx ..., nsymb %d (n_tx %d), awgn %d\n",nsymb,eNB->frame_parms.nb_antennas_tx,awgn_flag);
-          for (i=0; i<2*frame_parms->samples_per_tti; i++) {
-            for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
-              if (awgn_flag == 0) {
-                s_re[aa][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) + (i<<1)]);
-                s_im[aa][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
-              } else {
-                for (aarx=0; aarx<UE->frame_parms.nb_antennas_rx; aarx++) {
-                  if (aa==0) {
-                    r_re[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
-                    r_im[aarx][i] = ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
-                  } else {
-                    r_re[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)]);
-                    r_im[aarx][i] += ((double)(((short *)eNB->common_vars.txdata[eNB_id][aa]))[(2*subframe*UE->frame_parms.samples_per_tti) +(i<<1)+1]);
-                  }
-
-                }
-              }
-            }
-          }
-
-          // Multipath channel
-          if (awgn_flag == 0) {
-            multipath_channel(eNB2UE[round],s_re,s_im,r_re,r_im,
-                              2*frame_parms->samples_per_tti,hold_channel);
-
-            //      printf("amc: ****************** eNB2UE[%d]->n_rx = %d,dd %d\n",round,eNB2UE[round]->nb_rx,eNB2UE[round]->channel_offset);
-            if(abstx==1 && num_rounds>1)
-              if(round==0 && hold_channel==0) {
-                random_channel(eNB2UE[1],0);
-                random_channel(eNB2UE[2],0);
-                random_channel(eNB2UE[3],0);
-              }
+	    proc_eNB->subframe_tx = subframe;
 	    
-	    if (UE->perfect_ce==1) {
-                  // fill in perfect channel estimates
-                  freq_channel(eNB2UE[round],UE->frame_parms.N_RB_DL,12*UE->frame_parms.N_RB_DL + 1);
-		  /*
-		  write_output("channel.m","ch",eNB2UE[round]->ch[0],eNB2UE[round]->channel_length,1,8);
-                  write_output("channelF.m","chF",eNB2UE[round]->chF[0],12*UE->frame_parms.N_RB_DL + 1,1,8);
-		  */
-	    }
-	  }
-
-          if(abstx) {
-            if (trials==0 && round==0) {
-              // calculate freq domain representation to compute SINR
-              freq_channel(eNB2UE[0], NB_RB,2*NB_RB + 1);
-              // snr=pow(10.0,.1*SNR);
-              fprintf(csv_fd,"%f,",SNR);
-
-              for (u=0; u<2*NB_RB; u++) {
-                for (aarx=0; aarx<eNB2UE[0]->nb_rx; aarx++) {
-                  for (aatx=0; aatx<eNB2UE[0]->nb_tx; aatx++) {
-                    channelx = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].x;
-                    channely = eNB2UE[0]->chF[aarx+(aatx*eNB2UE[0]->nb_rx)][u].y;
-                    fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
-                  }
-                }
-              }
-
-              if(num_rounds>1) {
-                freq_channel(eNB2UE[1], NB_RB,2*NB_RB + 1);
-
-                for (u=0; u<2*NB_RB; u++) {
-                  for (aarx=0; aarx<eNB2UE[1]->nb_rx; aarx++) {
-                    for (aatx=0; aatx<eNB2UE[1]->nb_tx; aatx++) {
-                      channelx = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].x;
-                      channely = eNB2UE[1]->chF[aarx+(aatx*eNB2UE[1]->nb_rx)][u].y;
-                      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
-                    }
-                  }
-                }
-
-                freq_channel(eNB2UE[2], NB_RB,2*NB_RB + 1);
+	    phy_procedures_eNB_TX(eNB,proc_eNB,0,no_relay,NULL);
+	    
+	    
+	    start_meas(&eNB->ofdm_mod_stats);
+	    
+	    do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
+			  eNB->common_vars.txdata[eNB_id],
+			  (subframe*2),
+			  &eNB->frame_parms);
+	    
+	    do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
+			  eNB->common_vars.txdata[eNB_id],
+			  (subframe*2)+1,
+			  &eNB->frame_parms);
+	    
+	    stop_meas(&eNB->ofdm_mod_stats);
+	    stop_meas(&eNB->phy_proc_tx);
+	    
+	    // generate next subframe for channel estimation
+	    
+	    proc_eNB->subframe_tx = subframe+1;
+	    
+	    phy_procedures_eNB_TX(eNB,proc_eNB,0,no_relay,NULL);
+	    
+	    do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
+			  eNB->common_vars.txdata[eNB_id],
+			  (subframe*2)+2,
+			  &eNB->frame_parms);
 
-                for (u=0; u<2*NB_RB; u++) {
-                  for (aarx=0; aarx<eNB2UE[2]->nb_rx; aarx++) {
-                    for (aatx=0; aatx<eNB2UE[2]->nb_tx; aatx++) {
-                      channelx = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].x;
-                      channely = eNB2UE[2]->chF[aarx+(aatx*eNB2UE[2]->nb_rx)][u].y;
-                      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
-                    }
-                  }
-                }
+	    
+	    proc_eNB->frame_tx++;
 
-                freq_channel(eNB2UE[3], NB_RB,2*NB_RB + 1);
+            tx_lev = 0;
 
-                for (u=0; u<2*NB_RB; u++) {
-                  for (aarx=0; aarx<eNB2UE[3]->nb_rx; aarx++) {
-                    for (aatx=0; aatx<eNB2UE[3]->nb_tx; aatx++) {
-                      channelx = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].x;
-                      channely = eNB2UE[3]->chF[aarx+(aatx*eNB2UE[3]->nb_rx)][u].y;
-                      fprintf(csv_fd,"%e+i*(%e),",channelx,channely);
-                    }
-                  }
-                }
-              }
+            for (aa=0; aa<eNB->frame_parms.nb_antennas_tx; aa++) {
+              tx_lev += signal_energy(&eNB->common_vars.txdata[eNB_id][aa]
+                                      [subframe*eNB->frame_parms.samples_per_tti],
+                                      eNB->frame_parms.samples_per_tti);
             }
-          }
 
-          //AWGN
-          // This is the SNR on the PDSCH for OFDM symbols without pilots -> rho_A
-          sigma2_dB = 10*log10((double)tx_lev) +10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)) - SNR - get_pa_dB(eNB->pdsch_config_dedicated);
-          sigma2 = pow(10,sigma2_dB/10);
-
-          if (n_frames==1)
-            printf("Sigma2 %f (sigma2_dB %f,%f,%f )\n",sigma2,sigma2_dB,10*log10((double)eNB->frame_parms.ofdm_symbol_size/(double)(NB_RB*12)),get_pa_dB(eNB->pdsch_config_dedicated));
-
-          for (i=0; i<2*frame_parms->samples_per_tti; i++) {
-            for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
-              //printf("s_re[0][%d]=> %f , r_re[0][%d]=> %f\n",i,s_re[aa][i],i,r_re[aa][i]);
-              ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i] =
-                (short) (r_re[aa][i] + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
-              ((short*) UE->common_vars.rxdata[aa])[(2*subframe*UE->frame_parms.samples_per_tti)+2*i+1] =
-                (short) (r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0));
-            }
-          }
+            tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
 
-          //    lte_sync_time_init(eNB->frame_parms,common_vars);
-          //    lte_sync_time(common_vars->rxdata, eNB->frame_parms);
-          //    lte_sync_time_free();
+	      
+            if (n_frames==1) {
+              printf("tx_lev = %d (%d dB)\n",tx_lev,tx_lev_dB);
+              write_output("txsig0.m","txs0", &eNB->common_vars.txdata[eNB_id][0][subframe* eNB->frame_parms.samples_per_tti],
 
-          /*
-            // optional: read rx_frame from file
-            if ((rx_frame_file = fopen("rx_frame.dat","r")) == NULL)
-            {
-            printf("Cannot open rx_frame.m data file\n");
-            exit(0);
+                           eNB->frame_parms.samples_per_tti,1,1);
             }
+	  }
 
-            result = fread((void *)PHY_vars->rx_vars[0].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file);
-            printf("Read %d bytes\n",result);
-            result = fread((void *)PHY_vars->rx_vars[1].RX_DMA_BUFFER,4,FRAME_LENGTH_COMPLEX_SAMPLES,rx_frame_file);
-            printf("Read %d bytes\n",result);
+	  DL_channel(eNB,UE,subframe,awgn_flag,SNR,tx_lev,hold_channel,abstx,num_rounds,trials,round,eNB2UE,s_re,s_im,r_re,r_im,csv_fd);
+	  
+
+	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[subframe&1];
+	  proc->subframe_rx = subframe;
+	  UE->UE_mode[0] = PUSCH;
+	  UE->dlsch_errors[0] = 0;
+	  // first symbol has to be done separately in one-shot mode
+	  slot_fep(UE,
+		   0,
+		   (proc->subframe_rx<<1),
+		   UE->rx_offset,
+		   0,
+		   0);
+	  
+	  if (n_frames==1) printf("Running phy_procedures_UE_RX\n");
+	  phy_procedures_UE_RX(UE,proc,0,0,normal_txrx,no_relay,NULL);
+
+	  if (UE->dlsch[0][0]->active == 0) {
+	    printf("DCI not received\n");
+	    /*
+	    write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+	    write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],12*UE->frame_parms.N_RB_DL*3,1,1);
+	    
+	    write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*12*UE->frame_parms.N_RB_DL,1,1);
+	    write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,12*UE->frame_parms.N_RB_DL*4*2,1,4);
+	    write_output("txsigF0.m","txsF0", &eNB->common_vars.txdataF[eNB_id][0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],
+			 nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
 
-            fclose(rx_frame_file);
-          */
+	    write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+	    write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
-          if (n_frames==1) {
-            printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
-            printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
-            printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
-            printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
-          }
+	    exit(-1);
+	    */
+	  }
 
-          if (eNB->frame_parms.Ncp == 0) {  // normal prefix
+	  if ((test_perf ==0 ) && (n_frames==1)) {
+	    write_output("ch0.m","ch0",eNB2UE[0]->ch[0],eNB2UE[0]->channel_length,1,8);
+	    
+	    if (eNB->frame_parms.nb_antennas_tx>1)
+	      write_output("ch1.m","ch1",eNB2UE[0]->ch[eNB->frame_parms.nb_antennas_rx],eNB2UE[0]->channel_length,1,8);
+	    
+	    //common vars
+	    write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
+	    write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	    
+	    if (UE->frame_parms.nb_antennas_rx>1) {
+	      write_output("rxsig1.m","rxs1", UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
+	      write_output("rxsigF1.m","rxsF1", UE->common_vars.rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	    }
+	    
+	    write_output("dlsch00_r0.m","dl00_r0",
+			 &(UE->common_vars.dl_ch_estimates[eNB_id][0][0]),
+			 UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	    
+	    if (UE->frame_parms.nb_antennas_rx>1)
+	      write_output("dlsch01_r0.m","dl01_r0",
+			   &(UE->common_vars.dl_ch_estimates[eNB_id][1][0]),
+			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	    
+	    if (eNB->frame_parms.nb_antennas_tx>1)
+	      write_output("dlsch10_r0.m","dl10_r0",
+			   &(UE->common_vars.dl_ch_estimates[eNB_id][2][0]),
+			   UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	    
+	    if ((UE->frame_parms.nb_antennas_rx>1) && (eNB->frame_parms.nb_antennas_tx>1))
+	      write_output("dlsch11_r0.m","dl11_r0",
+			   &(UE->common_vars.dl_ch_estimates[eNB_id][3][0]),
+			   UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
+	    
+	    //pdsch_vars
+	    dump_dlsch2(UE,eNB_id,coded_bits_per_codeword,round);
+	    //dump_dlsch2(UE,eNB_id_i,coded_bits_per_codeword);
+	    write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+	    
+	    //pdcch_vars
+	    write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+	    write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+	    
+	    write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1);
+	    write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4);
+	    	    
+	  }
+	  
+	  
+	  /*
+	    if (n_frames==1) {
+	    printf("RX level in null symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
+	    printf("RX level in data symbol %d\n",dB_fixed(signal_energy(&UE->common_vars.rxdata[0][160+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES)],OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2)));
+	    printf("rx_level Null symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
+	    printf("rx_level data symbol %f\n",10*log10(signal_energy_fp(r_re,r_im,1,OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES/2,256+(2*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES))));
+	    }
+	    
+	    if (eNB->frame_parms.Ncp == 0) {  // normal prefix
             pilot1 = 4;
             pilot2 = 7;
             pilot3 = 11;
-          } else { // extended prefix
+	    } else { // extended prefix
             pilot1 = 3;
             pilot2 = 6;
             pilot3 = 9;
-          }
-
-          start_meas(&UE->phy_proc_rx);
+	    }
+	    
+	    start_meas(&UE->phy_proc_rx);
 
           // Inner receiver scheduling for 3 slots
           for (Ns=(2*subframe); Ns<((2*subframe)+3); Ns++) {
@@ -2874,18 +2678,7 @@ PMI_FEEDBACK:
               if (n_frames==1)
                 printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
 
-              /*
-              This function implements the OFDM front end processor (FEP).
-
-              Parameters:
-              frame_parms  LTE DL Frame Parameters
-              ue_common_vars   LTE UE Common Vars
-              l  symbol within slot (0..6/7)
-              Ns   Slot number (0..19)
-              sample_offset  offset within rxdata (points to beginning of subframe)
-              no_prefix  if 1 prefix is removed by HW
 
-              */
 
               start_meas(&UE->ofdm_demod_stats);
               slot_fep(UE,
@@ -2928,28 +2721,6 @@ PMI_FEEDBACK:
                                     subframe*UE->frame_parms.samples_per_tti,
                                     1,
                                     0);
-                /*
-                  debug_msg("RX RSSI %d dBm, digital (%d, %d) dB, linear (%d, %d), avg rx power %d dB (%d lin), RX gain %d dB\n",
-                  UE->measurements.rx_rssi_dBm[0] - ((UE->frame_parms.nb_antennas_rx==2) ? 3 : 0),
-                  UE->measurements.wideband_cqi_dB[0][0],
-                  UE->measurements.wideband_cqi_dB[0][1],
-                  UE->measurements.wideband_cqi[0][0],
-                  UE->measurements.wideband_cqi[0][1],
-                  UE->measurements.rx_power_avg_dB[0],
-                  UE->measurements.rx_power_avg[0],
-                  UE->rx_total_gain_dB);
-                  debug_msg("N0 %d dBm digital (%d, %d) dB, linear (%d, %d), avg noise power %d dB (%d lin)\n",
-                  UE->measurements.n0_power_tot_dBm,
-                  UE->measurements.n0_power_dB[0],
-                  UE->measurements.n0_power_dB[1],
-                  UE->measurements.n0_power[0],
-                  UE->measurements.n0_power[1],
-                  UE->measurements.n0_power_avg_dB,
-                  UE->measurements.n0_power_avg);
-                  debug_msg("Wideband CQI tot %d dB, wideband cqi avg %d dB\n",
-                  UE->measurements.wideband_cqi_tot[0],
-                  UE->measurements.wideband_cqi_avg[0]);
-                */
 
                 if (transmission_mode==5 || transmission_mode==6) {
                   if (pmi_feedback == 1) {
@@ -3027,10 +2798,6 @@ PMI_FEEDBACK:
                                                       UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->Nl,
                                                       UE->pdcch_vars[0]->num_pdcch_symbols,
                                                       0,subframe);
-                      /*
-                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs)][UE->dlsch[0][0]->nb_rb-1]/(coded_bits_per_codeword);
-                      rate*=get_Qm(UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->mcs);
-                      */
                       printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[0]->num_pdcch_symbols,coded_bits_per_codeword,
                              UE->dlsch[0][0]->harq_processes[UE->dlsch[0][0]->current_harq_pid]->TBS);
 
@@ -3337,13 +3104,13 @@ PMI_FEEDBACK:
             }
           }
 
-
+	  
           stop_meas(&UE->phy_proc_rx);
+	  */
 
+          if (UE->dlsch_errors[0] == 0) {
 
-          if (ret <= UE->dlsch[0][0]->max_turbo_iterations) {
-
-            avg_iter += ret;
+            avg_iter += UE->dlsch[eNB_id][0]->last_iteration_cnt;
             iter_trials++;
 
             if (n_frames==1)
@@ -3353,34 +3120,34 @@ PMI_FEEDBACK:
             TB0_active = 0;
 
             if (UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
-              /*
-              for (round = 0 ; round < UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->round ; round++) {
+              
+              //for (round = 0 ; round < UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->round ; round++) {
               // re-encoding of first stream
-              dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
-              dlsch0_eNB_harq = UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
-              dlsch0_eNB_harq->mimo_mode    = LARGE_CDD;
-              dlsch0_eNB_harq->rb_alloc[0]  = dlsch0_ue_harq->rb_alloc_even[0];
-              dlsch0_eNB_harq->nb_rb        = dlsch0_ue_harq->nb_rb;
-              dlsch0_eNB_harq->mcs          = dlsch0_ue_harq->mcs;
-              dlsch0_eNB_harq->rvidx        = dlsch0_ue_harq->rvidx;
-              dlsch0_eNB_harq->Nl           = dlsch0_ue_harq->Nl;
-
-              dlsch0_eNB_harq->TBS          = dlsch0_ue_harq->TBS;
-              dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
-              dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
-
-              UE->dlsch[eNB_id]->active       = UE->dlsch[eNB_id][0]->active;
-              UE->dlsch[eNB_id]->rnti         = UE->dlsch[eNB_id][0]->rnti;
-
-              dlsch_encoding(UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b,
-                   &UE->frame_parms,
-                   num_pdcch_symbols,
-                   UE->dlsch[0],
-                   0,subframe,
-                   &UE->dlsch_rate_matching_stats,
-                   &UE->dlsch_turbo_encoding_stats,
-                   &UE->dlsch_interleaving_stats
-                   );
+              //dlsch0_ue_harq = UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+              //dlsch0_eNB_harq = UE->dlsch[eNB_id]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid];
+              //dlsch0_eNB_harq->mimo_mode    = LARGE_CDD;
+              //dlsch0_eNB_harq->rb_alloc[0]  = dlsch0_ue_harq->rb_alloc_even[0];
+              //dlsch0_eNB_harq->nb_rb        = dlsch0_ue_harq->nb_rb;
+              //dlsch0_eNB_harq->mcs          = dlsch0_ue_harq->mcs;
+              //dlsch0_eNB_harq->rvidx        = dlsch0_ue_harq->rvidx;
+              //dlsch0_eNB_harq->Nl           = dlsch0_ue_harq->Nl;
+
+              //dlsch0_eNB_harq->TBS          = dlsch0_ue_harq->TBS;
+              //dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
+              //dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
+
+              //UE->dlsch[eNB_id]->active       = UE->dlsch[eNB_id][0]->active;
+              //UE->dlsch[eNB_id]->rnti         = UE->dlsch[eNB_id][0]->rnti;
+
+              //dlsch_encoding(UE->dlsch[eNB_id][0]->harq_processes[UE->dlsch[eNB_id][0]->current_harq_pid]->b,
+              //     &UE->frame_parms,
+              //     num_pdcch_symbols,
+              //     UE->dlsch[0],
+              //     0,subframe,
+              //     &UE->dlsch_rate_matching_stats,
+              //     &UE->dlsch_turbo_encoding_stats,
+              //     &UE->dlsch_interleaving_stats
+              //     );
 
                    //scrambling
 
@@ -3389,13 +3156,13 @@ PMI_FEEDBACK:
               //stripping (from matched filter output?)
 
               //detection of second stream
-              }
-              */
-            }
-          } else {
+	    }
+              
+	  } // DLSCH received ok
+	  else {
             errs[round]++;
 
-            avg_iter += ret-1;
+            avg_iter += UE->dlsch[eNB_id][0]->last_iteration_cnt-1;
             iter_trials++;
 
             if (n_frames==1) {
@@ -3421,15 +3188,15 @@ PMI_FEEDBACK:
               write_output(fname,vname, &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
               sprintf(fname,"rxsigF0_r%d.m",round);
               sprintf(vname,"rxs0F_r%d",round);
-              write_output(fname,vname, &UE->common_vars.rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+              write_output(fname,vname, &UE->common_vars.rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 	     
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"rxsig1_r%d.m",round);
                 sprintf(vname,"rxs1_r%d.m",round);
                 write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
-                sprintf(fname,"rxsig1F_r%d.m",round);
+                sprintf(fname,"rxsigF1_r%d.m",round);
                 sprintf(vname,"rxs1F_r%d.m",round);
-                write_output(fname,vname, UE->common_vars.rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+                write_output(fname,vname, UE->common_vars.rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
               }
 
               sprintf(fname,"dlsch00_r%d.m",round);
@@ -3464,13 +3231,18 @@ PMI_FEEDBACK:
 
               //pdsch_vars
               dump_dlsch2(UE,eNB_id,coded_bits_per_codeword,round);
-              /*
-              write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
-              write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
-              write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
-              write_output("dlsch_w.m","w",UE->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
-              */
-
+              
+              //write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
+              //write_output("dlsch_ber_bit.m","ber_bit",uncoded_ber_bit,coded_bits_per_codeword,1,0);
+              //write_output("dlsch_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
+              //write_output("dlsch_w.m","w",UE->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+	      //pdcch_vars
+	      write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[eNB_id]->rxdataF_ext[0],2*3*UE->frame_parms.ofdm_symbol_size,1,1);
+	      write_output("pdcch00_ch0_ext.m","pdcch00_ch0_ext",UE->pdcch_vars[eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+	      
+	      write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[eNB_id]->rxdataF_comp[0],4*300,1,1);
+	      write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[eNB_id]->llr,2400,1,4);              
+	      
               if (round == 3) exit(-1);
             }
 
@@ -3488,7 +3260,8 @@ PMI_FEEDBACK:
 			 subframe);
 	  }
 
-        }  //round
+	  UE->proc.proc_rxtx[subframe&1].frame_rx++;
+	}  //round
 
         //      printf("\n");
 
@@ -3498,7 +3271,7 @@ PMI_FEEDBACK:
         //len = chbch_stats_read(stats_buffer,NULL,0,4096);
         //printf("%s\n\n",stats_buffer);
 
-        if (UE->frame_rx % 10 == 0) {
+        if (UE->proc.proc_rxtx[subframe&1].frame_rx % 10 == 0) {
           UE->bitrate[eNB_id] = (UE->total_TBS[eNB_id] - UE->total_TBS_last[eNB_id])*10;
           LOG_D(PHY,"[UE %d] Calculating bitrate: total_TBS = %d, total_TBS_last = %d, bitrate = %d kbits/s\n",UE->Mod_id,UE->total_TBS[eNB_id],UE->total_TBS_last[eNB_id],
                 UE->bitrate[eNB_id]/1000);
@@ -3506,7 +3279,7 @@ PMI_FEEDBACK:
         }
 
 
-        UE->frame_rx++;
+
 
         /* calculate the total processing time for each packet,
          * get the max, min, and number of packets that exceed t>2000us
@@ -3642,10 +3415,9 @@ PMI_FEEDBACK:
 
       effective_rate = ((double)(round_trials[0]-dci_errors)/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3]));
 
-      printf("\n**********************SNR = %f dB (tx_lev %f, sigma2_dB %f)**************************\n",
+      printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n",
              SNR,
-             (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)),
-             sigma2_dB);
+             (double)tx_lev_dB+10*log10(UE->frame_parms.ofdm_symbol_size/(NB_RB*12)));
 
       printf("Errors (%d(%d)/%d %d/%d %d/%d %d/%d), Pe = (%e,%e,%e,%e), dci_errors %d/%d, Pe = %e => effective rate %f  (%2.1f%%,%f, %f), normalized delay %f (%f)\n",
              errs[0],
@@ -3728,7 +3500,7 @@ PMI_FEEDBACK:
                UE->dlsch_rx_pdcch_stats.trials);
         std_phy_proc_rx_demod = sqrt((double)UE->dlsch_llr_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
                                      2)/UE->dlsch_llr_stats.trials - pow((double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000,2));
-        printf("DLSCH Channel Compensation and LLR generation time  :%f us (%d trials)\n",(3)*(double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0,
+        printf("DLSCH Channel Compensation and LLR generation time  :%f us (%d trials)\n",(14-num_pdcch_symbols)*(double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0,
                UE->dlsch_llr_stats.trials/3);
         printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3);
         printf("DLSCH unscrambling time                             :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0,
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 7f8cf95c2bfd3be896823e3e0fa8c8648379c8a0..d67c6eb6d765f580d76eff8738cde25804dcc134 100755
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -298,7 +298,7 @@ void enb_config_display(void)
 	printf( "\ttx_scheduling_advance :\t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].tx_scheduling_advance);
 	printf( "\ttx_sample_advance :    \t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].tx_sample_advance);
 	printf( "\tiq_txshift :           \t%d:\n",enb_properties.properties[i]->rrh_gw_config[j].iq_txshift);
-	printf( "\ttransport  :           \t%s Ethernet:\n",(enb_properties.properties[i]->rrh_gw_config[j].raw == 1)? "RAW" : "UDP");
+	printf( "\ttransport  :           \t%s Ethernet:\n",(enb_properties.properties[i]->rrh_gw_config[j].raw == 1)? "RAW" : (enb_properties.properties[i]->rrh_gw_config[j].rawif4 == 1)? "RAW_IF4" : (enb_properties.properties[i]->rrh_gw_config[j].udpif4 == 1)? "UDP_IF4" : (enb_properties.properties[i]->rrh_gw_config[j].rawif5_mobipass == 1)? "RAW_IF5_MOBIPASS" : "UDP");
 	if (enb_properties.properties[i]->rrh_gw_config[j].exmimo == 1) {
 	  printf( "\tRF target  :           \tEXMIMO:\n\n");
 	} else if (enb_properties.properties[i]->rrh_gw_config[j].usrp_b200 == 1) {
@@ -2242,10 +2242,12 @@ const Enb_properties_array_t *enb_config_init(char* lib_config_file_name_pP)
               enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
             } else if (strcmp(tr_preference, "raw") == 0) {
               enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
-            } else if (strcmp(tr_preference, "udpif4") == 0) {
+            } else if (strcmp(tr_preference, "udp_if4") == 0) {
               enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udpif4 = 1; 
-            } else if (strcmp(tr_preference, "rawif4") == 0) {
+            } else if (strcmp(tr_preference, "raw_if4") == 0) {
               enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif4 = 1;
+            } else if (strcmp(tr_preference, "raw_if5_mobipass") == 0) {
+              enb_properties.properties[enb_properties_index]->rrh_gw_config[j].rawif5_mobipass = 1;
             } else {//if (strcmp(preference, "no") == 0) 
               enb_properties.properties[enb_properties_index]->rrh_gw_config[j].udp = 1;
               enb_properties.properties[enb_properties_index]->rrh_gw_config[j].raw = 1;
diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h
index e53921b4d0e3b9e067be09779c1137b7bc4978cd..716d40017880de5cdccbba7dfca120f5cadc8201 100755
--- a/openair2/ENB_APP/enb_config.h
+++ b/openair2/ENB_APP/enb_config.h
@@ -88,6 +88,7 @@ typedef struct rrh_gw_config_s {
   uint16_t  remote_port;
   uint8_t   udpif4;
   uint8_t   rawif4;
+  uint8_t   rawif5_mobipass;
   int tx_scheduling_advance;
   int tx_sample_advance;
   int iq_txshift;
diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c
index 34e47c257562588218fd5bd87aff2bec57eddfe5..a30aa10b0edb72abc71d0dc4b971b864f74ade80 100644
--- a/openair2/RRC/LITE/L2_interface.c
+++ b/openair2/RRC/LITE/L2_interface.c
@@ -677,13 +677,14 @@ void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
 void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
 {
   //-------------------------------------------------------------------------------------------//
-  LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ",
-        Mod_idP,frameP,eNB_index,
-	UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active,
-        UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt,
-        UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt,
-        UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt);
-
+  if (UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt>10)
+    LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ",
+	  Mod_idP,frameP,eNB_index,
+	  UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active,
+	  UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt,
+	  UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt,
+	  UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt);
+  
 #if defined(ENABLE_ITTI)
   {
     MessageDef *message_p;
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
index 780261d12adbf311f0555f4cd60e3f4d336117b2..17a9a677e0f4149378aed181195a0833e0051ef0 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/eth_raw.c
@@ -53,6 +53,7 @@
 #include "ethernet_lib.h"
 #include "if_defs.h"
 #include "openair1/PHY/LTE_TRANSPORT/if4_tools.h"
+#include "openair1/PHY/LTE_TRANSPORT/if5_mobipass_tools.h"
 
 #define DEBUG 0
 
@@ -123,8 +124,11 @@ int eth_socket_init_raw(openair0_device *device) {
  /* Construct the Ethernet header */ 
  ether_aton_r(local_mac, (struct ether_addr *)(&(eth->eh.ether_shost)));
  ether_aton_r(remote_mac, (struct ether_addr *)(&(eth->eh.ether_dhost)));
- eth->eh.ether_type = htons((short)device->openair0_cfg->my_port);
-
+// if (((*) device->priv)->flags == ETH_RAW_IF5_MOBIPASS) {
+   eth->eh.ether_type = htons(0xbffe);
+// } else {
+//   eth->eh.ether_type = htons((short)device->openair0_cfg->my_port);
+// } 
  printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5]);
  
  return 0;
@@ -214,6 +218,8 @@ int trx_eth_write_raw_IF4(openair0_device *device, openair0_timestamp timestamp,
     packet_size = RAW_IF4_PDLFFT_SIZE_BYTES(nblocks);    
   } else if (flags == IF4_PULFFT) {
     packet_size = RAW_IF4_PULFFT_SIZE_BYTES(nblocks);    
+  } else if (flags == IF5_MOBIPASS) {
+    packet_size = RAW_IF5_MOBIPASS_SIZE_BYTES;
   } else {
     packet_size = RAW_IF4_PRACH_SIZE_BYTES;
   }
@@ -390,6 +396,37 @@ int eth_set_dev_conf_raw(openair0_device *device) {
 }
 
 
+
+int eth_set_dev_conf_raw_IF4(openair0_device *device) {
+
+  int 	       Mod_id = device->Mod_id;
+  eth_state_t *eth = (eth_state_t*)device->priv;
+  void 	      *msg;
+  ssize_t      msg_len;
+  
+  /* a BBU client sends to RRH a set of configuration parameters (openair0_config_t)
+     so that RF front end is configured appropriately and
+     frame/packet size etc. can be set */ 
+  
+  msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
+  msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
+
+  
+  memcpy(msg,(void*)&eth->eh,MAC_HEADER_SIZE_BYTES);	
+  memcpy((msg+MAC_HEADER_SIZE_BYTES),(void*)device->openair0_cfg,sizeof(openair0_config_t));
+ 	  
+  if (send(eth->sockfd[Mod_id],
+	     msg,
+	     msg_len,
+	     0)==-1) {
+    perror("ETHERNET: ");
+    exit(0);
+  }
+  
+  return 0;
+}
+
+
 int eth_get_dev_conf_raw(openair0_device *device) {
 
   eth_state_t   *eth = (eth_state_t*)device->priv;
@@ -418,3 +455,33 @@ int eth_get_dev_conf_raw(openair0_device *device) {
  	  
   return 0;
 }
+
+
+int eth_get_dev_conf_raw_IF4(openair0_device *device) {
+
+  eth_state_t   *eth = (eth_state_t*)device->priv;
+  int 		Mod_id = device->Mod_id;
+  char 		str[INET_ADDRSTRLEN];
+  void 		*msg;
+  ssize_t	msg_len;
+  
+  msg = malloc(MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t));
+  msg_len = MAC_HEADER_SIZE_BYTES + sizeof(openair0_config_t);
+  
+  /* RRH receives from BBU openair0_config_t */
+  if (recv(eth->sockfd[Mod_id],
+	   msg,
+	   msg_len,
+	   0)==-1) {
+    perror("ETHERNET: ");
+    exit(0);
+  }
+  
+  /* RRH stores the remote MAC address */
+  memcpy(eth->eh.ether_dhost,(msg+ETH_ALEN),ETH_ALEN);	
+  //memcpy((void*)&device->openair0_cfg,(msg + MAC_HEADER_SIZE_BYTES), sizeof(openair0_config_t));
+  //device->openair0_cfg=(openair0_config_t *)(msg + MAC_HEADER_SIZE_BYTES);
+  printf("[%s] binding mod_%d to hardware address %x:%x:%x:%x:%x:%x           hardware address %x:%x:%x:%x:%x:%x\n",((device->host_type == BBU_HOST) ? "BBU": "RRH"),Mod_id,eth->eh.ether_shost[0],eth->eh.ether_shost[1],eth->eh.ether_shost[2],eth->eh.ether_shost[3],eth->eh.ether_shost[4],eth->eh.ether_shost[5],eth->eh.ether_dhost[0],eth->eh.ether_dhost[1],eth->eh.ether_dhost[2],eth->eh.ether_dhost[3],eth->eh.ether_dhost[4],eth->eh.ether_dhost[5]);
+ 	  
+  return 0;
+}
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
index 6e5aa111406d74bf64e923cff17e5179769ae74f..81e3d7b5585d4f155949beac3551cf1c1510fd8f 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
@@ -63,7 +63,7 @@ int trx_eth_start(openair0_device *device) {
   eth_state_t *eth = (eth_state_t*)device->priv;
   
   /* initialize socket */
-  if ((eth->flags & ETH_RAW_MODE) != 0 ) {     
+  if (eth->flags == ETH_RAW_MODE) {     
     if (eth_socket_init_raw(device)!=0)   return -1;
     /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
     if (device->host_type == BBU_HOST) {
@@ -73,6 +73,32 @@ int trx_eth_start(openair0_device *device) {
     }
     /* adjust MTU wrt number of samples per packet */
     if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0)  return -1;
+
+  } else if (eth->flags == ETH_RAW_IF4_MODE) {
+    if (eth_socket_init_raw(device)!=0)   return -1;
+    /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
+    if (device->host_type == BBU_HOST) {
+      if(eth_set_dev_conf_raw_IF4(device)!=0)  return -1;
+    } else {
+      if(eth_get_dev_conf_raw_IF4(device)!=0)  return -1;
+    }
+    /* adjust MTU wrt number of samples per packet */
+    if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0)  return -1;
+    
+  } else if (eth->flags == ETH_UDP_IF4_MODE) {
+    
+  
+  } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
+    if (eth_socket_init_raw(device)!=0)   return -1;
+    /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
+    //if (device->host_type == BBU_HOST) {
+      //if(eth_set_dev_conf_raw_IF4(device)!=0)  return -1;
+    //} else {
+      //if(eth_get_dev_conf_raw_IF4(device)!=0)  return -1;
+//
+    /* adjust MTU wrt number of samples per packet */
+   // if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0)  return -1;
+
   } else {
     if (eth_socket_init_udp(device)!=0)   return -1; 
     /* RRH gets openair0 device configuration - BBU sets openair0 device configuration*/
@@ -319,6 +345,8 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
     eth->flags = ETH_RAW_IF4_MODE;
   } else if (eth_params->transp_preference == 2) {
     eth->flags = ETH_UDP_IF4_MODE;
+  } else if (eth_params->transp_preference == 4) {
+    eth->flags = ETH_RAW_IF5_MOBIPASS;
   } else {
     printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference);
     eth->flags = ETH_RAW_MODE;
@@ -346,6 +374,9 @@ int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth
   } else if (eth->flags == ETH_RAW_IF4_MODE) {
     device->trx_write_func   = trx_eth_write_raw_IF4;
     device->trx_read_func    = trx_eth_read_raw_IF4;     
+  } else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
+    device->trx_write_func   = trx_eth_write_raw_IF4;
+    device->trx_read_func    = trx_eth_read_raw_IF4;     
   } else {
     //device->trx_write_func   = trx_eth_write_udp_IF4;
     //device->trx_read_func    = trx_eth_read_udp_IF4;     
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
index 66cb13ef12e14bb6515af7c539cf2b3ce1aed998..f7753fb51735d885a7f1753637b92ad119993e17 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h
@@ -226,6 +226,7 @@ int trx_eth_write_raw_IF4(openair0_device *device, openair0_timestamp timestamp,
 int trx_eth_read_raw_IF4(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc);
 int eth_get_dev_conf_raw(openair0_device *device);
 int eth_set_dev_conf_raw(openair0_device *device);
-
+int eth_get_dev_conf_raw_IF4(openair0_device *device);
+int eth_set_dev_conf_raw_IF4(openair0_device *device);
 
 #endif
diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
index 030bfda147e3b2fc6e990d9f1b25ae9a1e371837..e17890836bbe5dd210e9a905b3bf504b0762f2fe 100644
--- a/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
+++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/if_defs.h
@@ -46,6 +46,7 @@
 #define ETH_RAW_MODE        1
 #define ETH_UDP_IF4_MODE    2
 #define ETH_RAW_IF4_MODE    3
+#define ETH_RAW_IF5_MOBIPASS    4    
 
 // Time domain RRH packet sizes
 #define MAC_HEADER_SIZE_BYTES (sizeof(struct ether_header))
@@ -61,3 +62,7 @@
 #define RAW_IF4_PDLFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))  
 #define RAW_IF4_PULFFT_SIZE_BYTES(nblocks) (MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + DATA_BLOCK_SIZE_BYTES(nblocks))  
 #define RAW_IF4_PRACH_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF4_header_t + PRACH_BLOCK_SIZE_BYTES)
+
+// Mobipass packet sizes
+#define RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES 1280
+#define RAW_IF5_MOBIPASS_SIZE_BYTES (MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + RAW_IF5_MOBIPASS_BLOCK_SIZE_BYTES)
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index cfe857f9a2e53aa2dfa10832af11a647cd52785a..20a191a06cd1130688021bcd2f966b9fcc99e40b 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -211,15 +211,15 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
    int nsamps2;  // aligned to upper 32 or 16 byte boundary
 #if defined(__x86_64) || defined(__i386__)
 #ifdef __AVX2__
-   __m256i buff_tmp[2][nsamps>>3];
    nsamps2 = (nsamps+7)>>3;
+   __m256i buff_tmp[2][nsamps2];
 #else
-   __m128i buff_tmp[2][nsamps>>2];
    nsamps2 = (nsamps+3)>>2;
+   __m128i buff_tmp[2][nsamps2];
 #endif
 #elif defined(__arm__)
-   int16x8_t buff_tmp[2][nsamps>>2];
    nsamps2 = (nsamps+3)>>2;
+   int16x8_t buff_tmp[2][nsamps2];
 #endif
 
 
@@ -234,7 +234,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
     // receive a single channel (e.g. from connector RF A)
       samples_received = s->rx_stream->recv(buff_tmp[0], nsamps, s->rx_md);
     }
-   
+
   // bring RX data into 12 LSBs for softmodem RX
     for (int i=0;i<cc;i++) {
       for (int j=0; j<nsamps2; j++) {      
@@ -250,7 +250,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
       }
     }
   } else if (device->type == USRP_X300_DEV) {
-    if (cc>1) {
+    if (cc>1) { 
     // receive multiple channels (e.g. RF A and RF B)
       std::vector<void *> buff_ptrs;
  
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 5a03ad30c37fc20a4dd5e0b2da5ba63cbb02e02c..eb612134d3e786651e8ff41a3bb6a92fe7d1f4d6 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -69,6 +69,7 @@
 //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
 
 #include "PHY/LTE_TRANSPORT/if4_tools.h"
+#include "PHY/LTE_TRANSPORT/if5_mobipass_tools.h"
 
 #include "PHY/extern.h"
 #include "SCHED/extern.h"
@@ -297,7 +298,10 @@ static void* eNB_thread_rxtx( void* param ) {
   FILE  *tx_time_file = NULL;
   char tx_time_name[101];
   void *txp[PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx]; 
-
+  
+  uint16_t packet_type;
+  uint32_t symbol_number=0;
+  
   if (opp_enabled == 1) {
     snprintf(tx_time_name, 100,"/tmp/%s_tx_time_thread_sf", "eNB");
     tx_time_file = fopen(tx_time_name,"w");
@@ -488,19 +492,23 @@ static void* eNB_thread_rxtx( void* param ) {
       } else {
 
         /// **** recv_IF4 of txdataF from RCC **** ///             
-        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );   
-        //recv_IF4(PHY_vars_eNB_g[0][proc->CC_id], proc->frame_tx, proc->subframe_tx, packet_type, symbol_number);        
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 1 );  
+        while (symbol_number < PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.symbols_per_tti-1) { 
+          recv_IF4(PHY_vars_eNB_g[0][proc->CC_id], &proc->frame_tx, &proc->subframe_tx, &packet_type, &symbol_number);
+        }
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RECV_IF4, 0 );   
         
+        // Check the recv frame/subframe
       }
     }
 
-    // eNodeB_3GPP and RRU create txdata and write to RF device
+    // eNodeB_3GPP, _BBU and RRU create txdata
     if (PHY_vars_eNB_g[0][proc->CC_id]->node_function != NGFI_RCC_IF4) {
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 1 );
       do_OFDM_mod_rt( proc->subframe_tx, PHY_vars_eNB_g[0][proc->CC_id] );
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_SFGEN , 0 );
-  
+    }
+
       /*
         short *txdata = (short*)&PHY_vars_eNB_g[0][proc->CC_id]->common_vars.txdata[0][0][proc->subframe_tx*PHY_vars_eNB_g[0][proc->CC_id]->frame_parms.samples_per_tti];
         int i;
@@ -513,8 +521,12 @@ static void* eNB_thread_rxtx( void* param ) {
         txdata[i+5] = 0;
         txdata[i+6] = 0;
         txdata[i+7] = -2047;      }
-      */
+      */      
+          
 
+    // eNodeB_3GPP, RRU write to RF device    
+    if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP ||
+        PHY_vars_eNB_g[0][proc->CC_id]->node_function == NGFI_RRU_IF4) {
       // Transmit TX buffer based on timestamp from RX  
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
       // prepare tx buffer pointers
@@ -534,13 +546,15 @@ static void* eNB_thread_rxtx( void* param ) {
  
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-openair0_cfg[0].tx_sample_advance)&0xffffffff );
 
+    } else if (PHY_vars_eNB_g[0][proc->CC_id]->node_function == eNodeB_3GPP_BBU) {
+      /// **** trx_write_func to IF device **** ///       
+   //   send_IF5(PHY_vars_eNB_g[0][proc->CC_id], proc, 0);
+      
     } else { 
-	 
       /// **** send_IF4 of txdataF to RRU **** ///       
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 1 );   
       send_IF4(PHY_vars_eNB_g[0][proc->CC_id], proc->frame_tx, proc->subframe_tx, IF4_PDLFFT, 0);
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_SEND_IF4, 0 );
-
     }
 
     if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
@@ -611,10 +625,11 @@ static void* eNB_thread_rx_common( void* param ) {
   eNB_proc_t *proc = (eNB_proc_t*)param;
   PHY_VARS_eNB *eNB = PHY_vars_eNB_g[0][proc->CC_id];
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
-
+  
+  uint8_t seqno=0;
   FILE  *rx_time_file = NULL;
   char rx_time_name[101];
-  //int i;
+  int i;
   struct timespec wait;
 
   wait.tv_sec=0;
@@ -737,19 +752,27 @@ static void* eNB_thread_rx_common( void* param ) {
 #if defined(ENABLE_ITTI)
   wait_system_ready ("Waiting for eNB application to be ready %s\r", &start_eNB);
 #endif 
-  
-  // Start RF device for this CC
-  if (eNB->node_function != NGFI_RCC_IF4) {
-    if (eNB->rfdevice.trx_start_func(&eNB->rfdevice) != 0 ) 
-      LOG_E(HW,"Could not start the RF device\n");
-  }
-    
+
   // Start IF device for this CC
   if (eNB->node_function != eNodeB_3GPP) {
     if (eNB->ifdevice.trx_start_func(&eNB->ifdevice) != 0 ) 
       LOG_E(HW,"Could not start the IF device\n");
   }
+  
+  // Start RF device for this CC
+  if (eNB->node_function == eNodeB_3GPP || eNB->node_function == NGFI_RRU_IF4) {
+    if (eNB->rfdevice.trx_start_func(&eNB->rfdevice) != 0 ) 
+      LOG_E(HW,"Could not start the RF device\n");
+  }
 
+  //  proc->proc_rxtx[0].timestamp_tx = 0;
+  //  seqno = send_IF5(eNB, &proc->proc_rxtx[0], 0); 
+  
+ // for (i=0; i<1000;i++) {
+ //   seqno = send_IF5(eNB, &proc->proc_rxtx[0], seqno); 
+ //   proc->proc_rxtx[0].timestamp_tx += 7680*2;
+ // }
+      
   // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices
   while (!oai_exit) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX, 0 );
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 3508a26565d4a7b3c0fbc6f8fd0bfe936d74f20e..0c785619ce430c21d55a995e99f60cdab4c12394 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -299,35 +299,35 @@ struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
 
 struct timespec clock_difftime(struct timespec start, struct timespec end)
 {
-    struct timespec temp;
-    if ((end.tv_nsec-start.tv_nsec)<0) {
-        temp.tv_sec = end.tv_sec-start.tv_sec-1;
-	temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
-    } else {
-        temp.tv_sec = end.tv_sec-start.tv_sec;
-	temp.tv_nsec = end.tv_nsec-start.tv_nsec;
-    }
-    return temp;
+  struct timespec temp;
+  if ((end.tv_nsec-start.tv_nsec)<0) {
+    temp.tv_sec = end.tv_sec-start.tv_sec-1;
+    temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
+  } else {
+    temp.tv_sec = end.tv_sec-start.tv_sec;
+    temp.tv_nsec = end.tv_nsec-start.tv_nsec;
+  }
+  return temp;
 }
 
 void print_difftimes(void)
 {
 #ifdef DEBUG
-    printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
+  printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
 #else
-    LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
+  LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
 #endif
 }
 
 void update_difftimes(struct timespec start, struct timespec end)
 {
-    struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
-    int             changed = 0;
-    diff_time = clock_difftime(start, end);
-    if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
-    if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
+  struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
+  int             changed = 0;
+  diff_time = clock_difftime(start, end);
+  if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
+  if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
 #if 1
-    if (changed) print_difftimes();
+  if (changed) print_difftimes();
 #endif
 }
 
@@ -499,7 +499,7 @@ static void *scope_thread(void *arg)
 
   while (!oai_exit) {
     if (UE_flag==1) {
-      len = dump_ue_stats (PHY_vars_UE_g[0][0], stats_buffer, 0, mode,rx_input_level_dBm);
+      len = dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm);
       //fl_set_object_label(form_stats->stats_text, stats_buffer);
       fl_clear_browser(form_stats->stats_text);
       fl_add_browser_line(form_stats->stats_text, stats_buffer);
@@ -686,7 +686,8 @@ static void get_options (int argc, char **argv)
     LONG_OPTION_PHYTEST,
     LONG_OPTION_RCC,
     LONG_OPTION_RRU,
-    LONG_OPTION_ENB
+    LONG_OPTION_ENB,
+    LONG_OPTION_ENB_BBU
 #if T_TRACER
     ,
     LONG_OPTION_T_PORT,
@@ -713,6 +714,7 @@ static void get_options (int argc, char **argv)
     {"RCC", no_argument, NULL, LONG_OPTION_RCC},
     {"RRU", no_argument, NULL, LONG_OPTION_RRU},
     {"eNB", no_argument, NULL, LONG_OPTION_ENB},
+    {"BBU", no_argument, NULL, LONG_OPTION_ENB_BBU},
 #if T_TRACER
     {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
     {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
@@ -729,8 +731,8 @@ static void get_options (int argc, char **argv)
       else if (strlen(optarg)<=1024){
 	strcpy(rf_config_file,optarg);
       }else {
-         printf("Configuration filename is too long\n");
-         exit(-1);   
+	printf("Configuration filename is too long\n");
+	exit(-1);   
       }
       break;
     case LONG_OPTION_MAXPOWER:
@@ -815,6 +817,10 @@ static void get_options (int argc, char **argv)
     case LONG_OPTION_ENB:
       node_function = eNodeB_3GPP;
       break;
+
+    case LONG_OPTION_ENB_BBU:
+      node_function = eNodeB_3GPP_BBU;
+      break;
       
 #if T_TRACER
     case LONG_OPTION_T_PORT: {
@@ -894,14 +900,14 @@ static void get_options (int argc, char **argv)
       in_ip[sizeof(in_ip) - 1] = 0; // terminate string
       printf("Enabling OPT for wireshark for local interface");
       /*
-      if (optarg == NULL){
-      in_ip[0] =NULL;
-      printf("Enabling OPT for wireshark for local interface");
-      } else {
-      strncpy(in_ip, optarg, sizeof(in_ip));
-      in_ip[sizeof(in_ip) - 1] = 0; // terminate string
-      printf("Enabling OPT for wireshark with %s \n",in_ip);
-      }
+	if (optarg == NULL){
+	in_ip[0] =NULL;
+	printf("Enabling OPT for wireshark for local interface");
+	} else {
+	strncpy(in_ip, optarg, sizeof(in_ip));
+	in_ip[sizeof(in_ip) - 1] = 0; // terminate string
+	printf("Enabling OPT for wireshark with %s \n",in_ip);
+	}
       */
       break;
 
@@ -1065,6 +1071,8 @@ static void get_options (int argc, char **argv)
             (eth_params+j)->transp_preference       = ETH_RAW_IF4_MODE;             
           } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4 == 1) {
             (eth_params+j)->transp_preference       = ETH_UDP_IF4_MODE;             
+          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
+            (eth_params+j)->transp_preference       = ETH_RAW_IF5_MOBIPASS;             
           } else {
             (eth_params+j)->transp_preference       = ETH_UDP_MODE;	 
           }
@@ -1541,13 +1549,6 @@ int main( int argc, char **argv )
       openair0_cfg[card].my_port        = eth_params->my_port;    
     } 
     
-    //if (node_function == NGFI_RCC_IF4 || node_function == NGFI_RRU_IF4) {
-      //openair0_cfg[card].remote_addr    = eth_params->remote_addr;
-      //openair0_cfg[card].remote_port    = eth_params->remote_port;
-      //openair0_cfg[card].my_addr        = eth_params->my_addr;
-      //openair0_cfg[card].my_port        = eth_params->my_port;    
-    //}
-
     printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
            ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx),
            ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
@@ -1611,37 +1612,37 @@ int main( int argc, char **argv )
   int s;
   char cpu_affinity[1024];
   CPU_ZERO(&cpuset);
-  #ifdef CPU_AFFINITY
+#ifdef CPU_AFFINITY
   if (get_nprocs() > 2)
-  {
-    CPU_SET(0, &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");
+      CPU_SET(0, &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");
+	}
+      LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n");
     }
-    LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n");
-  }
-  #endif
+#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 ");
-  }
+    {
+      perror( "pthread_getaffinity_np");
+      exit_fun("Error getting processor affinity ");
+    }
   memset(cpu_affinity, 0 , sizeof(cpu_affinity));
   for (int j = 0; j < CPU_SETSIZE; j++)
-  {
-    if (CPU_ISSET(j, &cpuset))
-    {  
-      char temp[1024];
-      sprintf(temp, " CPU_%d ", j);    
-      strcat(cpu_affinity, temp);
+    {
+      if (CPU_ISSET(j, &cpuset))
+	{  
+	  char temp[1024];
+	  sprintf(temp, " CPU_%d ", j);    
+	  strcat(cpu_affinity, temp);
+	}
     }
-  }
   LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
 #endif
   
@@ -1649,68 +1650,71 @@ int main( int argc, char **argv )
 
   if (UE_flag == 0) {
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-      PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = BBU_HOST;
+      if (node_function == NGFI_RRU_IF4) {
+	PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = RRH_HOST;
+	PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = RRH_HOST;
+      } else {
+	PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = BBU_HOST;
+	PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = BBU_HOST;
+      }
+      
       PHY_vars_eNB_g[0][CC_id]->rfdevice.type = NONE_DEV;
       PHY_vars_eNB_g[0][CC_id]->rfdevice.transp_type = NONE_TP;
       
-      PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = BBU_HOST;
       PHY_vars_eNB_g[0][CC_id]->ifdevice.type = NONE_DEV;
       PHY_vars_eNB_g[0][CC_id]->ifdevice.transp_type = NONE_TP;
     }
   }
-
   /* 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;
-  //openair0_cfg[0].log_level = glog_level;
   
   // 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) {    
-    //}
+  //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) {    
-    //}
+  //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) {    
+  //}
   //}   
-  
-  //printf("Done\n");
-  
+    
   int returns=-1;
     
   // Handle spatially distributed MIMO antenna ports   
   // Load RF device and initialize
-  if ((UE_flag==1) || (node_function != NGFI_RCC_IF4)) { 
+
+  if (node_function == NGFI_RRU_IF4 || node_function == eNodeB_3GPP) { 
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {  
       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(&openair0, &openair0_cfg[0]);
 
         printf("openair0_device_init returns %d for CC_id %d\n",returns,CC_id);
         if (returns<0) {
-	        printf("Exiting, cannot initialize device\n");
-	        exit(-1);
+	  printf("Exiting, cannot initialize device\n");
+	  exit(-1);
         }
       }
       else if (mode==loop_through_memory) {    
@@ -1719,14 +1723,15 @@ int main( int argc, char **argv )
   }  
   
   // Load transport protocol and initialize
+
   if ((UE_flag==0) && (node_function != eNodeB_3GPP)){ 
     for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {  
       if (mode!=loop_through_memory) {
         returns=openair0_transport_load(&(PHY_vars_eNB_g[0][CC_id]->ifdevice), &openair0_cfg[0], (eth_params+CC_id));
         printf("openair0_transport_init returns %d for CC_id %d\n",returns,CC_id);
         if (returns<0) {
-	        printf("Exiting, cannot initialize transport protocol\n");
-	        exit(-1);
+	  printf("Exiting, cannot initialize transport protocol\n");
+	  exit(-1);
         }
       }
       else if (mode==loop_through_memory) {    
@@ -1858,8 +1863,8 @@ int main( int argc, char **argv )
 	    fl_set_button(form_enb[CC_id][UE_id]->button_0,0);
 	    fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF");
 	  }
-	}
-      }
+	} // CC_id
+      } // UE_id
     } else {
       form_stats = create_form_stats_form();
       fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
@@ -1869,15 +1874,15 @@ int main( int argc, char **argv )
       fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
 
       /*
-      if (openair_daq_vars.use_ia_receiver) {
+	if (openair_daq_vars.use_ia_receiver) {
         fl_set_button(form_ue[UE_id]->button_0,1);
         fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
-      } else {
+	} else {
         fl_set_button(form_ue[UE_id]->button_0,0);
         fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
 	}*/
-        fl_set_button(form_ue[UE_id]->button_0,0);
-        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
+      fl_set_button(form_ue[UE_id]->button_0,0);
+      fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
     }
 
     ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
@@ -1904,7 +1909,7 @@ int main( int argc, char **argv )
 
 
 
-// *** Handle per CC_id openair0
+  // *** Handle per CC_id openair0
 #ifndef USRP_DEBUG
   if ((UE_flag==1) && (mode!=loop_through_memory))
     if (openair0.trx_start_func(&openair0) != 0 ) 
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index ca3dbb93101a4b7a49969fd2f594e573c4e669b0..b94c48e7347af477a4da389f005719cc841cf5a7 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -306,7 +306,7 @@ static void *UE_thread_synch(void *arg)
   pthread_mutex_unlock(&sync_mutex);
   printf("unlocked sync_mutex (UE_sync_thread)\n");
 
-  printf("starting UE synch thread (IC %d)\n",UE->instance_cnt_synch);
+  printf("starting UE synch thread (IC %d)\n",UE->proc.instance_cnt_synch);
   ind = 0;
   found = 0;
 
@@ -367,19 +367,19 @@ static void *UE_thread_synch(void *arg)
 
   while (oai_exit==0) {
 
-    if (pthread_mutex_lock(&UE->mutex_synch) != 0) {
+    if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) {
       LOG_E( PHY, "[SCHED][UE] error locking mutex for UE initial synch thread\n" );
       exit_fun("noting to add");
       return &UE_thread_synch_retval;
     }
     
 
-    while (UE->instance_cnt_synch < 0) {
+    while (UE->proc.instance_cnt_synch < 0) {
       // the thread waits here most of the time
-      pthread_cond_wait( &UE->cond_synch, &UE->mutex_synch );
+      pthread_cond_wait( &UE->proc.cond_synch, &UE->proc.mutex_synch );
     }
 
-    if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {
+    if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) {
       LOG_E( PHY, "[SCHED][eNB] error unlocking mutex for UE Initial Synch thread\n" );
       exit_fun("nothing to add");
       return &UE_thread_synch_retval;
@@ -485,7 +485,7 @@ static void *UE_thread_synch(void *arg)
 
 	  if( UE->mode == rx_dump_frame ){
 	    FILE *fd;
-	    if ((UE->frame_rx&1) == 0) {  // this guarantees SIB1 is present 
+	    if ((UE->proc.proc_rxtx[0].frame_rx&1) == 0) {  // this guarantees SIB1 is present 
 	      if ((fd = fopen("rxsig_frame0.dat","w")) != NULL) {
 		fwrite((void*)&UE->common_vars.rxdata[0][0],
 		       sizeof(int32_t),
@@ -504,11 +504,6 @@ static void *UE_thread_synch(void *arg)
 	      UE->is_synchronized = 0;
 	    }
 	  }
-	  
-	  
-	  
-	  UE->slot_rx = 0;
-	  UE->slot_tx = 4;
 	}
       } else {
         // initial sync failed
@@ -577,16 +572,16 @@ static void *UE_thread_synch(void *arg)
 
 
 
-    if (pthread_mutex_lock(&UE->mutex_synch) != 0) {
+    if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) {
       LOG_E( PHY, "[SCHED][UE] error locking mutex for UE synch\n" );
       exit_fun("noting to add");
       return &UE_thread_synch_retval;
     }
 
     // indicate readiness
-    UE->instance_cnt_synch--;
+    UE->proc.instance_cnt_synch--;
 
-    if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {
+    if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) {
       LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE synch\n" );
       exit_fun("noting to add");
       return &UE_thread_synch_retval;
@@ -798,7 +793,6 @@ static void *UE_thread_rxn_txnp4(void *arg)
 {
   static int UE_thread_rx_retval;
   UE_rxtx_proc_t *proc = (UE_rxtx_proc_t *)arg;
-  int i;
   int ret;
   PHY_VARS_UE *UE=PHY_vars_UE_g[0][proc->CC_id];
   proc->instance_cnt_rxtx=-1;
@@ -934,11 +928,12 @@ static void *UE_thread_rxn_txnp4(void *arg)
     if ((subframe_select( &UE->frame_parms, proc->subframe_rx) == SF_DL) ||
 	(UE->frame_parms.frame_type == FDD) ||
 	(subframe_select( &UE->frame_parms, proc->subframe_rx ) == SF_S)) {
-      phy_procedures_UE_RX( UE, 0, 0, UE->mode, no_relay, NULL );
-    }
     
+      phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL );
+    }
     
-    if ((UE->mac_enabled==1) && (i==0)) {
+    if (UE->mac_enabled==1) {
+
       ret = mac_xface->ue_scheduler(UE->Mod_id,
 				    proc->frame_tx,
 				    proc->subframe_rx,
@@ -1007,14 +1002,18 @@ void *UE_thread(void *arg) {
   PHY_VARS_UE *UE = PHY_vars_UE_g[0][0];
   //  int tx_enabled = 0;
   unsigned int rxs;
-  int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti];
-  openair0_timestamp timestamp;
+  int dummy_rx[UE->frame_parms.nb_antennas_rx][UE->frame_parms.samples_per_tti] __attribute__((aligned(32)));
+  openair0_timestamp timestamp,timestamp1;
   void* rxp[2];
 
 #ifdef NAS_UE
   MessageDef *message_p;
 #endif
 
+  int start_rx_stream = 0;
+  int rx_off_diff = 0;
+  int rx_correction_timer = 0;
+
 #ifdef DEADLINE_SCHEDULER
 
   struct sched_attr attr;
@@ -1069,15 +1068,15 @@ void *UE_thread(void *arg) {
     
     if (UE->is_synchronized == 0) {
       
-      if (pthread_mutex_lock(&UE->mutex_synch) != 0) {
+      if (pthread_mutex_lock(&UE->proc.mutex_synch) != 0) {
 	LOG_E( PHY, "[SCHED][UE] verror locking mutex for UE initial synch thread\n" );
 	exit_fun("nothing to add");
 	return &UE_thread_retval;
       }
       
-      int instance_cnt_synch = UE->instance_cnt_synch;
+      int instance_cnt_synch = UE->proc.instance_cnt_synch;
       
-      if (pthread_mutex_unlock(&UE->mutex_synch) != 0) {
+      if (pthread_mutex_unlock(&UE->proc.mutex_synch) != 0) {
 	LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE initial synch thread\n" );
 	exit_fun("nothing to add");
 	return &UE_thread_retval;
@@ -1095,9 +1094,9 @@ void *UE_thread(void *arg) {
 				       UE->frame_parms.samples_per_tti*10,
 				       UE->frame_parms.nb_antennas_rx);
 	}
-	instance_cnt_synch = ++UE->instance_cnt_synch;
+	instance_cnt_synch = ++UE->proc.instance_cnt_synch;
 	if (instance_cnt_synch == 0) {
-	  if (pthread_cond_signal(&UE->cond_synch) != 0) {
+	  if (pthread_cond_signal(&UE->proc.cond_synch) != 0) {
 	    LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE sync thread\n" );
 	    exit_fun("nothing to add");
 	    return &UE_thread_retval;
@@ -1114,19 +1113,153 @@ void *UE_thread(void *arg) {
 	if (UE->mode != loop_through_memory) {
 	  for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
 	    rxp[i] = (void*)&dummy_rx[i][0];
-	  for (int sf=0;sf<10;sf++) 
+	  for (int sf=0;sf<10;sf++) {
 	    rxs = openair0.trx_read_func(&openair0,
 					 &timestamp,
 					 rxp,
 					 UE->frame_parms.samples_per_tti,
 					 UE->frame_parms.nb_antennas_rx);
+	  }
 	}
       }
       
-    } // UE->is_synchronized==1
+    } // UE->is_synchronized==0
     else {
-      exit(-1);
-    }
+      if (start_rx_stream==0) {
+	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);
+	  if (rxs != UE->rx_offset) {
+	    exit_fun("problem in rx");
+	    return &UE_thread_retval;
+	  }
+	  UE->rx_offset=0;
+	  UE->proc.proc_rxtx[0].frame_rx++;
+	  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);
+	  slot_fep(UE,
+		   0,
+		   0,
+		   0,
+		   0,
+		   0);
+	  if (rxs != UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0) {
+	    exit_fun("problem in rx");
+	    return &UE_thread_retval;
+	  }
+	} //UE->mode != loop_through_memory
+	else
+	  rt_sleep_ns(1000000);
+
+      }// start_rx_stream==0
+      else {
+	//	printf("Frame %d, rx_offset %d (diff %d, timer %d)\n",UE->proc.proc_rxtx[0].frame_rx,UE->rx_offset,rx_off_diff,rx_correction_timer);
+	UE->proc.proc_rxtx[0].frame_rx++;
+	UE->proc.proc_rxtx[1].frame_rx++;
+
+	for (int sf=0;sf<10;sf++) {
+	  for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++) 
+	    rxp[i] = (void*)&rxdata[i][UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0+(sf*UE->frame_parms.samples_per_tti)];
+	  // grab signal for subframe
+	  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);
+	    }
+
+	    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);
+	      // read in first symbol of next frame and adjust for timing drift
+	      rxs = openair0.trx_read_func(&openair0,
+					   &timestamp1,
+					   (void**)rxdata,
+					   UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 - rx_off_diff,
+					   UE->frame_parms.nb_antennas_rx);
+	      rx_off_diff = 0;
+	    }
+	  }
+
+	  // operate on thread sf mod 2
+	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sf&1];
+
+	  // lock mutex
+	  if (pthread_mutex_lock(&proc->mutex_rxtx) != 0) {
+	    LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RX\n" );
+	    exit_fun("nothing to add");
+	    return &UE_thread_retval;
+	  }
+	  // increment instance count and change proc subframe/frame variables
+	  int instance_cnt_rxtx = ++proc->instance_cnt_rxtx;
+	  proc->subframe_rx=sf;
+	  proc->subframe_tx=(sf+4)%10;
+	  proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5)?1:0;
+	  proc->timestamp_tx = timestamp+(4*UE->frame_parms.samples_per_tti)-UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
+
+
+	  if (pthread_mutex_unlock(&proc->mutex_rxtx) != 0) {
+	    LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE RX\n" );
+	    exit_fun("nothing to add");
+	    return &UE_thread_retval;
+	  }
+
+
+	  if (instance_cnt_rxtx == 0) {
+	    if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
+	      LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" );
+	      exit_fun("nothing to add");
+	      return &UE_thread_retval;
+	    }
+	  } else {
+	    LOG_E( PHY, "[SCHED][UE] UE RX thread busy (IC %d)!!\n", instance_cnt_rxtx);
+	    if (instance_cnt_rxtx > 2) {
+	      sleep(1);
+	      exit_fun("instance_cnt_rxtx > 2");
+	      return &UE_thread_retval;
+	    }
+	  }
+	  if (UE->mode == loop_through_memory) {
+	    printf("Processing subframe %d",proc->subframe_rx);
+	    getchar();
+	  }
+	}// for sf=0..10
+	if ((UE->rx_offset<(5*UE->frame_parms.samples_per_tti)) &&
+	    (UE->rx_offset > RX_OFF_MIN) && 
+	    (rx_correction_timer == 0)) {
+	  rx_off_diff = -UE->rx_offset + RX_OFF_MIN;
+	  LOG_D(PHY,"UE->rx_offset %d > %d, diff %d\n",UE->rx_offset,RX_OFF_MIN,rx_off_diff);
+	  rx_correction_timer = 5;
+	} else if ((UE->rx_offset>(5*UE->frame_parms.samples_per_tti)) && 
+		   (UE->rx_offset < ((10*UE->frame_parms.samples_per_tti)-RX_OFF_MIN)) &&
+		   (rx_correction_timer == 0)) {   // moving to the left so drop rx_off_diff samples
+	  rx_off_diff = 10*UE->frame_parms.samples_per_tti - RX_OFF_MIN - UE->rx_offset;
+	  LOG_D(PHY,"UE->rx_offset %d < %d, diff %d\n",UE->rx_offset,10*UE->frame_parms.samples_per_tti-RX_OFF_MIN,rx_off_diff);
+	  
+	  rx_correction_timer = 5;
+	}
+	
+	if (rx_correction_timer>0)
+	  rx_correction_timer--;
+      } // start_rx_stream==1
+    } // UE->is_synchronized==1
+      
   } // while !oai_exit
 } // UE_thread
 
@@ -1316,7 +1449,7 @@ void *UE_thread_old(void *arg)
 
         if (instance_cnt_rx == 0) {
 	  LOG_D(HW,"signalling rx thread to wake up, hw_frame %d, hw_subframe %d (time %lli)\n", frame, hw_subframe, rt_get_time_ns()-T0 );
-          if (pthread_cond_signal(&UE->cond_rx) != 0) {
+          if (pthread_cond_signal(&UE->proc.cond_rx) != 0) {
             LOG_E( PHY, "[SCHED][UE] ERROR pthread_cond_signal for UE RX thread\n" );
             exit_fun("nothing to add");
             return &UE_thread_retval;
@@ -1544,12 +1677,12 @@ void init_UE_threads(void)
   pthread_cond_init(&UE->proc.proc_rxtx[0].cond_rxtx,NULL);
   pthread_cond_init(&UE->proc.proc_rxtx[1].cond_rxtx,NULL);
   pthread_cond_init(&UE->proc.cond_synch,NULL);
-  pthread_create(&UE->proc.proc_rxtx[0].thread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[0]);
-  pthread_setname_np( UE->proc.proc_rxtx[0].thread_rxtx, "UE_thread_rxn_txnp4_even" );
-  pthread_create(&UE->proc.proc_rxtx[1].thread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[1]);
-  pthread_setname_np( UE->proc.proc_rxtx[1].thread_rxtx, "UE_thread_rxn_txnp4_odd" );
-  pthread_create(&UE->proc.thread_synch,NULL,UE_thread_synch,(void*)UE);
-  pthread_setname_np( UE->proc.thread_synch, "UE_thread_synch" );
+  pthread_create(&UE->proc.proc_rxtx[0].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[0]);
+  pthread_setname_np( UE->proc.proc_rxtx[0].pthread_rxtx, "UE_thread_rxn_txnp4_even" );
+  pthread_create(&UE->proc.proc_rxtx[1].pthread_rxtx,NULL,UE_thread_rxn_txnp4,(void*)&UE->proc.proc_rxtx[1]);
+  pthread_setname_np( UE->proc.proc_rxtx[1].pthread_rxtx, "UE_thread_rxn_txnp4_odd" );
+  pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
+  pthread_setname_np( UE->proc.pthread_synch, "UE_thread_synch" );
 }