diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 311f3952aa0433fcbf2a36c7ebfdbf241b2b5427..0dc8d3051bada4d83961684d22ea99a56b2fb4c6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,8 +2,6 @@ job1:
   script:
     - date
     - pwd
-    - echo $OAI_USER
-    - echo $OAI_PASS
     - echo $OAI_TEST_CASE_GROUP
     - echo $MACHINELIST
     - echo $MACHINELISTGENERIC
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 0c5a19784712687012a8cff5e891e7ba8daea4ea..e3e3e79913ff98473c4216feb7ca941a71cc86ed 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -237,6 +237,9 @@ add_boolean_option(XFORMS              False "This adds the possibility to see t
 add_boolean_option(PRINT_STATS         False "This adds the possibility to see the status")
 add_boolean_option(T_TRACER            False "Activate the T tracer, a debugging/monitoring framework" )
 add_boolean_option(UE_AUTOTEST_TRACE   False "Activate UE autotest specific logs")
+add_boolean_option(UE_DEBUG_TRACE      False "Activate UE debug trace")
+add_boolean_option(UE_TIMING_TRACE     False "Activate UE timing trace")
+add_boolean_option(DISABLE_LOG_X       False "Deactivate all LOG_* macros")
 
 add_boolean_option(DEBUG_CONSOLE False "makes debugging easier, disables stdout/stderr buffering")
 
@@ -542,6 +545,19 @@ set(TPLIB_ETHERNET_SOURCE
   )
 add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} )
 
+include_directories("${OPENAIR_TARGETS}/ARCH/mobipass/")
+set(TPLIB_MOBIPASS_SOURCE
+  ${OPENAIR_TARGETS}/ARCH/mobipass/interface.c
+  ${OPENAIR_TARGETS}/ARCH/mobipass/mobipass.c
+  ${OPENAIR_TARGETS}/ARCH/mobipass/queues.c
+  )
+add_library(oai_mobipass MODULE ${TPLIB_MOBIPASS_SOURCE} )
+
+# Hide all functions/variables in the mobipass library.
+# Use __attribute__((__visibility__("default")))
+# in the source code to unhide a function/variable.
+get_target_property(mobipas_cflags oai_mobipass COMPILE_FLAGS)
+set_target_properties(oai_mobipass PROPERTIES COMPILE_FLAGS "${mobipass_cflags} -fvisibility=hidden")
 
 ##########################################################
 
@@ -1651,9 +1667,25 @@ else()
 endif()
 
 # Atlas is required by some packages, but not found in pkg-config
-if(EXISTS "/usr/include/atlas/cblas.h")
+# So, here are some hacks here. Hope this gets fixed in future!
+if(EXISTS "/usr/include/atlas/cblas.h" OR EXISTS "/usr/include/cblas.h")
   include_directories("/usr/include/atlas")
-  list(APPEND ATLAS_LIBRARIES cblas atlas lapack)
+  LINK_DIRECTORIES("/usr/lib64")
+  LINK_DIRECTORIES("/usr/lib64/atlas") #Added because atlas libraries in CentOS 7 are here!
+  
+  if(EXISTS "/usr/lib64/libblas.so" OR EXISTS "/usr/lib/libblas.so") #Case for CentOS7
+     list(APPEND ATLAS_LIBRARIES blas)
+  else() # Case for Ubuntu
+     list(APPEND ATLAS_LIBRARIES cblas)
+  endif()
+
+  if(EXISTS "/usr/lib/atlas/libtatlas.so" OR EXISTS "/usr/lib64/atlas/libtatlas.so") #Case for CentOS7
+     list(APPEND ATLAS_LIBRARIES tatlas)
+  else()
+     list(APPEND ATLAS_LIBRARIES atlas) #Case for Ubuntu
+  endif()
+
+  list(APPEND ATLAS_LIBRARIES lapack)
 else()
   message("No Blas/Atlas libs found, some targets will fail")
 endif()
diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml
index 0c80e960a45286fe34d3387d3c0783267cb63dc7..d9ed38a4ec84faa06c69e610a37f07e039efbb1a 100644
--- a/cmake_targets/autotests/test_case_list.xml
+++ b/cmake_targets/autotests/test_case_list.xml
@@ -941,9 +941,14 @@
       (Test 7b, 5 MHz, R3-1.FDD (MCS 15), ETU70, 1.4 dB (30%)),
       (Test 10, 5 MHz, R6.FDD (MCS 25), EVA5, 17.4 dB (70%)),
       (Test 10b, 5 MHz, R6-1.FDD (MCS 24,18 PRB), EVA5, 17.5dB (70%)),
-      (Test 11, 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%))
+      (Test 11, 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)),
+      (Test 11b, 10 MHz, R7-1.FDD (MCS 25), EVA5, 16.7dB (70%)),
+      (Test 15, 20 MHz, R.9 FDD	(MCS 26), EVA5, 17.6dB (70%)),
+      (Test 15b, 20 MHz, R.9-2 FDD (MCS 26, 17PRB), EVA5, 17.3dB (70%)),
+      (Test 15c, 20 MHz, R.9-1 FDD (MCS 26, 83 PRB), EVA5, 16.6dB (70%)),
+
       (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)),
-      (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
+      (TM2 Test 1b 5 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)),
        </desc>
       <pre_compile_prog></pre_compile_prog>
       <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
@@ -960,6 +965,9 @@
                        -m25 -gF -s17.4 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O70
                        -m25 -gF -s17.5 -w1.0 -f.2 -n500 -B25 -c3 -z2 -r1022 -O70
                        -m26 -gF -s17.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O70
+                       -m26 -gF -s17.6 -w1.0 -f.2 -n500 -B100 -c2 -z2 -O70
+                       -m26 -gF -s17.3 -w1.0 -f.2 -n500 -B100 -c2 -z2 -r1600 -O70
+                       -m26 -gF -s16.6 -w1.0 -f.2 -n500 -B100 -c2 -z2 -r1899 -O70
 		       -m14 -gF -s6.8  -w1.0 -f.2 -n500 -B50 -c2 -x2 -y2 -z2 -O70
                        -m13 -gF -s5.9  -w1.0 -f.2 -n500 -B25 -c3 -x2 -y2 -z2 -O70</main_exec_args>
       <tags>dlsim.test1 dlsim.test5 dlsim.test6 dlsim.test6b dlsim.test7 dlsim.test7b dlsim.test10 dlsim.test10b dlsim.test11 dlsim.TM2_test1 dlsim.TM2_test1b</tags>
diff --git a/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml b/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml
index 971819ade587c7d578da052e43ab7cc7de55a8b6..43aef8c3222f7b14e9695162e6417cde78be9aba 100644
--- a/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml
+++ b/cmake_targets/autotests/testsuite_ue_noS1_TCL.xml
@@ -7,8 +7,8 @@
  <!-- <GitOAI5GRepo>git@gitlab.com:TCL_Communications/openairinterface5g.git</GitOAI5GRepo> -->
  <GitOpenair-cnRepo>https://gitlab.eurecom.fr/oai/openair-cn.git</GitOpenair-cnRepo> -->
  <!--<GitOAI5GRepoBranch>develop_integration_w15</GitOAI5GRepoBranch>-->
- <GitOAI5GRepoBranch>eNB_phy-test_fix_20MHz</GitOAI5GRepoBranch>
- <GitOAI5GHeadVersion>eNB_phy-test_fix_20MHz</GitOAI5GHeadVersion> -->
+ <GitOAI5GRepoBranch>develop</GitOAI5GRepoBranch>
+ <GitOAI5GHeadVersion>develop</GitOAI5GHeadVersion> -->
  <!-- <GitOAI5GHeadVersion>425b6fd525d9c4b0b3c2357926bbac5685e4b1e5</GitOAI5GHeadVersion> -->
  <!-- <GitOAI5GHeadVersion>23822ea203e00f2100fa41c7ee3084ec55b884fe</GitOAI5GHeadVersion> --> 
  <!-- <GitOAI5GHeadVersion></GitOAI5GHeadVersion>--> 
@@ -71,7 +71,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -96,6 +96,59 @@
             unit_of_meas = ""/> 
     </testCase> 
 
+<!-- ending with 3 TDD config3 TCs -->
+
+ <testCase id="030003" >
+    <class>lte-softmodem-noS1</class>
+    <desc></desc>
+    <eNB>TCT-Labo1</eNB>
+    <UE>TCT-Labo3</UE>
+    <TimeOut_cmd>300</TimeOut_cmd>
+    <eNB_working_dir>/tmp</eNB_working_dir> 
+    <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
+    <eNB_compile_prog_args>-c -w USRP --eNB --noS1</eNB_compile_prog_args>
+    <eNB_pre_exec>source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB</eNB_pre_exec>
+    <eNB_pre_exec_args></eNB_pre_exec_args>
+    <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
+    <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.25PRB.usrpb210.conf -W -m 0 --single-thread-disable --phy-test</eNB_main_exec_args>
+    <eNB_traffic_exec></eNB_traffic_exec>
+    <eNB_traffic_exec_args></eNB_traffic_exec_args>
+    <eNB_search_expr_true></eNB_search_expr_true>
+    <eNB_search_expr_false></eNB_search_expr_false>
+    <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
+
+    <UE_working_dir>/tmp</UE_working_dir>
+    <UE_config_file></UE_config_file>
+    <UE_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</UE_compile_prog>
+    <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
+    <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
+    <UE_pre_exec_args></UE_pre_exec_args>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -T -C2350000000 -r25 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec_args></UE_main_exec_args>
+    <UE_traffic_exec></UE_traffic_exec>
+    <UE_traffic_exec_args></UE_traffic_exec_args>
+    <UE_search_expr_true></UE_search_expr_true>
+    <UE_search_expr_false></UE_search_expr_false>
+    <UE_terminate_missing_procs>False</UE_terminate_missing_procs>
+    <UE_metric  id="UE_DLSCH_BITRATE" 
+        description="UE downlink physical throughput"  
+        regex='(UE_DLSCH_BITRATE) =\s+(\d+\.\d+) kbps.+frame = (\d+)\)' 
+        unit_of_meas = "kbps"
+        pass_fail_stat = "mean_value"
+        min_limit = "300"/>
+    <tags>UE_USRP.NOS1.PHYTEST_PERF.BAND40.5MHZ.MCS00</tags>
+    <nruns>1</nruns><max_ntries>1</max_ntries>
+    <UE_metric  id="UE_FREQ_OFFSET" 
+            description="UE downlink frequency channel offset"  
+            regex='(UE_FREQ_OFFSET) =\s+(-?\d+) Hz.+frame = (\d+)\)' 
+            unit_of_meas = "Hz"/> 
+    <UE_metric  id="UE_RX_OFFSET" 
+            description="UE downlink rx sample offset"  
+            regex='(UE_RX_OFFSET) =\s+(-?\d+).+frame = (\d+)\)' 
+            unit_of_meas = ""/> 
+    </testCase> 
+
+
  <testCase id="030001" >
     <class>lte-softmodem-noS1</class>
     <desc></desc>
@@ -173,7 +226,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -280,7 +333,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -382,7 +435,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -484,7 +537,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -586,7 +639,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -688,7 +741,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -790,7 +843,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -893,7 +946,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -995,7 +1048,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1097,7 +1150,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1199,7 +1252,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1301,7 +1354,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1404,7 +1457,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1506,7 +1559,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1608,7 +1661,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1762,7 +1815,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1865,7 +1918,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -1968,7 +2021,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec></UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2074,7 +2127,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2098,6 +2151,54 @@
     </testCase> 
 
 
+  <testCase id="036133" >
+	<class>lte-softmodem-noS1</class>
+	<desc></desc>
+	<eNB>TCT-Labo1</eNB>
+	<UE>TCT-Labo3</UE>
+	<TimeOut_cmd>300</TimeOut_cmd>
+	<eNB_working_dir>/tmp</eNB_working_dir>	
+	<eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
+	<eNB_compile_prog_args>-c -w USRP --eNB --noS1 </eNB_compile_prog_args>
+	<eNB_pre_exec>source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB</eNB_pre_exec>
+	<eNB_pre_exec_args></eNB_pre_exec_args>
+	<eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
+	<eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.50PRB.usrpb210.conf -W -m 28 </eNB_main_exec_args>
+	<eNB_traffic_exec>sleep 30;iperf -c 10.0.1.9 -i 1 -u -b 18M</eNB_traffic_exec>
+	<eNB_traffic_exec_args></eNB_traffic_exec_args>
+	<eNB_search_expr_true></eNB_search_expr_true>
+	<eNB_search_expr_false></eNB_search_expr_false>
+	<eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
+
+	<UE_working_dir>/tmp</UE_working_dir>
+	<UE_config_file></UE_config_file>
+	<UE_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</UE_compile_prog>
+	<UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
+	<UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
+	<UE_pre_exec_args></UE_pre_exec_args>
+	<UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -T -C2350000000 -r50 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100  -S</UE_main_exec>
+	<UE_main_exec_args></UE_main_exec_args>
+	<UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
+	<UE_traffic_exec_args></UE_traffic_exec_args>
+	<UE_search_expr_true>200</UE_search_expr_true>
+	<UE_search_expr_false></UE_search_expr_false>
+	<UE_terminate_missing_procs>False</UE_terminate_missing_procs>
+	<tags>UE_USRP.NOS1.DATA_IPERF.BAND40.10MHZ.MCS28</tags>
+	<nruns>3</nruns><max_ntries>6</max_ntries>
+	<UE_metric  id="UE_DLSCH_BITRATE" 
+	    description="UE downlink physical throughput"  
+	    regex='(UE_DLSCH_BITRATE) =\s+(\d+\.\d+) kbps.+frame = (\d+)\)' 
+	    unit_of_meas = "kbps"/> 
+	<UE_metric  id="UE_FREQ_OFFSET" 
+	    description="UE downlink frequency channel offset"  
+	    regex='(UE_FREQ_OFFSET) =\s+(-?\d+) Hz.+frame = (\d+)\)' 
+	    unit_of_meas = "Hz"/> 
+	<UE_metric  id="UE_RX_OFFSET" 
+	    description="UE downlink rx sample offset"  
+	    regex='(UE_RX_OFFSET) =\s+(-?\d+).+frame = (\d+)\)' 
+	unit_of_meas = ""/> 
+  </testCase> 
+
 
 
 
@@ -2441,7 +2542,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2518,7 +2619,8 @@
     <!-- USRP Band 7 5MHz SISO Iperf downlink performances -->
     <!-- 030030 030930 031030 031630 031730 031930 032730 032830 -->
 
-    <testCase id="030030" >
+
+    <testCase id="030003" >
         <class>lte-softmodem-noS1</class>
         <desc></desc>
         <eNB>TCT-Labo1</eNB>
@@ -2544,7 +2646,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2568,6 +2670,54 @@
     </testCase> 
 
 
+    <testCase id="030033" >
+        <class>lte-softmodem-noS1</class>
+        <desc></desc>
+        <eNB>TCT-Labo1</eNB>
+        <UE>TCT-Labo3</UE>
+        <TimeOut_cmd>300</TimeOut_cmd>
+        <eNB_working_dir>/tmp</eNB_working_dir>
+        <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
+        <eNB_compile_prog_args>-c -w USRP --eNB --noS1</eNB_compile_prog_args>
+        <eNB_pre_exec>source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB</eNB_pre_exec>
+        <eNB_pre_exec_args></eNB_pre_exec_args>
+        <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
+        <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.25PRB.usrpb210.conf -W -m 0 </eNB_main_exec_args>
+        <eNB_traffic_exec>sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 300K</eNB_traffic_exec>
+        <eNB_traffic_exec_args></eNB_traffic_exec_args>
+        <eNB_search_expr_true></eNB_search_expr_true>
+        <eNB_search_expr_false></eNB_search_expr_false>
+        <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
+
+        <UE_working_dir>/tmp</UE_working_dir>
+        <UE_config_file></UE_config_file>
+        <UE_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</UE_compile_prog>
+        <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
+        <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
+        <UE_pre_exec_args></UE_pre_exec_args>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -T -C2350000000 -r25 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100  -S</UE_main_exec>
+        <UE_main_exec_args></UE_main_exec_args>
+        <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
+        <UE_traffic_exec_args></UE_traffic_exec_args>
+        <UE_search_expr_true>200</UE_search_expr_true>
+        <UE_search_expr_false></UE_search_expr_false>
+        <UE_terminate_missing_procs>False</UE_terminate_missing_procs>
+        <tags>UE_USRP.NOS1.DATA_IPERF.BAND40.5MHZ.MCS00</tags>
+        <nruns>3</nruns><max_ntries>6</max_ntries>
+        <UE_metric  id="UE_DLSCH_BITRATE" 
+                description="UE downlink physical throughput"  
+                regex='(UE_DLSCH_BITRATE) =\s+(\d+\.\d+) kbps.+frame = (\d+)\)' 
+                unit_of_meas = "kbps"/> 
+        <UE_metric  id="UE_FREQ_OFFSET" 
+                description="UE downlink frequency channel offset"  
+                regex='(UE_FREQ_OFFSET) =\s+(-?\d+) Hz.+frame = (\d+)\)' 
+                unit_of_meas = "Hz"/> 
+        <UE_metric  id="UE_RX_OFFSET" 
+                description="UE downlink rx sample offset"  
+                regex='(UE_RX_OFFSET) =\s+(-?\d+).+frame = (\d+)\)' 
+                unit_of_meas = ""/> 
+    </testCase> 
+
 
     <testCase id="030930" >
         <class>lte-softmodem-noS1</class>
@@ -2595,7 +2745,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100 -S</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2645,7 +2795,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2696,7 +2846,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2719,6 +2869,54 @@
             unit_of_meas = ""/> 
     </testCase> 
     
+
+    <testCase id="031633" >
+        <class>lte-softmodem-noS1</class>
+        <desc></desc>
+        <eNB>TCT-Labo1</eNB>
+        <UE>TCT-Labo3</UE>
+        <TimeOut_cmd>300</TimeOut_cmd>
+        <eNB_working_dir>/tmp</eNB_working_dir>
+        <eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
+        <eNB_compile_prog_args>-c -w USRP --eNB --noS1</eNB_compile_prog_args>
+        <eNB_pre_exec>source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB</eNB_pre_exec>
+        <eNB_pre_exec_args></eNB_pre_exec_args>
+        <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
+        <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.25PRB.usrpb210.conf -W -m 0 </eNB_main_exec_args>
+        <eNB_traffic_exec>sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 1200K</eNB_traffic_exec>
+        <eNB_traffic_exec_args></eNB_traffic_exec_args>
+        <eNB_search_expr_true></eNB_search_expr_true>
+        <eNB_search_expr_false></eNB_search_expr_false>
+        <eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
+
+        <UE_working_dir>/tmp</UE_working_dir>
+        <UE_config_file></UE_config_file>
+        <UE_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</UE_compile_prog>
+        <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
+        <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
+        <UE_pre_exec_args></UE_pre_exec_args>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -T -C2350000000 -r25 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100  -S</UE_main_exec>
+        <UE_main_exec_args></UE_main_exec_args>
+        <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
+        <UE_traffic_exec_args></UE_traffic_exec_args>
+        <UE_search_expr_true>200</UE_search_expr_true>
+        <UE_search_expr_false></UE_search_expr_false>
+        <UE_terminate_missing_procs>False</UE_terminate_missing_procs>
+        <tags>UE_USRP.NOS1.DATA_IPERF.BAND40.5MHZ.MCS16</tags>
+        <nruns>3</nruns><max_ntries>6</max_ntries>
+        <UE_metric  id="UE_DLSCH_BITRATE" 
+                description="UE downlink physical throughput"  
+                regex='(UE_DLSCH_BITRATE) =\s+(\d+\.\d+) kbps.+frame = (\d+)\)' 
+                unit_of_meas = "kbps"/> 
+        <UE_metric  id="UE_FREQ_OFFSET" 
+                description="UE downlink frequency channel offset"  
+                regex='(UE_FREQ_OFFSET) =\s+(-?\d+) Hz.+frame = (\d+)\)' 
+                unit_of_meas = "Hz"/> 
+        <UE_metric  id="UE_RX_OFFSET" 
+                description="UE downlink rx sample offset"  
+                regex='(UE_RX_OFFSET) =\s+(-?\d+).+frame = (\d+)\)' 
+                unit_of_meas = ""/> 
+    </testCase> 
     
  <testCase id="031730" >
     <class>lte-softmodem-noS1</class>
@@ -2746,7 +2944,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2796,7 +2994,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+    <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2846,7 +3044,7 @@
     <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
     <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
     <UE_pre_exec_args></UE_pre_exec_args>
-    <UE_main_exec>sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S </UE_main_exec>
+    <UE_main_exec>sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S </UE_main_exec>
     <UE_main_exec_args></UE_main_exec_args>
     <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
     <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2905,7 +3103,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec></UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -2956,7 +3154,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S --phy-test</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec></UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3008,7 +3206,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S </UE_main_exec>
+        <UE_main_exec>sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100 -S </UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3037,6 +3235,55 @@
     </testCase> 
 
 
+     <testCase id="032833" >
+	<class>lte-softmodem-noS1</class>
+	<desc></desc>
+	<eNB>TCT-Labo1</eNB>
+	<UE>TCT-Labo3</UE>
+	<TimeOut_cmd>300</TimeOut_cmd>
+	<eNB_working_dir>/tmp</eNB_working_dir>
+	<eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
+	<eNB_compile_prog_args>-c -w USRP --eNB --noS1 </eNB_compile_prog_args>
+	<eNB_pre_exec>source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB</eNB_pre_exec>
+	<eNB_pre_exec_args></eNB_pre_exec_args>
+	<eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
+	<eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.25PRB.usrpb210.conf -W -m 28 </eNB_main_exec_args>
+	<eNB_traffic_exec>sleep 30;iperf -c 10.0.1.9 -i 1 -u -b 8220K</eNB_traffic_exec>
+	<eNB_traffic_exec_args></eNB_traffic_exec_args>
+	<eNB_search_expr_true></eNB_search_expr_true>
+	<eNB_search_expr_false></eNB_search_expr_false>
+	<eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
+
+	<UE_working_dir>/tmp</UE_working_dir>
+	<UE_config_file></UE_config_file>
+	<UE_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</UE_compile_prog>
+	<UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
+	<UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
+	<UE_pre_exec_args></UE_pre_exec_args>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -T -C2350000000 -r25 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100  -S</UE_main_exec>
+	<UE_main_exec_args></UE_main_exec_args>
+	<UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
+	<UE_traffic_exec_args></UE_traffic_exec_args>
+	<UE_search_expr_true>200</UE_search_expr_true>
+	<UE_search_expr_false></UE_search_expr_false>
+	<UE_terminate_missing_procs>False</UE_terminate_missing_procs>
+        <tags>UE_USRP.NOS1.DATA_IPERF.BAND40.5MHZ.MCS28</tags>
+	<nruns>3</nruns><max_ntries>6</max_ntries>
+	<UE_metric  id="UE_DLSCH_BITRATE" 
+	    description="UE downlink physical throughput"  
+	    regex='(UE_DLSCH_BITRATE) =\s+(\d+\.\d+) kbps.+frame = (\d+)\)' 
+	    unit_of_meas = "kbps"/> 
+	<UE_metric  id="UE_FREQ_OFFSET" 
+	    description="UE downlink frequency channel offset"  
+	    regex='(UE_FREQ_OFFSET) =\s+(-?\d+) Hz.+frame = (\d+)\)' 
+	    unit_of_meas = "Hz"/> 
+	<UE_metric  id="UE_RX_OFFSET" 
+	    description="UE downlink rx sample offset"  
+	    regex='(UE_RX_OFFSET) =\s+(-?\d+).+frame = (\d+)\)' 
+    unit_of_meas = ""/> 
+    </testCase> 
+
+
     <testCase id="032840" >
         <class>lte-softmodem-noS1</class>
         <desc></desc>
@@ -3066,7 +3313,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3116,7 +3363,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100 -S </UE_main_exec>
+        <UE_main_exec>sleep 5; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2660000000 -r25 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100 -S </UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3171,7 +3418,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 85 -A 24 --ue-rxgain 100  -S</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2685000000 -r50 --ue-scan-carrier --ue-txgain 80 -A 24 --ue-rxgain 100  -S</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3228,7 +3475,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100 -S --phy-test</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec></UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3254,6 +3501,9 @@
     </testCase> 
 
 
+
+
+
  <testCase id="036600" >
         <class>lte-softmodem-noS1</class>
         <desc></desc>
@@ -3280,7 +3530,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100 -S --phy-test</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec></UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3332,7 +3582,7 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 -S --phy-test</UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100 -S --phy-test</UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec></UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
@@ -3373,7 +3623,7 @@
         <eNB_pre_exec_args></eNB_pre_exec_args>
         <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
         <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 0</eNB_main_exec_args>
-        <eNB_traffic_exec>sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 2M</eNB_traffic_exec> 
+        <eNB_traffic_exec>sleep 60;iperf -c 10.0.1.9 -i 1 -u -b 2M</eNB_traffic_exec> 
         <eNB_traffic_exec_args></eNB_traffic_exec_args>
         <eNB_search_expr_true></eNB_search_expr_true>
         <eNB_search_expr_false></eNB_search_expr_false>
@@ -3385,11 +3635,11 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 </UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100 </UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
-        <UE_search_expr_true>600</UE_search_expr_true>
+        <UE_search_expr_true>200</UE_search_expr_true>
         <UE_search_expr_false></UE_search_expr_false>
         <UE_terminate_missing_procs>False</UE_terminate_missing_procs>
         <UE_metric  id="UE_DLSCH_BITRATE" 
@@ -3423,7 +3673,7 @@
         <eNB_pre_exec_args></eNB_pre_exec_args>
         <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
         <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 18</eNB_main_exec_args>
-        <eNB_traffic_exec>sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 24M</eNB_traffic_exec> 
+        <eNB_traffic_exec>sleep 60;iperf -c 10.0.1.9 -i 1 -u -b 24M</eNB_traffic_exec> 
         <eNB_traffic_exec_args></eNB_traffic_exec_args>
         <eNB_search_expr_true></eNB_search_expr_true>
         <eNB_search_expr_false></eNB_search_expr_false>
@@ -3435,11 +3685,11 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 </UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100 </UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
-        <UE_search_expr_true>600</UE_search_expr_true>
+        <UE_search_expr_true>200</UE_search_expr_true>
         <UE_search_expr_false></UE_search_expr_false>
         <UE_terminate_missing_procs>False</UE_terminate_missing_procs>
         <UE_metric  id="UE_DLSCH_BITRATE" 
@@ -3474,7 +3724,7 @@
         <eNB_pre_exec_args></eNB_pre_exec_args>
         <eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
         <eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpb210.conf -m 28</eNB_main_exec_args>
-        <eNB_traffic_exec>sleep 80;iperf -c 10.0.1.9 -i 1 -u -b 55M</eNB_traffic_exec> <!-- PHY max TP 73.334Mbps -> 75% = 55Mbps -->
+        <eNB_traffic_exec>sleep 60;iperf -c 10.0.1.9 -i 1 -u -b 55M</eNB_traffic_exec> <!-- PHY max TP 73.334Mbps -> 75% = 55Mbps -->
         <eNB_traffic_exec_args></eNB_traffic_exec_args>
         <eNB_search_expr_true></eNB_search_expr_true>
         <eNB_search_expr_false></eNB_search_expr_false>
@@ -3486,11 +3736,11 @@
         <UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
         <UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
         <UE_pre_exec_args></UE_pre_exec_args>
-        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 85 --ue-rxgain 100 </UE_main_exec>
+        <UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -C2680000000 -r100 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100 </UE_main_exec>
         <UE_main_exec_args></UE_main_exec_args>
         <UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
         <UE_traffic_exec_args></UE_traffic_exec_args>
-        <UE_search_expr_true>600</UE_search_expr_true>
+        <UE_search_expr_true>200</UE_search_expr_true>
         <UE_search_expr_false></UE_search_expr_false>
         <UE_terminate_missing_procs>False</UE_terminate_missing_procs>
         <UE_metric  id="UE_DLSCH_BITRATE" 
@@ -3509,7 +3759,53 @@
 	<nruns>3</nruns><max_ntries>6</max_ntries>
     </testCase> 
 
-
+  <testCase id="039433" >
+	<class>lte-softmodem-noS1</class>
+	<desc></desc>
+	<eNB>TCT-Labo1</eNB>
+	<UE>TCT-Labo3</UE>
+	<TimeOut_cmd>300</TimeOut_cmd>
+	<eNB_working_dir>/tmp</eNB_working_dir>	
+	<eNB_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</eNB_compile_prog>
+	<eNB_compile_prog_args>-c -w USRP --eNB --noS1 </eNB_compile_prog_args>
+	<eNB_pre_exec>source $OPENAIR_DIR/cmake_targets/tools/init_nas_nos1 eNB</eNB_pre_exec>
+	<eNB_pre_exec_args></eNB_pre_exec_args>
+	<eNB_main_exec>$OPENAIR_DIR/cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1</eNB_main_exec>
+	<eNB_main_exec_args> -O $OPENAIR_DIR/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.100PRB.usrpb210.conf -W -m 28 </eNB_main_exec_args>
+	<eNB_traffic_exec>sleep 30;iperf -c 10.0.1.9 -i 1 -u -b 33M</eNB_traffic_exec>
+	<eNB_traffic_exec_args></eNB_traffic_exec_args>
+	<eNB_search_expr_true></eNB_search_expr_true>
+	<eNB_search_expr_false></eNB_search_expr_false>
+	<eNB_terminate_missing_procs>False</eNB_terminate_missing_procs>
+
+	<UE_working_dir>/tmp</UE_working_dir>
+	<UE_config_file></UE_config_file>
+	<UE_compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</UE_compile_prog>
+	<UE_compile_prog_args>-c --UE -w USRP --noS1 --eNB --ue-autotest-trace </UE_compile_prog_args>
+	<UE_pre_exec>source ./targets/bin/init_nas_nos1 UE</UE_pre_exec>
+	<UE_pre_exec_args></UE_pre_exec_args>
+	<UE_main_exec>sleep 20; ./cmake_targets/autotests/tools/run_gdb ./cmake_targets/lte_noS1_build_oai/build/lte-softmodem-nos1 -U -T -C2350000000 -r100 --ue-scan-carrier --ue-txgain 80 --ue-rxgain 100  -S</UE_main_exec>
+	<UE_main_exec_args></UE_main_exec_args>
+	<UE_traffic_exec>iperf -s -i 1 -u</UE_traffic_exec>
+	<UE_traffic_exec_args></UE_traffic_exec_args>
+	<UE_search_expr_true>200</UE_search_expr_true>
+	<UE_search_expr_false></UE_search_expr_false>
+	<UE_terminate_missing_procs>False</UE_terminate_missing_procs>
+	<tags>UE_USRP.NOS1.DATA_IPERF.BAND40.20MHZ.MCS28</tags>
+	<nruns>3</nruns><max_ntries>6</max_ntries>
+	<UE_metric  id="UE_DLSCH_BITRATE" 
+	    description="UE downlink physical throughput"  
+	    regex='(UE_DLSCH_BITRATE) =\s+(\d+\.\d+) kbps.+frame = (\d+)\)' 
+	    unit_of_meas = "kbps"/> 
+	<UE_metric  id="UE_FREQ_OFFSET" 
+	    description="UE downlink frequency channel offset"  
+	    regex='(UE_FREQ_OFFSET) =\s+(-?\d+) Hz.+frame = (\d+)\)' 
+	    unit_of_meas = "Hz"/> 
+	<UE_metric  id="UE_RX_OFFSET" 
+	    description="UE downlink rx sample offset"  
+	    regex='(UE_RX_OFFSET) =\s+(-?\d+).+frame = (\d+)\)' 
+	unit_of_meas = ""/> 
+  </testCase> 
 
 
   </testCaseList>
diff --git a/cmake_targets/autotests/v2/actions/alu_hss.bash b/cmake_targets/autotests/v2/actions/alu_hss.bash
index be32fe9eb08d8d7c75292dcef1c35ad422ad17ec..1fb719c25b354b6ffb83b46c648bb5d85dd8be99 100644
--- a/cmake_targets/autotests/v2/actions/alu_hss.bash
+++ b/cmake_targets/autotests/v2/actions/alu_hss.bash
@@ -1,4 +1,5 @@
 sudo rmmod nasmesh || true
 sudo rmmod ue_ip || true
 sudo /opt/ltebox/tools/stop_ltebox || true
+sudo killall -9 hss_sim || true
 sudo /opt/hss_sim0609/starthss_real
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf
index c25b954e1ab532de744b65bed211876a86cabd7e..e09e068c63fed4af59d20935eae3fb6f9b0f5155 100644
--- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.10MHz.conf
@@ -47,7 +47,7 @@ eNBs =
         prach_zero_correlation  			      = 1;
         prach_freq_offset       			      = 2;
         pucch_delta_shift       			      = 1;
-        pucch_nRB_CQI           			      = 1;
+        pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
         pucch_n1_AN             			      = 32;
         pdsch_referenceSignalPower 			      = -24;
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf
index 0773f9c267fd5e2675ce54c7896db50bce8b74cc..1f992daba20cdee1a33e1939db2686bb6bf95e0a 100644
--- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.20MHz.conf
@@ -47,7 +47,7 @@ eNBs =
         prach_zero_correlation  			      = 1;
         prach_freq_offset       			      = 2;
         pucch_delta_shift       			      = 1;
-        pucch_nRB_CQI           			      = 1;
+        pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
         pucch_n1_AN             			      = 32;
         pdsch_referenceSignalPower 			      = -24;
diff --git a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf
index 024be3b77535bde64d8c6d346509cf8e6948de6b..bb7df8b72d654171fb088bc8ddfe95d6b9b64883 100644
--- a/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band38.tm1.usrpb210.tdd.5MHz.conf
@@ -47,7 +47,7 @@ eNBs =
         prach_zero_correlation  			      = 1;
         prach_freq_offset       			      = 2;
         pucch_delta_shift       			      = 1;
-        pucch_nRB_CQI           			      = 1;
+        pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
         pucch_n1_AN             			      = 32;
         pdsch_referenceSignalPower 			      = -24;
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf
index 3b15799eb7fe0b2524c24ff68d3a995d22eb1c2c..ff97827b579a4d97fe5b0a593b14247eb349c0fb 100644
--- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.10MHz.conf
@@ -47,7 +47,7 @@ eNBs =
         prach_zero_correlation  			      = 1;
         prach_freq_offset       			      = 2;
         pucch_delta_shift       			      = 1;
-        pucch_nRB_CQI           			      = 1;
+        pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
         pucch_n1_AN             			      = 32;
         pdsch_referenceSignalPower 			      = -24;
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf
index 869c7f05f1bb3006c3f8c9b11ec10d7ab7f77ffa..ebb9e417e7be717f810692a4a5ac42e564cbc58a 100644
--- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.20MHz.conf
@@ -47,7 +47,7 @@ eNBs =
         prach_zero_correlation  			      = 1;
         prach_freq_offset       			      = 2;
         pucch_delta_shift       			      = 1;
-        pucch_nRB_CQI           			      = 1;
+        pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
         pucch_n1_AN             			      = 32;
         pdsch_referenceSignalPower 			      = -24;
diff --git a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf
index d3c1a5354a377a8c570c76735104919c2db32ae1..4e8910276639267344316f765e9f9f20f50e1a0c 100644
--- a/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf
+++ b/cmake_targets/autotests/v2/config/enb.band7.tm1.usrpb210.fdd.5MHz.conf
@@ -47,7 +47,7 @@ eNBs =
         prach_zero_correlation  			      = 1;
         prach_freq_offset       			      = 2;
         pucch_delta_shift       			      = 1;
-        pucch_nRB_CQI           			      = 1;
+        pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
         pucch_n1_AN             			      = 32;
         pdsch_referenceSignalPower 			      = -24;
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf
index 81eed5f4b10946477df799fd0820e51ea2ffb71a..beaf5ae0f1405da2c8647f8970c7971b3a99a2a2 100644
--- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf
+++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.10MHz.conf
@@ -47,7 +47,7 @@ eNBs =
       prach_zero_correlation  			      = 1;
       prach_freq_offset       			      = 2;
       pucch_delta_shift       			      = 1;
-      pucch_nRB_CQI           			      = 1;
+      pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
       pucch_n1_AN             			      = 32;
       pdsch_referenceSignalPower 			      = -29;
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf
index 4b4190f8ce980cf107f62bd76eab8a9ca9ecf1da..b0efe66e14189d82f486524396309de98bd4e9fe 100644
--- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf
+++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.20MHz.conf
@@ -47,7 +47,7 @@ eNBs =
       prach_zero_correlation  			      = 1;
       prach_freq_offset       			      = 2;
       pucch_delta_shift       			      = 1;
-      pucch_nRB_CQI           			      = 1;
+      pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
       pucch_n1_AN             			      = 32;
       pdsch_referenceSignalPower 			      = -29;
diff --git a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf
index 99b9a66226f0b1d5bc821f632d59636e604fc4f0..1b33c7b3c216e7ef2e8573806db0176461ffa93f 100644
--- a/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf
+++ b/cmake_targets/autotests/v2/config/rcc.band7.tm1.if4p5.5MHz.conf
@@ -47,7 +47,7 @@ eNBs =
       prach_zero_correlation  			      = 1;
       prach_freq_offset       			      = 2;
       pucch_delta_shift       			      = 1;
-      pucch_nRB_CQI           			      = 1;
+      pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
       pucch_n1_AN             			      = 32;
       pdsch_referenceSignalPower 			      = -29;
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf
index 4cc40b6d84139da98b1250b62ba480bce60406f0..dc64a69c00cbf028ccbefc73e30b45096ed28851 100644
--- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf
+++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.10MHz.udp.usrpb210.conf
@@ -47,7 +47,7 @@ eNBs =
       prach_zero_correlation  			      = 1;
       prach_freq_offset       			      = 2;
       pucch_delta_shift       			      = 1;
-      pucch_nRB_CQI           			      = 1;
+      pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
       pucch_n1_AN             			      = 32;
       pdsch_referenceSignalPower 			      = -29;
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf
index 787cedb18d9972ef05e3d5d0f75074977cfc92e5..c93ce24d0841f73f64b3cf5f0ebbbb28a98c9818 100644
--- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf
+++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.20MHz.udp.usrpb210.conf
@@ -47,7 +47,7 @@ eNBs =
       prach_zero_correlation  			      = 1;
       prach_freq_offset       			      = 2;
       pucch_delta_shift       			      = 1;
-      pucch_nRB_CQI           			      = 1;
+      pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
       pucch_n1_AN             			      = 32;
       pdsch_referenceSignalPower 			      = -29;
diff --git a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf
index d9d46bf9446cef80a3fe8dd0a3c1eaa47d245972..57f7ef83b92e484d13eb4234982dc807ffafeccc 100644
--- a/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf
+++ b/cmake_targets/autotests/v2/config/rru.band7.tm1.if4p5.5MHz.udp.usrpb210.conf
@@ -47,7 +47,7 @@ eNBs =
       prach_zero_correlation  			      = 1;
       prach_freq_offset       			      = 2;
       pucch_delta_shift       			      = 1;
-      pucch_nRB_CQI           			      = 1;
+      pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
       pucch_n1_AN             			      = 32;
       pdsch_referenceSignalPower 			      = -29;
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 8ed9726e0fc5c7aec937ecae7e771da7c4bb2c83..7b612c8ef3ed7169ab0c9e15cd79fcd5df81c317 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -61,9 +61,12 @@ BUILD_DOXYGEN=0
 T_TRACER="False"
 DISABLE_HARDWARE_DEPENDENCY="False"
 CMAKE_BUILD_TYPE=""
+CMAKE_CMD="$CMAKE"
 UE_AUTOTEST_TRACE="False"
+UE_DEBUG_TRACE="False"
+UE_TIMING_TRACE="False"
+DISABLE_LOG_X="False"
 BUILD_ECLIPSE=0
-CMAKE_CMD='cmake'
 trap handle_ctrl_c INT
 
 function print_help() {
@@ -147,6 +150,12 @@ Options
    Disable HW dependency during installation
 --ue-autotest-trace
     Enable specific traces for UE autotest framework
+--ue-trace
+    Enable traces for UE debugging
+--ue-timing
+    Enable traces for timing
+--disable-log
+   Disable all LOG_* macros
 --build-eclipse
    Build eclipse project files. Paths are auto corrected by fixprj.sh
 Usage (first build):
@@ -316,6 +325,18 @@ function main() {
             UE_AUTOTEST_TRACE="True"
             echo_info "Enabling autotest specific trace for UE"
             shift 1;;
+        --ue-trace)
+            UE_DEBUG_TRACE="True"
+            echo_info "Enabling UE trace for debug"
+            shift 1;;
+        --ue-timing)
+            UE_TIMING_TRACE="True"
+            echo_info "Enabling UE timing trace"
+            shift 1;;
+        --disable-log)
+            DISABLE_LOG_X="True"
+            echo_info "Disabling all LOG_* traces"
+            shift 1;;
         --uhd-images-dir)
             UHD_IMAGES_DIR=$2
             echo_info "Downloading UHD images in the indicated location"
@@ -448,6 +469,11 @@ function main() {
         flash_firmware_bladerf
       fi
     fi
+    if [ "$FLEXRAN_AGENT" == "1" ] ; then
+      echo_info "installing protobuf/protobuf-c for flexran agent support"
+      install_protobuf_from_source
+      install_protobuf_c_from_source
+    fi
   fi
 
   if [ "$INSTALL_OPTIONAL" = "1" ] ; then
@@ -507,6 +533,9 @@ function main() {
     echo "set (CPU_AFFINITY \"${CPU_AFFINITY_FLAG_USER}\" )"      >>$cmake_file
     echo "set ( T_TRACER $T_TRACER )"              >>  $cmake_file
     echo "set (UE_AUTOTEST_TRACE $UE_AUTOTEST_TRACE)"        >>  $cmake_file
+    echo "set (UE_DEBUG_TRACE $UE_DEBUG_TRACE)"        >>  $cmake_file
+    echo "set (UE_TIMING_TRACE $UE_TIMING_TRACE)"        >>  $cmake_file
+    echo "set (DISABLE_LOG_X $DISABLE_LOG_X)"        >>  $cmake_file
     if [ "$UE" = 1 -a "$NOS1" = "0" ] ; then
      echo_info "Compiling UE S1 build : enabling Linux and NETLINK"
      echo "set (LINUX True )"              >>  $cmake_file
diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt
index 5ed4d93d800250f7ed1eae511e6615782e5cd46e..ab718a8503d3a1339d0ba3996eae2e082458319d 100644
--- a/cmake_targets/lte-simulators/CMakeLists.txt
+++ b/cmake_targets/lte-simulators/CMakeLists.txt
@@ -3,7 +3,7 @@ set(PACKAGE_NAME "unitary_tests_simulators")
 set(PHYSIM True)
 set(RF_BOARD None)
 set(XFORMS True)
-
+set(ENABLE_ITTI False)
 set(DEBUG_PHY False)
 set(MU_RECIEVER False)
 set(RANDOM_BF False)
diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper
index a57040449c7223d191be4df7c928ed036b4e5d62..f6c51944d2a1be7b9c467e4f91fe63caeb6a47aa 100755
--- a/cmake_targets/tools/build_helper
+++ b/cmake_targets/tools/build_helper
@@ -24,6 +24,22 @@
 # authors Laurent Thomas, Lionel GAUTHIER
 #
 #######################################
+if [ ! -f /etc/os-release ]; then
+  echo "No /etc/os-release file found. You're likely on an unsupported distro."
+  exit -1
+fi
+OS_DISTRO=$(grep "^ID=" /etc/os-release | sed "s/ID=//" | sed "s/\"//g")
+OS_RELEASE=$(grep "^VERSION_ID=" /etc/os-release | sed "s/VERSION_ID=//" | sed "s/\"//g")
+case "$OS_DISTRO" in
+  fedora) OS_BASEDISTRO="fedora"; INSTALLER="dnf"; CMAKE="cmake" ;;
+  rhel)   OS_BASEDISTRO="fedora"; INSTALLER="yum"; CMAKE="cmake3" ;;
+  centos) OS_BASEDISTRO="fedora"; INSTALLER="yum"; CMAKE="cmake3" ;;
+  debian) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
+  ubuntu) OS_BASEDISTRO="debian"; INSTALLER="apt-get"; CMAKE="cmake" ;;
+esac
+KERNEL_VERSION=$(uname -r | cut -d '.' -f1)
+KERNEL_MAJOR=$(uname -r | cut -d '.' -f2)
+
 SUDO='sudo -E'
 
 ###############################
@@ -66,12 +82,11 @@ echo_info()    { cecho "$*" $blue         ;}
 # If we can't check the distribution, it returns "Unknown"
 # This function return always true as exit code by design
 # Examples:
-#   Ubuntu16.04
-#   Debian8.5
+#   ubuntu16.04
+#   debian8.5
 get_distribution_release() {
-    local distributor
-    if distributor=$(lsb_release -si 2>/dev/null) ; then
-        echo $distributor$(lsb_release -sr)
+    if [[ ! -z "$OS_DISTRO$OS_RELEASE" ]]; then
+        echo "$OS_DISTRO$OS_RELEASE"
     else
         echo Unknown
     fi
@@ -80,8 +95,11 @@ get_distribution_release() {
 check_supported_distribution() {
     local distribution=$(get_distribution_release)
     case "$distribution" in
-        "Ubuntu16.04") return 0 ;;
-        "Ubuntu14.04") return 0 ;;
+        "ubuntu16.04") return 0 ;;
+        "ubuntu14.04") return 0 ;;
+        "fedora24")    return 0 ;;
+        "rhel7")       return 0 ;;
+        "centos7")     return 0 ;;
     esac
     return 1
 }
@@ -184,10 +202,14 @@ install_protobuf_from_source(){
     (
     cd /tmp
     echo "Downloading protobuf"
-    rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
-    wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
-    tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner 
-    cd protobuf-2.6.1/
+    #rm -rf /tmp/protobuf-2.6.1.tar.gz* /tmp/protobuf-2.6.1
+    #wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
+    #tar -xzvf protobuf-2.6.1.tar.gz --owner $USER --group $USER --no-same-owner
+    #cd protobuf-2.6.1/
+    rm -rf /tmp/protobuf-cpp-3.3.0.tar.gz* /tmp/protobuf-3.3.0
+    wget https://github.com/google/protobuf/releases/download/v3.3.0/protobuf-cpp-3.3.0.tar.gz
+    tar -xzvf protobuf-cpp-3.3.0.tar.gz --owner $USER --group $USER --no-same-owner
+    cd protobuf-3.3.0/
     ./configure
     echo "Compiling protobuf"
     make -j`nproc`
@@ -200,6 +222,9 @@ install_protobuf_c_from_source(){
     protobuf_c_install_log=$OPENAIR_DIR/cmake_targets/log/protobuf_c_install_log.txt
     echo_info "\nInstalling Google Protobuf_C from sources. The log file for Protobuf_C installation is here: $protobuf_c_install_log "
     (
+    if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
+        export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
+    fi
     cd /tmp
     echo "Downloading protobuf-c"
     rm -rf /tmp/protobuf-c
@@ -214,7 +239,29 @@ install_protobuf_c_from_source(){
     ) >& $protobuf_c_install_log
 }
 
+install_usrp_uhd_driver_from_source(){
+    uhd_install_log=$OPENAIR_DIR/cmake_targets/log/uhd_install_log.txt
+    echo_info "\nInstalling UHD driver from sources. The log file for UHD driver installation is here: $uhd_install_log "
+    (
+    cd /tmp
+    echo "Downloading UHD driver"
+    rm -rf /tmp/uhd
+    git clone git://github.com/EttusResearch/uhd.git
+    cd uhd
+    git checkout tags/release_003_010_001_001
+    mkdir -p host/build
+    cd host/build
+    $CMAKE ../
+    echo "Compiling UHD"
+    make
+    make test
+    $SUDO make install
+    $SUDO ldconfig
+    ) >& $uhd_install_log
+}
+
 check_install_usrp_uhd_driver(){
+    if [[ "$OS_DISTRO" == "ubuntu" ]]; then
         #first we remove old installation
         $SUDO apt-get remove -y uhd || true
         $SUDO apt-get remove libuhd-dev libuhd003 uhd-host -y
@@ -225,27 +272,72 @@ check_install_usrp_uhd_driver(){
         $SUDO apt-get update
         $SUDO apt-get -y --allow-unauthenticated install  python python-tk libboost-all-dev libusb-1.0-0-dev
         $SUDO apt-get -y --allow-unauthenticated install libuhd-dev libuhd003 uhd-host
+    elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
+        $SUDO $INSTALLER -y install python boost libusb-devel libusbx-devel boost-devel python-mako python-docutils cmake
+        if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
+            # until EPEL repo hasn't bumped UHD driver to >=3.10 in EPEL, build driver from source
+            $SUDO $INSTALLER -y remove uhd uhd-devel uhd-firmware
+            install_ursp_uhd_driver_from_source
+        else
+            $SUDO $INSTALLER -y install uhd uhd-devel uhd-firmware
+        fi
+    fi
 }
 
 install_usrp_uhd_driver() {
+    if [[ "$OS_DISTRO" == "ubuntu" ]]; then
         # We move uhd-host apart because it depends on linux kernel version
         # On newer kernels, it fails to install
         $SUDO apt-get -y install uhd-host
-        if [ -z $1 ]; then
-          $SUDO uhd_images_downloader
-        else
-          $SUDO uhd_images_downloader -i $1
-        fi
+    fi
+    if [ -z $1 ]; then
+      $SUDO uhd_images_downloader
+    else
+      $SUDO uhd_images_downloader -i $1
+    fi
+}
+
+install_bladerf_driver_from_source(){
+    bladerf_install_log=$OPENAIR_DIR/cmake_targets/log/bladerf_install_log.txt
+    echo_info "\nInstalling BladeRF driver from sources. The log file for BladeRF driver installation is here: $bladerf_install_log "
+    (
+    cd /tmp
+    echo "Downloading BladeRF driver"
+    rm -rf /tmp/bladeRF
+    git clone https://github.com/Nuand/bladeRF.git
+    cd bladeRF
+    git checkout tags/2016.06
+    mkdir -p build
+    cd build
+    $CMAKE ../
+    echo "Compiling BladeRF driver"
+    make
+    $SUDO make install
+    $SUDO ldconfig
+    echo "Downloading FPGA and firmware images"
+    cd /tmp/bladeRF
+    wget https://www.nuand.com/fx3/bladeRF_fw_latest.img
+    wget https://www.nuand.com/fpga/hostedx40-latest.rbf
+    sudo mkdir -p /usr/share/Nuand/bladeRF
+    sudo mv bladeRF_fw_latest.img /usr/share/Nuand/bladeRF/bladeRF_fw.img
+    sudo mv hostedx40-latest.rbf /usr/share/Nuand/bladeRF/hostedx40.rbf
+    ) >& $bladerf_install_log
 }
 
 check_install_bladerf_driver(){
-	if [ "$(get_distribution_release)" == "Ubuntu14.04" ] ; then
-		$SUDO add-apt-repository -y ppa:bladerf/bladerf
-		$SUDO apt-get update
-	fi
-	$SUDO apt-get install -y --allow-unauthenticated  bladerf libbladerf-dev
-	$SUDO apt-get install -y --allow-unauthenticated bladerf-firmware-fx3
-	$SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40	
+    if [[ "$OS_DISTRO" == "ubuntu" ]]; then
+        if [ "$(get_distribution_release)" == "ubuntu14.04" ] ; then
+            $SUDO add-apt-repository -y ppa:bladerf/bladerf
+            $SUDO apt-get update
+        fi
+        $SUDO apt-get install -y --allow-unauthenticated  bladerf libbladerf-dev
+        $SUDO apt-get install -y --allow-unauthenticated bladerf-firmware-fx3
+        $SUDO apt-get install -y --allow-unauthenticated bladerf-fpga-hostedx40	
+   elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
+        install_bladerf_driver_from_source
+   else
+        echo_error "BladeRF Installer for OAI does not support automatic build. Install BladeRF compiling sources manually from BladeRF website"
+   fi
 }
 
 flash_firmware_bladerf() {
@@ -268,8 +360,9 @@ check_install_lmssdr_driver(){
 }
 
 check_install_additional_tools (){
-    $SUDO apt-get update
-    $SUDO apt-get install -y \
+  $SUDO $INSTALLER update -y
+  if [[ "$OS_DISTRO" == "ubuntu" ]]; then
+    PACKAGE_LIST="\
 	check \
 	dialog \
 	dkms \
@@ -298,13 +391,73 @@ check_install_additional_tools (){
         bc \
         ntp \
         python-scipy \
-        python-matplotlib
+        python-matplotlib"
+  elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
+    PACKAGE_LIST="\
+      check \
+      dialog \
+      dkms \
+      gawk \
+      boost-devel \
+      openvpn \
+      pkgconfig \
+      pexpect \
+      sshfs \
+      swig  \
+      wireshark \
+      unzip  \
+      valgrind  \
+      vconfig	  \
+      ctags \
+      ntpdate \
+      iperf3 \
+      wvdial \
+      numpy \
+      sshpass \
+      nscd \
+      python2-paramiko \
+      python-pyroute2 \
+      python-netifaces \
+      scipy \
+      python-matplotlib"
+  elif [[ "$OS_DISTRO" == "fedora" ]]; then
+    PACKAGE_LIST=" \
+      check \
+      dialog \
+      dkms \
+      gawk \
+      boost-devel \
+      openvpn \
+      pkgconfig \
+      python-pexpect \
+      sshfs \
+      swig  \
+      wireshark \
+      unzip  \
+      valgrind  \
+      vconfig	  \
+      ctags \
+      ntpdate \
+      iperf3 \
+      wvdial \
+      python-numpy \
+      sshpass \
+      nscd \
+      python2-paramiko \
+      python-pyroute2 \
+      python-netifaces \
+      python2-scipy \
+      python2-matplotlib"
+  fi
+    $SUDO $INSTALLER install -y $PACKAGE_LIST
+    
+    $SUDO rm -fr /opt/ssh
+    $SUDO GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/ssh.git /opt/ssh
 
+  #The packages below are already installed for Redhat distros (RHEL, CentOS, Fedora)
+  if [[ "$OS_DISTRO" == "ubuntu" ]]; then
     $SUDO pip install paramiko
     $SUDO pip install pyroute2 colorama
-    $SUDO rm -fr /opt/ssh
-    $SUDO GIT_SSL_NO_VERIFY=true git clone https://gitlab.eurecom.fr/oai/ssh.git /opt/ssh
-    
     log_netiface=$OPENAIR_DIR/cmake_targets/log/netiface_install_log.txt
     echo_info "Installing Netinterfaces package. The logfile for installation is in $log_netiface"
     (
@@ -315,6 +468,7 @@ check_install_additional_tools (){
     $SUDO python setup.py install
     cd -
     ) >& $log_netiface
+  fi
 }
 
 check_install_oai_software() {
@@ -323,16 +477,17 @@ check_install_oai_software() {
         echo_error "Your distribution $(get_distribution_release) is not supported by oai !"
         exit 1
     fi
-    $SUDO apt-get update
+    $SUDO $INSTALLER update -y
+  if [[ "$OS_DISTRO" == "ubuntu" ]]; then
     $SUDO apt install -y software-properties-common
     case "$(get_distribution_release)" in
-        "Ubuntu14.04")
+        "ubuntu14.04")
             specific_packages="libtasn1-3-dev"
             # For iperf3
             $SUDO add-apt-repository "deb http://archive.ubuntu.com/ubuntu trusty-backports universe"
             $SUDO apt-get update
             ;;
-        "Ubuntu16.04")
+        "ubuntu16.04")
             specific_packages="libtasn1-6-dev"
             ;;
     esac
@@ -395,73 +550,97 @@ check_install_oai_software() {
 	python-pip \
 	pydb \
 	libyaml-dev \
-	wget
+	wget \
+	libxpm-dev
 
     $SUDO update-alternatives --set liblapack.so /usr/lib/atlas-base/atlas/liblapack.so
     
-    #Remove old gnutls/nettle installation that was done from sources
-    remove_nettle_from_source
-    
     $SUDO apt-get install -y nettle-dev nettle-bin
-    remove_gnutls_from_source
 
     $SUDO apt-get install -y libgnutls-dev
+  elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then
+    if [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
+      if rpm -q epel-release > /dev/null; then
+        echo "EPEL repos already present. Good."
+      else
+        echo "EPEL repos not present. Installing them."
+        $SUDO $INSTALLER install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
+      fi
+      $SUDO $INSTALLER install -y python-epdb
+      $SUDO $INSTALLER install -y gccxml
+    else
+      $SUDO $INSTALLER install -y mscgen pydb
+      # Fedora repos already contain gccxml's successor castxml.
+      $SUDO $INSTALLER install -y castxml
+    fi
     
+    $SUDO $INSTALLER install -y \
+      autoconf \
+      automake \
+      bc \
+      bison \
+      $CMAKE \
+      doxygen \
+      ethtool \
+      flex \
+      gdb \
+      git \
+      graphviz \
+      gtkwave \
+      guile-devel \
+      iperf \
+      iproute \
+      iptables \
+      iptables-devel \
+      atlas-devel \
+      blas-devel \
+      libconfig-devel \
+      libffi-devel \
+      xforms \
+      xforms-devel \
+      libgcrypt-devel \
+      gmp-devel \
+      gtk3-devel \
+      libidn2-devel  \
+      libidn-devel \
+      mariadb-devel \
+      octave-devel \
+      openpgm-devel \
+      lksctp-tools \
+      lksctp-tools-devel \
+      openssl-devel \
+      libtasn1 \
+      libtool \
+      libusb-devel \
+      libxml2 \
+      libxml2-devel \
+      libxslt-devel \
+      octave \
+      octave-signal \
+      openssh-clients \
+      openssh-server \
+      openssl \
+      patch \
+      psmisc \
+      python \
+      subversion \
+      xmlstarlet \
+      python-pip \
+      wget \
+      kernel-headers \
+      kernel-devel \
+      nettle-devel \
+      gnutls-devel \
+      libXpm-devel \
+      lapack \
+      lapack-devel \
+      blas \
+      blas-devel
+  fi
+
     install_asn1c_from_source
     $SUDO rm -fr /opt/ssh
     $SUDO git clone https://gist.github.com/2190472.git /opt/ssh
-    install_protobuf_from_source
-    install_protobuf_c_from_source
-}
-
-### Remove Nettle installation which was done from sources
-remove_nettle_from_source() {
-    nettle_uninstall_log=$OPENAIR_DIR/cmake_targets/log/nettle_uninstall_log.txt
-    echo_info "\nUn-Installing Nettle from sources. The log file for nettle un-installation is here: $nettle_uninstall_log "
-    (
-    $SUDO apt-get remove -y nettle-dev nettle-bin 
-    cd /tmp
-    echo "Downloading nettle archive"
-    $SUDO rm -rf /tmp/nettle-2.5.tar.gz* /tmp/nettle-2.5
-    wget https://ftp.gnu.org/gnu/nettle/nettle-2.5.tar.gz
-    if [ $? -ne 0 ]; then
-      wget ftp://ftp.lysator.liu.se/pub/security/lsh/nettle-2.5.tar.gz
-    fi
-    if [ ! -f nettle-2.5.tar.gz ]; then
-      echo_error "Could not download nettle source files"
-      cd -
-      return
-    fi
-    tar -xzf nettle-2.5.tar.gz
-    cd nettle-2.5/
-    ./configure --disable-openssl --enable-shared --prefix=/usr 
-    $SUDO make uninstall || true 
-    $SUDO ldconfig
-    ) >& $nettle_uninstall_log
-}
-
-### Remove Gnutls from source
-remove_gnutls_from_source(){
-    gnutls_uninstall_log=$OPENAIR_DIR/cmake_targets/log/gnutls_uninstall_log.txt
-    echo_info "\nUn-Installing Gnutls. The log file for Gnutls un-installation is here: $gnutls_uninstall_log "
-    (
-    $SUDO apt-get remove -y libgnutls-dev
-    cd /tmp 
-    echo "Downloading gnutls archive"
-    $SUDO rm -rf /tmp/gnutls-3.1.23.tar.xz* /tmp/gnutls-3.1.23
-    wget http://mirrors.dotsrc.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz || \
-      wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1/gnutls-3.1.23.tar.xz
-    if [ ! -f gnutls-3.1.23.tar.xz ]; then
-      echo_error "Could not download gnutls source files"
-      cd -
-      return
-    fi
-    tar -xJf gnutls-3.1.23.tar.xz
-    cd gnutls-3.1.23/
-    ./configure --prefix=/usr
-    $SUDO make uninstall || true
-    $SUDO ldconfig
-    )>& $gnutls_uninstall_log
 }
 
 install_asn1c_from_source(){
diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h
index e362db2bc6ceed740e0ac5a4a7a06cc8581f7d06..9cb4ff5773f44893f15848c5515dc202adad9f4c 100644
--- a/common/config/config_userapi.h
+++ b/common/config/config_userapi.h
@@ -52,6 +52,7 @@ extern int config_isparamset(paramdef_t *params,int paramidx);
 extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val);
 extern int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix);
 #define config_getlist config_get_if()->getlist
+#define CONFIG_GETCONFFILE (config_get_if()->cfgP[0])
 
 
 #ifdef __cplusplus
diff --git a/common/utils/T/T_defs.h b/common/utils/T/T_defs.h
index eb327bb261e54d6cf09183e92b75822ca6dc042d..65f2430265574103ceaccd47970f84307f6bfaa6 100644
--- a/common/utils/T/T_defs.h
+++ b/common/utils/T/T_defs.h
@@ -29,10 +29,10 @@ typedef struct {
 #define T_SHM_FILENAME "/T_shm_segment"
 
 /* number of VCD functions (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_FUNCTIONS 142
+#define VCD_NUM_FUNCTIONS 172
 
 /* number of VCD variables (to be kept up to date! see in T_messages.txt) */
-#define VCD_NUM_VARIABLES 107
+#define VCD_NUM_VARIABLES 118
 
 /* first VCD function (to be kept up to date! see in T_messages.txt) */
 #define VCD_FIRST_FUNCTION    ((uintptr_t)T_VCD_FUNCTION_RT_SLEEP)
diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt
index c78bc92d364c183fac608cf71ad462a251644749..9de5bfeceedbea6b5394e36f939b91d9e71fbe4f 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -45,6 +45,10 @@ ID = ENB_PHY_INPUT_SIGNAL
     DESC = eNodeB received signal in the time domain for a duration of 1ms
     GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
     FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,rxdata
+ID = ENB_PHY_OUTPUT_SIGNAL
+    DESC = eNodeB sent signal in the time domain for a duration of 1ms
+    GROUP = ALL:PHY:HEAVY:ENB
+    FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,antenna : buffer,txdata
 ID = ENB_PHY_UL_CHANNEL_ESTIMATE
     DESC = eNodeB channel estimation in the time domain
     GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
@@ -111,6 +115,10 @@ ID = ENB_MAC_UE_DL_PDU_WITH_DATA
     DESC = MAC downlink PDU for an UE
     GROUP = ALL:MAC:ENB
     FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data
+ID = ENB_MAC_SCHEDULING_REQUEST
+    DESC = MAC scheduling request detected for an UE
+    GROUP = ALL:MAC:ENB
+    FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,rnti
 
 #RLC logs
 ID = ENB_RLC_DL
@@ -1350,6 +1358,22 @@ ID = VCD_VARIABLE_UE0_SFN7
     DESC = VCD variable UE0_SFN7
     GROUP = ALL:VCD:ENB:VCD_VARIABLE
     FORMAT = ulong,value
+ID = VCD_VARIABLE_SEND_IF4_SYMBOL
+    DESC = VCD variable SEND_IF4_SYMBOL
+    GROUP = ALL:VCD:ENB:VCD_VARIABLE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RECV_IF4_SYMBOL
+    DESC = VCD variable RECV_IF4_SYMBOL
+    GROUP = ALL:VCD:ENB:VCD_VARIABLE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_SEND_IF5_PKT_ID
+    DESC = VCD variable SEND_IF5_PKT_ID
+    GROUP = ALL:VCD:ENB:VCD_VARIABLE
+    FORMAT = ulong,value
+ID = VCD_VARIABLE_RECV_IF5_PKT_ID
+    DESC = VCD variable RECV_IF5_PKT_ID
+    GROUP = ALL:VCD:ENB:VCD_VARIABLE
+    FORMAT = ulong,value
 ID = VCD_VARIABLE_UE_PDCP_FLUSH_SIZE
     DESC = VCD variable UE_PDCP_FLUSH_SIZE
     GROUP = ALL:VCD:ENB:UE:VCD_VARIABLE
@@ -2061,3 +2085,11 @@ ID = VCD_FUNCTION_RECV_IF5
     DESC = VCD function RECV_IF5
     GROUP = ALL:VCD:ENB:VCD_FUNCTION
     FORMAT = int,value
+ID = VCD_FUNCTION_TRX_COMPR_IF
+    DESC = VCD function TRX_COMPR_IF
+    GROUP = ALL:VCD:ENB:VCD_FUNCTION
+    FORMAT = int,value
+ID = VCD_FUNCTION_TRX_DECOMPR_IF
+    DESC = VCD function TRX_DECOMPR_IF
+    GROUP = ALL:VCD:ENB:VCD_FUNCTION
+    FORMAT = int,value
diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile
index f6c65f64000e6da238d14d843d1fe36e8325eda2..6546345968637809eeed85e630e393035dcf0589 100644
--- a/common/utils/T/tracer/Makefile
+++ b/common/utils/T/tracer/Makefile
@@ -5,7 +5,8 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I.
 
 LIBS=-lX11 -lm -lpng -lXft
 
-all: record replay extract_config textlog enb ue vcd macpdu2wireshark
+all: record replay extract_config textlog enb ue vcd macpdu2wireshark \
+     extract_input_subframe
 
 record: utils.o record.o database.o config.o
 	$(CC) $(CFLAGS) -o record $^ $(LIBS)
@@ -16,6 +17,10 @@ replay: utils.o replay.o
 extract_config: extract_config.o
 	$(CC) $(CFLAGS) -o extract_config $^ $(LIBS)
 
+extract_input_subframe: extract_input_subframe.o database.o event.o utils.o \
+    config.o
+	$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+
 textlog: utils.o textlog.o database.o event.o handler.o config.o \
          event_selector.o view/view.a gui/gui.a logger/logger.a \
          filter/filter.a
@@ -58,8 +63,8 @@ filter/filter.a:
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 clean:
-	rm -f *.o core tracer_remote textlog enb vcd record replay
-	rm -f extract_config macpdu2wireshark
+	rm -f *.o core tracer_remote textlog enb ue vcd record replay
+	rm -f extract_config macpdu2wireshark extract_input_subframe
 	cd gui && make clean
 	cd view && make clean
 	cd logger && make clean
diff --git a/common/utils/T/tracer/extract_input_subframe.c b/common/utils/T/tracer/extract_input_subframe.c
new file mode 100644
index 0000000000000000000000000000000000000000..b5f74b3b27baa4a4c69f4854dfb8287a616becff
--- /dev/null
+++ b/common/utils/T/tracer/extract_input_subframe.c
@@ -0,0 +1,109 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include "database.h"
+#include "event.h"
+#include "config.h"
+
+void usage(void)
+{
+  printf(
+"usage: [options] <file> <frame> <subframe>\n"
+"options:\n"
+"    -d <database file>        this option is mandatory\n"
+"    -v                        verbose\n"
+  );
+  exit(1);
+}
+
+int main(int n, char **v)
+{
+  char *database_filename = NULL;
+  void *database;
+  int i;
+  int input_event_id;
+  database_event_format f;
+  char *file = NULL;
+  int fd;
+  int frame = -1, subframe = -1;
+  int frame_arg, subframe_arg, buffer_arg;
+  int verbose = 0;
+
+  for (i = 1; i < n; i++) {
+    if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage();
+    if (!strcmp(v[i], "-d"))
+      { if (i > n-2) usage(); database_filename = v[++i]; continue; }
+    if (!strcmp(v[i], "-v")) { verbose = 1; continue; }
+    if (file == NULL) { file = v[i]; continue; }
+    if (frame == -1) { frame = atoi(v[i]); continue; }
+    if (subframe == -1) { subframe = atoi(v[i]); continue; }
+    usage();
+  }
+  if (file == NULL || frame == -1 || subframe == -1) usage();
+
+  if (database_filename == NULL) {
+    printf("ERROR: provide a database file (-d)\n");
+    exit(1);
+  }
+
+  database = parse_database(database_filename);
+
+  load_config_file(database_filename);
+
+  input_event_id = event_id_from_name(database, "ENB_PHY_INPUT_SIGNAL");
+  f = get_format(database, input_event_id);
+
+  frame_arg = subframe_arg = buffer_arg = -1;
+  for (i = 0; i < f.count; i++) {
+    if (!strcmp(f.name[i], "frame")) {
+      if (frame_arg != -1) goto err;
+      if (strcmp(f.type[i], "int")) goto err;
+      frame_arg = i;
+    }
+    if (!strcmp(f.name[i], "subframe")) {
+      if (subframe_arg != -1) goto err;
+      if (strcmp(f.type[i], "int")) goto err;
+      subframe_arg = i;
+    }
+    if (!strcmp(f.name[i], "rxdata")) {
+      if (buffer_arg != -1) goto err;
+      if (strcmp(f.type[i], "buffer")) goto err;
+      buffer_arg = i;
+    }
+    continue;
+err:
+    printf("cannot deal with ENB_PHY_INPUT_SIGNAL from database file\n");
+    exit(1);
+  }
+  if (frame_arg == -1 || subframe_arg == -1 || buffer_arg == -1) goto err;
+
+  fd = open(file, O_RDONLY);
+  if (fd == -1) { perror(file); exit(1); }
+
+  /* get wanted frame/subframe */
+  while (1) {
+    char v[T_BUFFER_MAX];
+    event e;
+    e = get_event(fd, v, database);
+    if (e.type == -1) break;
+    if (e.type != input_event_id) continue;
+    if (verbose)
+      printf("input frame %d subframe %d size %d\n",
+             e.e[frame_arg].i, e.e[subframe_arg].i, e.e[buffer_arg].bsize);
+    if (!(frame == e.e[frame_arg].i && subframe == e.e[subframe_arg].i))
+      continue;
+#if 0
+for (i = 0; i < e.e[buffer_arg].bsize/2; i++) {
+short *x = e.e[buffer_arg].b;
+x[i] *= 14;
+}
+#endif
+    fwrite(e.e[buffer_arg].b, e.e[buffer_arg].bsize, 1, stdout);
+    fflush(stdout);
+    return 0;
+  }
+
+  printf("frame %d subframe %d not found\n", frame, subframe);
+  return 0;
+}
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index a08981bd9a4a064fbf5ed4fe25ac6fd372799ba8..9c9ab1a29b951fdb530b1f47d6a654f75453ad08 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -1021,6 +1021,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
                              struct PhysicalConfigDedicated *physicalConfigDedicated )
 {
 
+  static uint8_t first_dedicated_configuration = 0;
   PHY_VARS_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id];
 
   phy_vars_ue->total_TBS[eNB_id]=0;
@@ -1211,9 +1212,13 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
   get_cqipmiri_params(phy_vars_ue,eNB_id);
 
   // disable MIB SIB decoding once we are on connected mode
-  LOG_I(PHY,"Disabling SIB MIB decoding \n");
-  phy_vars_ue->decode_SIB = 0;
-  phy_vars_ue->decode_MIB = 0;
+  first_dedicated_configuration ++;
+  if(first_dedicated_configuration > 1)
+  {
+  	LOG_I(PHY,"Disable SIB MIB decoding \n");
+  	phy_vars_ue->decode_SIB = 0;
+  	phy_vars_ue->decode_MIB = 0;
+  }
   //phy_vars_ue->pdcch_vars[1][eNB_id]->crnti = phy_vars_ue->pdcch_vars[0][eNB_id]->crnti;
   if(phy_vars_ue->pdcch_vars[0][eNB_id]->crnti == 0x1234)
     phy_vars_ue->pdcch_vars[0][eNB_id]->crnti = phy_vars_ue->pdcch_vars[1][eNB_id]->crnti;
@@ -1338,18 +1343,20 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
   // create shortcuts
   LTE_DL_FRAME_PARMS* const fp            = &ue->frame_parms;
   LTE_UE_COMMON* const common_vars        = &ue->common_vars;
-  LTE_UE_PDSCH** const pdsch_vars_th0     = ue->pdsch_vars[0];
-  LTE_UE_PDSCH** const pdsch_vars_th1     = ue->pdsch_vars[1];
   LTE_UE_PDSCH** const pdsch_vars_SI      = ue->pdsch_vars_SI;
   LTE_UE_PDSCH** const pdsch_vars_ra      = ue->pdsch_vars_ra;
+  LTE_UE_PDSCH** const pdsch_vars_p       = ue->pdsch_vars_p;
   LTE_UE_PDSCH** const pdsch_vars_mch     = ue->pdsch_vars_MCH;
+  LTE_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars;
+  LTE_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX]   = &ue->pdcch_vars;
   LTE_UE_PBCH** const pbch_vars           = ue->pbch_vars;
-  LTE_UE_PDCCH** const pdcch_vars_th0     = ue->pdcch_vars[0];
-  LTE_UE_PDCCH** const pdcch_vars_th1     = ue->pdcch_vars[1];
   LTE_UE_PRACH** const prach_vars         = ue->prach_vars;
 
+
+
   int i,j,k,l;
   int eNB_id;
+  int th_id;
 
   LOG_D(PHY,"Initializing UE vars (abstraction %"PRIu8") for eNB TXant %"PRIu8", UE RXant %"PRIu8"\n",abstraction_flag,fp->nb_antennas_tx,fp->nb_antennas_rx);
   LOG_D(PHY,"[MSC_NEW][FRAME 00000][PHY_UE][MOD %02u][]\n", ue->Mod_id+NB_eNB_INST);
@@ -1385,6 +1392,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
     ue->tx_power_dBm[i]=-127;
 
 
+
   // init TX buffers
   
   common_vars->txdata  = (int32_t**)malloc16( fp->nb_antennas_tx*sizeof(int32_t*) );
@@ -1411,145 +1419,167 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
 
   // Channel estimates
   for (eNB_id=0; eNB_id<7; eNB_id++) {
-    common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates[eNB_id]      = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
-    common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates[eNB_id]      = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
-    common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
-    common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id]      = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
+        common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id] = (int32_t**)malloc16_clear(8*sizeof(int32_t*));
+    }
 
     for (i=0; i<fp->nb_antennas_rx; i++)
       for (j=0; j<4; j++) {
         int idx = (j<<1) + i;
-        common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
-        common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
-        common_vars->common_vars_rx_data_per_thread[0].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
-        common_vars->common_vars_rx_data_per_thread[1].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
+        for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+            common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->symbols_per_tti*(fp->ofdm_symbol_size+LTE_CE_FILTER_LENGTH) );
+            common_vars->common_vars_rx_data_per_thread[th_id].dl_ch_estimates_time[eNB_id][idx] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
+        }
       }
   }
 
   // DLSCH
   for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
-    pdsch_vars_th0[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
-    pdsch_vars_th1[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        (*pdsch_vars_th)[th_id][eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
+    }
+
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+        (*pdcch_vars_th)[th_id][eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH));
+    }
+
     pdsch_vars_SI[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
     pdsch_vars_ra[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
+    pdsch_vars_p[eNB_id]   = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
     pdsch_vars_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
-    pdcch_vars_th0[eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH));
-    pdcch_vars_th1[eNB_id] = (LTE_UE_PDCCH *)malloc16_clear(sizeof(LTE_UE_PDCCH));
     prach_vars[eNB_id]     = (LTE_UE_PRACH *)malloc16_clear(sizeof(LTE_UE_PRACH));
     pbch_vars[eNB_id]      = (LTE_UE_PBCH *)malloc16_clear(sizeof(LTE_UE_PBCH));
 
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp );
+    }
 
-    phy_init_lte_ue__PDSCH( pdsch_vars_th0[eNB_id], fp );
-    phy_init_lte_ue__PDSCH( pdsch_vars_th1[eNB_id], fp );
-    
-    // thread 0
-    pdsch_vars_th0[eNB_id]->llr_shifts      = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
-    pdsch_vars_th0[eNB_id]->llr_shifts_p        = pdsch_vars_th0[eNB_id]->llr_shifts;
-    pdsch_vars_th0[eNB_id]->llr[1]              = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
-    pdsch_vars_th0[eNB_id]->llr128_2ndstream    = (int16_t**)malloc16_clear( sizeof(int16_t*) );
-    pdsch_vars_th0[eNB_id]->rho                 = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
-    
-    // thread 0
-    pdsch_vars_th1[eNB_id]->llr_shifts      = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
-    pdsch_vars_th1[eNB_id]->llr_shifts_p        = pdsch_vars_th0[eNB_id]->llr_shifts;
-    pdsch_vars_th1[eNB_id]->llr[1]              = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
-    pdsch_vars_th1[eNB_id]->llr128_2ndstream    = (int16_t**)malloc16_clear( sizeof(int16_t*) );
-    pdsch_vars_th1[eNB_id]->rho                 = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
-    
-    
-    
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts      = (uint8_t*)malloc16_clear(7*2*fp->N_RB_DL*12);
+      (*pdsch_vars_th)[th_id][eNB_id]->llr_shifts_p        = (*pdsch_vars_th)[0][eNB_id]->llr_shifts;
+      (*pdsch_vars_th)[th_id][eNB_id]->llr[1]              = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+      (*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream    = (int16_t**)malloc16_clear( sizeof(int16_t*) );
+      (*pdsch_vars_th)[th_id][eNB_id]->rho                 = (int32_t**)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t*) );
+    }
     
     for (int i=0; i<fp->nb_antennas_rx; i++){
-      pdsch_vars_th0[eNB_id]->rho[i]     = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-      pdsch_vars_th1[eNB_id]->rho[i]     = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	(*pdsch_vars_th)[th_id][eNB_id]->rho[i]     = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+      }
+      
+    }
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext      = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
     }
-    
-    pdsch_vars_th0[eNB_id]->dl_ch_rho2_ext      = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-    pdsch_vars_th1[eNB_id]->dl_ch_rho2_ext      = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
     
     for (i=0; i<fp->nb_antennas_rx; i++)
       for (j=0; j<4; j++) {
 	const int idx = (j<<1)+i;
 	const size_t num = 7*2*fp->N_RB_DL*12+4;
-	pdsch_vars_th0[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	pdsch_vars_th1[eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	  (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	}
+	
       }
     
-    
     //const size_t num = 7*2*fp->N_RB_DL*12+4;
     for (k=0;k<8;k++) { //harq_pid
       for (l=0;l<8;l++) { //round
-	pdsch_vars_th0[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-	pdsch_vars_th0[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-	pdsch_vars_th0[eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-	pdsch_vars_th0[eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-	
-	pdsch_vars_th1[eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-	pdsch_vars_th1[eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-	pdsch_vars_th1[eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-	pdsch_vars_th1[eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+	for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	  (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+	  (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+	  (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+	  (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+	}
 	
 	
 	for (int i=0; i<fp->nb_antennas_rx; i++)
 	  for (int j=0; j<4; j++) { //frame_parms->nb_antennas_tx; j++)
 	    const int idx = (j<<1)+i;
-	    pdsch_vars_th0[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-	    pdsch_vars_th0[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-	    pdsch_vars_th0[eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-	    pdsch_vars_th0[eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+	    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	      (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+	      (*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+	      (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+	      (*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
+	    }
 	    
-	    pdsch_vars_th1[eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-	    pdsch_vars_th1[eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-	    pdsch_vars_th1[eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
-	    pdsch_vars_th1[eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t*)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
 	  }
       }
     }
     phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp );
     phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp );
+    phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp );
     phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
     
     // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
-    pdcch_vars_th0[eNB_id]->llr   = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-    pdcch_vars_th0[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-    pdcch_vars_th0[eNB_id]->wbar  = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-    pdcch_vars_th0[eNB_id]->e_rx  = (int8_t*)malloc16_clear( 4*2*100*12 );
-    
-    pdcch_vars_th0[eNB_id]->rxdataF_comp        = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-    pdcch_vars_th0[eNB_id]->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-    pdcch_vars_th0[eNB_id]->rho                 = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-    pdcch_vars_th0[eNB_id]->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-    pdcch_vars_th0[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      (*pdcch_vars_th)[th_id][eNB_id]->llr   = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+      (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+      (*pdcch_vars_th)[th_id][eNB_id]->wbar  = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+      (*pdcch_vars_th)[th_id][eNB_id]->e_rx  = (int8_t*)malloc16_clear( 4*2*100*12 );
+      
+      (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp        = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->rho                 = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+    }
     
-    pdcch_vars_th1[eNB_id]->llr   = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-    pdcch_vars_th1[eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-    pdcch_vars_th1[eNB_id]->wbar  = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
-    pdcch_vars_th1[eNB_id]->e_rx  = (int8_t*)malloc16_clear( 4*2*100*12 );
+    for (i=0; i<fp->nb_antennas_rx; i++) {
+      //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) );
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	(*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
+      }
+      
+      for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++)
+	int idx = (j<<1)+i;
+	//  size_t num = 7*2*fp->N_RB_DL*12;
+	size_t num = 4*100*12;  // 4 symbols, 100 PRBs, 12 REs per PRB
+	for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	  (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx]        = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	  (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	  (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+              (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	}
+      }
+    }
+    phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp );
+    phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp );
+    phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp );
+    phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
     
-    pdcch_vars_th1[eNB_id]->rxdataF_comp        = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-    pdcch_vars_th1[eNB_id]->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-    pdcch_vars_th1[eNB_id]->rho                 = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
-    pdcch_vars_th1[eNB_id]->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
-    pdcch_vars_th1[eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+    // 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
+    for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      (*pdcch_vars_th)[th_id][eNB_id]->llr   = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+      (*pdcch_vars_th)[th_id][eNB_id]->llr16 = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+      (*pdcch_vars_th)[th_id][eNB_id]->wbar  = (uint16_t*)malloc16_clear( 2*4*100*12*sizeof(uint16_t) );
+      (*pdcch_vars_th)[th_id][eNB_id]->e_rx  = (int8_t*)malloc16_clear( 4*2*100*12 );
+      
+      (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp        = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext       = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->rho                 = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext         = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+      (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext = (int32_t**)malloc16_clear( 8*sizeof(int32_t*) );
+    }
     
     for (i=0; i<fp->nb_antennas_rx; i++) {
       //ue_pdcch_vars[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(fp->N_RB_DL*12*7*2) );
-      pdcch_vars_th0[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
-      pdcch_vars_th1[eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
+
+      for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	(*pdcch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t*)malloc16_clear( sizeof(int32_t)*(100*12*4) );
+      }
       
       for (j=0; j<4; j++) { //fp->nb_antennas_tx; j++)
 	int idx = (j<<1)+i;
 	//  size_t num = 7*2*fp->N_RB_DL*12;
 	size_t num = 4*100*12;  // 4 symbols, 100 PRBs, 12 REs per PRB
-	pdcch_vars_th0[eNB_id]->rxdataF_comp[idx]        = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	pdcch_vars_th0[eNB_id]->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	pdcch_vars_th0[eNB_id]->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	pdcch_vars_th0[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	
-	pdcch_vars_th1[eNB_id]->rxdataF_comp[idx]        = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	pdcch_vars_th1[eNB_id]->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	pdcch_vars_th1[eNB_id]->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
-	pdcch_vars_th1[eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+	  (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_comp[idx]        = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	  (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[idx]       = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	  (*pdcch_vars_th)[th_id][eNB_id]->rxdataF_ext[idx]         = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	  (*pdcch_vars_th)[th_id][eNB_id]->dl_ch_estimates_ext[idx] = (int32_t*)malloc16_clear( sizeof(int32_t) * num );
+	}
       }
     }
     
@@ -1576,17 +1606,19 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
   }
 
   // initialization for the last instance of pdsch_vars (used for MU-MIMO)
+  for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+      (*pdsch_vars_th)[th_id][eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
+  }
 
-  pdsch_vars_th0[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
-  pdsch_vars_th1[eNB_id]     = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
   pdsch_vars_SI[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
   pdsch_vars_ra[eNB_id]  = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
-  
-  phy_init_lte_ue__PDSCH( pdsch_vars_th0[eNB_id], fp );
-  pdsch_vars_th0[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
-  
-  phy_init_lte_ue__PDSCH( pdsch_vars_th1[eNB_id], fp );
-  pdsch_vars_th1[eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+  pdsch_vars_p[eNB_id]   = (LTE_UE_PDSCH *)malloc16_clear( sizeof(LTE_UE_PDSCH) );
+
+  for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+    phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp );
+    (*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
+  }
+
 
   ue->sinr_CQI_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
 
diff --git a/openair1/PHY/INIT/lte_param_init.c b/openair1/PHY/INIT/lte_param_init.c
index d982045c98afaf0ebcef1be99fc21f03946c9fb9..188b7237a41aa399cd29ed1a3f0accbb36b1433b 100644
--- a/openair1/PHY/INIT/lte_param_init.c
+++ b/openair1/PHY/INIT/lte_param_init.c
@@ -127,6 +127,9 @@ void lte_param_init(unsigned char N_tx_port_eNB,
 
   UE->perfect_ce = perfect_ce;
 
+  /* the UE code is multi-thread "aware", we need to setup this array */
+  for (i = 0; i < 10; i++) UE->current_thread_id[i] = i % 2;
+
   printf("Done lte_param_init\n");
 
 
diff --git a/openair1/PHY/INIT/lte_parms.c b/openair1/PHY/INIT/lte_parms.c
index 6aa15d38286dcf4e3421010f2e6bfc298f1ec333..e071a57bc85b88ce52e2ca2be3950587532305ee 100644
--- a/openair1/PHY/INIT/lte_parms.c
+++ b/openair1/PHY/INIT/lte_parms.c
@@ -44,7 +44,11 @@ int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf)
 
   uint8_t log2_osf;
 
+#if DISABLE_LOG_X
+  printf("Initializing frame parms for N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
+#else
   LOG_I(PHY,"Initializing frame parms for N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
+#endif
 
   if (frame_parms->Ncp==EXTENDED) {
     frame_parms->nb_prefix_samples0=512;
diff --git a/openair1/PHY/LTE_ESTIMATION/defs.h b/openair1/PHY/LTE_ESTIMATION/defs.h
index 20bdbc1f362019acc6f1621d536e72f70425aaa2..e1346bb9556e9c04101f2f2314d1ce116ef8756b 100644
--- a/openair1/PHY/LTE_ESTIMATION/defs.h
+++ b/openair1/PHY/LTE_ESTIMATION/defs.h
@@ -161,7 +161,7 @@ int lte_est_freq_offset(int **dl_ch_estimates,
                         LTE_DL_FRAME_PARMS *frame_parms,
                         int l,
                         int* freq_offset,
-			int reset);
+            int reset);
 
 int lte_mbsfn_est_freq_offset(int **dl_ch_estimates,
                               LTE_DL_FRAME_PARMS *frame_parms,
@@ -180,7 +180,7 @@ This function computes the time domain channel response, finds the peak and adju
 void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
                       PHY_VARS_UE *phy_vars_ue,
                       module_id_t eNb_id,
-					  uint8_t subframe,
+                      uint8_t subframe,
                       unsigned char clear,
                       short coef);
 
@@ -189,7 +189,8 @@ void lte_ue_measurements(PHY_VARS_UE *phy_vars_ue,
                          unsigned int subframe_offset,
                          unsigned char N0_symbol,
                          unsigned char abstraction_flag,
-						 uint8_t subframe);
+                         unsigned char rank_adaptation,
+                         uint8_t subframe);
 
 //! \brief This function performance RSRP/RSCP measurements
 void ue_rrc_measurements(PHY_VARS_UE *phy_vars_ue,
@@ -214,7 +215,7 @@ int8_t set_RSRQ_filtered(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,floa
 
 //! Automatic gain control
 void phy_adjust_gain (PHY_VARS_UE *phy_vars_ue,
-		      uint32_t rx_power_fil_dB,
+              uint32_t rx_power_fil_dB,
                       unsigned char eNB_id);
 
 int lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB,
@@ -245,7 +246,7 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms,
 int lte_est_timing_advance_pusch(PHY_VARS_eNB* phy_vars_eNB,module_id_t UE_id);
 
 void lte_eNB_I0_measurements(PHY_VARS_eNB *phy_vars_eNB,
-			     int subframe,
+                 int subframe,
                              module_id_t eNB_id,
                              unsigned char clear);
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
index c92d0c1f034b044e7af38a8b65ec9f2aa1d38146..8875b110237615187585954ba99d70421d768c4e 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
@@ -40,6 +40,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
 {
 
   static int max_pos_fil = 0;
+  static int count_max_pos_ok = 0;
+  static int first_time = 1;
   int temp = 0, i, aa, max_val = 0, max_pos = 0;
   int diff;
   short Re,Im,ncoef;
@@ -58,8 +60,8 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
     temp = 0;
 
     for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_id][aa])[(i<<2)];
-      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)];
+      Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<2)];
+      Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<2)];
       temp += (Re*Re/2) + (Im*Im/2);
     }
 
@@ -78,28 +80,59 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
   // do not filter to have proactive timing adjustment
   max_pos_fil = max_pos;
 
-  diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
-
-  if ( abs(diff) < SYNCH_HYST )
-	ue->rx_offset = 0;
-  else
-    ue->rx_offset = diff;
-
-  if ( ue->rx_offset < 0 )
-    ue->rx_offset += FRAME_LENGTH_COMPLEX_SAMPLES;
+  if(subframe == 6)
+  {
+      diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3);
+
+      if ( abs(diff) < SYNCH_HYST )
+          ue->rx_offset = 0;
+      else
+          ue->rx_offset = diff;
+
+      if(abs(diff)<5)
+          count_max_pos_ok ++;
+      else
+          count_max_pos_ok = 0;
+
+      if(count_max_pos_ok > 10 && first_time == 1)
+      {
+          first_time = 0;
+          ue->time_sync_cell = 1;
+          if (ue->mac_enabled==1) {
+              LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
+              //mac_resynch();
+              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 {
+              ue->UE_mode[0] = PUSCH;
+          }
+      }
 
-  if ( ue->rx_offset >= FRAME_LENGTH_COMPLEX_SAMPLES )
-    ue->rx_offset -= FRAME_LENGTH_COMPLEX_SAMPLES;
+      if ( ue->rx_offset < 0 )
+          ue->rx_offset += FRAME_LENGTH_COMPLEX_SAMPLES;
 
+      if ( ue->rx_offset >= FRAME_LENGTH_COMPLEX_SAMPLES )
+          ue->rx_offset -= FRAME_LENGTH_COMPLEX_SAMPLES;
 
 
-#ifdef DEBUG_PHY
-  LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (after) = %d : max_pos = %d,max_pos_fil = %d (peak %d) target_pos %d \n",
-        ue->proc.proc_rxtx[0].frame_rx,subframe,ue->rx_offset,max_pos,max_pos_fil,temp,(frame_parms->nb_prefix_samples>>3));
-#endif //DEBUG_PHY
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
+      #ifdef DEBUG_PHY
+      LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n",
+              ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx,
+              subframe,
+              ue->current_thread_id[subframe],
+              diff,
+              ue->rx_offset,
+              clear,
+              max_pos,
+              max_pos_fil,
+              temp,max_val,
+              (frame_parms->nb_prefix_samples>>3));
+      #endif //DEBUG_PHY
 
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT);
+  }
 }
 
 
@@ -188,10 +221,6 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms,
   else
     max_pos_fil2 = ((max_pos_fil2 * coef) + (max_pos * ncoef)) >> 15;
 
-#ifdef DEBUG_PHY
-  //LOG_D(PHY,"frame %d: max_pos = %d, max_pos_fil = %d\n",mac_xface->frame,max_pos,max_pos_fil2);
-#endif //DEBUG_PHY
-
   return(max_pos_fil2);
 }
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
index aea0394af2bf29351ef486fb010fda1512824935..4e7dbb350fee8f4e3bb0b0b666fb60ee535e8286 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
@@ -51,7 +51,7 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
   int uespec_pilot[300];
 
   LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->frame_parms;
-  LTE_UE_DLSCH_t **dlsch_ue       = phy_vars_ue->dlsch[(Ns>>1)&0x1][eNB_id];
+  LTE_UE_DLSCH_t **dlsch_ue       = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[Ns>>1]][eNB_id];
   LTE_DL_UE_HARQ_t *dlsch0_harq; 
 
   harq_pid    = dlsch_ue[0]->current_harq_pid;
@@ -63,9 +63,9 @@ int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
   else
     rballoc = dlsch0_harq->rb_alloc_even;
 
-  rxdataF = phy_vars_ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF;
+  rxdataF = phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[Ns>>1]].rxdataF;
 
-  dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[(Ns>>1)&0x1][eNB_id]->dl_bf_ch_estimates;
+  dl_bf_ch_estimates = phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[Ns>>1]][eNB_id]->dl_bf_ch_estimates;
   beamforming_mode   = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
 
   if (phy_vars_ue->high_speed_flag == 0) // use second channel estimate position for temporary storage
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
index cc1d7a7ebcea2714ce566984c74e6d4096ef5a0f..eea7e44fffca33281e9e3bbb4db61d598c7f25c8 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
@@ -49,11 +49,13 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
 
   uint16_t Nid_cell = (eNB_offset == 0) ? ue->frame_parms.Nid_cell : ue->measurements.adj_cell_id[eNB_offset-1];
 
-  uint8_t nushift,pilot1,pilot2,pilot3;
-  int **dl_ch_estimates         =ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[eNB_offset];
-  int **dl_ch_estimates_previous=ue->common_vars.common_vars_rx_data_per_thread[((Ns>>1)+1)&0x1].dl_ch_estimates[eNB_offset];
-  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF;
+  uint8_t nushift,pilot0,pilot1,pilot2,pilot3;
+  uint8_t previous_thread_id = ue->current_thread_id[Ns>>1]==0 ? (RX_NB_TH-1):(ue->current_thread_id[Ns>>1]-1);
+  int **dl_ch_estimates         =ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset];
+  int **dl_ch_estimates_previous=ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].dl_ch_estimates[eNB_offset];
+  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF;
 
+  pilot0 = 0;
   if (ue->frame_parms.Ncp == 0) {  // normal prefix
     pilot1 = 4;
     pilot2 = 7;
@@ -92,7 +94,7 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
   k = (nu + nushift)%6;
 
 #ifdef DEBUG_CH
-  printf("Channel Estimation : eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size,
+  printf("Channel Estimation : ThreadId %d, eNB_offset %d cell_id %d ch_offset %d, OFDM size %d, Ncp=%d, l=%d, Ns=%d, k=%d\n",ue->current_thread_id[Ns>>1], eNB_offset,Nid_cell,ch_offset,ue->frame_parms.ofdm_symbol_size,
          ue->frame_parms.Ncp,l,Ns,k);
 #endif
 
@@ -796,18 +798,23 @@ int lte_dl_channel_estimation(PHY_VARS_UE *ue,
     break;
   }
 
-  // do ifft of channel estimate
-  for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
-    for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
-      if (ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
-        idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
-             (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
-    }
-
+  if( ((Ns%2) == 0) && (l == pilot0))
+  {
+      // do ifft of channel estimate
+      for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++)
+          for (p=0; p<ue->frame_parms.nb_antenna_ports_eNB; p++) {
+              if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx])
+              {
+                  //LOG_I(PHY,"Channel Impulse Computation Slot %d ThreadId %d Symbol %d \n", Ns, ue->current_thread_id[Ns>>1], l);
+                  idft((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[eNB_offset][(p<<1)+aarx][8],
+                          (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][(p<<1)+aarx],1);
+              }
+          }
+  }
 #if T_TRACER
         T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(eNB_id), T_INT(ue->Mod_id),
-          T_INT(ue->proc.proc_rxtx[(Ns>>1)&1].frame_rx%1024), T_INT(ue->proc.proc_rxtx[(Ns>>1)&1].subframe_rx),
-          T_INT(0), T_BUFFER(&ue->common_vars.common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates_time[eNB_offset][0][0], 512  * 4));
+          T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].frame_rx%1024), T_INT(ue->proc.proc_rxtx[ue->current_thread_id[Ns>>1]].subframe_rx),
+          T_INT(0), T_BUFFER(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates_time[eNB_offset][0][0], 512  * 4));
 #endif
 
   return(0);
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
index 2ce0e45b14988c390b70a36f0dc5821f0da5047f..e1ad291eec90551270f04cfbbc648128c365a6c5 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
@@ -44,8 +44,8 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
   //  unsigned int n;
   //  int i;
 
-  int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0];
-  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF;
+  int **dl_ch_estimates=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[0];
+  int **rxdataF=ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 
   ch_offset     = (l*(ue->frame_parms.ofdm_symbol_size));
   symbol_offset = ch_offset;//phy_vars_ue->lte_frame_parms.ofdm_symbol_size*l;
@@ -734,31 +734,31 @@ int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
 
   // do ifft of channel estimate
   for (aa=0; aa<ue->frame_parms.nb_antennas_rx*ue->frame_parms.nb_antennas_tx; aa++) {
-    if (ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa]) {
+    if (ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa]) {
       switch (ue->frame_parms.N_RB_DL) {
       case 6:
-	idft128((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	idft128((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       case 25:
-	idft512((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	idft512((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       case 50:
-	idft1024((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	idft1024((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       case 75:
-	idft1536((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		 (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	idft1536((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		 (int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		 1);
 	break;
       case 100:
-	idft2048((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_offset][aa][8],
-		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_offset][aa],
+	idft2048((int16_t*) &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_offset][aa][8],
+		(int16_t*) ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_offset][aa],
 		1);
 	break;
       default:
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index 50f55156420b6d770762cc7cbdf116417c26a09f..cd37f19df0ca6c1e10a88dfc6e3af5f16726dfe9 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -34,6 +34,9 @@
 
 //#define DEBUG_MEAS_RRC
 //#define DEBUG_MEAS_UE
+//#define DEBUG_RANK_EST
+
+int16_t cond_num_threshold = 0;
 
 #ifdef USER_MODE
 void print_shorts(char *s,short *x)
@@ -186,8 +189,9 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
   uint16_t Nid_cell = ue->frame_parms.Nid_cell;
   uint8_t eNB_offset,nu,l,nushift,k;
   uint16_t off;
+  uint8_t previous_thread_id = ue->current_thread_id[subframe]==0 ? (RX_NB_TH-1):(ue->current_thread_id[subframe]-1);
 
-  //uint8_t isPss; // indicate if this is a slot for extracting PSS
+   //uint8_t isPss; // indicate if this is a slot for extracting PSS
   //uint8_t isSss; // indicate if this is a slot for extracting SSS
   //int32_t pss_ext[4][72]; // contain the extracted 6*12 REs for mapping the PSS
   //int32_t sss_ext[4][72]; // contain the extracted 6*12 REs for mapping the SSS
@@ -212,61 +216,61 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 
           if(ue->frame_parms.frame_type == FDD)
           {
-	      rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
-	      rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
+	      rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(5*ue->frame_parms.ofdm_symbol_size)];
+	      rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
           }
           else
           {
-              rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)];
-              rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)];
+              rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(13*ue->frame_parms.ofdm_symbol_size)];
+              rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(2*ue->frame_parms.ofdm_symbol_size)];
           }
               //-ve spectrum from SSS
 
               //+ve spectrum from SSS
-	          ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
+              ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+70]*rxF_sss[2+70])+((int32_t)rxF_sss[2+69]*rxF_sss[2+69]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+68]*rxF_sss[2+68])+((int32_t)rxF_sss[2+67]*rxF_sss[2+67]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+66]*rxF_sss[2+66])+((int32_t)rxF_sss[2+65]*rxF_sss[2+65]));
-	      //	      ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
-	      //	      printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
+              //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[2+64]*rxF_sss[2+64])+((int32_t)rxF_sss[2+63]*rxF_sss[2+63]));
+              //              printf("sssp32 %d\n",ue->measurements.n0_power[aarx]);
               //+ve spectrum from PSS
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+70]*rxF_pss[2+70])+((int32_t)rxF_pss[2+69]*rxF_pss[2+69]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+68]*rxF_pss[2+68])+((int32_t)rxF_pss[2+67]*rxF_pss[2+67]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
-	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
-	      //	      printf("pss32 %d\n",ue->measurements.n0_power[aarx]);              //-ve spectrum from PSS
+          //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
+          //          printf("pss32 %d\n",ue->measurements.n0_power[aarx]);              //-ve spectrum from PSS
               if(ue->frame_parms.frame_type == FDD)
               {
-                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
-                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(6*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
               }
               else
               {
-                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)];
-                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_sss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF[aarx][(14*ue->frame_parms.ofdm_symbol_size)];
+                  rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(3*ue->frame_parms.ofdm_symbol_size)];
               }
-	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
-	      //	      printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
+          //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
+          //          printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-68]*rxF_pss[-68])+((int32_t)rxF_pss[-67]*rxF_pss[-67]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-66]*rxF_pss[-66])+((int32_t)rxF_pss[-65]*rxF_pss[-65]));
-              
+
               ue->measurements.n0_power[aarx] = (((int32_t)rxF_sss[-70]*rxF_sss[-70])+((int32_t)rxF_sss[-69]*rxF_sss[-69]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-68]*rxF_sss[-68])+((int32_t)rxF_sss[-67]*rxF_sss[-67]));
               ue->measurements.n0_power[aarx] += (((int32_t)rxF_sss[-66]*rxF_sss[-66])+((int32_t)rxF_sss[-65]*rxF_sss[-65]));
 
-	      //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
-	      //	      printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
+          //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-64]*rxF_pss[-64])+((int32_t)rxF_pss[-63]*rxF_pss[-63]));
+          //          printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
               ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
               ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
-            }
+        }
 
             //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
 
-	    ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
-	    ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
-          } else {
+        ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
+        ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
+        } else {
             LOG_E(PHY, "Not yet implemented: noise power calculation when prefix length = EXTENDED\n");
-          }
+        }
         }
         else if ((ue->frame_parms.frame_type == TDD) &&
                  ((subframe == 1) || (subframe == 6))) {  // TDD PSS/SSS, compute noise in DTX REs // 2016-09-29 wilson fix incorrect noise power calculation
@@ -277,10 +281,10 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
           if (ue->frame_parms.Ncp==NORMAL) {
             for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
 
-                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF;
+                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(ue->current_thread_id[subframe])].rxdataF;
                 rxF_pss  = (int16_t *) &rxdataF[aarx][((pss_symb*(ue->frame_parms.ofdm_symbol_size)))];
 
-                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF;
+                rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[previous_thread_id].rxdataF;
                 rxF_sss  = (int16_t *) &rxdataF[aarx][((sss_symb*(ue->frame_parms.ofdm_symbol_size)))];
 
                 //-ve spectrum from SSS
@@ -305,7 +309,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
                 ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+66]*rxF_pss[2+66])+((int32_t)rxF_pss[2+65]*rxF_pss[2+65]));
             //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[2+64]*rxF_pss[2+64])+((int32_t)rxF_pss[2+63]*rxF_pss[2+63]));
             //          printf("pss32 %d\n",ue->measurements.n0_power[aarx]);              //-ve spectrum from PSS
-                rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
+                rxF_pss = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(7*ue->frame_parms.ofdm_symbol_size)];
             //              ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-72]*rxF_pss[-72])+((int32_t)rxF_pss[-71]*rxF_pss[-71]));
             //          printf("pssm36 %d\n",ue->measurements.n0_power[aarx]);
                 ue->measurements.n0_power[aarx] += (((int32_t)rxF_pss[-70]*rxF_pss[-70])+((int32_t)rxF_pss[-69]*rxF_pss[-69]));
@@ -315,12 +319,11 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
             //          printf("pssm32 %d\n",ue->measurements.n0_power[aarx]);
                 ue->measurements.n0_power_dB[aarx] = (unsigned short) dB_fixed(ue->measurements.n0_power[aarx]/12);
                 ue->measurements.n0_power_tot /*+=*/ = ue->measurements.n0_power[aarx];
-	    }
+        }
 
         ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/(12*aarx));
         ue->measurements.n0_power_tot_dBm = ue->measurements.n0_power_tot_dB - ue->rx_total_gain_dB - dB_fixed(ue->frame_parms.ofdm_symbol_size);
 
-
         //LOG_I(PHY,"Subframe %d RRC UE MEAS Noise Level %d \n", subframe, ue->measurements.n0_power_tot);
 
           }
@@ -352,7 +355,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 	//#endif
 
         for (aarx=0; aarx<ue->frame_parms.nb_antennas_rx; aarx++) {
-          rxF = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aarx][(l*ue->frame_parms.ofdm_symbol_size)];
+          rxF = (int16_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aarx][(l*ue->frame_parms.ofdm_symbol_size)];
           off  = (ue->frame_parms.first_carrier_offset+k)<<1;
 
           if (l==(4-ue->frame_parms.Ncp)) {
@@ -362,8 +365,8 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
 
               ue->measurements.rsrp[eNB_offset] += (((int32_t)(rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1]));
               //        printf("rb %d, off %d : %d\n",rb,off,((((int32_t)rxF[off])*rxF[off])+((int32_t)(rxF[off+1])*rxF[off+1])));
-	      //	      if ((ue->frame_rx&0x3ff) == 0)
-	      //                printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
+              //              if ((ue->frame_rx&0x3ff) == 0)
+              //                printf("rb %d, off %d : %d\n",rb,off,((rxF[off]*rxF[off])+(rxF[off+1]*rxF[off+1])));
 
 
               off+=12;
@@ -429,6 +432,7 @@ void ue_rrc_measurements(PHY_VARS_UE *ue,
     //    if (slot == 0) {
 
       if (eNB_offset == 0)
+	
         LOG_D(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),
@@ -459,7 +463,8 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
                          unsigned int subframe_offset,
                          unsigned char N0_symbol,
                          unsigned char abstraction_flag,
-						 uint8_t subframe)
+                         unsigned char rank_adaptation,
+                         uint8_t subframe)
 {
 
 
@@ -473,17 +478,17 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
   int16x8_t *dl_ch0_128, *dl_ch1_128;
 #endif
   int *dl_ch0,*dl_ch1;
+
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int nb_subbands,subband_size,last_subband_size;
   int N_RB_DL = frame_parms->N_RB_DL;
+
+
+  int rank_tm3_tm4;
+
+
   ue->measurements.nb_antennas_rx = frame_parms->nb_antennas_rx;
 
-    if (ue->transmission_mode[eNB_id]!=4)
-     ue->measurements.rank[eNB_id] = 0;
-    else
-    ue->measurements.rank[eNB_id] = 1;
-  //  printf ("tx mode %d\n", ue->transmission_mode[eNB_id]);
-  //  printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]);
 
   switch (N_RB_DL) {
   case 6:
@@ -517,7 +522,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
       for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++) {
         ue->measurements.rx_spatial_power[eNB_id][aatx][aarx] =
-          (signal_energy_nodc(&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0],
+          (signal_energy_nodc(&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][(aatx<<1) + aarx][0],
                               (N_RB_DL*12)));
         //- ue->measurements.n0_power[aarx];
 
@@ -544,6 +549,28 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
 
   } //eNB_id
 
+  eNB_id=0;
+  if (ue->transmission_mode[0]==4 || ue->transmission_mode[0]==3){
+    if (rank_adaptation == 1)
+      rank_tm3_tm4 = rank_estimation_tm3_tm4(&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][4],
+                                             &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][4],
+                                             &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][4],
+                                             &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][4],
+                                             N_RB_DL);
+    else
+      rank_tm3_tm4=1;
+#ifdef DEBUG_RANK_EST
+  printf("rank tm3 or tm4 %d\n", rank_tm3_tm4);
+#endif
+  }
+
+  if (ue->transmission_mode[eNB_id]!=4 && ue->transmission_mode[eNB_id]!=3)
+    ue->measurements.rank[eNB_id] = 0;
+  else
+    ue->measurements.rank[eNB_id] = rank_tm3_tm4;
+  //  printf ("tx mode %d\n", ue->transmission_mode[eNB_id]);
+  //  printf ("rank %d\n", ue->PHY_measurements.rank[eNB_id]);
+
   // filter to remove jitter
   if (ue->init_averaging == 0) {
     for (eNB_id = 0; eNB_id < ue->n_connected_eNB; eNB_id++)
@@ -552,7 +579,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
             (k2*((long long int)(ue->measurements.rx_power_tot[eNB_id]))))>>10);
 
     //LOG_I(PHY,"Noise Power Computation: k1 %d k2 %d n0 avg %d n0 tot %d\n", k1, k2, ue->measurements.n0_power_avg,
-  	//	  ue->measurements.n0_power_tot);
+    //    ue->measurements.n0_power_tot);
     ue->measurements.n0_power_avg = (int)
         (((k1*((long long int) (ue->measurements.n0_power_avg))) +
           (k2*((long long int) (ue->measurements.n0_power_tot))))>>10);
@@ -572,12 +599,12 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
 #ifdef DEBUG_MEAS_UE
       LOG_I(PHY,"[eNB %d] Subframe %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
             eNB_id,
-			subframe,
+            subframe,
             ue->measurements.rx_rssi_dBm[eNB_id],
             ue->measurements.rx_power_avg_dB[eNB_id],
             ue->measurements.wideband_cqi_avg[eNB_id],
             ue->measurements.rx_power_avg[eNB_id],
-            ue->measurements.n0_power_avg);
+            ue->measurements.n0_power_tot);
 #endif
   }
 
@@ -588,8 +615,8 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
       // cqi/pmi information
 
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1    = &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
+        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch1    = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4];
 
         for (subband=0; subband<nb_subbands; subband++) {
 
@@ -638,19 +665,19 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
       }
 
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-	//printf("aarx=%d", aarx);
+        //printf("aarx=%d", aarx);
         // skip the first 4 RE due to interpolation filter length of 5 (not possible to skip 5 due to 128i alignment, must be multiple of 128bit)
 
 #if defined(__x86_64__) || defined(__i386__)
        __m128i pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1 /* ,mmtmpPMI2,mmtmpPMI3 */ ;
 
-        dl_ch0_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
+        dl_ch0_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch1_128    = (__m128i *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4];
 #elif defined(__arm__)
         int32x4_t pmi128_re,pmi128_im,mmtmpPMI0,mmtmpPMI1,mmtmpPMI0b,mmtmpPMI1b;
 
-        dl_ch0_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
-        dl_ch1_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2+aarx][4];
+        dl_ch0_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch1_128    = (int16x8_t *)&ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2+aarx][4];
 
 #endif
         for (subband=0; subband<nb_subbands; subband++) {
@@ -659,12 +686,12 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
           // pmi
 #if defined(__x86_64__) || defined(__i386__)
 
-	  pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re);
+          pmi128_re = _mm_xor_si128(pmi128_re,pmi128_re);
           pmi128_im = _mm_xor_si128(pmi128_im,pmi128_im);
 #elif defined(__arm__)
 
           pmi128_re = vdupq_n_s32(0);
-	  pmi128_im = vdupq_n_s32(0);
+          pmi128_im = vdupq_n_s32(0);
 #endif
           // limit is the number of groups of 4 REs in a subband (12 = 4 RBs, 3 = 1 RB)
           // for 5 MHz channelization, there are 7 subbands, 6 of size 4 RBs and 1 of size 1 RB
@@ -676,48 +703,48 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
           for (i=0; i<limit; i++) {
 
 #if defined(__x86_64__) || defined(__i386__)
-	      mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
+              mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
               mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1);
 
             // For each RE in subband perform ch0 * conj(ch1)
             // multiply by conjugated channel
-		//  print_ints("ch0",&dl_ch0_128[0]);
-		//  print_ints("ch1",&dl_ch1_128[0]);
+                //  print_ints("ch0",&dl_ch0_128[0]);
+                //  print_ints("ch1",&dl_ch1_128[0]);
 
-	    mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
-	         //  print_ints("re",&mmtmpPMI0);
+            mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
+                 //  print_ints("re",&mmtmpPMI0);
             mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[0],_MM_SHUFFLE(2,3,0,1));
               //  print_ints("_mm_shufflelo_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1));
-	        //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
+                //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate[0]);
-	       //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
+               //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[0]);
-	       //   print_ints("mm_madd_epi16",&mmtmpPMI1);
+               //   print_ints("mm_madd_epi16",&mmtmpPMI1);
             // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit)
             pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0);
-	     //   print_ints(" pmi128_re 0",&pmi128_re);
+             //   print_ints(" pmi128_re 0",&pmi128_re);
             pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1);
-	       //   print_ints(" pmi128_im 0 ",&pmi128_im);
+               //   print_ints(" pmi128_im 0 ",&pmi128_im);
 
-	  /*  mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
+          /*  mmtmpPMI0 = _mm_xor_si128(mmtmpPMI0,mmtmpPMI0);
             mmtmpPMI1 = _mm_xor_si128(mmtmpPMI1,mmtmpPMI1);
 
-	    mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]);
-	         //  print_ints("re",&mmtmpPMI0);
+            mmtmpPMI0 = _mm_madd_epi16(dl_ch0_128[1],dl_ch1_128[1]);
+                 //  print_ints("re",&mmtmpPMI0);
             mmtmpPMI1 = _mm_shufflelo_epi16(dl_ch1_128[1],_MM_SHUFFLE(2,3,0,1));
               //  print_ints("_mm_shufflelo_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_shufflehi_epi16(mmtmpPMI1,_MM_SHUFFLE(2,3,0,1));
-	        //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
+                //  print_ints("_mm_shufflehi_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_sign_epi16(mmtmpPMI1,*(__m128i*)&conjugate);
-	       //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
+               //  print_ints("_mm_sign_epi16",&mmtmpPMI1);
             mmtmpPMI1 = _mm_madd_epi16(mmtmpPMI1,dl_ch0_128[1]);
-	       //   print_ints("mm_madd_epi16",&mmtmpPMI1);
+               //   print_ints("mm_madd_epi16",&mmtmpPMI1);
             // mmtmpPMI1 contains imag part of 4 consecutive outputs (32-bit)
             pmi128_re = _mm_add_epi32(pmi128_re,mmtmpPMI0);
-	        //  print_ints(" pmi128_re 1",&pmi128_re);
+                //  print_ints(" pmi128_re 1",&pmi128_re);
             pmi128_im = _mm_add_epi32(pmi128_im,mmtmpPMI1);
-	    //print_ints(" pmi128_im 1 ",&pmi128_im);*/
+            //print_ints(" pmi128_im 1 ",&pmi128_im);*/
 
 #elif defined(__arm__)
 
@@ -744,7 +771,7 @@ void lte_ue_measurements(PHY_VARS_UE *ue,
     else {
       // cqi information only for mode 1
       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
-        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][aarx][4];
+        dl_ch0    = &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][aarx][4];
 
         for (subband=0; subband<7; subband++) {
 
@@ -811,3 +838,553 @@ void lte_ue_measurements_emul(PHY_VARS_UE *ue,uint8_t subframe,uint8_t eNB_id)
   LOG_D(PHY,"EMUL UE lte_ue_measurements_emul subframe %d, eNB_id %d\n",subframe,eNB_id);
 }
 
+
+uint8_t rank_estimation_tm3_tm4 (int *dl_ch_estimates_00, // please respect the order of channel estimates
+                                 int *dl_ch_estimates_01,
+                                 int *dl_ch_estimates_10,
+                                 int *dl_ch_estimates_11,
+                                 unsigned short nb_rb)
+{
+
+  int i=0;
+  int rank=0;
+  int N_RB=nb_rb;
+  int *ch00_rank, *ch01_rank, *ch10_rank, *ch11_rank;
+
+  int32_t shift;
+  int avg_0[2];
+  int avg_1[2];
+
+  int count=0;
+
+  /* we need at least alignment to 16 bytes, let's put 32 to be sure
+   * (maybe not necessary but doesn't hurt)
+   */
+  int32_t conjch00_ch01[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch01_ch00[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch10_ch11[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch11_ch10[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch00_ch00[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch01_ch01[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch10_ch10[12*N_RB] __attribute__((aligned(32)));
+  int32_t conjch11_ch11[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_00[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_00_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_01_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_10_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_11_sq[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_01[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_10[12*N_RB] __attribute__((aligned(32)));
+  int32_t af_mf_11[12*N_RB] __attribute__((aligned(32)));
+  int32_t determ_fin[12*N_RB] __attribute__((aligned(32)));
+  int32_t denum_db[12*N_RB] __attribute__((aligned(32)));
+  int32_t numer_fin[12*N_RB] __attribute__((aligned(32)));
+  int32_t numer_db[12*N_RB] __attribute__((aligned(32)));
+  int32_t cond_db[12*N_RB] __attribute__((aligned(32)));
+
+  ch00_rank = dl_ch_estimates_00;
+  ch01_rank = dl_ch_estimates_01;
+  ch10_rank = dl_ch_estimates_10;
+  ch11_rank = dl_ch_estimates_11;
+
+  dlsch_channel_level_TM34_meas(ch00_rank,
+                                ch01_rank,
+                                ch10_rank,
+                                ch11_rank,
+                                avg_0,
+                                avg_1,
+                                N_RB);
+
+  avg_0[0] = (log2_approx(avg_0[0])/2);
+  shift = cmax(avg_0[0],0);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n shift %d \n" , shift);
+  printf("\n conj(ch00)ch01 \n");
+#endif
+
+  conjch0_mult_ch1(ch00_rank,
+                   ch01_rank,
+                   conjch00_ch01,
+                   N_RB,
+                   shift); // this is an arbitrary shift to avoid overflow. can be changed.
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch01)ch00 \n");
+#endif
+
+  conjch0_mult_ch1(ch01_rank,
+                   ch00_rank,
+                   conjch01_ch00,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch10)ch11 \n");
+#endif
+
+
+  conjch0_mult_ch1(ch10_rank,
+                   ch11_rank,
+                   conjch10_ch11,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch11)ch10 \n");
+#endif
+
+  conjch0_mult_ch1(ch11_rank,
+                   ch10_rank,
+                   conjch11_ch10,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch00)ch00 \n");
+#endif
+
+  conjch0_mult_ch1(ch00_rank,
+                   ch00_rank,
+                   conjch00_ch00,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch01)ch01 \n");
+#endif
+
+  conjch0_mult_ch1(ch01_rank,
+                   ch01_rank,
+                   conjch01_ch01,
+                   N_RB,
+                   shift);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch10)ch10 \n");
+#endif
+
+  conjch0_mult_ch1(ch10_rank,
+                   ch10_rank,
+                   conjch10_ch10,
+                   N_RB,
+                   shift);
+#ifdef DEBUG_RANK_EST
+  printf("\n conj(ch11)ch11 \n");
+#endif
+
+  conjch0_mult_ch1(ch11_rank,
+                   ch11_rank,
+                   conjch11_ch11,
+                   N_RB,
+                   shift);
+
+  construct_HhH_elements(conjch00_ch00,
+                         conjch01_ch01,
+                         conjch11_ch11,
+                         conjch10_ch10,
+                         conjch00_ch01,
+                         conjch01_ch00,
+                         conjch10_ch11,
+                         conjch11_ch10,
+                         af_mf_00,
+                         af_mf_01,
+                         af_mf_10,
+                         af_mf_11,
+                         N_RB);
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH00|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_00,
+                         af_mf_00_sq,
+                         N_RB);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH01|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_01,
+                         af_mf_01_sq,
+                         N_RB);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH10|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_10,
+                         af_mf_10_sq,
+                         N_RB);
+
+#ifdef DEBUG_RANK_EST
+  printf("\n |HhH11|^2 \n");
+#endif
+
+  squared_matrix_element(af_mf_11,
+                         af_mf_11_sq,
+                         N_RB);
+
+  det_HhH(af_mf_00,
+          af_mf_01,
+          af_mf_10,
+          af_mf_11,
+          determ_fin,
+          N_RB);
+
+  numer(af_mf_00_sq,
+        af_mf_01_sq,
+        af_mf_10_sq,
+        af_mf_11_sq,
+        numer_fin,
+        N_RB);
+
+  for (i=1; i<12*N_RB; i++)
+  {
+    denum_db[i]=dB_fixed(determ_fin[i]);
+    numer_db[i]=dB_fixed(numer_fin[i]);
+    cond_db[i]=(numer_db[i]-denum_db[i]);
+    if (cond_db[i] < cond_num_threshold)
+      count++;
+#ifdef DEBUG_RANK_EST
+    printf("cond_num_threshold =%d \n", cond_num_threshold);
+    printf("i %d  numer_db[i] = %d \n", i, numer_db[i]);
+    printf("i %d  denum_db[i] = %d \n", i, denum_db[i]);
+    printf("i %d  cond_db[i] =  %d \n", i, cond_db[i]);
+    printf("i %d counter = %d \n", i, count);
+#endif
+  }
+
+  if (count >= 6*N_RB) // conditional number is lower 10dB in half on more Res Blocks
+    rank=1;
+
+#ifdef DEBUG_RANK_EST
+    printf(" rank = %d \n", rank);
+#endif
+   return(rank);
+}
+
+void conjch0_mult_ch1(int *ch0,
+                      int *ch1,
+                      int32_t *ch0conj_ch1,
+                      unsigned short nb_rb,
+                      unsigned char output_shift0)
+{
+  //This function is used to compute multiplications in Hhermitian * H matrix
+  unsigned short rb;
+  __m128i *dl_ch0_128,*dl_ch1_128, *ch0conj_ch1_128, mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3;
+
+  dl_ch0_128 = (__m128i *)ch0;
+  dl_ch1_128 = (__m128i *)ch1;
+
+  ch0conj_ch1_128 = (__m128i *)ch0conj_ch1;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    mmtmpD0 = _mm_madd_epi16(dl_ch0_128[0],dl_ch1_128[0]);
+    mmtmpD1 = _mm_shufflelo_epi16(dl_ch0_128[0],_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_shufflehi_epi16(mmtmpD1,_MM_SHUFFLE(2,3,0,1));
+    mmtmpD1 = _mm_sign_epi16(mmtmpD1,*(__m128i*)&conjugate[0]);
+    mmtmpD1 = _mm_madd_epi16(mmtmpD1,dl_ch1_128[0]);
+    mmtmpD0 = _mm_srai_epi32(mmtmpD0,output_shift0);
+    mmtmpD1 = _mm_srai_epi32(mmtmpD1,output_shift0);
+    mmtmpD2 = _mm_unpacklo_epi32(mmtmpD0,mmtmpD1);
+    mmtmpD3 = _mm_unpackhi_epi32(mmtmpD0,mmtmpD1);
+
+    ch0conj_ch1_128[0] = _mm_packs_epi32(mmtmpD2,mmtmpD3);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing conjugates \n");
+    print_shorts("ch0:",(int16_t*)&dl_ch0_128[0]);
+    print_shorts("ch1:",(int16_t*)&dl_ch1_128[0]);
+    print_shorts("pack:",(int16_t*)&ch0conj_ch1_128[0]);
+#endif
+
+    dl_ch0_128+=1;
+    dl_ch1_128+=1;
+    ch0conj_ch1_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+void construct_HhH_elements(int *ch0conj_ch0, //00_00
+                            int *ch1conj_ch1,//01_01
+                            int *ch2conj_ch2,//11_11
+                            int *ch3conj_ch3,//10_10
+                            int *ch0conj_ch1,//00_01
+                            int *ch1conj_ch0,//01_00
+                            int *ch2conj_ch3,//10_11
+                            int *ch3conj_ch2,//11_10
+                            int32_t *after_mf_00,
+                            int32_t *after_mf_01,
+                            int32_t *after_mf_10,
+                            int32_t *after_mf_11,
+                            unsigned short nb_rb)
+{
+  unsigned short rb;
+  __m128i *ch0conj_ch0_128, *ch1conj_ch1_128, *ch2conj_ch2_128, *ch3conj_ch3_128;
+  __m128i *ch0conj_ch1_128, *ch1conj_ch0_128, *ch2conj_ch3_128, *ch3conj_ch2_128;
+  __m128i *after_mf_00_128, *after_mf_01_128, *after_mf_10_128, *after_mf_11_128;
+
+  ch0conj_ch0_128 = (__m128i *)ch0conj_ch0;
+  ch1conj_ch1_128 = (__m128i *)ch1conj_ch1;
+  ch2conj_ch2_128 = (__m128i *)ch2conj_ch2;
+  ch3conj_ch3_128 = (__m128i *)ch3conj_ch3;
+  ch0conj_ch1_128 = (__m128i *)ch0conj_ch1;
+  ch1conj_ch0_128 = (__m128i *)ch1conj_ch0;
+  ch2conj_ch3_128 = (__m128i *)ch2conj_ch3;
+  ch3conj_ch2_128 = (__m128i *)ch3conj_ch2;
+  after_mf_00_128 = (__m128i *)after_mf_00;
+  after_mf_01_128 = (__m128i *)after_mf_01;
+  after_mf_10_128 = (__m128i *)after_mf_10;
+  after_mf_11_128 = (__m128i *)after_mf_11;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    after_mf_00_128[0] =_mm_adds_epi16(ch0conj_ch0_128[0],ch3conj_ch3_128[0]);// _mm_adds_epi32(ch0conj_ch0_128[0], ch3conj_ch3_128[0]); //00_00 + 10_10
+    after_mf_11_128[0] =_mm_adds_epi16(ch1conj_ch1_128[0], ch2conj_ch2_128[0]); //01_01 + 11_11
+    after_mf_01_128[0] =_mm_adds_epi16(ch0conj_ch1_128[0], ch2conj_ch3_128[0]);//00_01 + 10_11
+    after_mf_10_128[0] =_mm_adds_epi16(ch1conj_ch0_128[0], ch3conj_ch2_128[0]);//01_00 + 11_10
+
+#ifdef DEBUG_RANK_EST
+    printf(" \n construct_HhH_elements \n");
+    print_shorts("ch0conj_ch0_128:",(int16_t*)&ch0conj_ch0_128[0]);
+    print_shorts("ch1conj_ch1_128:",(int16_t*)&ch1conj_ch1_128[0]);
+    print_shorts("ch2conj_ch2_128:",(int16_t*)&ch2conj_ch2_128[0]);
+    print_shorts("ch3conj_ch3_128:",(int16_t*)&ch3conj_ch3_128[0]);
+    print_shorts("ch0conj_ch1_128:",(int16_t*)&ch0conj_ch1_128[0]);
+    print_shorts("ch1conj_ch0_128:",(int16_t*)&ch1conj_ch0_128[0]);
+    print_shorts("ch2conj_ch3_128:",(int16_t*)&ch2conj_ch3_128[0]);
+    print_shorts("ch3conj_ch2_128:",(int16_t*)&ch3conj_ch2_128[0]);
+    print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
+    print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
+    print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
+    print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
+#endif
+
+    ch0conj_ch0_128+=1;
+    ch1conj_ch1_128+=1;
+    ch2conj_ch2_128+=1;
+    ch3conj_ch3_128+=1;
+    ch0conj_ch1_128+=1;
+    ch1conj_ch0_128+=1;
+    ch2conj_ch3_128+=1;
+    ch3conj_ch2_128+=1;
+
+    after_mf_00_128+=1;
+    after_mf_01_128+=1;
+    after_mf_10_128+=1;
+    after_mf_11_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+
+void squared_matrix_element(int32_t *Hh_h_00,
+                            int32_t *Hh_h_00_sq,
+                            unsigned short nb_rb)
+{
+   unsigned short rb;
+  __m128i *Hh_h_00_128,*Hh_h_00_sq_128;
+
+  Hh_h_00_128 = (__m128i *)Hh_h_00;
+  Hh_h_00_sq_128 = (__m128i *)Hh_h_00_sq;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    Hh_h_00_sq_128[0] = _mm_madd_epi16(Hh_h_00_128[0],Hh_h_00_128[0]);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing squared_matrix_element \n");
+    print_shorts("Hh_h_00_128:",(int16_t*)&Hh_h_00_128[0]);
+    print_ints("Hh_h_00_sq_128:",(int32_t*)&Hh_h_00_sq_128[0]);
+#endif
+
+    Hh_h_00_sq_128+=1;
+    Hh_h_00_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+
+
+void det_HhH(int32_t *after_mf_00,
+             int32_t *after_mf_01,
+             int32_t *after_mf_10,
+             int32_t *after_mf_11,
+             int32_t *det_fin,
+             unsigned short nb_rb)
+
+{
+  unsigned short rb;
+  __m128i *after_mf_00_128,*after_mf_01_128, *after_mf_10_128, *after_mf_11_128, ad_re_128, bc_re_128;
+  __m128i *det_fin_128, det_128;
+
+  after_mf_00_128 = (__m128i *)after_mf_00;
+  after_mf_01_128 = (__m128i *)after_mf_01;
+  after_mf_10_128 = (__m128i *)after_mf_10;
+  after_mf_11_128 = (__m128i *)after_mf_11;
+
+  det_fin_128 = (__m128i *)det_fin;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    ad_re_128 = _mm_madd_epi16(after_mf_00_128[0],after_mf_11_128[0]);
+    bc_re_128 = _mm_madd_epi16(after_mf_01_128[0],after_mf_01_128[0]);
+    det_128 = _mm_sub_epi32(ad_re_128, bc_re_128);
+    det_fin_128[0] = _mm_abs_epi32(det_128);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing denominator \n");
+    print_shorts("after_mf_00_128:",(int16_t*)&after_mf_00_128[0]);
+    print_shorts("after_mf_01_128:",(int16_t*)&after_mf_01_128[0]);
+    print_shorts("after_mf_10_128:",(int16_t*)&after_mf_10_128[0]);
+    print_shorts("after_mf_11_128:",(int16_t*)&after_mf_11_128[0]);
+    print_ints("ad_re_128:",(int32_t*)&ad_re_128);
+    print_ints("bc_re_128:",(int32_t*)&bc_re_128);
+    print_ints("det_fin_128:",(int32_t*)&det_fin_128[0]);
+#endif
+
+    det_fin_128+=1;
+    after_mf_00_128+=1;
+    after_mf_01_128+=1;
+    after_mf_10_128+=1;
+    after_mf_11_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+void numer(int32_t *Hh_h_00_sq,
+           int32_t *Hh_h_01_sq,
+           int32_t *Hh_h_10_sq,
+           int32_t *Hh_h_11_sq,
+           int32_t *num_fin,
+           unsigned short nb_rb)
+
+{
+  unsigned short rb;
+  __m128i *h_h_00_sq_128, *h_h_01_sq_128, *h_h_10_sq_128, *h_h_11_sq_128;
+  __m128i *num_fin_128, sq_a_plus_sq_d_128, sq_b_plus_sq_c_128;
+
+  h_h_00_sq_128 = (__m128i *)Hh_h_00_sq;
+  h_h_01_sq_128 = (__m128i *)Hh_h_01_sq;
+  h_h_10_sq_128 = (__m128i *)Hh_h_10_sq;
+  h_h_11_sq_128 = (__m128i *)Hh_h_11_sq;
+
+  num_fin_128 = (__m128i *)num_fin;
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+
+    sq_a_plus_sq_d_128 = _mm_add_epi32(h_h_00_sq_128[0],h_h_11_sq_128[0]);
+    sq_b_plus_sq_c_128 = _mm_add_epi32(h_h_01_sq_128[0],h_h_10_sq_128[0]);
+    num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128);
+
+#ifdef DEBUG_RANK_EST
+    printf("\n Computing numerator \n");
+    print_ints("h_h_00_sq_128:",(int32_t*)&h_h_00_sq_128[0]);
+    print_ints("h_h_01_sq_128:",(int32_t*)&h_h_01_sq_128[0]);
+    print_ints("h_h_10_sq_128:",(int32_t*)&h_h_10_sq_128[0]);
+    print_ints("h_h_11_sq_128:",(int32_t*)&h_h_11_sq_128[0]);
+    print_shorts("sq_a_plus_sq_d_128:",(int16_t*)&sq_a_plus_sq_d_128);
+    print_shorts("sq_b_plus_sq_c_128:",(int16_t*)&sq_b_plus_sq_c_128);
+    print_shorts("num_fin_128:",(int16_t*)&num_fin_128[0]);
+#endif
+
+    num_fin_128+=1;
+    h_h_00_sq_128+=1;
+    h_h_01_sq_128+=1;
+    h_h_10_sq_128+=1;
+    h_h_11_sq_128+=1;
+  }
+  _mm_empty();
+  _m_empty();
+}
+
+
+
+
+
+void dlsch_channel_level_TM34_meas(int *ch00,
+                                   int *ch01,
+                                   int *ch10,
+                                   int *ch11,
+                                   int *avg_0,
+                                   int *avg_1,
+                                   unsigned short nb_rb)
+{
+
+#if defined(__x86_64__)||defined(__i386__)
+
+  short rb;
+  unsigned char nre=12;
+  __m128i *ch00_128, *ch01_128, *ch10_128, *ch11_128;
+  __m128i avg_0_row0_128D, avg_1_row0_128D, avg_0_row1_128D, avg_1_row1_128D;
+  __m128i ch00_128_tmp, ch01_128_tmp, ch10_128_tmp, ch11_128_tmp;
+
+  avg_0[0] = 0;
+  avg_0[1] = 0;
+  avg_1[0] = 0;
+  avg_1[1] = 0;
+
+  ch00_128 = (__m128i *)ch00;
+  ch01_128 = (__m128i *)ch01;
+  ch10_128 = (__m128i *)ch10;
+  ch11_128 = (__m128i *)ch11;
+
+  avg_0_row0_128D = _mm_setzero_si128();
+  avg_1_row0_128D = _mm_setzero_si128();
+  avg_0_row1_128D = _mm_setzero_si128();
+  avg_1_row1_128D = _mm_setzero_si128();
+
+  for (rb=0; rb<3*nb_rb; rb++) {
+    ch00_128_tmp = _mm_load_si128(&ch00_128[0]);
+    ch01_128_tmp = _mm_load_si128(&ch01_128[0]);
+    ch10_128_tmp = _mm_load_si128(&ch10_128[0]);
+    ch11_128_tmp = _mm_load_si128(&ch11_128[0]);
+
+    avg_0_row0_128D = _mm_add_epi32(avg_0_row0_128D,_mm_madd_epi16(ch00_128_tmp,ch00_128_tmp));
+    avg_1_row0_128D = _mm_add_epi32(avg_1_row0_128D,_mm_madd_epi16(ch01_128_tmp,ch01_128_tmp));
+    avg_0_row1_128D = _mm_add_epi32(avg_0_row1_128D,_mm_madd_epi16(ch10_128_tmp,ch10_128_tmp));
+    avg_1_row1_128D = _mm_add_epi32(avg_1_row1_128D,_mm_madd_epi16(ch11_128_tmp,ch11_128_tmp));
+
+    ch00_128+=1;
+    ch01_128+=1;
+    ch10_128+=1;
+    ch11_128+=1;
+  }
+
+  avg_0[0] = (((int*)&avg_0_row0_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_0_row0_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_0_row0_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_0_row0_128D)[3])/(nb_rb*nre);
+
+  avg_1[0] = (((int*)&avg_1_row0_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_1_row0_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_1_row0_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_1_row0_128D)[3])/(nb_rb*nre);
+
+  avg_0[1] = (((int*)&avg_0_row1_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_0_row1_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_0_row1_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_0_row1_128D)[3])/(nb_rb*nre);
+
+  avg_1[1] = (((int*)&avg_1_row1_128D)[0])/(nb_rb*nre) +
+           (((int*)&avg_1_row1_128D)[1])/(nb_rb*nre) +
+           (((int*)&avg_1_row1_128D)[2])/(nb_rb*nre) +
+           (((int*)&avg_1_row1_128D)[3])/(nb_rb*nre);
+
+  avg_0[0] = avg_0[0] + avg_0[1];
+  avg_1[0] = avg_1[0] + avg_1[1];
+  avg_0[0] = min (avg_0[0], avg_1[0]);
+  avg_1[0] = avg_0[0];
+
+  _mm_empty();
+  _m_empty();
+
+#elif defined(__arm__)
+
+#endif
+}
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index c29f422213bc32fd3abce948aea35aa3d1c3df83..a4cfb9d9fc5f6f86282aaae384ea0329058aca3a 100755
--- a/openair1/PHY/LTE_TRANSPORT/dci.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci.c
@@ -414,7 +414,7 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
             for (i=0; i<4; i++) {
               wbar[mprime] = llr[tti_offset0+i];
 #ifdef DEBUG_DCI_DECODING
-              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
+//              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset0+i,symbol_offset,re_offset0,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
 #endif
               mprime++;
               re_offset0++;
@@ -430,7 +430,7 @@ void pdcch_demapping(uint16_t *llr,uint16_t *wbar,LTE_DL_FRAME_PARMS *frame_parm
             for (i=0; i<4; i++) {
               wbar[mprime] = llr[tti_offset+i];
 #ifdef DEBUG_DCI_DECODING
-              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
+//              LOG_I(PHY,"PDCCH demapping mprime %d.%d <= llr %d (symbol %d re %d) -> (%d,%d)\n",mprime/4,i,tti_offset+i,symbol_offset,re_offset+i,*(char*)&wbar[mprime],*(1+(char*)&wbar[mprime]));
 #endif
               mprime++;
             }
@@ -660,7 +660,7 @@ void pdcch_channel_level(int32_t **dl_ch_estimates_ext,
       //clear average level
 #if defined(__x86_64__) || defined(__i386__)
       avg128P = _mm_setzero_si128();
-      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][frame_parms->N_RB_DL*12];
+      dl_ch128=(__m128i *)&dl_ch_estimates_ext[(aatx<<1)+aarx][0];
 #elif defined(__arm__)
 
 #endif
@@ -1700,55 +1700,55 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
 
   LTE_UE_COMMON *common_vars      = &ue->common_vars;
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
-  LTE_UE_PDCCH **pdcch_vars       = ue->pdcch_vars[subframe & 0x1];
+  LTE_UE_PDCCH **pdcch_vars       = ue->pdcch_vars[ue->current_thread_id[subframe]];
 
   uint8_t log2_maxh,aatx,aarx;
 #ifdef MU_RECEIVER
   uint8_t eNB_id_i=eNB_id+1;//add 1 to eNB_id to separate from wanted signal, chosen as the B/F'd pilots from the SeNB are shifted by 1
 #endif
-  int32_t avgs,s;
-  uint8_t n_pdcch_symbols = 3; //pdcch_vars[eNB_id]->num_pdcch_symbols;
+  int32_t avgs;
+  uint8_t n_pdcch_symbols;
   uint8_t mi = get_mi(frame_parms,subframe);
 
   //printf("In rx_pdcch, subframe %d, eNB_id %d, pdcch_vars %d \n",subframe,eNB_id,pdcch_vars);
-
-  for (s=0; s<n_pdcch_symbols; s++) {
+  // procress ofdm symbol 0
     if (is_secondary_ue == 1) {
-      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
+      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
                                pdcch_vars[eNB_id]->rxdataF_ext,
                                pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                               s,
+                               0,
                                high_speed_flag,
                                frame_parms);
 #ifdef MU_RECEIVER
-      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
+      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
                                pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
                                pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
-                               s,
+                               0,
                                high_speed_flag,
                                frame_parms);
 #endif //MU_RECEIVER
     } else if (frame_parms->nb_antenna_ports_eNB>1) {
-      pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                             common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+      pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                             common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                              pdcch_vars[eNB_id]->rxdataF_ext,
                              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                             s,
+                             0,
                              high_speed_flag,
                              frame_parms);
     } else {
-      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                               common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+      pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                               common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                pdcch_vars[eNB_id]->rxdataF_ext,
                                pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                               s,
+                               0,
                                high_speed_flag,
                                frame_parms);
     }
-  }
 
+
+  // compute channel level based on ofdm symbol 0
   pdcch_channel_level(pdcch_vars[eNB_id]->dl_ch_estimates_ext,
                       frame_parms,
                       avgP,
@@ -1761,94 +1761,94 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
       avgs = cmax(avgs,avgP[(aarx<<1)+aatx]);
 
   log2_maxh = (log2_approx(avgs)/2) + 5;  //+frame_parms->nb_antennas_rx;
-#ifdef DEBUG_PHY
-  LOG_I(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs);
+#ifdef UE_DEBUG_TRACE
+  LOG_D(PHY,"subframe %d: pdcch log2_maxh = %d (%d,%d)\n",subframe,log2_maxh,avgP[0],avgs);
 #endif
 
 #if T_TRACER
   T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id),  T_INT(0), T_INT(frame%1024), T_INT(subframe),
                            T_INT(avgP[0]), T_INT(avgP[1]),    T_INT(avgP[2]),             T_INT(avgP[3]));
 #endif
-  for (s=0; s<n_pdcch_symbols; s++) {
-    pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
-                               pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                               pdcch_vars[eNB_id]->rxdataF_comp,
-                               (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
-                               frame_parms,
-                               s,
-                               log2_maxh); // log2_maxh+I0_shift
+
+  // compute LLRs for ofdm symbol 0 only
+  pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
+          pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+          pdcch_vars[eNB_id]->rxdataF_comp,
+          (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
+                  frame_parms,
+                  0,
+                  log2_maxh); // log2_maxh+I0_shift
 
 
 #ifdef DEBUG_PHY
 
-    if (subframe==5)
+  if (subframe==5)
       write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
 
 #endif
 
 #ifdef MU_RECEIVER
 
-    if (is_secondary_ue) {
+  if (is_secondary_ue) {
       //get MF output for interfering stream
       pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext,
-                                 pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                 pdcch_vars[eNB_id_i]->rxdataF_comp,
-                                 (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
-                                 frame_parms,
-                                 s,
-                                 log2_maxh); // log2_maxh+I0_shift
+              pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id_i]->rxdataF_comp,
+              (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
+                      frame_parms,
+                      0,
+                      log2_maxh); // log2_maxh+I0_shift
 #ifdef DEBUG_PHY
       write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
 #endif
       pdcch_dual_stream_correlation(frame_parms,
-                                    s,
-                                    pdcch_vars[eNB_id]->dl_ch_estimates_ext,
-                                    pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
-                                    pdcch_vars[eNB_id]->dl_ch_rho_ext,
-                                    log2_maxh);
-    }
+              0,
+              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id]->dl_ch_rho_ext,
+              log2_maxh);
+  }
 
 #endif //MU_RECEIVER
 
 
-    if (frame_parms->nb_antennas_rx > 1) {
+  if (frame_parms->nb_antennas_rx > 1) {
 #ifdef MU_RECEIVER
 
       if (is_secondary_ue) {
-        pdcch_detection_mrc_i(frame_parms,
-                              pdcch_vars[eNB_id]->rxdataF_comp,
-                              pdcch_vars[eNB_id_i]->rxdataF_comp,
-                              pdcch_vars[eNB_id]->rho,
-                              pdcch_vars[eNB_id]->dl_ch_rho_ext,
-                              s);
+          pdcch_detection_mrc_i(frame_parms,
+                  pdcch_vars[eNB_id]->rxdataF_comp,
+                  pdcch_vars[eNB_id_i]->rxdataF_comp,
+                  pdcch_vars[eNB_id]->rho,
+                  pdcch_vars[eNB_id]->dl_ch_rho_ext,
+                  0);
 #ifdef DEBUG_PHY
-        write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
-        write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+          write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+          write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
 #endif
       } else
 #endif //MU_RECEIVER
-        pdcch_detection_mrc(frame_parms,
-                            pdcch_vars[eNB_id]->rxdataF_comp,
-                            s);
-
-    }
+          pdcch_detection_mrc(frame_parms,
+                  pdcch_vars[eNB_id]->rxdataF_comp,
+                  0);
+  }
 
-    if (mimo_mode == SISO)
-      pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
-    else
-      pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
+  if (mimo_mode == SISO)
+      pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0);
+  else
+      pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,0);
 
 
 #ifdef MU_RECEIVER
 
-    if (is_secondary_ue) {
+  if (is_secondary_ue) {
       pdcch_qpsk_qpsk_llr(frame_parms,
-                          pdcch_vars[eNB_id]->rxdataF_comp,
-                          pdcch_vars[eNB_id_i]->rxdataF_comp,
-                          pdcch_vars[eNB_id]->dl_ch_rho_ext,
-                          pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
-                          pdcch_vars[eNB_id]->llr,
-                          s);
+              pdcch_vars[eNB_id]->rxdataF_comp,
+              pdcch_vars[eNB_id_i]->rxdataF_comp,
+              pdcch_vars[eNB_id]->dl_ch_rho_ext,
+              pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
+              pdcch_vars[eNB_id]->llr,
+              0);
       /*
       #ifdef DEBUG_PHY
       if (subframe==5) {
@@ -1856,22 +1856,21 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
       write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
       }
       #endif*/
-    } else {
+  } else {
 #endif //MU_RECEIVER
       pdcch_llr(frame_parms,
-                pdcch_vars[eNB_id]->rxdataF_comp,
-                (char *)pdcch_vars[eNB_id]->llr,
-                s);
+              pdcch_vars[eNB_id]->rxdataF_comp,
+              (char *)pdcch_vars[eNB_id]->llr,
+              0);
       /*#ifdef DEBUG_PHY
       write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
       #endif*/
 
 #ifdef MU_RECEIVER
-    }
+  }
 
 #endif //MU_RECEIVER
 
-  }
 
 #if T_TRACER
   T(T_UE_PHY_PDCCH_IQ, T_INT(frame_parms->N_RB_DL), T_INT(frame_parms->N_RB_DL),
@@ -1879,7 +1878,7 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
     T_BUFFER(pdcch_vars[eNB_id]->rxdataF_comp, frame_parms->N_RB_DL*12*n_pdcch_symbols* 4));
 #endif
 
-  // decode pcfich here
+  // decode pcfich here and find out pdcch ofdm symbol number
   n_pdcch_symbols = rx_pcfich(frame_parms,
                               subframe,
                               pdcch_vars[eNB_id],
@@ -1895,6 +1894,147 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
   LOG_I(PHY,"demapping: subframe %d, mi %d, tdd_config %d\n",subframe,get_mi(frame_parms,subframe),frame_parms->tdd_config);
 #endif
 
+  // process pdcch ofdm symbol 1 and 2 if necessary
+  for (int s=1; s<n_pdcch_symbols; s++){
+      if (is_secondary_ue == 1) {
+          pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id+1], //add 1 to eNB_id to compensate for the shifted B/F'd pilots from the SeNB
+                  pdcch_vars[eNB_id]->rxdataF_ext,
+                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                  s,
+                  high_speed_flag,
+                  frame_parms);
+#ifdef MU_RECEIVER
+pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+        common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i - 1],//subtract 1 to eNB_id_i to compensate for the non-shifted pilots from the PeNB
+        pdcch_vars[eNB_id_i]->rxdataF_ext,//shift by two to simulate transmission from a second antenna
+        pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,//shift by two to simulate transmission from a second antenna
+        s,
+        high_speed_flag,
+        frame_parms);
+#endif //MU_RECEIVER
+      } else if (frame_parms->nb_antenna_ports_eNB>1) {
+          pdcch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
+                  pdcch_vars[eNB_id]->rxdataF_ext,
+                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                  s,
+                  high_speed_flag,
+                  frame_parms);
+      } else {
+          pdcch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
+                  pdcch_vars[eNB_id]->rxdataF_ext,
+                  pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+                  s,
+                  high_speed_flag,
+                  frame_parms);
+      }
+
+
+      pdcch_channel_compensation(pdcch_vars[eNB_id]->rxdataF_ext,
+              pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+              pdcch_vars[eNB_id]->rxdataF_comp,
+              (aatx>1) ? pdcch_vars[eNB_id]->rho : NULL,
+                      frame_parms,
+                      s,
+                      log2_maxh); // log2_maxh+I0_shift
+
+
+#ifdef DEBUG_PHY
+
+if (subframe==5)
+    write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+
+#endif
+
+#ifdef MU_RECEIVER
+
+if (is_secondary_ue) {
+    //get MF output for interfering stream
+    pdcch_channel_compensation(pdcch_vars[eNB_id_i]->rxdataF_ext,
+            pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+            pdcch_vars[eNB_id_i]->rxdataF_comp,
+            (aatx>1) ? pdcch_vars[eNB_id_i]->rho : NULL,
+                    frame_parms,
+                    s,
+                    log2_maxh); // log2_maxh+I0_shift
+#ifdef DEBUG_PHY
+write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+#endif
+pdcch_dual_stream_correlation(frame_parms,
+        s,
+        pdcch_vars[eNB_id]->dl_ch_estimates_ext,
+        pdcch_vars[eNB_id_i]->dl_ch_estimates_ext,
+        pdcch_vars[eNB_id]->dl_ch_rho_ext,
+        log2_maxh);
+}
+
+#endif //MU_RECEIVER
+
+
+if (frame_parms->nb_antennas_rx > 1) {
+#ifdef MU_RECEIVER
+
+    if (is_secondary_ue) {
+        pdcch_detection_mrc_i(frame_parms,
+                pdcch_vars[eNB_id]->rxdataF_comp,
+                pdcch_vars[eNB_id_i]->rxdataF_comp,
+                pdcch_vars[eNB_id]->rho,
+                pdcch_vars[eNB_id]->dl_ch_rho_ext,
+                s);
+#ifdef DEBUG_PHY
+write_output("rxF_comp_d.m","rxF_c_d",&pdcch_vars[eNB_id]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+write_output("rxF_comp_i.m","rxF_c_i",&pdcch_vars[eNB_id_i]->rxdataF_comp[0][s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);
+#endif
+    } else
+#endif //MU_RECEIVER
+        pdcch_detection_mrc(frame_parms,
+                pdcch_vars[eNB_id]->rxdataF_comp,
+                s);
+
+}
+
+if (mimo_mode == SISO)
+    pdcch_siso(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
+else
+    pdcch_alamouti(frame_parms,pdcch_vars[eNB_id]->rxdataF_comp,s);
+
+
+#ifdef MU_RECEIVER
+
+if (is_secondary_ue) {
+    pdcch_qpsk_qpsk_llr(frame_parms,
+            pdcch_vars[eNB_id]->rxdataF_comp,
+            pdcch_vars[eNB_id_i]->rxdataF_comp,
+            pdcch_vars[eNB_id]->dl_ch_rho_ext,
+            pdcch_vars[eNB_id]->llr16, //subsequent function require 16 bit llr, but output must be 8 bit (actually clipped to 4, because of the Viterbi decoder)
+            pdcch_vars[eNB_id]->llr,
+            s);
+    /*
+        #ifdef DEBUG_PHY
+        if (subframe==5) {
+        write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+        write_output("llr16_seq.m","llr16",&pdcch_vars[eNB_id]->llr16[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+        }
+        #endif*/
+} else {
+#endif //MU_RECEIVER
+    pdcch_llr(frame_parms,
+            pdcch_vars[eNB_id]->rxdataF_comp,
+            (char *)pdcch_vars[eNB_id]->llr,
+            s);
+    /*#ifdef DEBUG_PHY
+        write_output("llr8_seq.m","llr8",&pdcch_vars[eNB_id]->llr[s*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,4);
+        #endif*/
+
+#ifdef MU_RECEIVER
+}
+
+#endif //MU_RECEIVER
+
+  }
+
   pdcch_demapping(pdcch_vars[eNB_id]->llr,
                   pdcch_vars[eNB_id]->wbar,
                   frame_parms,
@@ -2038,15 +2178,18 @@ uint8_t get_num_pdcch_symbols(uint8_t num_dci,
   }
 
 
+
   //  LOG_I(PHY," dci.c: get_num_pdcch_symbols subframe %d FATAL, illegal numCCE %d (num_dci %d)\n",subframe,numCCE,num_dci);
   //for (i=0;i<num_dci;i++) {
   //  printf("dci_alloc[%d].L = %d\n",i,dci_alloc[i].L);
   //}
   //exit(-1);
+exit(1);
   return(0);
 }
 */
 
+
 uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
 			 uint8_t num_dci,
                          DCI_ALLOC_t *dci_alloc,
@@ -2057,6 +2200,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
                          uint32_t subframe)
 {
 
+
   uint8_t *e_ptr;
   int8_t L;
   uint32_t i, lprime;
@@ -2104,7 +2248,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
     break;
   }
 
-  
+
   generate_pcfich(num_pdcch_symbols,
                   amp,
                   frame_parms,
@@ -2123,6 +2267,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
 
   e_ptr = e;
 
+
   // generate DCIs in order of decreasing aggregation level, then common/ue spec
   // MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization
   for (L=8; L>=1; L>>=1) {
@@ -2355,6 +2500,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
 }
 
 
+
 void dci_decoding(uint8_t DCI_LENGTH,
                   uint8_t aggregation_level,
                   int8_t *e,
@@ -2419,7 +2565,7 @@ void dci_decoding(uint8_t DCI_LENGTH,
 }
 
 
-static uint8_t dci_decoded_output[2][(MAX_DCI_SIZE_BITS+64)/8];
+static uint8_t dci_decoded_output[RX_NB_TH][(MAX_DCI_SIZE_BITS+64)/8];
 
 uint16_t get_nCCE(uint8_t num_pdcch_symbols,LTE_DL_FRAME_PARMS *frame_parms,uint8_t mi)
 {
@@ -2558,7 +2704,8 @@ int get_nCCE_offset_l1(int *CCE_table,
       search_space_free = 1;
 
       for (l=0; l<L; l++) {
-        if (CCE_table[(((Yk+m)%(nCCE/L))*L) + l] == 1) {
+        int cce = (((Yk+m)%(nCCE/L))*L) + l;
+        if (cce >= nCCE || CCE_table[cce] == 1) {
           search_space_free = 0;
           break;
         }
@@ -2583,6 +2730,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
 			     uint8_t subframe,
                              DCI_ALLOC_t *dci_alloc,
                              int16_t eNB_id,
+                             uint8_t current_thread_id,
                              LTE_DL_FRAME_PARMS *frame_parms,
                              uint8_t mi,
                              uint16_t si_rnti,
@@ -2708,23 +2856,25 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
     if (CCEmap_cand == 0) {
 
       if (do_common == 1)
-
-        LOG_D(PHY,"[DCI search - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
+        LOG_D(PHY,"[DCI search nPdcch %d - common] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",
+                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
       else
-        LOG_D(PHY,"[DCI search - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x)\n",m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask);
+        LOG_D(PHY,"[DCI search nPdcch %d - ue spec] Attempting candidate %d Aggregation Level %d DCI length %d at CCE %d/%d (CCEmap %x,CCEmap_cand %x) format %d\n",
+                pdcch_vars[eNB_id]->num_pdcch_symbols,m,L2,sizeof_bits,CCEind,nCCE,*CCEmap,CCEmap_mask,format_c);
 
-      dci_decoding(sizeof_bits,
+       dci_decoding(sizeof_bits,
                    L,
                    &pdcch_vars[eNB_id]->e_rx[CCEind*72],
-                   &dci_decoded_output[subframe&0x1][0]);
+                   &dci_decoded_output[current_thread_id][0]);
       /*
         for (i=0;i<3+(sizeof_bits>>3);i++)
         printf("dci_decoded_output[%d] => %x\n",i,dci_decoded_output[i]);
       */
-      crc = (crc16(&dci_decoded_output[subframe&0x1][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[subframe&0x1][0],sizeof_bits);
-      //#ifdef DEBUG_DCI_DECODING
-      LOG_D(PHY,"crc =>%x\n",crc);
-      //#endif
+
+      crc = (crc16(&dci_decoded_output[current_thread_id][0],sizeof_bits)>>16) ^ extract_crc(&dci_decoded_output[current_thread_id][0],sizeof_bits);
+#ifdef DEBUG_DCI_DECODING
+      printf("crc =>%x\n",crc);
+#endif
 
       if (((L>1) && ((crc == si_rnti)||
 		     (crc == p_rnti)||
@@ -2737,29 +2887,29 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
 
         //printf("DCI FOUND !!! crc =>%x,  sizeof_bits %d, sizeof_bytes %d \n",crc, sizeof_bits, sizeof_bytes);
         if (sizeof_bytes<=4) {
-          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[subframe&0x1][0];
-          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe&0x1][1];
-          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe&0x1][2];
-          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe&0x1][3];
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][3];
 #ifdef DEBUG_DCI_DECODING
-          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[subframe&0x1][0],
-                  dci_decoded_output[subframe&0x1][1],
-                  dci_decoded_output[subframe&0x1][2],
-                  dci_decoded_output[subframe&0x1][3]);
+          printf("DCI => %x,%x,%x,%x\n",dci_decoded_output[current_thread_id][0],
+                  dci_decoded_output[current_thread_id][1],
+                  dci_decoded_output[current_thread_id][2],
+                  dci_decoded_output[current_thread_id][3]);
 #endif
         } else {
-          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[subframe&0x1][0];
-          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[subframe&0x1][1];
-          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[subframe&0x1][2];
-          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[subframe&0x1][3];
-          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[subframe&0x1][4];
-          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[subframe&0x1][5];
-          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[subframe&0x1][6];
-          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[subframe&0x1][7];
+          dci_alloc[*dci_cnt].dci_pdu[7] = dci_decoded_output[current_thread_id][0];
+          dci_alloc[*dci_cnt].dci_pdu[6] = dci_decoded_output[current_thread_id][1];
+          dci_alloc[*dci_cnt].dci_pdu[5] = dci_decoded_output[current_thread_id][2];
+          dci_alloc[*dci_cnt].dci_pdu[4] = dci_decoded_output[current_thread_id][3];
+          dci_alloc[*dci_cnt].dci_pdu[3] = dci_decoded_output[current_thread_id][4];
+          dci_alloc[*dci_cnt].dci_pdu[2] = dci_decoded_output[current_thread_id][5];
+          dci_alloc[*dci_cnt].dci_pdu[1] = dci_decoded_output[current_thread_id][6];
+          dci_alloc[*dci_cnt].dci_pdu[0] = dci_decoded_output[current_thread_id][7];
 #ifdef DEBUG_DCI_DECODING
           printf("DCI => %x,%x,%x,%x,%x,%x,%x,%x\n",
-              dci_decoded_output[subframe&0x1][0],dci_decoded_output[subframe&0x1][1],dci_decoded_output[subframe&0x1][2],dci_decoded_output[subframe&0x1][3],
-              dci_decoded_output[subframe&0x1][4],dci_decoded_output[subframe&0x1][5],dci_decoded_output[subframe&0x1][6],dci_decoded_output[subframe&0x1][7]);
+              dci_decoded_output[current_thread_id][0],dci_decoded_output[current_thread_id][1],dci_decoded_output[current_thread_id][2],dci_decoded_output[current_thread_id][3],
+              dci_decoded_output[current_thread_id][4],dci_decoded_output[current_thread_id][5],dci_decoded_output[current_thread_id][6],dci_decoded_output[current_thread_id][7]);
 #endif
         }
 
@@ -2776,7 +2926,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
           *dci_cnt = *dci_cnt+1;
         } else if (crc==pdcch_vars[eNB_id]->crnti) {
 
-          if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[subframe&0x1][0]&0x80)==0)) {// check if pdu is format 0 or 1A
+          if ((mode&UL_DCI)&&(format_c == format0)&&((dci_decoded_output[current_thread_id][0]&0x80)==0)) {// check if pdu is format 0 or 1A
             if (*format0_found == 0) {
               dci_alloc[*dci_cnt].format     = format0;
               *format0_found = 1;
@@ -2798,7 +2948,7 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
           }
         }
 
-        LOG_D(PHY,"DCI decoding CRNTI  [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2);
+        //LOG_I(PHY,"DCI decoding CRNTI  [format: %d, nCCE[subframe: %d]: %d ], AggregationLevel %d \n",format_c, subframe, pdcch_vars[eNB_id]->nCCE[subframe],L2);
         //  memcpy(&dci_alloc[*dci_cnt].dci_pdu[0],dci_decoded_output,sizeof_bytes);
 
 
@@ -2822,19 +2972,200 @@ void dci_decoding_procedure0(LTE_UE_PDCCH **pdcch_vars,
         }
 
 #ifdef DEBUG_DCI_DECODING
-        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x)\n",
-              *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap);
+        LOG_I(PHY,"[DCI search] Found DCI %d rnti %x Aggregation %d length %d format %s in CCE %d (CCEmap %x) candidate %d / %d \n",
+              *dci_cnt,crc,1<<L,sizeof_bits,dci_format_strings[dci_alloc[*dci_cnt-1].format],CCEind,*CCEmap,m,nb_candidates );
         dump_dci(frame_parms,&dci_alloc[*dci_cnt-1]);
 
 #endif
-
-        //  if (crc==pdcch_vars[eNB_id]->crnti)
-        //    return;
+         return;
       } // rnti match
     }  // CCEmap_cand == 0
+/*    
+	if ( agregationLevel != 0xFF &&
+        (format_c == format0 && m==0 && si_rnti != SI_RNTI))
+    {
+      //Only valid for OAI : Save some processing time when looking for DCI format0. From the log we see the DCI only on candidate 0.
+      return;
+    }
+*/
   } // candidate loop
 }
 
+uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
+                                DCI_ALLOC_t *dci_alloc,
+                                uint8_t DCIFormat,
+                                uint8_t agregationLevel,
+                                int16_t eNB_id,
+                                uint8_t subframe)
+{
+
+  uint8_t  dci_cnt=0,old_dci_cnt=0;
+  uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
+  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]];
+  LTE_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
+  uint8_t mi = get_mi(&ue->frame_parms,subframe);
+  uint16_t ra_rnti=99;
+  uint8_t format0_found=0,format_c_found=0;
+  uint8_t tmode = ue->transmission_mode[eNB_id];
+  uint8_t frame_type = frame_parms->frame_type;
+  uint8_t format0_size_bits=0,format0_size_bytes=0;
+  uint8_t format1_size_bits=0,format1_size_bytes=0;
+  dci_detect_mode_t mode = dci_detect_mode_select(&ue->frame_parms,subframe);
+
+  switch (frame_parms->N_RB_DL) {
+  case 6:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_1_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
+
+    } else {
+      format0_size_bits  = sizeof_DCI0_1_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_1_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_1_5MHz_FDD_t);
+    }
+
+    break;
+
+  case 25:
+  default:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_5MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_TDD_t);
+    } else {
+      format0_size_bits  = sizeof_DCI0_5MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_5MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_5MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_5MHz_FDD_t);
+    }
+
+    break;
+
+  case 50:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_10MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_TDD_t);
+
+    } else {
+      format0_size_bits  = sizeof_DCI0_10MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_10MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_10MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_10MHz_FDD_t);
+    }
+
+    break;
+
+  case 100:
+    if (frame_type == TDD) {
+      format0_size_bits  = sizeof_DCI0_20MHz_TDD_1_6_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_TDD_1_6_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_TDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_TDD_t);
+    } else {
+      format0_size_bits  = sizeof_DCI0_20MHz_FDD_t;
+      format0_size_bytes = sizeof(DCI0_20MHz_FDD_t);
+      format1_size_bits  = sizeof_DCI1_20MHz_FDD_t;
+      format1_size_bytes = sizeof(DCI1_20MHz_FDD_t);
+    }
+
+    break;
+  }
+
+  if (ue->prach_resources[eNB_id])
+    ra_rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+
+  // Now check UE_SPEC format0/1A ue_spec search spaces at aggregation 8
+  dci_decoding_procedure0(pdcch_vars,0,mode,
+                          subframe,
+                          dci_alloc,
+                          eNB_id,
+                          ue->current_thread_id[subframe],
+                          frame_parms,
+                          mi,
+                          ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                          ra_rnti,
+              P_RNTI,
+              agregationLevel,
+                          format1A,
+                          format1A,
+                          format1A,
+                          format0,
+                          format0_size_bits,
+                          format0_size_bytes,
+                          &dci_cnt,
+                          &format0_found,
+                          &format_c_found,
+                          &CCEmap0,
+                          &CCEmap1,
+                          &CCEmap2);
+
+  if ((CCEmap0==0xffff)||
+      ((format0_found==1)&&(format_c_found==1)))
+    return(dci_cnt);
+
+  if (DCIFormat == 1)
+  {
+      if ((tmode < 3) || (tmode == 7)) {
+          //printf("Crnti decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);
+
+          // Now check UE_SPEC format 1 search spaces at aggregation 1
+
+           //printf("[DCI search] Format 1/1A aggregation 1\n");
+
+          old_dci_cnt=dci_cnt;
+          dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
+                                  dci_alloc,
+                                  eNB_id,
+                                  ue->current_thread_id[subframe],
+                                  frame_parms,
+                                  mi,
+                                  ((ue->decode_SIB == 1) ? SI_RNTI : 0),
+                                  ra_rnti,
+                                  P_RNTI,
+                                  0,
+                                  format1A,
+                                  format1A,
+                                  format1A,
+                                  format1,
+                                  format1_size_bits,
+                                  format1_size_bytes,
+                                  &dci_cnt,
+                                  &format0_found,
+                                  &format_c_found,
+                                  &CCEmap0,
+                                  &CCEmap1,
+                                  &CCEmap2);
+
+          if ((CCEmap0==0xffff) ||
+              (format_c_found==1))
+            return(dci_cnt);
+
+          if (dci_cnt>old_dci_cnt)
+            return(dci_cnt);
+
+          //printf("Crnti 1 decoding frame param agregation %d DCI %d \n",agregationLevel,DCIFormat);
+
+      }
+      else
+      {
+          AssertFatal(0,"Other Transmission mode not yet coded\n");
+      }
+  }
+  else
+  {
+     AssertFatal(0,"DCI format %d not yet implemented \n",DCIFormat);
+  }
+
+  return(dci_cnt);
+
+}
+
 uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                                 DCI_ALLOC_t *dci_alloc,
                                 int do_common,
@@ -2844,7 +3175,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
 
   uint8_t  dci_cnt=0,old_dci_cnt=0;
   uint32_t CCEmap0=0,CCEmap1=0,CCEmap2=0;
-  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[subframe & 0x1];
+  LTE_UE_PDCCH **pdcch_vars = ue->pdcch_vars[ue->current_thread_id[subframe]];
   LTE_DL_FRAME_PARMS *frame_parms  = &ue->frame_parms;
   uint8_t mi = get_mi(&ue->frame_parms,subframe);
   uint16_t ra_rnti=99;
@@ -3063,6 +3394,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0) ,
@@ -3091,6 +3423,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3123,6 +3456,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3151,6 +3485,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,1,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3185,6 +3520,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3208,12 +3544,16 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
-  //  printf("[DCI search] Format 0 aggregation 4\n");
+  //printf("[DCI search] Format 0 aggregation 1 dci_cnt %d\n",dci_cnt);
+
+  if (dci_cnt == 0)
+  {
   // Now check UE_SPEC format 0 search spaces at aggregation 4
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3237,16 +3577,18 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
-  if ((CCEmap0==0xffff)||
-      ((format0_found==1)&&(format_c_found==1)))
-    return(dci_cnt);
 
-  //  printf("[DCI search] Format 0 aggregation 2\n");
+  //printf("[DCI search] Format 0 aggregation 2 dci_cnt %d\n",dci_cnt);
+  }
+
+  if (dci_cnt == 0)
+  {
   // Now check UE_SPEC format 0 search spaces at aggregation 2
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3270,12 +3612,17 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
-  //  printf("[DCI search] Format 0 aggregation 4\n");
+  //printf("[DCI search] Format 0 aggregation 4 dci_cnt %d\n",dci_cnt);
+  }
+
+  if (dci_cnt == 0)
+  {
   // Now check UE_SPEC format 0 search spaces at aggregation 1
   dci_decoding_procedure0(pdcch_vars,0,mode,
                           subframe,
                           dci_alloc,
                           eNB_id,
+                          ue->current_thread_id[subframe],
                           frame_parms,
                           mi,
                           ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3299,9 +3646,9 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
       ((format0_found==1)&&(format_c_found==1)))
     return(dci_cnt);
 
+  //printf("[DCI search] Format 0 aggregation 8 dci_cnt %d\n",dci_cnt);
 
-
-
+  }
   // These are for CRNTI based on transmission mode
   if ((tmode < 3) || (tmode == 7)) {
     // Now check UE_SPEC format 1 search spaces at aggregation 1
@@ -3309,6 +3656,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3327,6 +3675,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 1 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff) ||
         (format_c_found==1))
@@ -3340,6 +3689,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3358,7 +3708,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
-
+    //printf("[DCI search] Format 1 aggregation 2 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff)||
         (format_c_found==1))
@@ -3372,6 +3722,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3390,6 +3741,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 4 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff)||
         ((format0_found==1)&&(format_c_found==1)))
@@ -3404,6 +3756,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
     dci_decoding_procedure0(pdcch_vars,0,mode,subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3422,6 +3775,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             &CCEmap0,
                             &CCEmap1,
                             &CCEmap2);
+    //printf("[DCI search] Format 1 aggregation 8 dci_cnt %d\n",dci_cnt);
 
     if ((CCEmap0==0xffff)||
         ((format0_found==1)&&(format_c_found==1)))
@@ -3441,6 +3795,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3476,6 +3831,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3510,6 +3866,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3545,6 +3902,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3579,6 +3937,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3611,6 +3970,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3643,6 +4003,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3676,6 +4037,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3706,6 +4068,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3739,6 +4102,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3771,6 +4135,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
@@ -3805,6 +4170,7 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *ue,
                             subframe,
                             dci_alloc,
                             eNB_id,
+                            ue->current_thread_id[subframe],
                             frame_parms,
                             mi,
                             ((ue->decode_SIB == 1) ? SI_RNTI : 0),
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 66f86e44afec0f662ec31079399c5c154fb3b4b1..75ce744247e727b5028c530c91b204f9aad2c7d3 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -1220,6 +1220,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci
 
     if (dlsch0_harq->round == 0) {
       dlsch0_harq->status = ACTIVE;
+
       //            printf("Setting DLSCH process %d to ACTIVE\n",rel8->harq_process);
       // MCS and TBS don't change across HARQ rounds
       dlsch0_harq->mcs         = rel8->mcs_1;
@@ -1375,6 +1376,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci
 
     // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
     // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated
+
     // This must be set as in TM4, does not work properly now.
     if (rel8->transport_block_to_codeword_swap_flag == 1) {
       dlsch0 = eNB->dlsch[UE_id][1];
@@ -2470,8 +2472,6 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
 
 int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
 {
-
-
   switch (dci->format) {
 
   case format0:   // This is an UL SCH allocation so nothing here, inform MAC
@@ -4433,6 +4433,7 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format,
     LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC        %d\n", TPC);
 #endif
 
+
     // I- check dci content minimum coherency
     if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0)
     {
@@ -4573,7 +4574,7 @@ int check_dci_format1c_coherency(uint8_t N_RB_DL,
 
     // I- check dci content minimum coherency
 
-    if((rnti!=si_rnti) || (rnti!=p_rnti) || (rnti!=ra_rnti))
+    if((rnti!=si_rnti) && (rnti!=p_rnti) && (rnti!=ra_rnti))
       return(0);
 
     switch (N_RB_DL) {
@@ -4684,22 +4685,15 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
       }
     }
 
-    /*
-    if((pdlsch0_harq->round > 0) && (mcs1 != pdlsch0_harq->mcs))
-    {
-      // DCI false detection
-      return(0);
-    }*/
-
 
-    if((pdlsch0_harq->round == 0) && (rv1 > 0))
+    if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0))
     {
       // DCI false detection
         LOG_I(PHY,"bad rv1\n");
       return(0);
     }
 
-    if((pdlsch1_harq->round == 0) && (rv2 > 0))
+    if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0))
     {
       // DCI false detection
         LOG_I(PHY,"bad rv2\n");
@@ -4777,10 +4771,70 @@ int check_dci_format2_2a_coherency(DCI_format_t dci_format,
    return(1);
 }
 
+void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms,
+                        LTE_UE_PDCCH *pdcch_vars,
+                        LTE_UE_PDSCH *pdsch_vars,
+                        LTE_DL_UE_HARQ_t *dlsch0_harq,
+                        uint8_t nb_rb_alloc,
+                        uint8_t subframe)
+{
+    uint32_t pbch_pss_sss_re;
+    uint32_t crs_re;
+    uint32_t granted_re;
+    uint32_t data_re;
+    uint32_t llr_offset;
+    uint8_t symbol;
+    uint8_t symbol_mod;
+
+    pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0;
+
+    //LOG_I(PHY,"compute_llr_offset:  nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm);
+
+    //dlsch0_harq->rb_alloc_even;
+    //dlsch0_harq->rb_alloc_odd;
+
+    for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++)
+    {
+        symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
+        if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp))
+        {
+	  if (frame_parms->nb_antennas_tx == 2) 
+	    crs_re = 4;
+	  else
+	    crs_re = 2;
+        }
+        else
+        {
+            crs_re = 0;
+        }
+
+        granted_re = nb_rb_alloc * (12-crs_re);
+        pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol);
+        pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12);
+        data_re = granted_re - pbch_pss_sss_re;
+        llr_offset = data_re * dlsch0_harq->Qm * 2;
+
+        pdsch_vars->llr_length[symbol]   = data_re;
+        if(symbol < (frame_parms->symbols_per_tti-1))
+          pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset;
+
+        //LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb);
+        //LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re);
+        //LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re);
+        //LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re);
+
+
+
+        //LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol,
+        //      pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]);
+    }
+}
 void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                                     uint8_t N_RB_DL,
                                     DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                     LTE_DL_FRAME_PARMS *frame_parms,
+                                    LTE_UE_PDCCH *pdcch_vars,
+                                    LTE_UE_PDSCH *pdsch_vars,
                                     uint8_t  subframe,
                                     uint16_t rnti,
 									uint16_t tc_rnti,
@@ -4801,8 +4855,10 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
     uint8_t  rah       = pdci_info_extarcted->rah;
     uint8_t  dai       = pdci_info_extarcted->dai;
 
+
     uint8_t  NPRB      = 0;
     uint8_t  NPRB4TBS  = 0;
+    uint8_t  nb_rb_alloc = 0;
 
     if(dci_format == format1A)
     {
@@ -4842,13 +4898,16 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                 NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
                 break;
             }
+
 	  */
+	  nb_rb_alloc = NPRB;
         }
     }
     else // format1
     {
         NPRB = conv_nprb(rah, rballoc, N_RB_DL);
 	NPRB4TBS=NPRB;
+	nb_rb_alloc = NPRB;
     }
 
     pdlsch0->current_harq_pid = harq_pid;
@@ -4860,7 +4919,6 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
     if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
     {
         pdlsch0_harq->round    = 0;
-        pdlsch0_harq->first_tx = 1;
         pdlsch0_harq->status   = ACTIVE;
     }
     else //CRNTI
@@ -4872,27 +4930,38 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
 		rnti,harq_pid,pdlsch0_harq->DCINdi);
     	}
 
-        // DCI has been toggled or this is the first transmission
-        if (ndi1!=pdlsch0_harq->DCINdi)
+        // NDI has been toggled or this is the first transmission
+        if ((ndi1!=pdlsch0_harq->DCINdi) || (pdlsch0_harq->first_tx==1))
         {
             pdlsch0_harq->round    = 0;
-            pdlsch0_harq->first_tx = 1;
+            pdlsch0_harq->first_tx = 0;
             pdlsch0_harq->status   = ACTIVE;
-        }
 
-        if( ((ndi1 == pdlsch0_harq->DCINdi) && (pdlsch0_harq->round == 0)) ||
-            ((rv1  != 0) && (pdlsch0_harq->round == 0))
-          )
+        }else if (rv1  != 0 )
+            //NDI has not been toggled but rv was increased by eNB: retransmission
         {
-            LOG_D(PHY,"skip pdsch decoding and report ack\n");
-            // skip pdsch decoding and report ack
-            pdlsch0_harq->status   = SCH_IDLE;
-            pdlsch0->active       = 0;
-            pdlsch0->harq_ack[subframe].ack = 1;
-            pdlsch0->harq_ack[subframe].harq_id = harq_pid;
-            pdlsch0->harq_ack[subframe].send_harq_status = 1;
-
-            pdlsch0_harq->first_tx = 0;
+            if (pdlsch0_harq->status == SCH_IDLE)
+                //packet was actually decoded in previous transmission (ACK was missed by eNB)
+                //However, the round is not a good check as it might have been decoded in a retransmission prior to this one.
+            {
+                LOG_D(PHY,"skip pdsch decoding and report ack\n");
+                // skip pdsch decoding and report ack
+                //pdlsch0_harq->status   = SCH_IDLE;
+                pdlsch0->active       = 0;
+                pdlsch0->harq_ack[subframe].ack = 1;
+                pdlsch0->harq_ack[subframe].harq_id = harq_pid;
+                pdlsch0->harq_ack[subframe].send_harq_status = 1;
+
+                //pdlsch0_harq->first_tx = 0;
+            }
+            else  //normal retransmission
+            {
+                // nothing special to do
+            }
+        }
+        else
+        {
+            pdlsch0_harq->status   = ACTIVE;
         }
     }
 
@@ -5003,7 +5072,6 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
         pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2];
         pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3];
     }
-
     if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
     {
         pdlsch0_harq->TBS = TBStable[mcs1][NPRB4TBS-1];
@@ -5017,11 +5085,20 @@ void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
             pdlsch0_harq->Qm  = get_Qm(mcs1);
         }
     }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       nb_rb_alloc,
+                       subframe);
 }
 
 void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
                                   DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                   LTE_DL_FRAME_PARMS *frame_parms,
+                                  LTE_UE_PDCCH *pdcch_vars,
+                                  LTE_UE_PDSCH *pdsch_vars,
                                   uint32_t rnti,
                                   uint32_t si_rnti,
                                   uint32_t ra_rnti,
@@ -5124,6 +5201,14 @@ void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
         AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL);
         break;
     }
+
+    compute_llr_offset(frame_parms,
+                       pdcch_vars,
+                       pdsch_vars,
+                       pdlsch0_harq,
+                       pdlsch0_harq->nb_rb,
+                       subframe);
+
 }
 
 void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq)
@@ -5152,6 +5237,9 @@ switch (tpmi) {
                 dlsch1_harq->pmi_alloc   = pmi_alloc;
                 dlsch0_harq->pmi_alloc   = pmi_alloc^0x1555;
             }
+#ifdef DEBUG_HARQ
+              printf ("\n \n compute_precoding_info_2cw pmi_alloc_new = %d\n", dlsch0_harq->pmi_alloc);
+  #endif
           break;
           default:
           break;
@@ -5183,20 +5271,17 @@ switch (tpmi) {
             break;
             case 5:
               dlsch_harq->mimo_mode   = PUSCH_PRECODING0;
-              dlsch_harq->pmi_alloc   = pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0);
-  #ifdef DEBUG_HARQ
-              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc);
-  #endif
+              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0);
             break;
             case 6:
               dlsch_harq->mimo_mode   = PUSCH_PRECODING1;
-              dlsch_harq->pmi_alloc   = pmi_alloc;;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
+              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
+            break;
+            }
   #ifdef DEBUG_HARQ
-              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d\n", dlsch0->pmi_alloc);
+              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi);
   #endif
-            break;
             }
-}
 
 void compute_precoding_info_format2A(uint8_t tpmi,
                                      uint8_t nb_antenna_ports_eNB,
@@ -5297,6 +5382,8 @@ void compute_precoding_info_format2A(uint8_t tpmi,
 void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
                                     DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                     LTE_DL_FRAME_PARMS *frame_parms,
+                                    LTE_UE_PDCCH *pdcch_vars,
+                                    LTE_UE_PDSCH *pdsch_vars,
                                     uint16_t rnti,
                                     uint8_t subframe,
                                     LTE_DL_UE_HARQ_t *dlsch0_harq,
@@ -5318,14 +5405,11 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
     uint8_t  ndi1     = pdci_info_extarcted->ndi1;
     uint8_t  ndi2     = pdci_info_extarcted->ndi2;
 
-    uint8_t TB0_active = 0;
-    uint8_t TB1_active = 0;
-
+    uint8_t TB0_active = 1;
+    uint8_t TB1_active = 1;
 
+   // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc);
 
-      // check if either TB is disabled (see 36-213 V8.6 p. 26)
-      TB0_active = 1;
-      TB1_active = 1;
 
       if ((rv1 == 1) && (mcs1 == 0)) {
         TB0_active=0;
@@ -5373,6 +5457,16 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
         dlsch1_harq->codeword = 0;
       }
 
+
+      if (!TB0_active && TB1_active){
+        dlsch1_harq->codeword = 0;
+      }
+
+      if (TB0_active && !TB1_active){
+        dlsch0_harq->codeword = 0;
+      }
+
+
       if (TB0_active==0) {
         dlsch0_harq->status = SCH_IDLE;
         pdlsch0->active     = 0;
@@ -5386,9 +5480,9 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
         pdlsch1->active     = 0;
       }
 
-//#ifdef DEBUG_HARQ
+#ifdef DEBUG_HARQ
       printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-//#endif
+#endif
 
       // compute resource allocation
       if (TB0_active == 1){
@@ -5443,10 +5537,13 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
       {
       if ((TB0_active) && (TB1_active)){  //two CW active
         compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq);
+
+   //   printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
       } else if ((TB0_active) && (!TB1_active))  { // only CW 0 active
         compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq);
       } else {
-        compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch1_harq);
+        compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq);
+       // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi);
       }
       //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode);
       if ((frame_parms->nb_antenna_ports_eNB == 1) && (TB0_active))
@@ -5461,11 +5558,14 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
                                       dlsch0_harq,
                                       dlsch1_harq);
       }
-
+  //    printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
       // reset round + compute Qm
       if (TB0_active) {
+       // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx);
         if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1))  {
           dlsch0_harq->round = 0;
+           dlsch0_harq->status = ACTIVE;
+           dlsch0_harq->DCINdi = ndi1;
 
           //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n",
           //           subframe,harq_pid,dlsch0_harq->round);
@@ -5473,18 +5573,18 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
             LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n");
             dlsch0_harq->first_tx = 0;
           }
-        }else{
-         if(dlsch0_harq->round == 0) {
-#if 0
+        }
+	/*else if (rv1  != 0 )
+	  //NDI has not been toggled but rv was increased by eNB: retransmission
+	  {
+	    if(dlsch0_harq->status == SCH_IDLE) {
             // skip pdsch decoding and report ack
-            dlsch0_harq->status   = SCH_IDLE;
+	      //dlsch0_harq->status   = SCH_IDLE;
             pdlsch0->active       = 0;
             pdlsch0->harq_ack[subframe].ack = 1;
             pdlsch0->harq_ack[subframe].harq_id = harq_pid;
             pdlsch0->harq_ack[subframe].send_harq_status = 1;
-#endif
-         }
-        }
+	    }*/
 
         // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
         // PDCCH for the same trasport block using Imcs in [0 .. 28]
@@ -5507,27 +5607,33 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
             dlsch0_harq->Qm = (mcs1-28)<<1;
       }
 
+   //   printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+
       if (TB1_active) {
+       // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx);
         if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) {
           dlsch1_harq->round = 0;
+          dlsch1_harq->status = ACTIVE;
+          dlsch1_harq->DCINdi = ndi2;
           //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n",
           //           subframe,harq_pid,dlsch0_harq->round);
           if (dlsch1_harq->first_tx==1) {
             LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n");
             dlsch1_harq->first_tx = 0;
           }
-        }else{
-#if 0
-         if(dlsch1_harq->round == 0) {
+        }
+	/*else if (rv1  != 0 )
+	//NDI has not been toggled but rv was increased by eNB: retransmission
+	  {
+	    if(dlsch1_harq->status == SCH_IDLE) {
             // skip pdsch decoding and report ack
-            dlsch1_harq->status   = SCH_IDLE;
+	      //dlsch1_harq->status   = SCH_IDLE;
             pdlsch1->active       = 0;
             pdlsch1->harq_ack[subframe].ack = 1;
             pdlsch1->harq_ack[subframe].harq_id = harq_pid;
             pdlsch1->harq_ack[subframe].send_harq_status = 1;
          }
-#endif
-        }
+	  }*/
 
         // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
         // PDCCH for the same trasport block using Imcs in [0 .. 28]
@@ -5548,18 +5654,25 @@ void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
             dlsch1_harq->Qm = (mcs2-28)<<1;
       }
 
-//#ifdef DEBUG_HARQ
-      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
-//#endif
 
-  #ifdef DEBUG_HARQ
+      compute_llr_offset(frame_parms,
+                         pdcch_vars,
+                         pdsch_vars,
+                         dlsch0_harq,
+                         dlsch0_harq->nb_rb,
+                         subframe);
+
+
+ /* #ifdef DEBUG_HARQ
+      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
+      printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active);
       if (dlsch0 != NULL && dlsch1 != NULL)
         printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status);
       else if (dlsch0 == NULL && dlsch1 != NULL)
         printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status);
       else if (dlsch0 != NULL && dlsch1 == NULL)
         printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status);
-  #endif
+  #endif*/
 }
 
 int generate_ue_dlsch_params_from_dci(int frame,
@@ -5567,6 +5680,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       void *dci_pdu,
                                       uint16_t rnti,
                                       DCI_format_t dci_format,
+                                      LTE_UE_PDCCH *pdcch_vars,
+                                      LTE_UE_PDSCH *pdsch_vars,
                                       LTE_UE_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
@@ -5577,12 +5692,12 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       uint16_t tc_rnti)
 {
 
-
     uint8_t harq_pid=0;
     uint8_t frame_type=frame_parms->frame_type;
     uint8_t tpmi=0;
     LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
     LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+
     DCI_INFO_EXTRACTED_t dci_info_extarcted;
     uint8_t status=0;
 
@@ -5646,7 +5761,10 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                               &dci_info_extarcted,
                                               dlsch0_harq);
       if(status == 0)
+      {
+        printf("bad DCI 1A !!! \n");
         return(-1);
+      }
 
       // dci is correct ==> update internal structure and prepare dl decoding
 #ifdef DEBUG_DCI
@@ -5656,6 +5774,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                      frame_parms->N_RB_DL,
                                      &dci_info_extarcted,
                                      frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
                                      subframe,
                                      rnti,
 									 tc_rnti,
@@ -5706,6 +5826,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
       prepare_dl_decoding_format1C(frame_parms->N_RB_DL,
                                    &dci_info_extarcted,
                                    frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
                                    rnti,
                                    si_rnti,
                                    ra_rnti,
@@ -5747,7 +5869,11 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                               &dci_info_extarcted,
                                               dlsch0_harq);
       if(status == 0)
-        return(-1);
+      {
+          printf("bad DCI 1 !!! \n");
+          return(-1);
+      }
+
 
       // dci is correct ==> update internal structure and prepare dl decoding
 #ifdef DEBUG_DCI
@@ -5757,6 +5883,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                      frame_parms->N_RB_DL,
                                      &dci_info_extarcted,
                                      frame_parms,
+                                     pdcch_vars,
+                                     pdsch_vars,
                                      subframe,
                                      rnti,
 									 tc_rnti,
@@ -5778,20 +5906,19 @@ int generate_ue_dlsch_params_from_dci(int frame,
                 dci_pdu,
                 &dci_info_extarcted);
 
+
         // check dci content
-        dlsch[0]->active = 0;
-        dlsch[1]->active = 0;
+        dlsch[0]->active = 1;
+        dlsch[1]->active = 1;
 
-        if (dci_info_extarcted.tb_swap == 0) {
             dlsch0 = dlsch[0];
             dlsch1 = dlsch[1];
-        } else {
-            dlsch0 = dlsch[1];
-            dlsch1 = dlsch[0];
-        }
 
-        dlsch0_harq = dlsch0->harq_processes[harq_pid];
-        dlsch1_harq = dlsch1->harq_processes[harq_pid];
+    dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
+    dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];
+   // printf("before coherency dlsch[1]->pmi_alloc %d\n",dlsch[1]->pmi_alloc);
+   // printf("before coherency dlsch1->pmi_alloc %d\n",dlsch1->pmi_alloc);
+   // printf("before coherency dlsch1_harq->pmi_alloc %d\n",dlsch1_harq->pmi_alloc);
 
         //LOG_I(PHY,"[DCI-format2] check dci content \n");
         status = check_dci_format2_2a_coherency(format2,
@@ -5806,18 +5933,20 @@ int generate_ue_dlsch_params_from_dci(int frame,
         if(status == 0)
             return(-1);
 
+
         // dci is correct ==> update internal structure and prepare dl decoding
         //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n");
         prepare_dl_decoding_format2_2A(format2,
                 &dci_info_extarcted,
                 frame_parms,
+                pdcch_vars,
+                pdsch_vars,
                 rnti,
                 subframe,
                 dlsch0_harq,
                 dlsch1_harq,
                 dlsch0,
                 dlsch1);
-
     }
     break;
 
@@ -5865,6 +5994,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
     prepare_dl_decoding_format2_2A(format2A,
                                    &dci_info_extarcted,
                                    frame_parms,
+                                   pdcch_vars,
+                                   pdsch_vars,
                                    rnti,
                                    subframe,
                                    dlsch0_harq,
@@ -6003,11 +6134,15 @@ int generate_ue_dlsch_params_from_dci(int frame,
         dlsch0_harq->mimo_mode   = SISO;
 
 
-      if (dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) {
+      if ((dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) ||
+	(dlsch0_harq->first_tx==1)) {
 
         dlsch0_harq->round = 0;
+	dlsch0_harq->first_tx = 0;
         dlsch0_harq->status = ACTIVE;
-      } else if (dlsch0_harq->status == SCH_IDLE) { // we got an Ndi = 0 for a previously decoded process,
+      }
+      /*
+	else if (dlsch0_harq->status == SCH_IDLE) { // we got same ndi for a previously decoded process,
         // this happens if either another harq process in the same
         // is NAK or an ACK was not received
 
@@ -6017,6 +6152,7 @@ int generate_ue_dlsch_params_from_dci(int frame,
         dlsch0->active = 0;
         return(0);
       }
+      */
 
       dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
       dlsch0_harq->mcs    = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
@@ -6044,23 +6180,21 @@ int generate_ue_dlsch_params_from_dci(int frame,
       break;
     }
 
-
-#ifdef DEBUG_DCI
+#ifdef UE_DEBUG_TRACE
 
     if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
-      printf("dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe);
-      printf("PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
-      printf("PDSCH dlsch0 UE: NBRB     %d\n",dlsch0_harq->nb_rb);
-      printf("PDSCH dlsch0 UE: rballoc  %x\n",dlsch0_harq->rb_alloc_even[0]);
-      printf("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid);
-      //printf("PDSCH dlsch0 UE: tpc      %d\n",TPC);
-      printf("PDSCH dlsch0 UE: g        %d\n",dlsch[0]->g_pucch);
-      printf("PDSCH dlsch0 UE: round    %d\n",dlsch0_harq->round);
-      printf("PDSCH dlsch0 UE: DCINdi   %d\n",dlsch0_harq->DCINdi);
-      printf("PDSCH dlsch0 UE: rvidx    %d\n",dlsch0_harq->rvidx);
-      printf("PDSCH dlsch0 UE: TBS      %d\n",dlsch0_harq->TBS);
-      printf("PDSCH dlsch0 UE: mcs      %d\n",dlsch0_harq->mcs);
-      printf("PDSCH dlsch0 UE: pwr_off  %d\n",dlsch0_harq->dl_power_off);
+        LOG_I(PHY,"dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe);
+        LOG_I(PHY,"PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
+        LOG_D(PHY,"PDSCH dlsch0 UE: NBRB     %d\n",dlsch0_harq->nb_rb);
+        LOG_D(PHY,"PDSCH dlsch0 UE: rballoc  %x\n",dlsch0_harq->rb_alloc_even[0]);
+        LOG_I(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",dci_info_extarcted.harq_pid);
+        LOG_I(PHY,"PDSCH dlsch0 UE: g        %d\n",dlsch[0]->g_pucch);
+        LOG_D(PHY,"PDSCH dlsch0 UE: round    %d\n",dlsch0_harq->round);
+        LOG_D(PHY,"PDSCH dlsch0 UE: DCINdi   %d\n",dlsch0_harq->DCINdi);
+        LOG_D(PHY,"PDSCH dlsch0 UE: rvidx    %d\n",dlsch0_harq->rvidx);
+        LOG_D(PHY,"PDSCH dlsch0 UE: TBS      %d\n",dlsch0_harq->TBS);
+        LOG_D(PHY,"PDSCH dlsch0 UE: mcs      %d\n",dlsch0_harq->mcs);
+        LOG_D(PHY,"PDSCH dlsch0 UE: pwr_off  %d\n",dlsch0_harq->dl_power_off);
     }
 #endif
 
@@ -6851,7 +6985,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
   uint8_t transmission_mode = ue->transmission_mode[eNB_id];
   ANFBmode_t AckNackFBMode;
   LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id];
-  LTE_UE_DLSCH_t **dlsch = ue->dlsch[subframe&0x1][0];
+  LTE_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[subframe]][0];
   PHY_MEASUREMENTS *meas = &ue->measurements;
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   //  uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id];
@@ -7658,7 +7792,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
       //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);
       int dl_subframe = subframe;
 
-      if (ue->dlsch[dl_subframe&0x1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission
+      if (ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission
         ulsch->harq_processes[harq_pid]->O_ACK = 1;
       } else {
         ulsch->harq_processes[harq_pid]->O_ACK = 0;
@@ -7673,7 +7807,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
       if (ulsch->bundling)
         ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1;
       else
-        ulsch->harq_processes[harq_pid]->O_ACK = (dai+1)&3;
+        ulsch->harq_processes[harq_pid]->O_ACK = (dai >= 2)? 2 : (dai+1)&3; //(dai+1)&3;
 
       //      ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1;
     }
@@ -7744,28 +7878,28 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
 
   // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
 
-#ifdef DEBUG_DCI
-
-    printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe);
-    printf("Format 0 DCI : ulsch (ue): NBRB        %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
-    printf("Format 0 DCI :ulsch (ue): first_rb    %d\n",ulsch->harq_processes[harq_pid]->first_rb);
-    printf("Format 0 DCI :ulsch (ue): rballoc     %d\n",rballoc);
-    printf("Format 0 DCI :ulsch (ue): harq_pid    %d\n",harq_pid);
-    printf("Format 0 DCI :ulsch (ue): first_tx       %d\n",ulsch->harq_processes[harq_pid]->first_tx);
-    printf("Format 0 DCI :ulsch (ue): DCINdi       %d\n",ulsch->harq_processes[harq_pid]->DCINdi);
-    printf("Format 0 DCI :ulsch (ue): round       %d\n",ulsch->harq_processes[harq_pid]->round);
-    //printf("Format 0 DCI :ulsch (ue): TBS         %d\n",ulsch->harq_processes[harq_pid]->TBS);
-    printf("Format 0 DCI :ulsch (ue): mcs         %d\n",ulsch->harq_processes[harq_pid]->mcs);
-    //printf("Format 0 DCI :ulsch (ue): O           %d\n",ulsch->O);
-    //printf("Format 0 DCI :ulsch (ue): cqiReq      %d\n",cqi_req);
+#ifdef UE_DEBUG_TRACE
+
+    LOG_I(PHY,"Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe);
+    LOG_D(PHY,"Format 0 DCI : ulsch (ue): NBRB        %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_rb    %d\n",ulsch->harq_processes[harq_pid]->first_rb);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): rballoc     %d\n",rballoc);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): harq_pid    %d\n",harq_pid);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_tx       %d\n",ulsch->harq_processes[harq_pid]->first_tx);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): DCINdi       %d\n",ulsch->harq_processes[harq_pid]->DCINdi);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): round       %d\n",ulsch->harq_processes[harq_pid]->round);
+    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): TBS         %d\n",ulsch->harq_processes[harq_pid]->TBS);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): mcs         %d\n",ulsch->harq_processes[harq_pid]->mcs);
+    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): O           %d\n",ulsch->O);
+    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): cqiReq      %d\n",cqi_req);
     //if (frame_parms->frame_type == TDD)
-    //  printf("Format 0 DCI :ulsch (ue): O_ACK/DAI   %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai);
+    //  LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK/DAI   %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai);
     //else
-    //  printf("Format 0 DCI :ulsch (ue): O_ACK       %d\n",ulsch->harq_processes[harq_pid]->O_ACK);
+    //  LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK       %d\n",ulsch->harq_processes[harq_pid]->O_ACK);
 
-    printf("Format 0 DCI :ulsch (ue): Nsymb_pusch   %d\n",ulsch->Nsymb_pusch);
-    printf("Format 0 DCI :ulsch (ue): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
-    printf("Format 0 DCI :ulsch (ue): phich status  %d\n",ulsch->harq_processes[harq_pid]->status);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): Nsymb_pusch   %d\n",ulsch->Nsymb_pusch);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
+    LOG_D(PHY,"Format 0 DCI :ulsch (ue): phich status  %d\n",ulsch->harq_processes[harq_pid]->status);
 #else
     UNUSED_VARIABLE(dai);
 #endif
@@ -8417,7 +8551,7 @@ double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe)
   uint8_t transmission_mode = ue->transmission_mode[eNB_id];
   PHY_MEASUREMENTS *meas = &ue->measurements;
   LTE_DL_FRAME_PARMS *frame_parms =  &ue->frame_parms;
-  int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[subframe &0x1].dl_ch_estimates[eNB_id];
+  int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
   double *s_dB;
   s_dB = ue->sinr_CQI_dB;
   //  LTE_UE_ULSCH_t *ulsch  = ue->ulsch[eNB_id];
diff --git a/openair1/PHY/LTE_TRANSPORT/defs.h b/openair1/PHY/LTE_TRANSPORT/defs.h
index 7053a8b5bccba716bec8f8066c8acaebfd3614eb..258d5449d9480ca3178e5ee77063680cc0e29649 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -860,7 +860,10 @@ typedef enum {
 } RX_type_t;
 
 
-
+typedef enum {
+  DCI_COMMON_SPACE,
+  DCI_UE_SPACE
+} dci_space_t;
 
 
 /**@}*/
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index fc0c3d61fa8bd7eb788f8d628a5b5e356ac07fdf..f4a06837b9eb13bfe7ab11452536e44005a60165 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -602,7 +602,9 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
 
   //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
   if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-
+#ifdef DEBUG_DLSCH_CODING
+  printf("encoding thinks this is a new packet \n");
+#endif
     /*
     int i;
     printf("dlsch (tx): \n");
@@ -709,6 +711,9 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
 #endif
 
     start_meas(rm_stats);
+#ifdef DEBUG_DLSCH_CODING
+  printf("rvidx in encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#endif
     r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                         G,  //G
                                         dlsch->harq_processes[harq_pid]->w[r],
@@ -779,7 +784,9 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
 
   //  if (dlsch->harq_processes[harq_pid]->Ndi == 1) {  // this is a new packet
   if (dlsch->harq_processes[harq_pid]->round == 0) {  // this is a new packet
-
+#ifdef DEBUG_DLSCH_CODING
+  printf("SIC encoding thinks this is a new packet \n");
+#endif
     /*
     int i;
     printf("dlsch (tx): \n");
@@ -886,6 +893,9 @@ int dlsch_encoding_SIC(PHY_VARS_UE *ue,
 #endif
 
     start_meas(rm_stats);
+#ifdef DEBUG_DLSCH_CODING
+    printf("rvidx in SIC encoding = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#endif
     r_offset += lte_rate_matching_turbo(dlsch->harq_processes[harq_pid]->RTC[r],
                                         G,  //G
                                         dlsch->harq_processes[harq_pid]->w[r],
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
index 35b3bd3e3b94c6df9bda240caf39a6d263e3ea09..d23a7d7e21ab40e546389a949c4837e3bd76d5c7 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_decoding.c
@@ -167,10 +167,11 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
                          uint8_t llr8_flag)
 {
 
-
+#if UE_TIMING_TRACE
   time_stats_t *dlsch_rate_unmatching_stats=&phy_vars_ue->dlsch_rate_unmatching_stats;
   time_stats_t *dlsch_turbo_decoding_stats=&phy_vars_ue->dlsch_turbo_decoding_stats;
   time_stats_t *dlsch_deinterleaving_stats=&phy_vars_ue->dlsch_deinterleaving_stats;
+#endif
   uint32_t A,E;
   uint32_t G;
   uint32_t ret,offset;
@@ -271,7 +272,7 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     return(max_turbo_iterations);
     }*/
 
-  /*harq_pid = dlsch->current_harq_pid[subframe&0x1];
+  /*harq_pid = dlsch->current_harq_pid[phy_vars_ue->current_thread_id[subframe]];
   if (harq_pid >= 8) {
     printf("dlsch_decoding.c: Illegal harq_pid %d\n",harq_pid);
     return(max_turbo_iterations);
@@ -372,7 +373,9 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     printf("f1 %d, f2 %d, F %d\n",f1f2mat_old[2*iind],f1f2mat_old[1+(2*iind)],(r==0) ? harq_process->F : 0);
 #endif
 
+#if UE_TIMING_TRACE
     start_meas(dlsch_rate_unmatching_stats);
+#endif
     memset(&dummy_w[r][0],0,3*(6144+64)*sizeof(short));
     harq_process->RTC[r] = generate_dummy_w(4+(Kr_bytes*8),
                                             (uint8_t*) &dummy_w[r][0],
@@ -390,7 +393,9 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
           harq_process->round);
 #endif
 
-//printf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#ifdef DEBUG_DLSCH_DECODING
+    printf(" in decoding dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
+#endif
     if (lte_rate_matching_turbo_rx(harq_process->RTC[r],
                                    G,
                                    harq_process->w[r],
@@ -406,12 +411,17 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
                                    harq_process->Nl,
                                    r,
                                    &E)==-1) {
+#if UE_TIMING_TRACE
       stop_meas(dlsch_rate_unmatching_stats);
+#endif
       LOG_E(PHY,"dlsch_decoding.c: Problem in rate_matching\n");
       return(dlsch->max_turbo_iterations);
     } else
+    {
+#if UE_TIMING_TRACE
       stop_meas(dlsch_rate_unmatching_stats);
-
+#endif
+    }
     r_offset += E;
 
     /*
@@ -419,13 +429,16 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
      harq_process->d[r],
      harq_process->w);
     */
+#if UE_TIMING_TRACE
     start_meas(dlsch_deinterleaving_stats);
+#endif
     sub_block_deinterleaving_turbo(4+Kr,
                                    &harq_process->d[r][96],
 
                                    harq_process->w[r]);
+#if UE_TIMING_TRACE
     stop_meas(dlsch_deinterleaving_stats);
-
+#endif
 #ifdef DEBUG_DLSCH_DECODING
     /*
     if (r==0) {
@@ -470,8 +483,9 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
     		AssertFatal (Kr >= 256, "turbo algo issue Kr=%d cb_cnt=%d C=%d nbRB=%d TBSInput=%d TBSHarq=%d TBSplus24=%d mcs=%d Qm=%d RIV=%d round=%d\n",
     				Kr,r,harq_process->C,harq_process->nb_rb,A,harq_process->TBS,harq_process->B,harq_process->mcs,harq_process->Qm,harq_process->rvidx,harq_process->round);
     	}
-
-      start_meas(dlsch_turbo_decoding_stats);
+#if UE_TIMING_TRACE
+        start_meas(dlsch_turbo_decoding_stats);
+#endif
       LOG_D(PHY,"AbsSubframe %d.%d Start turbo segment %d/%d \n",frame%1024,subframe,r,harq_process->C-1);
       ret = tc
             (&harq_process->d[r][96],
@@ -490,14 +504,17 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
              &phy_vars_ue->dlsch_tc_intl1_stats,
              &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
 
-
+#if UE_TIMING_TRACE
       stop_meas(dlsch_turbo_decoding_stats);
+#endif
     }
 #else
     if ((harq_process->C == 1) ||
 	((r==harq_process->C-1) && (skipped_last==0))) { // last segment with odd number of segments
 
-      start_meas(dlsch_turbo_decoding_stats);
+#if UE_TIMING_TRACE
+        start_meas(dlsch_turbo_decoding_stats);
+#endif
       ret = tc
             (&harq_process->d[r][96],
              harq_process->c[r],
@@ -514,7 +531,9 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
              &phy_vars_ue->dlsch_tc_ext_stats,
              &phy_vars_ue->dlsch_tc_intl1_stats,
              &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
+ #if UE_TIMING_TRACE
       stop_meas(dlsch_turbo_decoding_stats);
+#endif
       //      printf("single decode, exit\n");
       //      exit(-1);
     }
@@ -531,7 +550,9 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
 #ifdef DEBUG_DLSCH_DECODING
 	  printf("single decoding segment %d (%p)\n",r-1,&harq_process->d[r-1][96]);
 #endif
+#if UE_TIMING_TRACE
 	  start_meas(dlsch_turbo_decoding_stats);
+#endif
 #ifdef DEBUG_DLSCH_DECODING
 	  printf("double decoding segments %d,%d (%p,%p)\n",r-1,r,&harq_process->d[r-1][96],&harq_process->d[r][96]);
 #endif
@@ -572,10 +593,14 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
              &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
 
 	     exit(-1);*/
-	  stop_meas(dlsch_turbo_decoding_stats);
+#if UE_TIMING_TRACE
+      stop_meas(dlsch_turbo_decoding_stats);
+#endif
 	}
 	else { // Kr_last != Kr
+#if UE_TIMING_TRACE
 	  start_meas(dlsch_turbo_decoding_stats);
+#endif
 	  ret = tc
             (&harq_process->d[r-1][96],
              harq_process->c[r-1],
@@ -592,9 +617,12 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
              &phy_vars_ue->dlsch_tc_ext_stats,
              &phy_vars_ue->dlsch_tc_intl1_stats,
              &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
-	  stop_meas(dlsch_turbo_decoding_stats);
+#if UE_TIMING_TRACE
+      stop_meas(dlsch_turbo_decoding_stats);
 
 	  start_meas(dlsch_turbo_decoding_stats);
+#endif
+
 	  ret = tc
             (&harq_process->d[r][96],
              harq_process->c[r],
@@ -611,6 +639,9 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
              &phy_vars_ue->dlsch_tc_ext_stats,
              &phy_vars_ue->dlsch_tc_intl1_stats,
              &phy_vars_ue->dlsch_tc_intl2_stats); //(is_crnti==0)?harq_pid:harq_pid+1);
+
+#if UE_TIMING_TRACE
+
 	  stop_meas(dlsch_turbo_decoding_stats);
 
 	  /*printf("Segmentation: C %d r %d, dlsch_rate_unmatching_stats %5.3f dlsch_deinterleaving_stats %5.3f  dlsch_turbo_decoding_stats %5.3f \n",
@@ -619,7 +650,7 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
               dlsch_rate_unmatching_stats->p_time/(cpuf*1000.0),
               dlsch_deinterleaving_stats->p_time/(cpuf*1000.0),
               dlsch_turbo_decoding_stats->p_time/(cpuf*1000.0));*/
-
+#endif
 	}
       }
     }
@@ -641,9 +672,10 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
   frame_rx_prev = frame_rx_prev%1024;
 
   if (err_flag == 1) {
-    //LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
-    //    phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
-
+#if UE_DEBUG_TRACE
+    LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
+        phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
+#endif
     dlsch->harq_ack[subframe].ack = 0;
     dlsch->harq_ack[subframe].harq_id = harq_pid;
     dlsch->harq_ack[subframe].send_harq_status = 1;
@@ -664,9 +696,10 @@ uint32_t  dlsch_decoding(PHY_VARS_UE *phy_vars_ue,
 
     return((1+dlsch->max_turbo_iterations));
   } else {
-
-      //LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d harq_process->mcs %d harq_process->nb_rb %d\n",
-                   //phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
+#if UE_DEBUG_TRACE
+      LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n",
+           phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb);
+#endif
 
     harq_process->status = SCH_IDLE;
     harq_process->round  = 0;
@@ -928,10 +961,9 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
 
   case PDSCH: // TB0
-    dlsch_ue  = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0];
+    dlsch_ue  = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0];
     harq_pid = dlsch_ue->current_harq_pid;
-
-    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[0][(uint32_t)eNB_id]->crnti,RC.eNB[eNB_id2][CC_id]);
+    ue_id= (uint32_t)find_ue((int16_t)phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][(uint32_t)eNB_id]->crnti,RC.eNB[eNB_id2][CC_id]);
     DevAssert( ue_id != (uint32_t)-1 );
     dlsch_eNB = RC.eNB[eNB_id2][CC_id]->dlsch[ue_id][0];
 
@@ -975,9 +1007,10 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
 
   case PDSCH1: { // TB1
-    dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1];
+    dlsch_ue = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1];
     harq_pid = dlsch_ue->current_harq_pid;
-    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[0][eNB_id]->crnti, RC.eNB[eNB_id2][CC_id] );
+    int8_t UE_id = find_ue( phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->crnti, RC.eNB[eNB_id2][CC_id] );
+
     DevAssert( UE_id != -1 );
     dlsch_eNB = RC.eNB[eNB_id2][CC_id]->dlsch[UE_id][1];
     // reset HARQ
@@ -1029,7 +1062,7 @@ uint32_t dlsch_decoding_emul(PHY_VARS_UE *phy_vars_ue,
     break;
 
   default:
-    dlsch_ue = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0];
+    dlsch_ue = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0];
     LOG_E(PHY,"dlsch_decoding_emul: FATAL, unknown DLSCH_id %d\n",dlsch_id);
     dlsch_ue->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 091beddec7d5472725bec1bf7bf0a0e4c81d33c4..4949419447e1586c56e8fdc20197f57cbb1078b3 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_demodulation.c
@@ -48,6 +48,7 @@
  * default value: 0
  */
 int16_t dlsch_demod_shift = 0;
+int16_t interf_unaw_shift = 13;
 
 //#define DEBUG_HARQ
 
@@ -61,9 +62,6 @@ int16_t dlsch_demod_shift = 0;
 
 // [MCS][i_mod (0,1,2) = (2,4,6)]
 unsigned char offset_mumimo_llr_drange_fix=0;
-uint8_t interf_unaw_shift0=0;
-uint8_t interf_unaw_shift1=0;
-uint8_t interf_unaw_shift=0;
 //inferference-free case
 unsigned char interf_unaw_shift_tm4_mcs[29]={5, 3, 4, 3, 3, 2, 1, 1, 2, 0, 1, 1, 1, 1, 0, 0,
                                              1, 1, 1, 1, 0, 2, 1, 0, 1, 0, 1, 0, 0} ;
@@ -113,10 +111,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
   int avg_0[2];
   int avg_1[2];
 
+#if UE_TIMING_TRACE
+  uint8_t slot = 0;
+#endif
+
   unsigned char aatx,aarx;
 
   unsigned short nb_rb = 0, round;
-  int avgs, rb;
+  int avgs = 0, rb;
   LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq = 0;
 
   uint8_t beamforming_mode;
@@ -145,8 +147,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
     break;
 
   case PDSCH:
-    pdsch_vars = ue->pdsch_vars[subframe&0x1];
-    dlsch = ue->dlsch[subframe&0x1][eNB_id];
+    pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe]];
+    dlsch = ue->dlsch[ue->current_thread_id[subframe]][eNB_id];
+    //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status);
     LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d,  harq status %d.%d \n",
                    frame,subframe,symbol,harq_pid,
                    dlsch[0]->harq_processes[harq_pid]->status,
@@ -158,6 +161,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
       codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword;
       dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid];
       dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid];
+#ifdef DEBUG_HARQ
+      printf("[DEMOD] I am assuming both TBs are active\n");
+#endif
     }
      else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) &&
               (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) {
@@ -165,6 +171,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
       dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
       dlsch1_harq = NULL;
       codeword_TB1 = -1;
+#ifdef DEBUG_HARQ
+      printf("[DEMOD] I am assuming only TB0 is active\n");
+#endif
     }
      else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) &&
               (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){
@@ -172,6 +181,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
       dlsch0_harq  = dlsch[1]->harq_processes[harq_pid];
       dlsch1_harq  = NULL;
       codeword_TB0 = -1;
+#ifdef DEBUG_HARQ
+      printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch0_harq->codeword);
+#endif
     }
     else {
       LOG_E(PHY,"[UE][FATAL] Frame %d subframe %d: no active DLSCH\n",ue->proc.proc_rxtx[0].frame_rx,subframe);
@@ -192,6 +204,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
   DevAssert(dlsch0_harq);
   round = dlsch0_harq->round;
+  //printf("round = %d\n", round);
 
   if (eNB_id > 2) {
     LOG_W(PHY,"dlsch_demodulation.c: Illegal eNB_id %d\n",eNB_id);
@@ -231,7 +244,6 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
 
 
-
   if ((dlsch0_harq->mimo_mode==LARGE_CDD) || ((dlsch0_harq->mimo_mode>=DUALSTREAM_UNIFORM_PRECODING1) && (dlsch0_harq->mimo_mode<=DUALSTREAM_PUSCH_PRECODING)))  {
     DevAssert(dlsch1_harq);
     if (eNB_id!=eNB_id_i) {
@@ -240,13 +252,27 @@ int rx_pdsch(PHY_VARS_UE *ue,
     }
   }
 
+#if UE_TIMING_TRACE
+  if(symbol > ue->frame_parms.symbols_per_tti>>1)
+  {
+      slot = 1;
+  }
+#endif
+
+#ifdef DEBUG_HARQ
+  printf("Demod  dlsch0_harq->pmi_alloc %d\n",  dlsch0_harq->pmi_alloc);
+#endif
+
   if (frame_parms->nb_antenna_ports_eNB>1 && beamforming_mode==0) {
 #ifdef DEBUG_DLSCH_MOD
     LOG_I(PHY,"dlsch: using pmi %x (%p), rb_alloc %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc),dlsch[0],dlsch0_harq->rb_alloc_even[0]);
 #endif
 
-    nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                                   common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
+    nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                   common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                    pdsch_vars[eNB_id]->rxdataF_ext,
                                    pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                    dlsch0_harq->pmi_alloc,
@@ -266,8 +292,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
    if (rx_type >= rx_IC_single_stream) {
       if (eNB_id_i<ue->n_connected_eNB) // we are in TM5
-      nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                                       common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
+      nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                       common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i],
                                        pdsch_vars[eNB_id_i]->rxdataF_ext,
                                        pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                        dlsch0_harq->pmi_alloc,
@@ -279,8 +305,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                        frame_parms,
                                        dlsch0_harq->mimo_mode);
       else
-        nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                                       common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+        nb_rb = dlsch_extract_rbs_dual(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                       common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                        pdsch_vars[eNB_id_i]->rxdataF_ext,
                                        pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                        dlsch0_harq->pmi_alloc,
@@ -293,8 +319,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                        dlsch0_harq->mimo_mode);
     }
   } else if (beamforming_mode==0) { //else if nb_antennas_ports_eNB==1 && beamforming_mode == 0
-    nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                                     common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+    nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                     common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                      pdsch_vars[eNB_id]->rxdataF_ext,
                                      pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                                      dlsch0_harq->pmi_alloc,
@@ -307,8 +333,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
 
    if (rx_type==rx_IC_single_stream) {
      if (eNB_id_i<ue->n_connected_eNB)
-        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                                         common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id_i],
+        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                         common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id_i],
                                          pdsch_vars[eNB_id_i]->rxdataF_ext,
                                          pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                          dlsch0_harq->pmi_alloc,
@@ -319,8 +345,8 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                          ue->high_speed_flag,
                                          frame_parms);
       else
-        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                                         common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+        nb_rb = dlsch_extract_rbs_single(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                                         common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                                          pdsch_vars[eNB_id_i]->rxdataF_ext,
                                          pdsch_vars[eNB_id_i]->dl_ch_estimates_ext,
                                          dlsch0_harq->pmi_alloc,
@@ -332,7 +358,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                          frame_parms);
     }
   } else if (beamforming_mode==7) { //else if beamforming_mode == 7
-    nb_rb = dlsch_extract_rbs_TM7(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
+    nb_rb = dlsch_extract_rbs_TM7(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
                                   pdsch_vars[eNB_id]->dl_bf_ch_estimates,
                                   pdsch_vars[eNB_id]->rxdataF_ext,
                                   pdsch_vars[eNB_id]->dl_bf_ch_estimates_ext,
@@ -353,11 +379,21 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
 
 
-  //#ifdef DEBUG_PHY
-  LOG_D(PHY,"[DLSCH] nb_rb %d log2_maxh = %d (%d,%d)\n",nb_rb,pdsch_vars[eNB_id]->log2_maxh,avg[0],avgs);
-  LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
-  //#endif
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction %5.2f \n",frame,subframe,slot,
+            symbol,ue->high_speed_flag,type,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d Flag %d type %d: Pilot/Data extraction  %5.2f \n",frame,subframe,slot,symbol,
+            ue->high_speed_flag,type,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
 
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
   aatx = frame_parms->nb_antenna_ports_eNB;
   aarx = frame_parms->nb_antennas_rx;
 
@@ -380,6 +416,18 @@ int rx_pdsch(PHY_VARS_UE *ue,
                         nb_rb);
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Scale  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
   if (first_symbol_flag==1) {
     if (beamforming_mode==0){
       if (dlsch0_harq->mimo_mode<LARGE_CDD) {
@@ -408,23 +456,20 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                  nb_rb,
                                  dlsch0_harq->mimo_mode);
 
-      LOG_D(PHY,"Channel Level TM34  avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, interf_unaw_shift %d \n", avg_0[0],
-              avg_1[0], rx_type, rx_standard, interf_unaw_shift);
+      LOG_D(PHY,"Channel Level TM34  avg_0 %d, avg_1 %d, rx_type %d, rx_standard %d, dlsch_demod_shift %d \n", avg_0[0],
+              avg_1[0], rx_type, rx_standard, dlsch_demod_shift);
         if (rx_type>rx_standard) {
           avg_0[0] = (log2_approx(avg_0[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4;
           avg_1[0] = (log2_approx(avg_1[0])/2) + dlsch_demod_shift;// + 2 ;//+ 4;
           pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
           pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
-          //printf("TM4 I-A log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
-          //printf("TM4 I-A log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
+         // printf("dlsch_demod_shift  %d\n", dlsch_demod_shift);
          }
           else {
           avg_0[0] = (log2_approx(avg_0[0])/2) - 13 + interf_unaw_shift;
           avg_1[0] = (log2_approx(avg_1[0])/2) - 13 + interf_unaw_shift;
           pdsch_vars[eNB_id]->log2_maxh0 = cmax(avg_0[0],0);
           pdsch_vars[eNB_id]->log2_maxh1 = cmax(avg_1[0],0);
-          //printf("TM4 I-UA log2_maxh0 = %d\n", pdsch_vars[eNB_id]->log2_maxh0);
-          //printf("TM4 I-UA log2_maxh1 = %d\n", pdsch_vars[eNB_id]->log2_maxh1);
         }
       }
       else if (dlsch0_harq->mimo_mode<DUALSTREAM_UNIFORM_PRECODING1) {// single-layer precoding (TM5, TM6)
@@ -465,16 +510,28 @@ int rx_pdsch(PHY_VARS_UE *ue,
                               avg,
                               symbol,
                               nb_rb);
-#ifdef DEBUG_PHY
-    LOG_I(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
+#ifdef UE_DEBUG_TRACE
+    LOG_D(PHY,"[DLSCH] AbsSubframe %d.%d log2_maxh = %d [log2_maxh0 %d log2_maxh1 %d] (%d,%d)\n",
             frame%1024,subframe, pdsch_vars[eNB_id]->log2_maxh,
                                                  pdsch_vars[eNB_id]->log2_maxh0,
                                                  pdsch_vars[eNB_id]->log2_maxh1,
                                                  avg[0],avgs);
-    LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
+    //LOG_D(PHY,"[DLSCH] mimo_mode = %d\n", dlsch0_harq->mimo_mode);
 #endif
+
+    //wait until pdcch is decoded
+    //proc->channel_level = 1;
   }
 
+  /*
+  uint32_t wait = 0;
+  while(proc->channel_level == 0)
+  {
+      usleep(1);
+      wait++;
+  }
+  */
+
 #if T_TRACER
     if (type == PDSCH)
     {
@@ -483,6 +540,19 @@ int rx_pdsch(PHY_VARS_UE *ue,
     }
 #endif
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d first_symbol_flag %d: Channel Level  %5.2f \n",frame,subframe,slot,symbol,first_symbol_flag,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
 // Now channel compensation
   if (dlsch0_harq->mimo_mode<LARGE_CDD) {
     dlsch_channel_compensation(pdsch_vars[eNB_id]->rxdataF_ext,
@@ -677,8 +747,18 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                  measurements); // log2_maxh+I0_shift
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d log2_maxh %d channel_level %d: Channel Comp  %5.2f \n",frame,subframe,slot,symbol,pdsch_vars[eNB_id]->log2_maxh,proc->channel_level,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
 // MRC
-
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
 
    if (frame_parms->nb_antennas_rx > 1) {
     if ((dlsch0_harq->mimo_mode == LARGE_CDD) ||
@@ -746,19 +826,59 @@ int rx_pdsch(PHY_VARS_UE *ue,
     //i_mod should have been passed as a parameter
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: Channel Combine  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#endif
   //printf("LLR dlsch0_harq->Qm %d rx_type %d cw0 %d cw1 %d symbol %d \n",dlsch0_harq->Qm,rx_type,codeword_TB0,codeword_TB1,symbol);
+  // compute LLRs
+  // -> // compute @pointer where llrs should filled for this ofdm-symbol
+  int8_t  *pllr_symbol_cw0;
+  int8_t  *pllr_symbol_cw1;
+  uint32_t llr_offset_symbol;
+  llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol];
+  pllr_symbol_cw0  = (int8_t*)pdsch_vars[eNB_id]->llr[0];
+  pllr_symbol_cw1  = (int8_t*)pdsch_vars[eNB_id]->llr[1];
+  pllr_symbol_cw0 += llr_offset_symbol;
+  pllr_symbol_cw1 += llr_offset_symbol;
+
+  /*LOG_I(PHY,"compute LLRs [AbsSubframe %d.%d-%d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n",
+             proc->frame_rx, proc->subframe_rx,symbol,
+             nb_rb,dlsch0_harq->Qm,
+             pdsch_vars[eNB_id]->llr_length[symbol],
+             pdsch_vars[eNB_id]->llr_offset[symbol],
+             (int16_t*)pdsch_vars[eNB_id]->llr[0],
+             pllr_symbol);*/
 
   switch (dlsch0_harq->Qm) {
   case 2 :
-    if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
+    if ((rx_type==rx_standard) || (codeword_TB1 == -1)) {
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
-                       pdsch_vars[eNB_id]->llr[0],
+                       (int16_t*)pllr_symbol_cw0,
+                       symbol,
+                       first_symbol_flag,
+                       nb_rb,
+                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
+                       beamforming_mode);
+
+    } else if (codeword_TB0 == -1){
+
+        dlsch_qpsk_llr(frame_parms,
+                       pdsch_vars[eNB_id]->rxdataF_comp0,
+                       (int16_t*)pllr_symbol_cw1,
                        symbol,
                        first_symbol_flag,
                        nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128,
                        beamforming_mode);
     }
       else if (rx_type >= rx_IC_single_stream) {
@@ -829,7 +949,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
       }
     break;
   case 4 :
-    if ((rx_type==rx_standard ) || (codeword_TB0 == -1) || (codeword_TB1 == -1)) {
+    if ((rx_type==rx_standard ) || (codeword_TB1 == -1)) {
       dlsch_16qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
                       pdsch_vars[eNB_id]->llr[0],
@@ -838,6 +958,15 @@ int rx_pdsch(PHY_VARS_UE *ue,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
                       pdsch_vars[eNB_id]->llr128,
                       beamforming_mode);
+    } else if (codeword_TB0 == -1){
+      dlsch_16qam_llr(frame_parms,
+                      pdsch_vars[eNB_id]->rxdataF_comp0,
+                      pdsch_vars[eNB_id]->llr[1],
+                      pdsch_vars[eNB_id]->dl_ch_mag0,
+                      symbol,first_symbol_flag,nb_rb,
+                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,4,subframe,symbol),
+                      pdsch_vars[eNB_id]->llr128_2ndstream,
+                      beamforming_mode);
     }
     else if (rx_type >= rx_IC_single_stream) {
       if (dlsch1_harq->Qm == 2) {
@@ -913,17 +1042,25 @@ int rx_pdsch(PHY_VARS_UE *ue,
     }
     break;
   case 6 :
-    //printf("LLR rx_type %d cw0 %d cw1 %d symbol %d first symbol %d nb_rb %d rballoceven %d sfn %d beamforming_mode %d\n",
-    //        rx_type,codeword_TB0,codeword_TB1,symbol,first_symbol_flag,nb_rb,dlsch0_harq->rb_alloc_even,subframe,beamforming_mode);
-    if ((rx_type==rx_standard) || (codeword_TB0 == -1) || (codeword_TB1 == -1))  {
+    if ((rx_type==rx_standard) || (codeword_TB1 == -1))  {
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
-                      pdsch_vars[eNB_id]->llr[0],
+                      (int16_t*)pllr_symbol_cw0,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       pdsch_vars[eNB_id]->dl_ch_magb0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128,
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
+                      beamforming_mode);
+    } else if (codeword_TB0 == -1){
+      dlsch_64qam_llr(frame_parms,
+                      pdsch_vars[eNB_id]->rxdataF_comp0,
+                      (int16_t*)pllr_symbol_cw1,
+                      pdsch_vars[eNB_id]->dl_ch_mag0,
+                      pdsch_vars[eNB_id]->dl_ch_magb0,
+                      symbol,first_symbol_flag,nb_rb,
+                      adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
     }
     else if (rx_type >= rx_IC_single_stream) {
@@ -980,10 +1117,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
                               pdsch_vars[eNB_id]->dl_ch_mag0,
                               dl_ch_mag_ptr,//i
                               pdsch_vars[eNB_id]->dl_ch_rho2_ext,
-                              pdsch_vars[eNB_id]->llr[0],
+                              (int16_t*)pllr_symbol_cw0,
                               symbol,first_symbol_flag,nb_rb,
                               adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                              pdsch_vars[eNB_id]->llr128);
+                              pdsch_vars[eNB_id]->llr_offset[symbol]);
         if (rx_type==rx_IC_dual_stream) {
           dlsch_64qam_64qam_llr(frame_parms,
                                 rxdataF_comp_ptr,
@@ -991,10 +1128,10 @@ int rx_pdsch(PHY_VARS_UE *ue,
                                 dl_ch_mag_ptr,
                                 pdsch_vars[eNB_id]->dl_ch_mag0,//i
                                 pdsch_vars[eNB_id]->dl_ch_rho_ext[harq_pid][round],
-                                pdsch_vars[eNB_id]->llr[1],
+                                (int16_t*)pllr_symbol_cw1,
                                 symbol,first_symbol_flag,nb_rb,
                                 adjust_G2(frame_parms,dlsch1_harq->rb_alloc_even,6,subframe,symbol),
-                                pdsch_vars[eNB_id]->llr128_2ndstream);
+                                pdsch_vars[eNB_id]->llr_offset[symbol]);
         }
       }
     }
@@ -1010,10 +1147,9 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if (rx_type==rx_standard) {
         dlsch_qpsk_llr(frame_parms,
                        pdsch_vars[eNB_id]->rxdataF_comp0,
-                       pdsch_vars[eNB_id]->llr[0],
+                       (int16_t*)pllr_symbol_cw0,
                        symbol,first_symbol_flag,nb_rb,
                        adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,2,subframe,symbol),
-                       pdsch_vars[eNB_id]->llr128,
                        beamforming_mode);
     }
     break;
@@ -1033,12 +1169,12 @@ int rx_pdsch(PHY_VARS_UE *ue,
     if (rx_type==rx_standard) {
       dlsch_64qam_llr(frame_parms,
                       pdsch_vars[eNB_id]->rxdataF_comp0,
-                      pdsch_vars[eNB_id]->llr[0],
+                      (int16_t*)pllr_symbol_cw0,
                       pdsch_vars[eNB_id]->dl_ch_mag0,
                       pdsch_vars[eNB_id]->dl_ch_magb0,
                       symbol,first_symbol_flag,nb_rb,
                       adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,6,subframe,symbol),
-                      pdsch_vars[eNB_id]->llr128,
+                      pdsch_vars[eNB_id]->llr_offset[symbol],
                       beamforming_mode);
   }
     break;
@@ -1049,6 +1185,14 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
   }
 
+#if UE_TIMING_TRACE
+    stop_meas(&ue->generic_stat_bis[ue->current_thread_id[subframe]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_I(PHY, "[AbsSFN %d.%d] Slot%d Symbol %d: LLR Computation  %5.2f \n",frame,subframe,slot,symbol,ue->generic_stat_bis[ue->current_thread_id[subframe]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
 // Please keep it: useful for debugging
 #if 0
   if( (symbol == 13) && (subframe==0) && (dlsch0_harq->Qm == 6) /*&& (nb_rb==25)*/)
@@ -1057,12 +1201,12 @@ int rx_pdsch(PHY_VARS_UE *ue,
       if(1)
       {
 #if 1
-      write_output("rxdataF0.m"    , "rxdataF0",             &common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("rxdataF1.m"    , "rxdataF1",             &common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
-      write_output("dl_ch_estimates00.m", "dl_ch_estimates00",   &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("dl_ch_estimates01.m", "dl_ch_estimates01",   &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("dl_ch_estimates10.m", "dl_ch_estimates10",   &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1);
-      //write_output("dl_ch_estimates11.m", "dl_ch_estimates11",   &common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1);
+      write_output("rxdataF0.m"    , "rxdataF0",             &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("rxdataF1.m"    , "rxdataF1",             &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0][0],14*frame_parms->ofdm_symbol_size,1,1);
+      write_output("dl_ch_estimates00.m", "dl_ch_estimates00",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("dl_ch_estimates01.m", "dl_ch_estimates01",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("dl_ch_estimates10.m", "dl_ch_estimates10",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0],14*frame_parms->ofdm_symbol_size,1,1);
+      //write_output("dl_ch_estimates11.m", "dl_ch_estimates11",   &common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0],14*frame_parms->ofdm_symbol_size,1,1);
 
 
       //write_output("rxdataF_ext00.m"    , "rxdataF_ext00",       &pdsch_vars[eNB_id]->rxdataF_ext[0][0],14*frame_parms->N_RB_DL*12,1,1);
@@ -1095,7 +1239,6 @@ int rx_pdsch(PHY_VARS_UE *ue,
     T_BUFFER(&pdsch_vars[eNB_id]->rxdataF_comp0[eNB_id][0],
              2 * /* ulsch[UE_id]->harq_processes[harq_pid]->nb_rb */ frame_parms->N_RB_UL *12*frame_parms->symbols_per_tti*2));
 #endif
-
   return(0);
 
 }
@@ -3377,7 +3520,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
 
   short rb;
   unsigned char aatx,aarx,nre=12,symbol_mod;
-  __m128i *dl_ch128, avg128D, coeff128;
+  __m128i *dl_ch128, avg128D;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
@@ -3388,11 +3531,10 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
   else
     nre=12;
 
-  double one_over_nb_re = 0.0;
-  one_over_nb_re = 1/((double)(nb_rb*nre));
-  int16_t one_over_nb_re_q1_15 = (int16_t)(one_over_nb_re * (double)(1<<15) );
-  coeff128 = _mm_set_epi16(one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,
-                            one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15,one_over_nb_re_q1_15);
+  //nb_rb*nre = y * 2^x
+  int16_t x = factor2(nb_rb*nre);
+  int16_t y = (nb_rb*nre)>>x;
+  //printf("nb_rb*nre = %d = %d * 2^(%d)\n",nb_rb*nre,y,x);
 
   for (aatx=0; aatx<frame_parms->nb_antenna_ports_eNB; aatx++)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
@@ -3405,14 +3547,18 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
       for (rb=0;rb<nb_rb;rb++) {
         //      printf("rb %d : ",rb);
         //      print_shorts("ch",&dl_ch128[0]);
-        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[0], coeff128),15)));
-        avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[1], coeff128),15)));
+	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),x));
+	avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[1],dl_ch128[1]),x));
+
+        //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[0],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[0], coeff128),15)));
+        //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[1],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[1], coeff128),15)));
 
         if (((symbol_mod == 0) || (symbol_mod == (frame_parms->Ncp-1)))&&(frame_parms->nb_antenna_ports_eNB!=1)) {
           dl_ch128+=2;
         }
         else {
-          avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15)));
+	  avg128D = _mm_add_epi32(avg128D,_mm_srai_epi16(_mm_madd_epi16(dl_ch128[2],dl_ch128[2]),x));
+          //avg128D = _mm_add_epi32(avg128D,_mm_madd_epi16(dl_ch128[2],_mm_srai_epi16(_mm_mulhi_epi16(dl_ch128[2], coeff128),15)));
           dl_ch128+=3;
         }
         /*
@@ -3427,7 +3573,7 @@ void dlsch_channel_level(int **dl_ch_estimates_ext,
       avg[(aatx<<1)+aarx] =(((int32_t*)&avg128D)[0] +
                             ((int32_t*)&avg128D)[1] +
                             ((int32_t*)&avg128D)[2] +
-                            ((int32_t*)&avg128D)[3]);
+			      ((int32_t*)&avg128D)[3])/y;
                 //  printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
     }
 
@@ -4604,7 +4750,7 @@ unsigned short dlsch_extract_rbs_dual(int **rxdataF,
                                       unsigned char subframe,
                                       uint32_t high_speed_flag,
                                       LTE_DL_FRAME_PARMS *frame_parms,
-                                                              MIMO_mode_t mimo_mode) {
+                                      MIMO_mode_t mimo_mode) {
 
   int prb,nb_rb=0;
   int prb_off,prb_off2;
@@ -5894,50 +6040,50 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c
 
   sprintf(fname,"dlsch%d_rxF_r%d_ext0.m",eNB_id,round);
   sprintf(vname,"dl%d_rxF_r%d_ext0",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0],12*N_RB_DL*nsymb,1,1);
 
   if (ue->frame_parms.nb_antennas_rx >1) {
     sprintf(fname,"dlsch%d_rxF_r%d_ext1.m",eNB_id,round);
     sprintf(vname,"dl%d_rxF_r%d_ext1",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1],12*N_RB_DL*nsymb,1,1);
   }
 
   sprintf(fname,"dlsch%d_ch_r%d_ext00.m",eNB_id,round);
   sprintf(vname,"dl%d_ch_r%d_ext00",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
 
   if (ue->transmission_mode[eNB_id]==7){
     sprintf(fname,"dlsch%d_bf_ch_r%d.m",eNB_id,round);
     sprintf(vname,"dl%d_bf_ch_r%d",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_bf_ch_estimates[0],512*nsymb,1,1);
     //write_output(fname,vname,phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_bf_ch_estimates[0],512,1,1);
 
     sprintf(fname,"dlsch%d_bf_ch_r%d_ext00.m",eNB_id,round);
     sprintf(vname,"dl%d_bf_ch_r%d_ext00",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_bf_ch_estimates_ext[0],12*N_RB_DL*nsymb,1,1);
   }
 
   if (ue->frame_parms.nb_antennas_rx == 2) {
     sprintf(fname,"dlsch%d_ch_r%d_ext01.m",eNB_id,round);
     sprintf(vname,"dl%d_ch_r%d_ext01",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
   }
 
   if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
     sprintf(fname,"dlsch%d_ch_r%d_ext10.m",eNB_id,round);
     sprintf(vname,"dl%d_ch_r%d_ext10",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*nsymb,1,1);
 
     if (ue->frame_parms.nb_antennas_rx == 2) {
       sprintf(fname,"dlsch%d_ch_r%d_ext11.m",eNB_id,round);
       sprintf(vname,"dl%d_ch_r%d_ext11",eNB_id,round);
-      write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
+      write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[3],12*N_RB_DL*nsymb,1,1);
     }
   }
 
   sprintf(fname,"dlsch%d_rxF_r%d_uespec0.m",eNB_id,round);
   sprintf(vname,"dl%d_rxF_r%d_uespec0",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_uespec_pilots[0],12*N_RB_DL,1,1);
 
   /*
     write_output("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*nsymb,1,1);
@@ -5947,31 +6093,31 @@ void dump_dlsch2(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t subframe,unsigned int *c
   sprintf(fname,"dlsch%d_r%d_rho.m",eNB_id,round);
   sprintf(vname,"dl_rho_r%d_%d",eNB_id,round);
 
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
 
   sprintf(fname,"dlsch%d_r%d_rho2.m",eNB_id,round);
   sprintf(vname,"dl_rho2_r%d_%d",eNB_id,round);
 
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_rho2_ext[0],12*N_RB_DL*nsymb,1,1);
 
   sprintf(fname,"dlsch%d_rxF_r%d_comp0.m",eNB_id,round);
   sprintf(vname,"dl%d_rxF_r%d_comp0",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0],12*N_RB_DL*nsymb,1,1);
   if (ue->frame_parms.nb_antenna_ports_eNB == 2) {
     sprintf(fname,"dlsch%d_rxF_r%d_comp1.m",eNB_id,round);
     sprintf(vname,"dl%d_rxF_r%d_comp1",eNB_id,round);
-    write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
+    write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[harq_pid][round][0],12*N_RB_DL*nsymb,1,1);
   }
 
   sprintf(fname,"dlsch%d_rxF_r%d_llr.m",eNB_id,round);
   sprintf(vname,"dl%d_r%d_llr",eNB_id,round);
-  write_output(fname,vname, ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
+  write_output(fname,vname, ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->llr[0],coded_bits_per_codeword[0],1,0);
   sprintf(fname,"dlsch%d_r%d_mag1.m",eNB_id,round);
   sprintf(vname,"dl%d_r%d_mag1",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0],12*N_RB_DL*nsymb,1,1);
   sprintf(fname,"dlsch%d_r%d_mag2.m",eNB_id,round);
   sprintf(vname,"dl%d_r%d_mag2",eNB_id,round);
-  write_output(fname,vname,ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
+  write_output(fname,vname,ue->pdsch_vars[ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb,1,1);
 
   //  printf("log2_maxh = %d\n",ue->pdsch_vars[eNB_id]->log2_maxh);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
index ce9afa767fa0e84551013d70d91490d7d9d25efc..26c76c553125d090605b813b80b2e60c3354ebd3 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_llr_computation.c
@@ -636,7 +636,6 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                    uint8_t first_symbol_flag,
                    uint16_t nb_rb,
                    uint16_t pbch_pss_sss_adjust,
-                   int16_t **llr32p,
                    uint8_t beamforming_mode)
 {
 
@@ -645,12 +644,14 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
   int i,len;
   uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
 
+  /*
   if (first_symbol_flag==1) {
     llr32 = (uint32_t*)dlsch_llr;
   } else {
     llr32 = (uint32_t*)(*llr32p);
-  }
+  }*/
 
+  llr32 = (uint32_t*)dlsch_llr;
   if (!llr32) {
     LOG_E(PHY,"dlsch_qpsk_llr: llr is null, symbol %d, llr32=%p\n",symbol, llr32);
     return(-1);
@@ -672,6 +673,13 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
 
   //printf("dlsch_qpsk_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+  /*LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / FirstSym %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             dlsch_llr,
+             llr32);*/
+
   //printf("ll32p=%p , dlsch_llr=%p, symbol=%d, flag=%d \n", llr32, dlsch_llr, symbol, first_symbol_flag);
   for (i=0; i<len; i++) {
     *llr32 = *rxF;
@@ -680,7 +688,7 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
     llr32++;
   }
 
-  *llr32p = (int16_t *)llr32;
+  //*llr32p = (int16_t *)llr32;
 
   return(0);
 }
@@ -693,9 +701,8 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                            uint8_t num_pdcch_symbols,
                            uint16_t nb_rb,
                            uint8_t subframe,
-                           uint32_t rb_alloc,
                            uint16_t mod_order_0,
-                           LTE_UE_DLSCH_t *dlsch0)
+                           uint32_t rb_alloc)
 {
 
   int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12];
@@ -726,7 +733,7 @@ int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
       amp_tmp=0x1fff;//1.5*dlsch0->sqrt_rho_a; already taken into account
 
     if (mod_order_0==6)
-      amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation to avoid overflow
+      amp_tmp=amp_tmp<<1; // to compensate for >> 1 shift in modulation
 
 
     pbch_pss_sss_adjust=adjust_G2(frame_parms,&rb_alloc,2,subframe,symbol);
@@ -933,10 +940,8 @@ void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
                           int32_t **dl_ch_mag,
                           uint16_t nb_rb,
                           uint8_t subframe,
-                          uint32_t rb_alloc,
                           uint16_t mod_order_0,
-                          LTE_UE_DLSCH_t *dlsch0
-                          )
+                          uint32_t rb_alloc)
 {
   int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12];
   int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
@@ -1043,7 +1048,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
                      uint16_t pbch_pss_sss_adjust,
-                     int16_t **llr_save,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
                      uint8_t beamforming_mode)
 {
 #if defined(__x86_64__) || defined(__i386__)
@@ -1057,11 +1063,18 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   unsigned char symbol_mod,len_mod4;
   short *llr;
   int16_t *llr2;
+  int8_t *pllr_symbol;
 
+  /*
   if (first_symbol_flag==1)
     llr = dlsch_llr;
   else
     llr = *llr_save;
+  */
+  llr = dlsch_llr;
+
+  pllr_symbol = (int8_t*)dlsch_llr;
+  pllr_symbol += llr_offset;
 
   symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol;
 
@@ -1085,6 +1098,15 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
+//  printf("dlsch_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+
+/*  LOG_I(PHY,"dlsch_64qam_llr [symb %d / FirstSym %d / Length %d]: @LLR Buff %x \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             dlsch_llr,
+             pllr_symbol);*/
+
   llr2 = llr;
   llr += (len*6);
 
@@ -1179,7 +1201,6 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 
   }
 
-  *llr_save = llr;
 #if defined(__x86_64__) || defined(__i386__)
   _mm_empty();
   _m_empty();
@@ -1197,10 +1218,8 @@ void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                          int32_t **dl_ch_magb,
                          uint16_t nb_rb,
                          uint8_t subframe,
-                         uint32_t rb_alloc,
                          uint16_t mod_order_0,
-                         LTE_UE_DLSCH_t *dlsch0
-                         )
+                         uint32_t rb_alloc)
 {
   int16_t rho_amp_x0[2*frame_parms->N_RB_DL*12];
   int16_t rho_rho_amp_x0[2*frame_parms->N_RB_DL*12];
@@ -8772,7 +8791,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                           uint8_t first_symbol_flag,
                           uint16_t nb_rb,
                           uint16_t pbch_pss_sss_adjust,
-                          int16_t **llr16p)
+                          //int16_t **llr16p,
+                          uint32_t llr_offset)
 {
 
   int16_t *rxF      = (int16_t*)&rxdataF_comp[0][(symbol*frame_parms->N_RB_DL*12)];
@@ -8781,18 +8801,22 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
   int16_t *ch_mag_i = (int16_t*)&dl_ch_mag_i[0][(symbol*frame_parms->N_RB_DL*12)];
   int16_t *rho      = (int16_t*)&rho_i[0][(symbol*frame_parms->N_RB_DL*12)];
   int16_t *llr16;
+  int8_t  *pllr_symbol; // pointer where llrs should filled for this ofdm symbol
   int len;
   uint8_t symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
 
   //first symbol has different structure due to more pilots
-  if (first_symbol_flag == 1) {
+  /*if (first_symbol_flag == 1) {
     llr16 = (int16_t*)dlsch_llr;
   } else {
     llr16 = (int16_t*)(*llr16p);
-  }
+  }*/
+
+  llr16 = (int16_t*)dlsch_llr;
 
   AssertFatal(llr16!=NULL,"dlsch_16qam_64qam_llr:llr is null, symbol %d\n",symbol);
 
+
   if ((symbol_mod==0) || (symbol_mod==(4-frame_parms->Ncp))) {
     // if symbol has pilots
     if (frame_parms->nb_antenna_ports_eNB!=1)
@@ -8806,6 +8830,18 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
     len = (nb_rb*12) - pbch_pss_sss_adjust;
   }
 
+  pllr_symbol = (int8_t*)dlsch_llr;
+  pllr_symbol += llr_offset;
+  //printf("dlsch_64qam_64qam_llr: symbol %d,nb_rb %d, len %d,pbch_pss_sss_adjust %d\n",symbol,nb_rb,len,pbch_pss_sss_adjust);
+  /*LOG_I(PHY,"dlsch_64qam_64qam_llr [symb %d / FirstSym %d / Length %d / LLR Offset %d]: @LLR Buff %x, @LLR Buff(symb) %x, , @Compute LLR Buff(symb) %x  \n",
+             symbol,
+             first_symbol_flag,
+             len,
+             llr_offset,
+             (int16_t*)dlsch_llr,
+             llr16,
+             pllr_symbol);*/
+
 #ifdef __AVX2__
 
   // Round length up to multiple of 16 words
@@ -8839,6 +8875,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                    (int32_t *) rho_256i,
                    len);
 #endif
+  
   free16(rxF_256i, sizeof(rxF_256i));
   free16(rxF_i_256i, sizeof(rxF_i_256i));
   free16(ch_mag_256i, sizeof(ch_mag_256i));
@@ -8856,6 +8893,7 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 #endif
 
   llr16 += (6*len);
-  *llr16p = (short *)llr16;
+  //*llr16p = (short *)llr16;
+
   return(0);
 }
diff --git a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c
index 170ca4ce767d6fc6cf8da5d18c2bd87b5ba02a06..861a25fabb4e505a524ed9462f0a3bebe168ce06 100644
--- a/openair1/PHY/LTE_TRANSPORT/drs_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/drs_modulation.c
@@ -87,7 +87,7 @@ int generate_drs_pusch(PHY_VARS_UE *ue,
   if (Msc_idx_ptr)
     Msc_RS_idx = Msc_idx_ptr - dftsizes;
   else {
-    printf("generate_drs_pusch: index for Msc_RS=%d not found\n",Msc_RS);
+    LOG_I(PHY,"generate_drs_pusch: index for Msc_RS=%d not found\n",Msc_RS);
     return(-1);
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/extern.h b/openair1/PHY/LTE_TRANSPORT/extern.h
index 88c034e9db0efbb5b442d734e4f6023f52431ed0..af4dc20df611b1bff4d66b9e575ccb70411c6f93 100644
--- a/openair1/PHY/LTE_TRANSPORT/extern.h
+++ b/openair1/PHY/LTE_TRANSPORT/extern.h
@@ -23,6 +23,8 @@ extern unsigned int dlsch_tbs25[27][25],TBStable[27][110],TBStable1C[32];
 extern unsigned short lte_cqi_eff1024[16];
 extern char lte_cqi_snr_dB[15];
 extern short conjugate[8],conjugate2[8];
+extern short minus_one[8];
+extern short minus_one[8];
 extern short *ul_ref_sigs[30][2][33];
 extern short *ul_ref_sigs_rx[30][2][33];
 extern unsigned short dftsizes[33];
diff --git a/openair1/PHY/LTE_TRANSPORT/if5_tools.c b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
index ac4ee1f0c1c2232092caf1ecdbd1717f8cea3860..72253742e20a6d97c89106fa762351b4fc965878 100644
--- a/openair1/PHY/LTE_TRANSPORT/if5_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if5_tools.c
@@ -139,9 +139,6 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
           for (element_id=0; element_id< spp_eth; element_id++){
             j = (uint16_t*) &ru->common.rxdata[i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id];
             data_block[element_id] = ((uint16_t) lin2alaw_if5[*j]) | (lin2alaw_if5[*(j+1)]<<8);
-            if (packet_id == 0 && element_id == 0) {
-              //printf("(UL_Tx)Ori: %u(%d, %d); ALAW: %u; SF %u\n",eNB->common_vars.rxdata[0][i][subframe*fp->samples_per_tti+packet_id*spp_eth+element_id],*j,*(j+1),data_block[element_id],subframe);
-            }
           }
         }
         clock_gettime( CLOCK_MONOTONIC, &end_comp);
@@ -182,63 +179,115 @@ void send_IF5(RU_t *ru, openair0_timestamp proc_timestamp, int subframe, uint8_t
       }    
     }
   } else if (packet_type == IF5_MOBIPASS) {    
-    uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
-    
-    __m128i *data_block=NULL, *data_block_head=NULL;
+    /* the only difference between mobipass standalone and the other one
+     * is the timestamp in trx_write_func, but let's duplicate anyway
+     * (plus we don't call malloc for the standalone case)
+     */
+    if (ru->if_timing == synch_to_mobipass_standalone) {
+      uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
 
-    __m128i *txp128;
-    __m128i t0, t1;
+      __m128i *data_block=NULL, *data_block_head=NULL;
+      __m128i *txp128;
+      __m128i t0, t1;
 
-    // tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
-    tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
-    IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES);
-    data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
-  
-    header->flags = 0;
-    header->fifo_status = 0;  
-    header->seqno = *seqno;
-    header->ack = 0;
-    header->word0 = 0;  
-    
-    txp[0] = (void*)&ru->common.txdata[subframe*ru->frame_parms.samples_per_tti];
-    txp128 = (__m128i *) txp[0];
-              
-    for (packet_id=0; packet_id<fp->samples_per_tti/db_fulllength; packet_id++) {
-      header->time_stamp = htonl((uint32_t)(proc_timestamp + packet_id*db_fulllength));
-      data_block = data_block_head; 
-    
-      for (i=0; i<db_fulllength>>2; i+=2) {
-        t0 = _mm_srai_epi16(*txp128++, 4);
-        t1 = _mm_srai_epi16(*txp128++, 4);   
-//        *data_block++ = _mm_packs_epi16(t0, t1);     
-       _mm_storeu_si128(data_block++, _mm_packs_epi16(t0, t1));     
+      unsigned char _tx_buffer[MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)];
+      tx_buffer=(int32_t *)_tx_buffer;
+
+      IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES);
+      data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
+
+      header->flags = 0;
+      header->fifo_status = 0;
+      header->seqno = *seqno;
+      header->ack = 0;
+      header->word0 = 0;
+
+      txp[0] = (void*)&ru->common.txdata[0][subframe*ru->frame_parms.samples_per_tti];
+      txp128 = (__m128i *) txp[0];
+
+      for (packet_id=0; packet_id<fp->samples_per_tti/db_fulllength; packet_id++) {
+        header->time_stamp = htonl((uint32_t)(proc_timestamp + packet_id*db_fulllength));
+        data_block = data_block_head;
+
+        for (i=0; i<db_fulllength>>2; i+=2) {
+          t0 = _mm_srai_epi16(*txp128++, 4);
+          t1 = _mm_srai_epi16(*txp128++, 4);
+         _mm_storeu_si128(data_block++, _mm_packs_epi16(t0, t1));
+        }
+
+        // Write the packet to the fronthaul
+        if ((ru->ifdevice.trx_write_func(&ru->ifdevice,
+                                          proc_timestamp + packet_id*db_fulllength,
+                                          (void**)&tx_buffer,
+                                          db_fulllength,
+                                          1,
+                                          IF5_MOBIPASS)) < 0) {
+          perror("ETHERNET write for IF5_MOBIPASS\n");
+        }
+        header->seqno += 1;
       }
+      *seqno = header->seqno;
+      tx_buffer = NULL;
+    } else {
+      uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
       
-      // Write the packet to the fronthaul
-      if ((ru->ifdevice.trx_write_func(&ru->ifdevice,
-                                        packet_id,
-                                        (void**)&tx_buffer,
-                                        db_fulllength,
-                                        1,
-                                        IF5_MOBIPASS)) < 0) {
-        perror("ETHERNET write for IF5_MOBIPASS\n");
-      }
+      __m128i *data_block=NULL, *data_block_head=NULL;
+
+      __m128i *txp128;
+      __m128i t0, t1;
+
+      // tx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
+      tx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
+      IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES);
+      data_block_head = (__m128i *)((uint8_t *)tx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
+    
+      header->flags = 0;
+      header->fifo_status = 0;  
+      header->seqno = *seqno;
+      header->ack = 0;
+      header->word0 = 0;  
+      
+      txp[0] = (void*)&ru->common.txdata[0][subframe*ru->frame_parms.samples_per_tti];
+      txp128 = (__m128i *) txp[0];
+                
+      for (packet_id=0; packet_id<fp->samples_per_tti/db_fulllength; packet_id++) {
+        header->time_stamp = htonl((uint32_t)(proc_timestamp + packet_id*db_fulllength));
+        data_block = data_block_head; 
+      
+        for (i=0; i<db_fulllength>>2; i+=2) {
+          t0 = _mm_srai_epi16(*txp128++, 4);
+          t1 = _mm_srai_epi16(*txp128++, 4);   
+//        *data_block++ = _mm_packs_epi16(t0, t1);     
+         _mm_storeu_si128(data_block++, _mm_packs_epi16(t0, t1));     
+        }
+        
+        // Write the packet to the fronthaul
+        if ((ru->ifdevice.trx_write_func(&ru->ifdevice,
+                                          packet_id,
+                                          (void**)&tx_buffer,
+                                          db_fulllength,
+                                          1,
+                                          IF5_MOBIPASS)) < 0) {
+          perror("ETHERNET write for IF5_MOBIPASS\n");
+        }
+
 #ifdef DEBUG_DL_MOBIPASS
-     if ((subframe==0)&&(dummy_cnt == 100)) {
-        memcpy((void*)&dummy_buffer[packet_id*db_fulllength*2],(void*)data_block_head,db_fulllength*2);
-      }
+       if ((subframe==0)&&(dummy_cnt == 100)) {
+          memcpy((void*)&dummy_buffer[packet_id*db_fulllength*2],(void*)data_block_head,db_fulllength*2);
+        }
 #endif
-      header->seqno += 1;    
-    }  
-    *seqno = header->seqno;
+        header->seqno += 1;    
+      }  
+      *seqno = header->seqno;
 
 #ifdef DEBUG_DL_MOBIPASS
-    uint8_t txe;
-    txe = dB_fixed(signal_energy(txp[0],fp->samples_per_tti));
-    if (txe > 0){
-      LOG_D(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, txe);
-    }
+      uint8_t txe;
+      txe = dB_fixed(signal_energy(txp[0],fp->samples_per_tti));
+      if (txe > 0){
+        LOG_D(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, txe);
+      }
 #endif  
+    }
   } else {    
     AssertFatal(1==0, "send_IF5 - Unknown packet_type %x", packet_type);     
   }  
@@ -394,93 +443,173 @@ void recv_IF5(RU_t *ru, openair0_timestamp *proc_timestamp, int subframe, uint16
     *proc_timestamp = timestamp[0];
       
   } else if (packet_type == IF5_MOBIPASS) {
-    
-    uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
-    openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
+    if (ru->if_timing == synch_to_mobipass_standalone) {
+      uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
+      openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
+      int32_t *rx_buffer=NULL;
+      __m128i *data_block=NULL, *data_block_head=NULL;
+      __m128i *rxp128;
+      __m128i r0;
+
+      unsigned char _rx_buffer[MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t)];
+      rx_buffer = (int32_t *)_rx_buffer;
+      data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
+
+      rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms.samples_per_tti];
+      rxp128 = (__m128i *) (rxp[0]);
+
+      packet_id=0;
+      while(packet_id<fp->samples_per_tti/db_fulllength) {
+        data_block = data_block_head;
+
+        ru->ifdevice.trx_read_func(&ru->ifdevice,
+                                         &timestamp_mobipass[packet_id],
+                                         (void**)&rx_buffer,
+                                         db_fulllength,
+                                          1
+                                          );
+
+          //store rxdata and increase packet_id
+          rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms.samples_per_tti)+packet_id*db_fulllength];
+          rxp128 = (__m128i *) (rxp[0]);
+          for (i=0; i<db_fulllength>>2; i+=2) {
+            r0 = _mm_loadu_si128(data_block++);
+            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
+            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
+          }
+          packet_id++;
+      }//end while
+
+      *proc_timestamp = ntohl(timestamp_mobipass[0]);
+    } else {
+      
+      uint16_t db_fulllength = PAYLOAD_MOBIPASS_NUM_SAMPLES;
+      openair0_timestamp timestamp_mobipass[fp->samples_per_tti/db_fulllength];
 #ifdef DEBUG_UL_MOBIPASS
-    int lower_offset = 0;
-    int  upper_offset = 70000;
+      int lower_offset = 0;
+      int  upper_offset = 70000;
 #endif
-    int subframe_skip = 0;
-    int reset_flag = 0;
-    int32_t *rx_buffer=NULL;
-    __m128i *data_block=NULL, *data_block_head=NULL;
-    __m128i *rxp128;
-    __m128i r0;
-
-    //rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
-    rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
-    IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES);
-    data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
- 
-    rxp[0] = (void*)&ru->common.rxdata[subframe*ru->frame_parms.samples_per_tti];
-    rxp128 = (__m128i *) (rxp[0]);
- 
-    RU_proc_t *proc = &ru->proc;
-
+      int subframe_skip = 0;
+      int reset_flag = 0;
+      int32_t *rx_buffer=NULL;
+      __m128i *data_block=NULL, *data_block_head=NULL;
+      __m128i *rxp128;
+      __m128i r0;
+
+      //rx_buffer = memalign(16, MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
+      rx_buffer = malloc(MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t + db_fulllength*sizeof(int16_t));
+      IF5_mobipass_header_t *header = (IF5_mobipass_header_t *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES);
+      data_block_head = (__m128i *)((uint8_t *)rx_buffer + MAC_HEADER_SIZE_BYTES + sizeof_IF5_mobipass_header_t);
+   
+      rxp[0] = (void*)&ru->common.rxdata[0][subframe*ru->frame_parms.samples_per_tti];
+      rxp128 = (__m128i *) (rxp[0]);
+   
+      RU_proc_t *proc = &ru->proc;
+/*
+   //   while(packet_id<fp->samples_per_tti/db_fulllength) {
+        data_block = data_block_head;
+
+        eNB->ifdevice.trx_read_func(&eNB->ifdevice,
+                                         &ts0,
+                                         (void**)&rx_buffer,
+                                         db_fulllength,
+                                          1
+                                          );
+
+        if ((header->seqno == 1)&&(first_packet==1))  { 
+           first_packet = 0;  //ignore the packets before synchnorization
+           packet_id = 0;
+          ts_offset = ntohl(ts0);
+        } 
+        if (first_packet==0) { 
+          packet_cnt++;
+          ts = ntohl(ts0);
+          packet_id = (ts-ts_offset)/db_fulllength;
+          packet_id = packet_id % (fp->samples_per_tti/db_fulllength);
+
+          printf("[IF5_tools]packet_id:%d\n", packet_id);
+          // if (ts_stored == 0) {
+          //   ts_stored = 1;
+          *proc_timestamp = ntohl(ts - (packet_id*db_fulllength));
+          // }
+          rxp[0] = (void*)&eNB->common_vars.rxdata[0][0][(subframe*eNB->frame_parms.samples_per_tti)+packet_id*db_fulllength];
+          rxp128 = (__m128i *) (rxp[0]);
+
+          for (i=0; i<db_fulllength>>2; i+=2) {
+            r0 = _mm_loadu_si128(data_block++);
+            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
+            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
+          }
+        }
+    //  }//end while
+*/
+   
 
-    packet_id=0; 
-    while(packet_id<fp->samples_per_tti/db_fulllength) {
-      data_block = data_block_head;
+      packet_id=0; 
+      while(packet_id<fp->samples_per_tti/db_fulllength) {
+        data_block = data_block_head;
 
-      ru->ifdevice.trx_read_func(&ru->ifdevice,
+	
+	ru->ifdevice.trx_read_func(&ru->ifdevice,
 				 &timestamp_mobipass[packet_id],
 				 (void**)&rx_buffer,
 				 db_fulllength,
 				 1
 				 );
 #ifdef DEBUG_UL_MOBIPASS
-      if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) {
-        //ignore the packet
-        subframe_skip_extra = (subframe_skip_extra + 1)%67;         
-       LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno);
-      }             
+        if (((proc->timestamp_tx + lower_offset) > ntohl(timestamp_mobipass[packet_id])) || ((proc->timestamp_tx + upper_offset) < ntohl(timestamp_mobipass[packet_id]))) {
+          //ignore the packet
+          subframe_skip_extra = (subframe_skip_extra + 1)%67;         
+         LOG_D("[Mobipass] ignored packet, id:[%d,%d], proc->timestamp_tx:%llu, proc->timestamp_rx:%llu, seqno:%d\n", packet_id,subframe_skip_extra, proc->timestamp_tx, ntohl(timestamp_mobipass[packet_id]), header->seqno);
+        }             
 #endif
-      //skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets
-      if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){
-        subframe_skip++;
-        offset_cnt = header->seqno;
-      } else {
-        if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
+        //skip SUBFRAME_SKIP_NUM_MOBIPASS additional UL packets
+        if ((start_flag == 1) && (subframe_skip < SUBFRAME_SKIP_NUM_MOBIPASS)){
+          subframe_skip++;
+          offset_cnt = header->seqno;
+        } else {
+          if ((offset_cnt != header->seqno) && (start_flag == 0) && (proc->first_rx > 3)){
 #ifdef DEBUG_UL_MOBIPASS
-           LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id);
+             LOG_D(PHY,"[Mobipass] Reset sequence number, offset_cnt:%d, header->seqno:%d, packet_id:%d\n", offset_cnt, header->seqno, packet_id);
 #endif
-           reset_flag=1;
-        }
-        if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
-           packet_id = 1;  
-           reset_flag = 0;
+             reset_flag=1;
+          }
+          if ((reset_flag == 1) && (proc->first_rx > 3 ) && (start_flag == 0) && (packet_id == 0)) {
+             packet_id = 1;  
+             reset_flag = 0;
+          }
+          start_flag = 0;
+
+          //store rxdata and increase packet_id
+          rxp[0] = (void*)&ru->common.rxdata[0][(subframe*ru->frame_parms.samples_per_tti)+packet_id*db_fulllength];
+          rxp128 = (__m128i *) (rxp[0]);
+          for (i=0; i<db_fulllength>>2; i+=2) {
+            r0 = _mm_loadu_si128(data_block++);
+            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
+            *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
+          }   
+          packet_id++; 
+          offset_cnt = (header->seqno+1)&255;
         }
-        start_flag = 0;
-
-        //store rxdata and increase packet_id
-        rxp[0] = (void*)&ru->common.rxdata[(subframe*ru->frame_parms.samples_per_tti)+packet_id*db_fulllength];
-        rxp128 = (__m128i *) (rxp[0]);
-        for (i=0; i<db_fulllength>>2; i+=2) {
-          r0 = _mm_loadu_si128(data_block++);
-          *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpacklo_epi8(r0,r0),8),4);
-          *rxp128++ =_mm_slli_epi16(_mm_srai_epi16(_mm_unpackhi_epi8(r0,r0),8),4);
-        }   
-        packet_id++; 
-        offset_cnt = (header->seqno+1)&255;
-      }
-    }//end while
-  
-      *proc_timestamp = ntohl(timestamp_mobipass[0]); 
+      }//end while
+    
+        *proc_timestamp = ntohl(timestamp_mobipass[0]); 
 #ifdef DEBUG_UL_MOBIPASS
-   LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ",  *proc_timestamp);
-   if (ru->idx>0) {
-    rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti)); 
-    if (rxe > 0){
-      LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe);
-//    write_output("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5); 
-//    exit(-1);
-    }
-}
+	LOG_I(PHY,"[Mobipass][Recv_MOBIPASS] timestamp: %llu\n ",  *proc_timestamp);
+	if (eNB->CC_id>0) {
+	  rxe = dB_fixed(signal_energy(rxp[0],fp->samples_per_tti)); 
+	  if (rxe > 0){
+	    LOG_I(PHY,"[Mobipass] frame:%d, subframe:%d, energy %d\n", (*proc_timestamp/(10*fp->samples_per_tti))&1023,subframe, rxe);
+	    
+	    //    write_output("rxsigmb.m","rxs",(void*)dummy_buffer_rx, fp->samples_per_tti,1, 5); 
+	    //    exit(-1);
+	  }
+	}
 #endif
 
 
-   
+     
+    }
   } else {
     AssertFatal(1==0, "recv_IF5 - Unknown packet_type %x", packet_type);     
   }  
diff --git a/openair1/PHY/LTE_TRANSPORT/initial_sync.c b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
index 1a609a618d277e86cf9b1d4e421269d6be9fed82..ab66c6fc5481c8f5a677a877bcc017e4b15cf47a 100644
--- a/openair1/PHY/LTE_TRANSPORT/initial_sync.c
+++ b/openair1/PHY/LTE_TRANSPORT/initial_sync.c
@@ -43,13 +43,13 @@ extern openair0_config_t openair0_cfg[];
 
 #define DEBUG_INITIAL_SYNCH
 
-int pbch_detection(PHY_VARS_UE *ue, runmode_t mode) 
+int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
 {
 
   uint8_t l,pbch_decoded,frame_mod4,pbch_tx_ant,dummy;
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   char phich_resource[6];
-  
+
 #ifdef DEBUG_INITIAL_SYNCH
   LOG_I(PHY,"[UE%d] Initial sync: starting PBCH detection (rx_offset %d)\n",ue->Mod_id,
         ue->rx_offset);
@@ -63,7 +63,7 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
 	     ue->rx_offset,
 	     0,
 	     1);
-  }  
+  }
   for (l=0; l<frame_parms->symbols_per_tti/2; l++) {
 
     slot_fep(ue,
@@ -72,7 +72,7 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
 	     ue->rx_offset,
 	     0,
 	     1);
-  }  
+  }
   slot_fep(ue,
 	   0,
 	   2,
@@ -83,9 +83,11 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
   lte_ue_measurements(ue,
 		      ue->rx_offset,
 		      0,
-		      0,0);
-  
-  
+                      0,
+		      0,
+                      0);
+
+
   if (ue->frame_parms.frame_type == TDD) {
     ue_rrc_measurements(ue,
 			2,
@@ -230,19 +232,17 @@ int pbch_detection(PHY_VARS_UE *ue, runmode_t mode)
       break;
     }
 
-    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;
+    for(int i=0; i<RX_NB_TH;i++)
+    {
+        ue->proc.proc_rxtx[i].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
+        ue->proc.proc_rxtx[i].frame_rx =   (((ue->pbch_vars[0]->decoded_output[2]&3)<<6) + (ue->pbch_vars[0]->decoded_output[1]>>2))<<2;
 
 #ifndef USER_MODE
-    // one frame delay
-    ue->proc.proc_rxtx[0].frame_rx ++;
-    ue->proc.proc_rxtx[1].frame_rx ++;
+        // one frame delay
+        ue->proc.proc_rxtx[i].frame_rx ++;
 #endif
-    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;
+        ue->proc.proc_rxtx[i].frame_tx = ue->proc.proc_rxtx[0].frame_rx;
+    }
 #ifdef DEBUG_INITIAL_SYNCH
     LOG_I(PHY,"[UE%d] Initial sync: pbch decoded sucessfully p %d, tx_ant %d, frame %d, N_RB_DL %d, phich_duration %d, phich_resource %s!\n",
           ue->Mod_id,
@@ -467,13 +467,21 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
   if( (abs(ue->common_vars.freq_offset) > 150) && (ret == 0) )
   {
 	  ret=-1;
-	  LOG_E(HW,"Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
+#if DISABLE_LOG_X
+	  printf("Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
+#else
+	  LOG_E(HW, "Ignore MIB with high freq offset [%d Hz] estimation \n",ue->common_vars.freq_offset);
+#endif
   }
 
   if (ret==0) {  // PBCH found so indicate sync to higher layers and configure frame parameters
 
     //#ifdef DEBUG_INITIAL_SYNCH
-    LOG_I(PHY,"[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
+#if DISABLE_LOG_X
+    printf("[UE%d] In synch, rx_offset %d samples\n",ue->Mod_id, ue->rx_offset);
+#else
+    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) {
@@ -486,6 +494,8 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
               ue->common_vars.freq_offset );
     #endif
 
+// send sync status to higher layers later when timing offset converge to target timing
+#if OAISIM
       if (ue->mac_enabled==1) {
 	LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id);
 	//mac_resynch();
@@ -495,6 +505,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
       else {
 	ue->UE_mode[0] = PUSCH;
       }
+#endif
 
       generate_pcfich_reg_mapping(frame_parms);
       generate_phich_reg_mapping(frame_parms);
@@ -504,7 +515,29 @@ 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,
+#if DISABLE_LOG_X
+    printf("[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->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,
+	  ue->measurements.n0_power_tot_dBm,
+	  10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
+	  (10*log10(ue->measurements.rsrq[0])));
+
+
+    printf("[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->proc.proc_rxtx[0].frame_rx,
+	  duplex_string[ue->frame_parms.frame_type],
+	  prefix_string[ue->frame_parms.Ncp],
+	  ue->frame_parms.Nid_cell,
+	  ue->frame_parms.N_RB_DL,
+	  ue->frame_parms.phich_config_common.phich_duration,
+	  phich_string[ue->frame_parms.phich_config_common.phich_resource],
+	  ue->frame_parms.nb_antenna_ports_eNB);
+#else
+    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->proc.proc_rxtx[0].frame_rx,
 	  10*log10(ue->measurements.rssi)-ue->rx_total_gain_dB,
 	  10*log10(ue->measurements.rssi),
@@ -512,9 +545,8 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 	  ue->measurements.n0_power_tot_dBm,
 	  10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB,
 	  (10*log10(ue->measurements.rsrq[0])));
-    
-    
-    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",
+
+    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->proc.proc_rxtx[0].frame_rx,
 	  duplex_string[ue->frame_parms.frame_type],
@@ -524,13 +556,22 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 	  ue->frame_parms.phich_config_common.phich_duration,
 	  phich_string[ue->frame_parms.phich_config_common.phich_resource],
 	  ue->frame_parms.nb_antenna_ports_eNB);
+#endif
 
 #if defined(OAI_USRP) || defined(EXMIMO) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-    LOG_I(PHY,"[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
+#  if DISABLE_LOG_X
+    printf("[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
 	  ue->Mod_id,
 	  ue->proc.proc_rxtx[0].frame_rx,
 	  openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
 	  ue->common_vars.freq_offset);
+#  else
+    LOG_I(PHY, "[UE %d] Frame %d Measured Carrier Frequency %.0f Hz (offset %d Hz)\n",
+	  ue->Mod_id,
+	  ue->proc.proc_rxtx[0].frame_rx,
+	  openair0_cfg[0].rx_freq[0]-ue->common_vars.freq_offset,
+	  ue->common_vars.freq_offset);
+#  endif
 #endif
   } else {
 #ifdef DEBUG_INITIAL_SYNC
@@ -561,7 +602,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
       rx_power += signal_energy(&ue->common_vars.rxdata[aarx][sync_pos2],
 				frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
-    
+
     /*
     // do a measurement on the full frame
     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++)
@@ -570,7 +611,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
     */
 
     // we might add a low-pass filter here later
-    ue->measurements.rx_power_avg[0] = rx_power/frame_parms->nb_antennas_rx; 
+    ue->measurements.rx_power_avg[0] = rx_power/frame_parms->nb_antennas_rx;
 
     ue->measurements.rx_power_avg_dB[0] = dB_fixed(ue->measurements.rx_power_avg[0]);
 
@@ -579,7 +620,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
 #endif
 
 #ifndef OAI_USRP
-#ifndef OAI_BLADERF 
+#ifndef OAI_BLADERF
 #ifndef OAI_LMSSDR
   phy_adjust_gain(ue,ue->measurements.rx_power_avg_dB[0],0);
 #endif
@@ -590,7 +631,7 @@ int initial_sync(PHY_VARS_UE *ue, runmode_t mode)
   else {
 
 #ifndef OAI_USRP
-#ifndef OAI_BLADERF 
+#ifndef OAI_BLADERF
 #ifndef OAI_LMSSDR
   phy_adjust_gain(ue,dB_fixed(ue->measurements.rssi),0);
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c
index da215ef9a8e3cec65065f539343857c7da675d8d..48ba27956e8d3efdff052783dbf6fd4a390efd00 100644
--- a/openair1/PHY/LTE_TRANSPORT/phich.c
+++ b/openair1/PHY/LTE_TRANSPORT/phich.c
@@ -1078,7 +1078,7 @@ void rx_phich(PHY_VARS_UE *ue,
 
 
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
-  LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[subframe & 0x1][eNB_id];
+  LTE_UE_PDCCH **pdcch_vars = &ue->pdcch_vars[ue->current_thread_id[subframe]][eNB_id];
 
   //  uint8_t HI;
   uint8_t harq_pid = phich_subframe_to_harq_pid(frame_parms,proc->frame_rx,subframe);
@@ -1098,6 +1098,8 @@ void rx_phich(PHY_VARS_UE *ue,
   uint8_t NSF_PHICH = 4;
   uint8_t pusch_subframe;
 
+  int8_t delta_PUSCH_acc[4] = {-1,0,1,3};
+
   // 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,proc->frame_rx,subframe);
 
@@ -1387,6 +1389,14 @@ void rx_phich(PHY_VARS_UE *ue,
             nseq_PHICH,
             ngroup_PHICH);
 
+      ulsch->f_pusch += delta_PUSCH_acc[ulsch->harq_processes[harq_pid]->TPC];
+
+      LOG_I(PHY,"[PUSCH %d] AbsSubframe %d.%d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n",
+                 harq_pid,proc->frame_rx,subframe,ulsch->f_pusch,
+                    delta_PUSCH_acc[ulsch->harq_processes[harq_pid]->TPC],
+                    ulsch->harq_processes[harq_pid]->TPC);
+
+
       ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
       //      ulsch->harq_processes[harq_pid]->Ndi = 0;
       ulsch->harq_processes[harq_pid]->round++;
@@ -1399,7 +1409,7 @@ void rx_phich(PHY_VARS_UE *ue,
         ue->ulsch_Msg3_active[eNB_id] = 0;
       }
     } else {
-      //#ifdef DEBUG_PHICH
+#ifdef UE_DEBUG_TRACE
       LOG_I(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH, received NAK (%d) nseq %d, ngroup %d round %d (Mlimit %d)\n",
             ue->Mod_id,harq_pid,
             proc->frame_rx%1024,
@@ -1409,7 +1419,7 @@ void rx_phich(PHY_VARS_UE *ue,
             ngroup_PHICH,
             ulsch->harq_processes[harq_pid]->round,
             ulsch->Mlimit);
-      //#endif
+#endif
 
       //      ulsch->harq_processes[harq_pid]->Ndi = 0;
       ulsch->harq_processes[harq_pid]->round++;
@@ -1455,13 +1465,13 @@ void rx_phich(PHY_VARS_UE *ue,
             HI16,
             nseq_PHICH,ngroup_PHICH);
     } else {
-      //#ifdef PHICH_DEBUG
+#ifdef UE_DEBUG_TRACE
       LOG_I(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d PHICH, received ACK (%d) nseq %d, ngroup %d\n\n",
             ue->Mod_id,harq_pid,
             proc->frame_rx%1024,
             subframe, HI16,
             nseq_PHICH,ngroup_PHICH);
-      //#endif
+#endif
     }
 
    // LOG_I(PHY,"[HARQ-UL harqId: %d] subframe_scheduling_flag = %d \n",harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag);
diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c
index 40f157e56b2e287f758d390dab5743e15e338763..eb2fa1d8431c2e22cbae2845c6db4c12abf06935 100644
--- a/openair1/PHY/LTE_TRANSPORT/pmch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pmch.c
@@ -74,7 +74,7 @@ void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,in
   write_output(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_magb0[0],12*N_RB_DL*nsymb_pmch,1,1);
 
   write_output("mch00_ch0.m","pmch00_ch0",
-               &(ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+               &(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                ue->frame_parms.ofdm_symbol_size*12,1,1);
 
   write_output("rxsig_mch.m","rxs_mch",
@@ -967,8 +967,8 @@ int rx_pmch(PHY_VARS_UE *ue,
 
   //printf("*********************mch: symbol %d\n",symbol);
 
-  mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF,
-                  common_vars->common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id],
+  mch_extract_rbs(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF,
+                  common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id],
                   pdsch_vars[eNB_id]->rxdataF_ext,
                   pdsch_vars[eNB_id]->dl_ch_estimates_ext,
                   symbol,
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index a49e1806a2015a0cee93edc811b4521c2c33b157..d09e8dc3927e27c145a06c5ef65fe573cacff587 100644
--- a/openair1/PHY/LTE_TRANSPORT/proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/proto.h
@@ -113,7 +113,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag);
     @returns status
 */
 int32_t dlsch_encoding(PHY_VARS_eNB *eNB,
-		       uint8_t *a,
+                       uint8_t *a,
                        uint8_t num_pdcch_symbols,
                        LTE_eNB_DLSCH_t *dlsch,
                        int frame,
@@ -158,14 +158,14 @@ int32_t dlsch_encoding_SIC(PHY_VARS_UE *ue,
     @returns status
 */
 int32_t dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
-				uint8_t *a,
-				uint8_t num_pdcch_symbols,
-				LTE_eNB_DLSCH_t *dlsch,
-				int frame,
-				uint8_t subframe,
-				time_stats_t *rm_stats,
-				time_stats_t *te_stats,
-				time_stats_t *i_stats);
+                                uint8_t *a,
+                                uint8_t num_pdcch_symbols,
+                                LTE_eNB_DLSCH_t *dlsch,
+                                int frame,
+                                uint8_t subframe,
+                                time_stats_t *rm_stats,
+                                time_stats_t *te_stats,
+                                time_stats_t *i_stats);
 
 void dlsch_encoding_emul(PHY_VARS_eNB *phy_vars_eNB,
                          uint8_t *DLSCH_pdu,
@@ -264,11 +264,11 @@ int32_t allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
                            uint32_t *re_allocated,
                            uint8_t skip_dc,
                            uint8_t skip_half,
-			   uint8_t lprime,
-			   uint8_t mprime,
-			   uint8_t Ns,
-			   int *P1_SHIFT,
-			   int *P2_SHIFT);
+                           uint8_t lprime,
+                           uint8_t mprime,
+                           uint8_t Ns,
+                           int *P1_SHIFT,
+                           int *P2_SHIFT);
 
 
 /** \fn int32_t dlsch_modulation(int32_t **txdataF,
@@ -388,7 +388,7 @@ int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB,
 
 int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB,
                              eNB_rxtx_proc_t *proc,
-			     int32_t **txdataF,
+                             int32_t **txdataF,
                              int16_t amp);
 
 void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB,
@@ -396,7 +396,7 @@ void generate_ue_spec_pilots(PHY_VARS_eNB *phy_vars_eNB,
                              int32_t **txdataF,
                              int16_t amp,
                              uint16_t Ntti,
-		             uint8_t beamforming_mode);
+                             uint8_t beamforming_mode);
 
 int32_t generate_pss(int32_t **txdataF,
                      int16_t amp,
@@ -803,7 +803,8 @@ int dlsch_64qam_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                           unsigned char first_symbol_flag,
                           unsigned short nb_rb,
                           uint16_t pbch_pss_sss_adjust,
-                          short **llr16p);
+                          //short **llr16p,
+                          uint32_t llr_offset);
 
 
 /** \brief This function generates log-likelihood ratios (decoder input) for single-stream QPSK received waveforms.
@@ -824,7 +825,7 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
                        uint8_t first_symbol_flag,
                        uint16_t nb_rb,
                        uint16_t pbch_pss_sss_adj,
-                       int16_t **llr128p,
+                       //int16_t **llr128p,
                        uint8_t beamforming_mode);
 
 /**
@@ -842,16 +843,15 @@ int32_t dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms,
 */
 
 int32_t dlsch_qpsk_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
-                       int **rxdataF_comp,
-                                   int32_t **sic_buffer,
-                                   int **rho_i,
-                       short *dlsch_llr,
-                                   uint8_t num_pdcch_symbols,
-                       uint16_t nb_rb,
-                       uint8_t subframe,
-                                   uint32_t rb_alloc,
-                       uint16_t mod_order_0,
-                                   LTE_UE_DLSCH_t *dlsch0);
+                           int **rxdataF_comp,
+                           int32_t **sic_buffer,
+                           int **rho_i,
+                           short *dlsch_llr,
+                           uint8_t num_pdcch_symbols,
+                           uint16_t nb_rb,
+                           uint8_t subframe,
+                           uint16_t mod_order_0,
+                           uint32_t rb_alloc);
 
 void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      int32_t **rxdataF_comp,
@@ -878,30 +878,28 @@ void dlsch_16qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
 */
 void dlsch_16qam_llr_SIC (LTE_DL_FRAME_PARMS *frame_parms,
                           int32_t **rxdataF_comp,
-                                            int32_t **sic_buffer,  //Q15
-                                      int32_t **rho_i,
-                                            int16_t *dlsch_llr,
-                                            uint8_t num_pdcch_symbols,
-                                            int32_t **dl_ch_mag,
-                                            uint16_t nb_rb,
-                                            uint8_t subframe,
-                                            uint32_t rb_alloc,
+                          int32_t **sic_buffer,  //Q15
+                          int32_t **rho_i,
+                          int16_t *dlsch_llr,
+                          uint8_t num_pdcch_symbols,
+                          int32_t **dl_ch_mag,
+                          uint16_t nb_rb,
+                          uint8_t subframe,
                           uint16_t mod_order_0,
-                                            LTE_UE_DLSCH_t *dlsch0);
+                          uint32_t rb_alloc);
 
 void dlsch_64qam_llr_SIC(LTE_DL_FRAME_PARMS *frame_parms,
                          int32_t **rxdataF_comp,
-                                           int32_t **sic_buffer,  //Q15
-                                     int32_t **rho_i,
-                                           int16_t *dlsch_llr,
-                                           uint8_t num_pdcch_symbols,
-                                           int32_t **dl_ch_mag,
-                                           int32_t **dl_ch_magb,
-                                           uint16_t nb_rb,
-                                           uint8_t subframe,
-                                           uint32_t rb_alloc,
+                         int32_t **sic_buffer,  //Q15
+                         int32_t **rho_i,
+                         int16_t *dlsch_llr,
+                         uint8_t num_pdcch_symbols,
+                         int32_t **dl_ch_mag,
+                         int32_t **dl_ch_magb,
+                         uint16_t nb_rb,
+                         uint8_t subframe,
                          uint16_t mod_order_0,
-                                           LTE_UE_DLSCH_t *dlsch0);
+                         uint32_t rb_alloc);
 
 
 void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
@@ -913,7 +911,8 @@ void dlsch_64qam_llr(LTE_DL_FRAME_PARMS *frame_parms,
                      uint8_t first_symbol_flag,
                      uint16_t nb_rb,
                      uint16_t pbch_pss_sss_adjust,
-                     int16_t **llr_save,
+                     //int16_t **llr_save,
+                     uint32_t llr_offset,
                      uint8_t beamforming_mode);
 
 
@@ -1171,6 +1170,58 @@ void dlsch_dual_stream_correlationTM34(LTE_DL_FRAME_PARMS *frame_parms,
                                    int **dl_ch_rho_ext,
                                    unsigned char output_shift0,
                                    unsigned char output_shift1);
+//This function is used to compute multiplications in Hhermitian * H matrix
+void conjch0_mult_ch1(int *ch0,
+                      int *ch1,
+                      int32_t *ch0conj_ch1,
+                      unsigned short nb_rb,
+                      unsigned char output_shift0);
+
+void construct_HhH_elements(int *ch0conj_ch0,
+                         int *ch1conj_ch1,
+                         int *ch2conj_ch2,
+                         int *ch3conj_ch3,
+                         int *ch0conj_ch1,
+                         int *ch1conj_ch0,
+                         int *ch2conj_ch3,
+                         int *ch3conj_ch2,
+                         int32_t *after_mf_00,
+                         int32_t *after_mf_01,
+                         int32_t *after_mf_10,
+                         int32_t *after_mf_11,
+                         unsigned short nb_rb);
+
+void squared_matrix_element(int32_t *Hh_h_00,
+                            int32_t *Hh_h_00_sq,
+                            unsigned short nb_rb);
+
+void dlsch_channel_level_TM34_meas(int *ch00,
+                                   int *ch01,
+                                   int *ch10,
+                                   int *ch11,
+                                   int *avg_0,
+                                   int *avg_1,
+                                   unsigned short nb_rb);
+
+void det_HhH(int32_t *after_mf_00,
+             int32_t *after_mf_01,
+             int32_t *after_mf_10,
+             int32_t *after_mf_11,
+             int32_t *det_fin_128,
+             unsigned short nb_rb);
+
+void numer(int32_t *Hh_h_00_sq,
+           int32_t *Hh_h_01_sq,
+           int32_t *Hh_h_10_sq,
+           int32_t *Hh_h_11_sq,
+           int32_t *num_fin,
+           unsigned short nb_rb);
+
+uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00,
+                                int *dl_ch_estimates_01,
+                                int *dl_ch_estimates_10,
+                                int *dl_ch_estimates_11,
+                                unsigned short nb_rb);
 
 void dlsch_channel_compensation_TM56(int **rxdataF_ext,
                                      int **dl_ch_estimates_ext,
@@ -1326,7 +1377,7 @@ int32_t rx_pdcch(PHY_VARS_UE *ue,
 int pss_sss_extract(PHY_VARS_UE *phy_vars_ue,
                     int32_t pss_ext[4][72],
                     int32_t sss_ext[4][72],
-					uint8_t subframe);
+                                        uint8_t subframe);
 
 /*! \brief Extract only PSS resource elements
   @param phy_vars_ue Pointer to UE variables
@@ -1413,6 +1464,7 @@ void dci_encoding(uint8_t *a,
   \param sub_frame_offset subframe offset in frame
   @returns Number of PDCCH symbols
 */
+
 uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
 			 uint8_t num_dci,
                          DCI_ALLOC_t *dci_alloc,
@@ -1423,8 +1475,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
                          uint32_t sub_frame_offset);
 
 uint8_t generate_dci_top_emul(PHY_VARS_eNB *phy_vars_eNB,
-                              uint8_t num_ue_spec_dci,
-                              uint8_t num_common_dci,
+                              int num_dci,
                               DCI_ALLOC_t *dci_alloc,
                               uint8_t subframe);
 
@@ -1473,6 +1524,12 @@ uint16_t dci_decoding_procedure(PHY_VARS_UE *phy_vars_ue,
                                 int16_t eNB_id,
                                 uint8_t subframe);
 
+uint16_t dci_CRNTI_decoding_procedure(PHY_VARS_UE *ue,
+                                DCI_ALLOC_t *dci_alloc,
+                                uint8_t DCIFormat,
+                                uint8_t agregationLevel,
+                                int16_t eNB_id,
+                                uint8_t subframe);
 
 uint16_t dci_decoding_procedure_emul(LTE_UE_PDCCH **lte_ue_pdcch_vars,
                                      uint8_t num_ue_spec_dci,
@@ -1599,7 +1656,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,
+                           UE_rxtx_proc_t *proc,
                            uint8_t eNB_id,
                            int16_t amp,
                            uint32_t subframe,
@@ -1647,6 +1704,8 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       void *dci_pdu,
                                       rnti_t rnti,
                                       DCI_format_t dci_format,
+                                      LTE_UE_PDCCH *pdcch_vars,
+                                      LTE_UE_PDSCH *pdsch_vars,
                                       LTE_UE_DLSCH_t **dlsch,
                                       LTE_DL_FRAME_PARMS *frame_parms,
                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
@@ -1693,7 +1752,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
                                       DCI_format_t dci_format,
                                       PHY_VARS_UE *phy_vars_ue,
                                       UE_rxtx_proc_t *proc,
-				      uint16_t si_rnti,
+                                      uint16_t si_rnti,
                                       uint16_t ra_rnti,
                                       uint16_t p_rnti,
                                       uint16_t cba_rnti,
@@ -1701,21 +1760,21 @@ 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,
-					  UE_rxtx_proc_t *proc,
-					  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,
-						 uint8_t subframe);
+                                                 uint8_t subframe);
 
 uint8_t sinr2cqi(double sinr,uint8_t trans_mode);
 
 int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB,
-				       eNB_rxtx_proc_t *proc,
-				       void *dci_pdu,
+                                       eNB_rxtx_proc_t *proc,
+                                       void *dci_pdu,
                                        rnti_t rnti,
-				       DCI_format_t dci_format,
+                                       DCI_format_t dci_format,
                                        uint8_t UE_id,
-				       uint16_t si_rnti,
+                                       uint16_t si_rnti,
                                        uint16_t ra_rnti,
                                        uint16_t p_rnti,
                                        uint16_t cba_rnti,
@@ -1824,7 +1883,7 @@ int32_t ulsch_encoding_emul(uint8_t *ulsch_buffer,
   @returns 0 on success
 */
 unsigned int  ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
-			     eNB_rxtx_proc_t *proc,
+                             eNB_rxtx_proc_t *proc,
                              uint8_t UE_id,
                              uint8_t control_only_flag,
                              uint8_t Nbundled,
@@ -1839,9 +1898,9 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB,
   @returns 0 on success
 */
 int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
-				int UE_id,
-				int harq_pid,
-				int llr8_flag);
+                                int UE_id,
+                                int harq_pid,
+                                int llr8_flag);
 
 /*!
   \brief Decoding of ULSCH data component from 36-212. This one is single thread.
@@ -1852,13 +1911,13 @@ int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,
   @returns 0 on success
 */
 int ulsch_decoding_data(PHY_VARS_eNB *eNB,
-			int UE_id,
-			int harq_pid,
-			int llr8_flag);
+                        int UE_id,
+                        int harq_pid,
+                        int llr8_flag);
 
 uint32_t ulsch_decoding_emul(PHY_VARS_eNB *phy_vars_eNB,
                              eNB_rxtx_proc_t *proc,
-			     uint8_t UE_index,
+                             uint8_t UE_index,
                              uint16_t *crnti);
 
 void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
@@ -1873,7 +1932,7 @@ void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB,
 */
 
 void rx_phich(PHY_VARS_UE *phy_vars_ue,
-	      UE_rxtx_proc_t *proc,
+              UE_rxtx_proc_t *proc,
               uint8_t subframe,
               uint8_t eNB_id);
 
@@ -1987,28 +2046,28 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
 void init_ncs_cell(LTE_DL_FRAME_PARMS *frame_parms,uint8_t ncs_cell[20][7]);
 
 void generate_pucch1x(int32_t **txdataF,
-		      LTE_DL_FRAME_PARMS *frame_parms,
-		      uint8_t ncs_cell[20][7],
-		      PUCCH_FMT_t fmt,
-		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-		      uint16_t n1_pucch,
-		      uint8_t shortened_format,
-		      uint8_t *payload,
-		      int16_t amp,
-		      uint8_t subframe);
+                      LTE_DL_FRAME_PARMS *frame_parms,
+                      uint8_t ncs_cell[20][7],
+                      PUCCH_FMT_t fmt,
+                      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+                      uint16_t n1_pucch,
+                      uint8_t shortened_format,
+                      uint8_t *payload,
+                      int16_t amp,
+                      uint8_t subframe);
 
 void generate_pucch2x(int32_t **txdataF,
-		      LTE_DL_FRAME_PARMS *fp,
-		      uint8_t ncs_cell[20][7],
-		      PUCCH_FMT_t fmt,
-		      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
-		      uint16_t n2_pucch,
-		      uint8_t *payload,
-		      int A,
-		      int B2,
-		      int16_t amp,
-		      uint8_t subframe,
-		      uint16_t rnti);
+                      LTE_DL_FRAME_PARMS *fp,
+                      uint8_t ncs_cell[20][7],
+                      PUCCH_FMT_t fmt,
+                      PUCCH_CONFIG_DEDICATED *pucch_config_dedicated,
+                      uint16_t n2_pucch,
+                      uint8_t *payload,
+                      int A,
+                      int B2,
+                      int16_t amp,
+                      uint8_t subframe,
+                      uint16_t rnti);
 
 void generate_pucch3x(int32_t **txdataF,
                     LTE_DL_FRAME_PARMS *frame_parms,
@@ -2023,7 +2082,7 @@ void generate_pucch3x(int32_t **txdataF,
                     uint16_t rnti);
 
 void generate_pucch_emul(PHY_VARS_UE *phy_vars_ue,
-			 UE_rxtx_proc_t *proc,
+                         UE_rxtx_proc_t *proc,
                          PUCCH_FMT_t format,
                          uint8_t ncs1,
                          uint8_t *pucch_ack_payload,
@@ -2043,11 +2102,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *phy_vars_eNB,
                   uint8_t pucch1_thres);
 
 int32_t rx_pucch_emul(PHY_VARS_eNB *phy_vars_eNB,
-		      eNB_rxtx_proc_t *proc,
-		      uint8_t UE_index,
-		      PUCCH_FMT_t fmt,
-		      uint8_t n1_pucch_sel,
-		      uint8_t *payload);
+                      eNB_rxtx_proc_t *proc,
+                      uint8_t UE_index,
+                      PUCCH_FMT_t fmt,
+                      uint8_t n1_pucch_sel,
+                      uint8_t *payload);
 
 
 /*!
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index 201c027089da3f2cf422871e18ba55006442ee97..8375a4f82491ecc8d8acc9771229bfa12ecd173d 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -2060,12 +2060,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
       rxptr = (int16_t *)&common_vars->rxdataF[aa][symbol_offset];
 
       for (i=0; i<12; i++,j+=2,re_offset++) {
-        rxcomp[aa][j]   = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[j])>>15)   - ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[1+j])>>15);
-        rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[j])>>15);
-
         if (re_offset==frame_parms->ofdm_symbol_size)
           re_offset = 0;
 
+        rxcomp[aa][j]   = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[j])>>15)   - ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[1+j])>>15);
+        rxcomp[aa][1+j] = (int16_t)((rxptr[re_offset<<1]*(int32_t)zptr[1+j])>>15) + ((rxptr[1+(re_offset<<1)]*(int32_t)zptr[j])>>15);
+
 #ifdef DEBUG_PUCCH_RX
         printf("[eNB] PUCCH subframe %d (%d,%d,%d,%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,i,re_offset,m,j,
               rxptr[re_offset<<1],rxptr[1+(re_offset<<1)],
@@ -2139,8 +2139,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 
     } //phase
 
-    stat_max *= nsymb;  // normalize to energy per symbol
-    stat_max /= (frame_parms->N_RB_UL*12); // 
+//    stat_max *= nsymb;  // normalize to energy per symbol
+//    stat_max /= (frame_parms->N_RB_UL*12); // 
+    stat_max /= (nsymb*12);
 #ifdef DEBUG_PUCCH_RX
     printf("[eNB] PUCCH: stat %d, stat_max %d, phase_max %d\n", stat,stat_max,phase_max);
 #endif
@@ -2188,7 +2189,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
     LOG_I(PHY,"Doing PUCCH detection for format 1a/1b\n");
 #endif
 
-    for (phase=3;phase<4;phase++){ //phase=0; phase<7; phase++) {
+    for (phase=0; phase<7; phase++) {
       stat=0;
 
       for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
@@ -2325,8 +2326,8 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
             off=(re<<1) + (24*l);
             tmp_re = ((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15);
             tmp_im = ((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15);
-            stat_re += (((tmp_re*chest_re)>>15) + ((tmp_im*chest_im)>>15)/4);
-            stat_im += (((tmp_re*chest_im)>>15) - ((tmp_im*chest_re)>>15)/4);
+            stat_re += (((tmp_re*chest_re)>>15) + ((tmp_im*chest_im)>>15))/4;
+            stat_im += (((tmp_re*chest_im)>>15) - ((tmp_im*chest_re)>>15))/4;
             off+=2;
 #ifdef DEBUG_PUCCH_RX
             printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,re,
@@ -2517,7 +2518,7 @@ int32_t rx_pucch_emul(PHY_VARS_eNB *eNB,
   rnti = eNB->ulsch[UE_index]->rnti;
 
   for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
-    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe & 0x1][0]->crnti)
+    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[PHY_vars_UE_g[UE_id][CC_id]->current_thread_id[subframe]][0]->crnti)
       break;
   }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/sss.c b/openair1/PHY/LTE_TRANSPORT/sss.c
index 5eada8bc9c3eef2af838b2ae7901644d0a806d29..bb12be9157126f6d8798786c0526191506d41ab1 100644
--- a/openair1/PHY/LTE_TRANSPORT/sss.c
+++ b/openair1/PHY/LTE_TRANSPORT/sss.c
@@ -160,6 +160,7 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
   int32_t *pss_rxF,*pss_rxF_ext;
   int32_t *sss_rxF,*sss_rxF_ext;
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  uint8_t next_thread_id = ue->current_thread_id[subframe]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe]+1);
 
   int rx_offset = frame_parms->ofdm_symbol_size-3*12;
   uint8_t pss_symb,sss_symb;
@@ -173,7 +174,7 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
 	    pss_symb = 6-frame_parms->Ncp;
 	    sss_symb = pss_symb-1;
 
-	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 	    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 	    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 
@@ -183,18 +184,18 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
 
 	    if(subframe==5 || subframe==0)
 	    {
-	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 	    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 
-	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)&0x1)].rxdataF;
+	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
 	    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 	    }
 	    else if(subframe==6 || subframe==1)
 	    {
-		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF;
+		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
 		    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 
-		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF;
+		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
 		    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 	    }
 	    else
@@ -222,18 +223,18 @@ int _do_pss_sss_extract(PHY_VARS_UE *ue,
         {
         	if(subframe==5 || subframe==0)
         	{
-    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF;
+    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
     	    sss_rxF  =  &rxdataF[aarx][(1 + (sss_symb*(frame_parms->ofdm_symbol_size)))];
 
-    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[((subframe+1)&0x1)].rxdataF;
+    	    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
     	    pss_rxF  =  &rxdataF[aarx][(1 + (pss_symb*(frame_parms->ofdm_symbol_size)))];
         	}
     	    else if(subframe==6 || subframe==1)
     	    {
-    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe&0x1)].rxdataF;
+    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF;
     		    pss_rxF  =  &rxdataF[aarx][(rx_offset + (pss_symb*(frame_parms->ofdm_symbol_size)))];
 
-    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF;
+    		    rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF;
     		    sss_rxF  =  &rxdataF[aarx][(rx_offset + (sss_symb*(frame_parms->ofdm_symbol_size)))];
     	    }
     	    else
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
index 52f302ce92ce0e870e5c3534ef88aa23969f4b78..f4d7cee401ddc6d1f7d6f6d7921541c486bd2cdd 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_coding.c
@@ -262,7 +262,7 @@ uint32_t ulsch_encoding(uint8_t *a,
   // fill CQI/PMI information
   if (ulsch->O>0) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ULSCH_ENCODING_FILL_CQI, VCD_FUNCTION_IN);
-    rnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti;
+    rnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
     fill_CQI(ulsch,meas,0,harq_pid,ue->frame_parms.N_RB_DL,rnti, tmode,ue->sinr_eff);
 
     LOG_D(PHY,"ULSCH Encoding rnti %x \n", rnti);
@@ -971,7 +971,7 @@ int ulsch_encoding_emul(uint8_t *ulsch_buffer,
   LTE_UE_DLSCH_t **dlsch = ue->dlsch[0][eNB_id];
   PHY_MEASUREMENTS *meas = &ue->measurements;
   uint8_t tmode = ue->transmission_mode[eNB_id];
-  uint16_t rnti=ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti;
+  uint16_t rnti=ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
   LOG_D(PHY,"EMUL UE ulsch_encoding for eNB %d,mod_id %d, harq_pid %d rnti %x, ACK(%d,%d) \n",
         eNB_id,ue->Mod_id, harq_pid, rnti,ulsch->o_ACK[0],ulsch->o_ACK[1]);
 
@@ -1005,7 +1005,7 @@ int ulsch_encoding_emul(uint8_t *ulsch_buffer,
   //UE_transport_info_TB_index[ue->Mod_id]+=ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3;
   // navid: currently more than one eNB is not supported in the code
   UE_transport_info[ue->Mod_id][ue->CC_id].num_eNB = 1;
-  UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[subframe_rx & 0x1][0]->crnti;
+  UE_transport_info[ue->Mod_id][ue->CC_id].rnti[0] = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][0]->crnti;
   UE_transport_info[ue->Mod_id][ue->CC_id].eNB_id[0]  = eNB_id;
   UE_transport_info[ue->Mod_id][ue->CC_id].harq_pid[0] = harq_pid;
   UE_transport_info[ue->Mod_id][ue->CC_id].tbs[0]     = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3 ;
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 94dfdbb5f07769253dc733ae6b85f2548d416a5b..ff3e3e112698f7b93ca96985792f547103dffeb1 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -1996,7 +1996,7 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
 #endif
 
   for (UE_id=0; UE_id<NB_UE_INST; UE_id++) {
-    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[subframe & 0x1][0]->crnti)
+    if (rnti == PHY_vars_UE_g[UE_id][CC_id]->pdcch_vars[PHY_vars_UE_g[UE_id][CC_id]->current_thread_id[subframe]][0]->crnti)
       break;
 
   }
diff --git a/openair1/PHY/LTE_TRANSPORT/vars.h b/openair1/PHY/LTE_TRANSPORT/vars.h
index ba589398786fb528a7745dff4a399df127083d3a..4845ab6925aef5ca9de38339e4a4e7f263d1adeb 100644
--- a/openair1/PHY/LTE_TRANSPORT/vars.h
+++ b/openair1/PHY/LTE_TRANSPORT/vars.h
@@ -59,8 +59,8 @@ char lte_cqi_snr_dB[15] = { -2,
 
 unsigned char ue_power_offsets[25] = {14,11,9,8,7,6,6,5,4,4,4,3,3,3,2,2,2,1,1,1,1,1,0,0,0};
 
-short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1} ;
-short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ;
+short conjugate[8]__attribute__((aligned(16))) = {-1,1,-1,1,-1,1,-1,1};
+short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1};
 
 int qam64_table[8],qam16_table[4];
 
diff --git a/openair1/PHY/MODULATION/defs.h b/openair1/PHY/MODULATION/defs.h
index a4625c257046a2476ad162b1eac0863845449436..65bfda2fbfd16d7fb7a59184b72a32ca78daedce 100644
--- a/openair1/PHY/MODULATION/defs.h
+++ b/openair1/PHY/MODULATION/defs.h
@@ -76,6 +76,17 @@ int slot_fep_ul(RU_t *ru,
                 unsigned char Ns,
                 int no_prefix);
 
+int front_end_fft(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int sample_offset,
+             int no_prefix);
+
+int front_end_chanEst(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+            int reset_freq_est);
+
 void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRAME_PARMS *frame_parms);
 
 void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t next_slot, LTE_DL_FRAME_PARMS *frame_parms);
diff --git a/openair1/PHY/MODULATION/slot_fep.c b/openair1/PHY/MODULATION/slot_fep.c
index 3a3b3b4c0d48ed810ba7c1236314b7e994c2a24f..d97ffbc543e080a5d594b430ccb798c85daf25d6 100644
--- a/openair1/PHY/MODULATION/slot_fep.c
+++ b/openair1/PHY/MODULATION/slot_fep.c
@@ -109,7 +109,7 @@ int slot_fep(PHY_VARS_UE *ue,
 
 
   for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    memset(&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
+    memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
 
     rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
     // Align with 256 bit
@@ -127,13 +127,17 @@ int slot_fep(PHY_VARS_UE *ue,
                (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
         dft((int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
-        start_meas(&ue->rx_dft_stats);
+#if UE_TIMING_TRACE
+          start_meas(&ue->rx_dft_stats);
+#endif
 
         dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+#if UE_TIMING_TRACE
         stop_meas(&ue->rx_dft_stats);
+#endif
 
       }
     } else {
@@ -150,22 +154,24 @@ int slot_fep(PHY_VARS_UE *ue,
         memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
                (void *)&common_vars->rxdata[aa][0],
                frame_parms->ofdm_symbol_size*sizeof(int));
-
+#if UE_TIMING_TRACE
       start_meas(&ue->rx_dft_stats);
+#endif
 
       if ((rx_offset&7)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
         memcpy((void *)tmp_dft_in,
                (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
                frame_parms->ofdm_symbol_size*sizeof(int));
         dft((int16_t *)tmp_dft_in,
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       } else { // use dft input from RX buffer directly
 
         dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
-            (int16_t *)&common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
       }
-
+#if UE_TIMING_TRACE
       stop_meas(&ue->rx_dft_stats);
+#endif
 
 
     }
@@ -183,13 +189,17 @@ int slot_fep(PHY_VARS_UE *ue,
 #ifdef DEBUG_FEP
         printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
 #endif
+#if UE_TIMING_TRACE
         start_meas(&ue->dlsch_channel_estimation_stats);
+#endif
         lte_dl_channel_estimation(ue,eNB_id,0,
                                   Ns,
                                   aa,
                                   l,
                                   symbol);
+#if UE_TIMING_TRACE
         stop_meas(&ue->dlsch_channel_estimation_stats);
+#endif
 
         for (i=0; i<ue->measurements.n_adj_cells; i++) {
           lte_dl_channel_estimation(ue,eNB_id,i+1,
@@ -208,13 +218,19 @@ int slot_fep(PHY_VARS_UE *ue,
 #endif
 
       if (l==(4-frame_parms->Ncp)) {
-        start_meas(&ue->dlsch_freq_offset_estimation_stats);
-        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[0],
+
+#if UE_TIMING_TRACE
+          start_meas(&ue->dlsch_freq_offset_estimation_stats);
+#endif
+
+        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[Ns>>1]].dl_ch_estimates[0],
                             frame_parms,
                             l,
                             &common_vars->freq_offset,
 			    reset_freq_est);
+#if UE_TIMING_TRACE
         stop_meas(&ue->dlsch_freq_offset_estimation_stats);
+#endif
 
       }
     }
@@ -226,3 +242,219 @@ int slot_fep(PHY_VARS_UE *ue,
 #endif
   return(0);
 }
+
+int front_end_fft(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int sample_offset,
+             int no_prefix)
+{
+  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  LTE_UE_COMMON *common_vars   = &ue->common_vars;
+  unsigned char aa;
+  unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
+  unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples);
+  unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0);
+  unsigned int subframe_offset;//,subframe_offset_F;
+  unsigned int slot_offset;
+  unsigned int frame_length_samples = frame_parms->samples_per_tti * 10;
+  unsigned int rx_offset;
+  uint8_t  threadId;
+
+  /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
+  unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
+  int uespec_pilot[9][1200];*/
+
+  void (*dft)(int16_t *,int16_t *, int);
+  int tmp_dft_in[2048] __attribute__ ((aligned (32)));  // This is for misalignment issues for 6 and 15 PRBs
+
+  switch (frame_parms->ofdm_symbol_size) {
+  case 128:
+    dft = dft128;
+    break;
+
+  case 256:
+    dft = dft256;
+    break;
+
+  case 512:
+    dft = dft512;
+    break;
+
+  case 1024:
+    dft = dft1024;
+    break;
+
+  case 1536:
+    dft = dft1536;
+    break;
+
+  case 2048:
+    dft = dft2048;
+    break;
+
+  default:
+    dft = dft512;
+    break;
+  }
+
+  if (no_prefix) {
+    subframe_offset = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
+    slot_offset = frame_parms->ofdm_symbol_size * (frame_parms->symbols_per_tti>>1) * (Ns%2);
+  } else {
+    subframe_offset = frame_parms->samples_per_tti * (Ns>>1);
+    slot_offset = (frame_parms->samples_per_tti>>1) * (Ns%2);
+  }
+
+  //  subframe_offset_F = frame_parms->ofdm_symbol_size * frame_parms->symbols_per_tti * (Ns>>1);
+
+
+  if (l<0 || l>=7-frame_parms->Ncp) {
+    printf("slot_fep: l must be between 0 and %d\n",7-frame_parms->Ncp);
+    return(-1);
+  }
+
+  if (Ns<0 || Ns>=20) {
+    printf("slot_fep: Ns must be between 0 and 19\n");
+    return(-1);
+  }
+
+
+
+  threadId = ue->current_thread_id[Ns>>1];
+  for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+      // change thread index
+    memset(&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],0,frame_parms->ofdm_symbol_size*sizeof(int));
+
+    rx_offset = sample_offset + slot_offset + nb_prefix_samples0 + subframe_offset - SOFFSET;
+    // Align with 256 bit
+    //    rx_offset = rx_offset&0xfffffff8;
+
+    if (l==0) {
+
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((short *)&common_vars->rxdata[aa][frame_length_samples],
+               (short *)&common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 256-bit aligned, issue for size 6,15 and 25 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *)&common_vars->rxdata[aa][rx_offset % frame_length_samples],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      } else { // use dft input from RX buffer directly
+        start_meas(&ue->rx_dft_stats);
+
+        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+        stop_meas(&ue->rx_dft_stats);
+
+      }
+    } else {
+      rx_offset += (frame_parms->ofdm_symbol_size+nb_prefix_samples)*l;// +
+      //                   (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1);
+
+#ifdef DEBUG_FEP
+      //  if (ue->frame <100)
+      LOG_I(PHY,"slot_fep: frame %d: slot %d, threadId %d, symbol %d, nb_prefix_samples %d, nb_prefix_samples0 %d, slot_offset %d, subframe_offset %d, sample_offset %d,rx_offset %d, frame_length_samples %d\n",
+              ue->proc.proc_rxtx[threadId].frame_rx,Ns, threadId,symbol,
+          nb_prefix_samples,nb_prefix_samples0,slot_offset,subframe_offset,sample_offset,rx_offset,frame_length_samples);
+#endif
+
+      if (rx_offset > (frame_length_samples - frame_parms->ofdm_symbol_size))
+        memcpy((void *)&common_vars->rxdata[aa][frame_length_samples],
+               (void *)&common_vars->rxdata[aa][0],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+
+      start_meas(&ue->rx_dft_stats);
+
+      if ((rx_offset&7)!=0) {  // if input to dft is not 128-bit aligned, issue for size 6 and 15 PRBs
+        memcpy((void *)tmp_dft_in,
+               (void *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+               frame_parms->ofdm_symbol_size*sizeof(int));
+        dft((int16_t *)tmp_dft_in,
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      } else { // use dft input from RX buffer directly
+
+        dft((int16_t *)&common_vars->rxdata[aa][(rx_offset) % frame_length_samples],
+            (int16_t *)&common_vars->common_vars_rx_data_per_thread[threadId].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],1);
+      }
+
+      stop_meas(&ue->rx_dft_stats);
+
+
+    }
+
+    #ifdef DEBUG_FEP
+        //  if (ue->frame <100)
+        printf("slot_fep: frame %d: symbol %d rx_offset %d\n", ue->proc.proc_rxtx[threadId].frame_rx, symbol,rx_offset);
+    #endif
+  }
+  return(0);
+}
+
+int front_end_chanEst(PHY_VARS_UE *ue,
+             unsigned char l,
+             unsigned char Ns,
+             int reset_freq_est)
+{
+  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  LTE_UE_COMMON *common_vars   = &ue->common_vars;
+  uint8_t eNB_id = 0;//ue_common_vars->eNb_id;
+  unsigned char aa;
+  unsigned char symbol = l+((7-frame_parms->Ncp)*(Ns&1)); ///symbol within sub-frame
+  int i;
+
+  /*LTE_UE_DLSCH_t **dlsch_ue = phy_vars_ue->dlsch_ue[eNB_id];
+  unsigned char harq_pid = dlsch_ue[0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *dlsch0_harq = dlsch_ue[0]->harq_processes[harq_pid];
+  int uespec_pilot[9][1200];*/
+
+  if (ue->perfect_ce == 0) {
+    if ((l==0) || (l==(4-frame_parms->Ncp))) {
+      for (aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
+
+#ifdef DEBUG_FEP
+        printf("Channel estimation eNB %d, aatx %d, slot %d, symbol %d\n",eNB_id,aa,Ns,l);
+#endif
+        start_meas(&ue->dlsch_channel_estimation_stats);
+        lte_dl_channel_estimation(ue,eNB_id,0,
+                                  Ns,
+                                  aa,
+                                  l,
+                                  symbol);
+        stop_meas(&ue->dlsch_channel_estimation_stats);
+
+        for (i=0; i<ue->measurements.n_adj_cells; i++) {
+          lte_dl_channel_estimation(ue,eNB_id,i+1,
+                                    Ns,
+                                    aa,
+                                    l,
+                                    symbol);
+        }
+      }
+
+
+      // do frequency offset estimation here!
+      // use channel estimates from current symbol (=ch_t) and last symbol (ch_{t-1})
+#ifdef DEBUG_FEP
+      printf("Frequency offset estimation\n");
+#endif
+
+      if (l==(4-frame_parms->Ncp)) {
+        start_meas(&ue->dlsch_freq_offset_estimation_stats);
+        lte_est_freq_offset(common_vars->common_vars_rx_data_per_thread[(Ns>>1)&0x1].dl_ch_estimates[0],
+                            frame_parms,
+                            l,
+                            &common_vars->freq_offset,
+                reset_freq_est);
+        stop_meas(&ue->dlsch_freq_offset_estimation_stats);
+
+      }
+    }
+
+  }
+  return(0);
+}
diff --git a/openair1/PHY/MODULATION/slot_fep_mbsfn.c b/openair1/PHY/MODULATION/slot_fep_mbsfn.c
index 471d3111820f214dcd1a4f54668cbba2d559de31..adcd8cd186bd7d50c556c536f9c7dd90a78baa84 100644
--- a/openair1/PHY/MODULATION/slot_fep_mbsfn.c
+++ b/openair1/PHY/MODULATION/slot_fep_mbsfn.c
@@ -109,15 +109,19 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
 #endif
 
   for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
-    memset(&common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*l],0,frame_parms->ofdm_symbol_size*sizeof(int));
+    memset(&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],0,frame_parms->ofdm_symbol_size*sizeof(int));
     if (l==0) {
-      start_meas(&ue->rx_dft_stats);
+#if UE_TIMING_TRACE
+        start_meas(&ue->rx_dft_stats);
+#endif
       dft((int16_t *)&common_vars->rxdata[aa][(sample_offset +
           nb_prefix_samples0 +
           subframe_offset -
           SOFFSET) % frame_length_samples],
-          (int16_t *)&common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+          (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+#if UE_TIMING_TRACE
       stop_meas(&ue->rx_dft_stats);
+#endif
     } else {
       if ((sample_offset +
            (frame_parms->ofdm_symbol_size+nb_prefix_samples0+nb_prefix_samples) +
@@ -128,14 +132,18 @@ int slot_fep_mbsfn(PHY_VARS_UE *ue,
                (short *)&common_vars->rxdata[aa][0],
                frame_parms->ofdm_symbol_size*sizeof(int));
 
+#if UE_TIMING_TRACE
       start_meas(&ue->rx_dft_stats);
+#endif
       dft((int16_t *)&common_vars->rxdata[aa][(sample_offset +
           (frame_parms->ofdm_symbol_size+nb_prefix_samples0+nb_prefix_samples) +
           (frame_parms->ofdm_symbol_size+nb_prefix_samples)*(l-1) +
           subframe_offset-
           SOFFSET) % frame_length_samples],
-          (int16_t *)&common_vars->common_vars_rx_data_per_thread[subframe&0x1].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+          (int16_t *)&common_vars->common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[aa][frame_parms->ofdm_symbol_size*l],1);
+#if UE_TIMING_TRACE
       stop_meas(&ue->rx_dft_stats);
+#endif
     }
   }
 
diff --git a/openair1/PHY/TOOLS/defs.h b/openair1/PHY/TOOLS/defs.h
index 542b8edba5820b37c9e4d343fef07dfc6715414a..a90a8b718cfc36ec6ccbd3927eae8f70ae3abfea 100644
--- a/openair1/PHY/TOOLS/defs.h
+++ b/openair1/PHY/TOOLS/defs.h
@@ -338,6 +338,9 @@ uint8_t log2_approx64(unsigned long long int x);
 int16_t invSqrt(int16_t x);
 uint32_t angle(struct complex16 perrror);
 
+/// computes the number of factors 2 in x
+unsigned char factor2(unsigned int x);
+
 /*!\fn int32_t phy_phase_compensation_top (uint32_t pilot_type, uint32_t initial_pilot,
         uint32_t last_pilot, int32_t ignore_prefix);
 Compensate the phase rotation of the RF. WARNING: This function is currently unused. It has not been tested!
diff --git a/openair1/PHY/TOOLS/log2_approx.c b/openair1/PHY/TOOLS/log2_approx.c
index 0317a97d2f5d6fa1b3dd068dc97aee9d42612f0d..bd4d5d04ab87fec8fad51b0026163fa1a3bce3c2 100644
--- a/openair1/PHY/TOOLS/log2_approx.c
+++ b/openair1/PHY/TOOLS/log2_approx.c
@@ -37,6 +37,26 @@ unsigned char log2_approx(unsigned int x)
   return(l2);
 }
 
+unsigned char factor2(unsigned int x)
+{
+
+  int i;
+  unsigned char l2;
+
+  l2=0;
+
+  for (i=0; i<31; i++)
+    if ((x&(1<<i)) != 0)
+      break;
+
+  l2 = i;
+
+  //printf("factor2(%d) = %d\n",x,l2);
+  return(l2);
+}
+
+
+
 unsigned char log2_approx64(unsigned long long int x)
 {
 
diff --git a/openair1/PHY/TOOLS/lte_phy_scope.c b/openair1/PHY/TOOLS/lte_phy_scope.c
index a3e96e528414ab8ec91f526181e31864e42131ec..ad51a348ec467a1ef5239b822b9744b331735d08 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope.c
@@ -514,32 +514,32 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
 
 
-  if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) {
-    harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+    harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
 
     if (harq_pid>=8)
       return;
 
-    mcs = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs;
+    mcs = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
 
     // Button 0
-    if(!phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
+    if(!phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
       // we are in TM5
       fl_show_object(form->button_0);
     }
   }
 
-  if (phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]!=NULL) {
-    num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols;
+  if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
+    num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
   }
 
   //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-  if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) {
+  if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
     coded_bits_per_codeword = get_G(frame_parms,
-                                    phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                                    phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+                                    phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+                                    phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
                                     get_Qm(mcs),
-                                    phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl,
+                                    phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
                                     num_pdcch_symbols,
                                     frame,
                                     subframe,
@@ -563,16 +563,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
   bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
 
   rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
-  chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_id];
-  chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id];
+  chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
+  chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
   pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
   pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
-  pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->llr;
-  pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0];
-  pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 0
+  pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
+  pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
+  pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
   //    pdsch_llr = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars_SI[eNB_id]->llr[0]; // stream 0
-  pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0];
-  pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag0[0];
+  pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
+  pdsch_mag = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
 
   // Received signal in time domain of receive antenna 0
   if (rxsig_t != NULL) {
diff --git a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
index 92a0d9f218e2ebedc09ecbdcf4eecccfa55ad022..e5d667c3c20c6528cb2126f27a49fdaac9c225b6 100644
--- a/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
+++ b/openair1/PHY/TOOLS/lte_phy_scope_tm4.c
@@ -24,6 +24,7 @@
 #include "lte_phy_scope.h"
 #define TPUT_WINDOW_LENGTH 100
 int otg_enabled;
+int use_sic_receiver=0;
 FL_COLOR rx_antenna_colors[4] = {FL_RED,FL_BLUE,FL_GREEN,FL_YELLOW};
 float tput_time_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
 float tput_enb[NUMBER_OF_UE_MAX][TPUT_WINDOW_LENGTH] = {{0}};
@@ -54,6 +55,21 @@ static void dl_traffic_on_off( FL_OBJECT *button, long arg)
     fl_set_object_color(button, FL_RED, FL_RED);
   }
 }
+
+static void sic_receiver_on_off( FL_OBJECT *button, long arg)
+{
+
+  if (fl_get_button(button)) {
+    fl_set_object_label(button, "SIC Receiver ON");
+    use_sic_receiver = 1;
+    fl_set_object_color(button, FL_GREEN, FL_GREEN);
+  } else {
+    fl_set_object_label(button, "SIC Receiver OFF");
+    use_sic_receiver = 0;
+    fl_set_object_color(button, FL_RED, FL_RED);
+  }
+}
+
 FD_lte_phy_scope_enb *create_lte_phy_scope_enb( void )
 {
   FL_OBJECT *obj;
@@ -398,16 +414,17 @@ FD_lte_phy_scope_ue *create_lte_phy_scope_ue( void ) {
     fl_set_object_boxtype( fdui->pdsch_tput, FL_EMBOSSED_BOX );
     fl_set_object_color( fdui->pdsch_tput, FL_BLACK, FL_WHITE );
     fl_set_object_lcolor( fdui->pdsch_tput, FL_WHITE ); // Label color
+    */
     // Generic UE Button
     fdui->button_0 = fl_add_button( FL_PUSH_BUTTON, 540, 720, 240, 40, "" );
     fl_set_object_lalign(fdui->button_0, FL_ALIGN_CENTER );
-    //openair_daq_vars.use_ia_receiver = 0;
+    //use_sic_receiver = 0;
     fl_set_button(fdui->button_0,0);
-    fl_set_object_label(fdui->button_0, "IA Receiver OFF");
+    fl_set_object_label(fdui->button_0, "SIC Receiver OFF");
     fl_set_object_color(fdui->button_0, FL_RED, FL_RED);
-    fl_set_object_callback(fdui->button_0, ia_receiver_on_off, 0 );
+    fl_set_object_callback(fdui->button_0, sic_receiver_on_off, 0 );
     fl_hide_object(fdui->button_0);
-    */
+
     fl_end_form( );
     fdui->lte_phy_scope_ue->fdui = fdui;
     return fdui;
@@ -448,11 +465,11 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
     int mcs1=0;
     unsigned char harq_pid = 0;
     int beamforming_mode = phy_vars_ue->transmission_mode[eNB_id]>6 ? phy_vars_ue->transmission_mode[eNB_id] : 0;
-    if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
+        harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
   if (harq_pid>=8)
     return;
-    mcs0 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->mcs;
+    mcs0 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->mcs;
         // Button 0
   /*
         if(!phy_vars_ue->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off) {
@@ -461,23 +478,24 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
         }
   */
     }
-       if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) {
-        harq_pid = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid;
+    fl_show_object(form->button_0);
+      if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
+        harq_pid = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->current_harq_pid;
   if (harq_pid>=8)
     return;
-    mcs1 = phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->mcs;
+    mcs1 = phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->mcs;
     }
-    if (phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]!=NULL) {
-        num_pdcch_symbols = phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->num_pdcch_symbols;
+    if (phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]!=NULL) {
+        num_pdcch_symbols = phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->num_pdcch_symbols;
     }
     //    coded_bits_per_codeword = frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
-    if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]!=NULL) {
+    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]!=NULL) {
       mod0 = get_Qm(mcs0);
       coded_bits_per_codeword0 = get_G(frame_parms,
-              phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-              phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+              phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+              phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
               get_Qm(mcs0),
-              phy_vars_ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl,
+              phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
               num_pdcch_symbols,
               frame,
               subframe,
@@ -486,13 +504,13 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
       coded_bits_per_codeword0 = 0; //frame_parms->N_RB_DL*12*get_Qm(mcs)*(frame_parms->symbols_per_tti);
       mod0=0;
     }
-    if (phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]!=NULL) {
+    if (phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]!=NULL) {
       mod1 = get_Qm(mcs1);
       coded_bits_per_codeword1 = get_G(frame_parms,
-               phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
-               phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
+               phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->nb_rb,
+               phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->rb_alloc_even,
                get_Qm(mcs1),
-               phy_vars_ue->dlsch[subframe&0x1][eNB_id][1]->harq_processes[harq_pid]->Nl,
+               phy_vars_ue->dlsch[phy_vars_ue->current_thread_id[subframe]][eNB_id][1]->harq_processes[harq_pid]->Nl,
                num_pdcch_symbols,
                frame,
                subframe,
@@ -515,23 +533,23 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
     llr_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float)); // init to zero
     bit_pdcch = (float*) calloc(12*frame_parms->N_RB_DL*num_pdcch_symbols*2,sizeof(float));
     rxsig_t = (int16_t**) phy_vars_ue->common_vars.rxdata;
-    chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates_time[eNB_id];
-    chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id];
+    chest_t = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id];
+    chest_f = (int16_t**) phy_vars_ue->common_vars.common_vars_rx_data_per_thread[phy_vars_ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
     pbch_llr = (int8_t*) phy_vars_ue->pbch_vars[eNB_id]->llr;
     pbch_comp = (int16_t*) phy_vars_ue->pbch_vars[eNB_id]->rxdataF_comp[0];
-    pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->llr;
-    pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0];
-    pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0]; // stream 0
-    pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[1]; // stream 1
-    pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp0[0];
-    //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[0];
-    //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[subframe&0x1][eNB_id]->rxdataF_ext[1];
-    pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0])[0];
+    pdcch_llr = (int8_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr;
+    pdcch_comp = (int16_t*) phy_vars_ue->pdcch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0];
+    pdsch_llr = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[0]; // stream 0
+    pdsch_llr1 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->llr[1]; // stream 1
+    pdsch_comp = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0];
+    //pdsch_comp = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0];
+    //pdsch_comp1 = (int16_t*) phy_vars_ue->lte_ue_pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[1];
+    pdsch_comp1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[0][0])[0];
     //pdsch_comp1 = (int16_t*) (phy_vars_ue->lte_ue_pdsch_vars[eNB_id]->dl_ch_rho_ext[0][0])[0];
-    pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag0[0];
-    pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[0][0])[0];
-    pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb0[0];
-    pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[0][0])[0];
+    pdsch_mag0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0];
+    pdsch_mag1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[0][0])[0];
+    pdsch_magb0 = (int16_t*) phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0];
+    pdsch_magb1 = (int16_t*) (phy_vars_ue->pdsch_vars[phy_vars_ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[0][0])[0];
     fl_freeze_form(form->lte_phy_scope_ue);
     // Received signal in time domain of receive antenna 0
     if (rxsig_t != NULL) {
@@ -797,4 +815,16 @@ void phy_scope_UE(FD_lte_phy_scope_ue *form,
     for (arx=0;arx<nb_antennas_rx;arx++) {
         free(chest_t_abs[arx]);
     }
+
+    //This is done to avoid plotting old data when TB0 is disabled, and TB1 is mapped onto CW0
+    /*if (phy_vars_ue->transmission_mode[eNB_id]==3 && phy_vars_ue->transmission_mode[eNB_id]==4){
+      for (int i = 0; i<8; ++i)
+        for (int j = 0; j < 7*2*frame_parms->N_RB_DL*12+4; ++j )
+          phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[0][0][i][j]=0;
+
+      for (int m=0; m<coded_bits_per_codeword1; ++m)
+          phy_vars_ue->pdsch_vars[subframe&0x1][eNB_id]->llr[0][m]=0;
+      }*/
   }
+
+
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 0fb7b2b01b761b35c7684a6bb1c3a4c71a7f261e..01318b8b91ec0ef293f6def6850559020e060a50 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -80,6 +80,10 @@
 #define openair_free(y,x) free((y))
 #define PAGE_SIZE 4096
 
+#define RX_NB_TH_MAX 2
+#define RX_NB_TH 2
+
+
 //! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards.
 //! If no more memory is available, this function will terminate the program with an assertion error.
 static inline void* malloc16_clear( size_t size )
@@ -205,8 +209,10 @@ typedef enum  {
 } node_function_t;
 
 typedef enum {
+
   synch_to_ext_device=0,  // synch to RF or Ethernet device
-  synch_to_other          // synch to another source_(timer, other RU)
+  synch_to_other,          // synch to another source_(timer, other RU)
+  synch_to_mobipass_standalone  // special case for mobipass in standalone mode
 } node_timing_t;
 #endif
 
@@ -572,6 +578,32 @@ typedef struct {
   pthread_mutex_t mutex_rxtx;
   /// scheduling parameters for RXn-TXnp4 thread
   struct sched_param sched_param_rxtx;
+
+  /// internal This variable is protected by ref mutex_fep_slot1.
+  //int instance_cnt_slot0_dl_processing;
+  int instance_cnt_slot1_dl_processing;
+  /// pthread descriptor fep_slot1 thread
+  //pthread_t pthread_slot0_dl_processing;
+  pthread_t pthread_slot1_dl_processing;
+  /// pthread attributes for fep_slot1 processing thread
+ // pthread_attr_t attr_slot0_dl_processing;
+  pthread_attr_t attr_slot1_dl_processing;
+  /// condition variable for UE fep_slot1 thread;
+  //pthread_cond_t cond_slot0_dl_processing;
+  pthread_cond_t cond_slot1_dl_processing;
+  /// mutex for UE synch thread
+  //pthread_mutex_t mutex_slot0_dl_processing;
+  pthread_mutex_t mutex_slot1_dl_processing;
+  //
+  uint8_t chan_est_pilot0_slot1_available;
+  uint8_t chan_est_slot1_available;
+  uint8_t llr_slot1_available;
+  uint8_t dci_slot0_available;
+  uint8_t first_symbol_available;
+  //uint8_t channel_level;
+  /// scheduling parameters for fep_slot1 thread
+  struct sched_param sched_param_fep_slot1;
+
   int sub_frame_start;
   int sub_frame_step;
   unsigned long long gotIQs;
@@ -605,7 +637,7 @@ typedef struct {
   /// instance count for eNBs
   int instance_cnt_eNBs;
   /// set of scheduling variables RXn-TXnp4 threads
-  UE_rxtx_proc_t proc_rxtx[2];
+  UE_rxtx_proc_t proc_rxtx[RX_NB_TH];
 } UE_proc_t;
 
 typedef enum {
@@ -1157,16 +1189,19 @@ typedef struct {
   LTE_DL_FRAME_PARMS  frame_parms_before_ho;
   LTE_UE_COMMON    common_vars;
 
-  LTE_UE_PDSCH     *pdsch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads
+  // point to the current rxTx thread index
+  uint8_t current_thread_id[10];
+
+  LTE_UE_PDSCH     *pdsch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX+1]; // two RxTx Threads
   LTE_UE_PDSCH_FLP *pdsch_vars_flp[NUMBER_OF_CONNECTED_eNB_MAX+1];
   LTE_UE_PDSCH     *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1];
   LTE_UE_PDSCH     *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1];
   LTE_UE_PDSCH     *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1];
   LTE_UE_PDSCH     *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_PBCH      *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX];
-  LTE_UE_PDCCH     *pdcch_vars[2][NUMBER_OF_CONNECTED_eNB_MAX];
+  LTE_UE_PDCCH     *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_PRACH     *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX];
-  LTE_UE_DLSCH_t   *dlsch[2][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads
+  LTE_UE_DLSCH_t   *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX][2]; // two RxTx Threads
   LTE_UE_ULSCH_t   *ulsch[NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_DLSCH_t   *dlsch_SI[NUMBER_OF_CONNECTED_eNB_MAX];
   LTE_UE_DLSCH_t   *dlsch_ra[NUMBER_OF_CONNECTED_eNB_MAX];
@@ -1257,6 +1292,7 @@ typedef struct {
   uint8_t               decode_MIB;
   int              rx_offset; /// Timing offset
   int              rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
+  int              time_sync_cell;
   int              timing_advance; ///timing advance signalled from eNB
   int              hw_timing_advance;
   int              N_TA_offset; ///timing offset used in TDD
@@ -1323,9 +1359,9 @@ typedef struct {
   /// Transmission mode per eNB
   uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX];
 
-  time_stats_t phy_proc;
+  time_stats_t phy_proc[RX_NB_TH];
   time_stats_t phy_proc_tx;
-  time_stats_t phy_proc_rx[2];
+  time_stats_t phy_proc_rx[RX_NB_TH];
 
   uint32_t use_ia_receiver;
 
@@ -1339,8 +1375,13 @@ typedef struct {
   time_stats_t ulsch_multiplexing_stats;
 
   time_stats_t generic_stat;
-  time_stats_t pdsch_procedures_stat;
-  time_stats_t dlsch_procedures_stat;
+  time_stats_t generic_stat_bis[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
+  time_stats_t ue_front_end_stat[RX_NB_TH];
+  time_stats_t ue_front_end_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
+  time_stats_t pdcch_procedures_stat[RX_NB_TH];
+  time_stats_t pdsch_procedures_stat[RX_NB_TH];
+  time_stats_t pdsch_procedures_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
+  time_stats_t dlsch_procedures_stat[RX_NB_TH];
 
   time_stats_t ofdm_demod_stats;
   time_stats_t dlsch_rx_pdcch_stats;
@@ -1353,6 +1394,7 @@ typedef struct {
   time_stats_t dlsch_turbo_decoding_stats;
   time_stats_t dlsch_deinterleaving_stats;
   time_stats_t dlsch_llr_stats;
+  time_stats_t dlsch_llr_stats_parallelization[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME];
   time_stats_t dlsch_unscrambling_stats;
   time_stats_t dlsch_rate_matching_stats;
   time_stats_t dlsch_turbo_encoding_stats;
@@ -1371,10 +1413,13 @@ typedef struct {
   openair0_device rfdevice; 
 } PHY_VARS_UE;
 
-
-
-
-
+/* this structure is used to pass both UE phy vars and
+ * proc to the function UE_thread_rxn_txnp4
+ */
+struct rx_tx_thread_data {
+  PHY_VARS_UE    *UE;
+  UE_rxtx_proc_t *proc;
+};
 
 void exit_fun(const char* s);
 
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index fd6e36246fa6658a61ef10dadc2d9d1cb6e00737..b5b1774c6e7af9fadbb09477ddc0c1d8a45fb2b7 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -39,6 +39,11 @@
 //#include "defs.h"
 #include "openair2/COMMON/platform_types.h"
 
+#define RX_NB_TH_MAX 2
+#define RX_NB_TH 2
+
+#define LTE_SLOTS_PER_SUBFRAME 2
+
 #define LTE_NUMBER_OF_SUBFRAMES_PER_FRAME 10
 #define LTE_SLOTS_PER_FRAME  20
 #define LTE_CE_FILTER_LENGTH 5
@@ -954,7 +959,7 @@ typedef struct {
   /// - second index: sample [0..FRAME_LENGTH_COMPLEX_SAMPLES+2048[
   int32_t **rxdata;
 
-  LTE_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[2];
+  LTE_UE_COMMON_PER_THREAD common_vars_rx_data_per_thread[RX_NB_TH_MAX];
 
   /// holds output of the sync correlator
   int32_t *sync_corr;
@@ -1057,6 +1062,10 @@ typedef struct {
   //uint32_t *rb_alloc;
   //uint8_t Qm[2];
   //MIMO_mode_t mimo_mode;
+  // llr offset per ofdm symbol
+  uint32_t llr_offset[14];
+  // llr length per ofdm symbol
+  uint32_t llr_length[14];
 } LTE_UE_PDSCH;
 
 typedef struct {
@@ -1157,6 +1166,9 @@ typedef struct {
   uint32_t dci_missed;
   /// nCCE for PUCCH per subframe
   uint8_t nCCE[10];
+  //Check for specific DCIFormat and AgregationLevel
+  uint8_t dciFormat;
+  uint8_t agregationLevel;
 } LTE_UE_PDCCH;
 
 #define PBCH_A 24
diff --git a/openair1/PHY/vars.h b/openair1/PHY/vars.h
index a74813cb8ffb374a7e545a50396fd2b6b6e1ac94..7bdb072b967a6e6238b9e6902fff19870c2ddaec 100644
--- a/openair1/PHY/vars.h
+++ b/openair1/PHY/vars.h
@@ -76,6 +76,7 @@ unsigned int ULSCH_max_consecutive_errors = 20;
 
 int number_of_cards;
 
+
 int flag_LA=0;
 int flagMag;
 //extern  channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index f414e28f6309f845feae2e8e2dd1778222b6cb3d..785e34e3c4459a911953993a8e0a6b24f41d4cb8 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -43,6 +43,7 @@ enum THREAD_INDEX { OPENAIR_THREAD_INDEX = 0,
 
 #define OPENAIR_THREAD_STACK_SIZE     PTHREAD_STACK_MIN //4096 //RTL_PTHREAD_STACK_MIN*6
 //#define DLC_THREAD_STACK_SIZE        4096 //DLC stack size
+//#define UE_SLOT_PARALLELISATION
 
 enum openair_SCHED_STATUS {
   openair_SCHED_STOPPED=1,
@@ -102,7 +103,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,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);
+void phy_procedures_UE_lte(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
 
 #if defined(Rel10) || defined(Rel14)
 /*! \brief Top-level entry routine for relay node procedures when acting as eNB. This proc will make us of the existing eNB procs.
@@ -138,7 +139,13 @@ void phy_procedures_UE_TX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,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
 */
-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);
+int phy_procedures_UE_RX(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
+int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
+                                              uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
+                                              relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn);
+#ifdef UE_SLOT_PARALLELISATION
+void *UE_thread_slot1_dl_processing(void *arg);
+#endif
 
 /*! \brief Scheduling for UE TX procedures in TDD S-subframes.
   @param phy_vars_ue Pointer to UE variables on which to act
diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c
index f750253c6787a329aee900c8171778beb45c37a6..835066748dabecbc7f4b87a578ec5a2686675b6b 100644
--- a/openair1/SCHED/phy_mac_stub.c
+++ b/openair1/SCHED/phy_mac_stub.c
@@ -72,19 +72,19 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
   LOG_D(PHY,"frame %d, subframe %d, transmission_mode %d\n",proc->frame_tx,proc->subframe_tx,transmission_mode);
 
-  DCI_pdu->Num_common_dci = 0;
-  DCI_pdu->Num_ue_spec_dci=0;
+  DCI_pdu->Num_dci = 0;
 
   switch (subframe) {
   case 5:
    if ( !(proc->frame_tx&1) ) // SI message on even frame only (SFN mod 2 == 0)
    {
-	DCI_pdu->Num_common_dci = 1;
-	DCI_pdu->dci_alloc[0].L          = 2;
-	DCI_pdu->dci_alloc[0].firstCCE   = 0;
-	DCI_pdu->dci_alloc[0].rnti       = SI_RNTI;
-	DCI_pdu->dci_alloc[0].format     = format1A;
-	DCI_pdu->dci_alloc[0].ra_flag    = 0;
+	DCI_pdu->Num_dci = 1;
+	DCI_pdu->dci_alloc[0].L            = 2;
+	DCI_pdu->dci_alloc[0].firstCCE     = 0;
+	DCI_pdu->dci_alloc[0].rnti         = SI_RNTI;
+	DCI_pdu->dci_alloc[0].format       = format1A;
+	DCI_pdu->dci_alloc[0].ra_flag      = 0;
+	DCI_pdu->dci_alloc[0].search_space = DCI_COMMON_SPACE;
 
     switch (eNB->frame_parms.N_RB_DL) {
     case 6:
@@ -206,12 +206,13 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
     }
     /*
   case 6:
-      DCI_pdu->Num_ue_spec_dci = 1;
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI2_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[0].format     = format2_2A_M10PRB;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->Num_dci = 1;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI2_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[0].format       = format2_2A_M10PRB;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu1.rballoc          = 0x00ff;
       DLSCH_alloc_pdu1.TPC              = 0;
@@ -228,12 +229,13 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
   default:
   case 7:
-    DCI_pdu->Num_ue_spec_dci = 1;
-    DCI_pdu->dci_alloc[0].L          = 2;
-    DCI_pdu->dci_alloc[0].firstCCE   = 0;
-    DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-    DCI_pdu->dci_alloc[0].format     = format1;
-    DCI_pdu->dci_alloc[0].ra_flag    = 0;
+    DCI_pdu->Num_dci = 1;
+    DCI_pdu->dci_alloc[0].L            = 2;
+    DCI_pdu->dci_alloc[0].firstCCE     = 0;
+    DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+    DCI_pdu->dci_alloc[0].format       = format1;
+    DCI_pdu->dci_alloc[0].ra_flag      = 0;
+    DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
     if (transmission_mode<3 || transmission_mode == 7) {
       //user 1
@@ -459,10 +461,11 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
     
 
-    DCI_pdu->dci_alloc[1].L          = 2;
-    DCI_pdu->dci_alloc[1].rnti       = 0x1235;
-    DCI_pdu->dci_alloc[1].format     = format0;
-    DCI_pdu->dci_alloc[1].ra_flag    = 0;
+    DCI_pdu->dci_alloc[1].L            = 2;
+    DCI_pdu->dci_alloc[1].rnti         = 0x1235;
+    DCI_pdu->dci_alloc[1].format       = format0;
+    DCI_pdu->dci_alloc[1].ra_flag      = 0;
+    DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
 
     if (eNB->frame_parms.frame_type == FDD) {
       switch (eNB->frame_parms.N_RB_DL) {
@@ -601,13 +604,14 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
       }
     }
     } else if (transmission_mode==4) {
-      DCI_pdu->Num_ue_spec_dci = 1;
+      DCI_pdu->Num_dci = 1;
       // user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI2_5MHz_2A_FDD_t;
-      DCI_pdu->dci_alloc[0].L          = 3;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format2;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI2_5MHz_2A_FDD_t;
+      DCI_pdu->dci_alloc[0].L            = 3;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format2;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       ((DCI2_5MHz_2A_FDD_t*) (&DCI_pdu->dci_alloc[0].dci_pdu))->tpmi     = 0;
       ((DCI2_5MHz_2A_FDD_t*) (&DCI_pdu->dci_alloc[0].dci_pdu))->rv1      = 0;
@@ -623,13 +627,14 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
       ((DCI2_5MHz_2A_FDD_t*) (&DCI_pdu->dci_alloc[0].dci_pdu))->rah      = 0;
 
     } else if (transmission_mode==5) {
-      DCI_pdu->Num_ue_spec_dci = 2;
+      DCI_pdu->Num_dci = 2;
       // user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 3;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 3;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu1E.tpmi             = 5; //5=use feedback
       DLSCH_alloc_pdu1E.rv               = 0;
@@ -648,11 +653,12 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
       memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
 
       //user 2
-      DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[1].L          = 0;
-      DCI_pdu->dci_alloc[1].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[1].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[1].ra_flag    = 0;
+      DCI_pdu->dci_alloc[1].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[1].L            = 0;
+      DCI_pdu->dci_alloc[1].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[1].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[1].ra_flag      = 0;
+      DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
       //DLSCH_alloc_pdu1E.mcs            = eNB->target_ue_dl_mcs;
       //DLSCH_alloc_pdu1E.mcs            = (unsigned char) (taus()%28);
       //DLSCH_alloc_pdu1E.mcs            = (unsigned char) ((eNB->frame%1024)%28);
@@ -669,12 +675,13 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
     /*
       case 8:
-      DCI_pdu->Num_common_dci = 1;
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0xbeef;
-      DCI_pdu->dci_alloc[0].format     = format1A;
-      DCI_pdu->dci_alloc[0].ra_flag    = 1;
+      DCI_pdu->Num_dci = 1;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1A_5MHz_TDD_1_6_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0xbeef;
+      DCI_pdu->dci_alloc[0].format       = format1A;
+      DCI_pdu->dci_alloc[0].ra_flag      = 1;
+      DCI_pdu->dci_alloc[0].search_space = DCI_COMMON_SPACE;
 
       RA_alloc_pdu.type                = 1;
       RA_alloc_pdu.vrb_type            = 0;
@@ -721,7 +728,7 @@ void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
   /*
   DCI_pdu->nCCE = 0;
 
-  for (i=0; i<DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci; i++) {
+  for (i=0; i<DCI_pdu->Num_dci; i++) {
     DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L));
   }
   */
@@ -743,20 +750,20 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
     rand = (rand%4)+5;
   */
 
-  DCI_pdu->Num_common_dci = 0;
-  DCI_pdu->Num_ue_spec_dci=0;
+  DCI_pdu->Num_dci = 0;
 
   switch (subframe) {
   case 5:
-    DCI_pdu->Num_ue_spec_dci = 1;
+    DCI_pdu->Num_dci = 1;
 
     if (transmission_mode<3) {
       //user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1_5MHz_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format1;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1_5MHz_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format1;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu.rballoc          = eNB->ue_dl_rb_alloc;
       DLSCH_alloc_pdu.TPC              = 0;
@@ -769,11 +776,12 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
 
       /*
       //user2
-      DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1_5MHz_TDD_t;
-      DCI_pdu->dci_alloc[1].L          = 2;
-      DCI_pdu->dci_alloc[1].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[1].format     = format1;
-      DCI_pdu->dci_alloc[1].ra_flag    = 0;
+      DCI_pdu->dci_alloc[1].dci_length   = sizeof_DCI1_5MHz_TDD_t;
+      DCI_pdu->dci_alloc[1].L            = 2;
+      DCI_pdu->dci_alloc[1].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[1].format       = format1;
+      DCI_pdu->dci_alloc[1].ra_flag      = 0;
+      DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu.rballoc          = rballoc2;
       DLSCH_alloc_pdu.TPC              = 0;
@@ -785,13 +793,14 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
       memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_TDD_t));
       */
     } else if (transmission_mode==5) {
-      DCI_pdu->Num_ue_spec_dci = 2;
+      DCI_pdu->Num_dci = 2;
       // user 1
-      DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[0].L          = 2;
-      DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-      DCI_pdu->dci_alloc[0].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[0].ra_flag    = 0;
+      DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[0].L            = 2;
+      DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+      DCI_pdu->dci_alloc[0].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[0].ra_flag      = 0;
+      DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
       DLSCH_alloc_pdu1E.tpmi             = 5; //5=use feedback
       DLSCH_alloc_pdu1E.rv               = 0;
@@ -806,11 +815,12 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
       memcpy((void*)&DCI_pdu->dci_alloc[0].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
 
       //user 2
-      DCI_pdu->dci_alloc[1].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
-      DCI_pdu->dci_alloc[1].L          = 2;
-      DCI_pdu->dci_alloc[1].rnti       = 0x1236;
-      DCI_pdu->dci_alloc[1].format     = format1E_2A_M10PRB;
-      DCI_pdu->dci_alloc[1].ra_flag    = 0;
+      DCI_pdu->dci_alloc[1].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      DCI_pdu->dci_alloc[1].L            = 2;
+      DCI_pdu->dci_alloc[1].rnti         = 0x1236;
+      DCI_pdu->dci_alloc[1].format       = format1E_2A_M10PRB;
+      DCI_pdu->dci_alloc[1].ra_flag      = 0;
+      DCI_pdu->dci_alloc[1].search_space = DCI_UE_SPACE;
 
       memcpy((void*)&DCI_pdu->dci_alloc[1].dci_pdu[0],(void *)&DLSCH_alloc_pdu1E,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
 
@@ -821,12 +831,13 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
     break;
 
   case 7:
-    DCI_pdu->Num_common_dci = 1;
-    DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI1A_5MHz_TDD_1_6_t;
-    DCI_pdu->dci_alloc[0].L          = 2;
-    DCI_pdu->dci_alloc[0].rnti       = 0xbeef;
-    DCI_pdu->dci_alloc[0].format     = format1A;
-    DCI_pdu->dci_alloc[0].ra_flag    = 1;
+    DCI_pdu->Num_dci = 1;
+    DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI1A_5MHz_TDD_1_6_t;
+    DCI_pdu->dci_alloc[0].L            = 2;
+    DCI_pdu->dci_alloc[0].rnti         = 0xbeef;
+    DCI_pdu->dci_alloc[0].format       = format1A;
+    DCI_pdu->dci_alloc[0].ra_flag      = 1;
+    DCI_pdu->dci_alloc[0].search_space = DCI_COMMON_SPACE;
 
     RA_alloc_pdu.type                = 1;
     RA_alloc_pdu.vrb_type            = 0;
@@ -841,14 +852,15 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
     break;
 
   case 9:
-    DCI_pdu->Num_ue_spec_dci = 1;
+    DCI_pdu->Num_dci = 1;
 
     //user 1
-    DCI_pdu->dci_alloc[0].dci_length = sizeof_DCI0_5MHz_TDD_1_6_t ;
-    DCI_pdu->dci_alloc[0].L          = 2;
-    DCI_pdu->dci_alloc[0].rnti       = 0x1235;
-    DCI_pdu->dci_alloc[0].format     = format0;
-    DCI_pdu->dci_alloc[0].ra_flag    = 0;
+    DCI_pdu->dci_alloc[0].dci_length   = sizeof_DCI0_5MHz_TDD_1_6_t ;
+    DCI_pdu->dci_alloc[0].L            = 2;
+    DCI_pdu->dci_alloc[0].rnti         = 0x1235;
+    DCI_pdu->dci_alloc[0].format       = format0;
+    DCI_pdu->dci_alloc[0].ra_flag      = 0;
+    DCI_pdu->dci_alloc[0].search_space = DCI_UE_SPACE;
 
     UL_alloc_pdu.type    = 0;
     UL_alloc_pdu.hopping = 0;
@@ -894,7 +906,7 @@ void fill_dci_emos(DCI_PDU *DCI_pdu, uint8_t subframe, PHY_VARS_eNB *eNB)
   /*
   DCI_pdu->nCCE = 0;
 
-  for (i=0; i<DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci; i++) {
+  for (i=0; i<DCI_pdu->Num_dci; i++) {
     DCI_pdu->nCCE += (1<<(DCI_pdu->dci_alloc[i].L));
   }
   */
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 7149ae1f03944e22aaa51e1087d4f829a9e345c1..66e43b6960d4249801ead781653113fa0d9bf180 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -572,16 +572,16 @@ uint8_t get_reset_ack(LTE_DL_FRAME_PARMS *frame_parms,
 
     case 4:
           if (subframe_tx == 2) {  // ACK subframes 4, 5 and 0
-            subframe_dl0 = 4;
-            subframe_dl1 = 5;
-            subframe_dl2 = 0;
+            subframe_dl0 = 0;
+            subframe_dl1 = 4;
+            subframe_dl2 = 5;
             subframe_ul  = 2;
             //printf("subframe_tx 2, TDD config 3: harq_ack[5] = %d (%d),harq_ack[6] = %d (%d)\n",harq_ack[5].ack,harq_ack[5].send_harq_status,harq_ack[6].ack,harq_ack[6].send_harq_status);
           } else if (subframe_tx == 3) { // ACK subframes 6, 7 8 and 9
-            subframe_dl0 = 6;
-            subframe_dl1 = 7;
-            subframe_dl2 = 8;
-            subframe_dl3 = 9;
+            subframe_dl0 = 7;
+            subframe_dl1 = 8;
+            subframe_dl2 = 9;
+            subframe_dl3 = 6;
             subframe_ul  = 3;
             //printf("Subframe 3, TDD config 3: harq_ack[7] = %d,harq_ack[8] = %d\n",harq_ack[7].ack,harq_ack[8].ack);
             //printf("status %d : o_ACK (%d,%d)\n", status,o_ACK[0],o_ACK[1]);
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index ffa41898b34537bc84c4ec3ad54919ad9cb72fd7..8b2fb967bc66c81393abc40ca000e89d2f6dfa2c 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -471,6 +471,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   }
 
 
+
   //  num_pdcch_symbols = DCI_pdu->num_pdcch_symbols;
   num_pdcch_symbols = eNB->pdcch_vars[subframe&1].num_pdcch_symbols;
   num_dci           = eNB->pdcch_vars[subframe&1].num_dci;
@@ -486,6 +487,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   if (num_dci > 0)
     LOG_D(PHY,"[eNB %"PRIu8"] Frame %d, subframe %d: Calling generate_dci_top (pdcch) (num_dci %"PRIu8")\n",eNB->Mod_id,frame, subframe,
 	  num_dci);
+
     
   generate_dci_top(num_pdcch_symbols,
 		   num_dci,
@@ -525,6 +527,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
       }
 
+
       else if ((dlsch0)&&
 	       (dlsch0->rnti>0)&&
 	       (dlsch0->active == 0)) {
@@ -545,12 +548,12 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   
 }
 
+
 void prach_procedures(PHY_VARS_eNB *eNB,
 #ifdef Rel14
 		      int br_flag
 #endif
 		      ) {
-
   uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4];
   uint16_t i;
   int frame,subframe;
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index cb6e997772d4bea30a2f80922aadc14912c286db..64ba2a1b9885393f5c1b259f1a6773f903135d78 100644
--- a/openair1/SCHED/phy_procedures_lte_ue.c
+++ b/openair1/SCHED/phy_procedures_lte_ue.c
@@ -30,12 +30,16 @@
  * \warning
  */
 
+#define _GNU_SOURCE
+
 #include "assertions.h"
 #include "defs.h"
 #include "PHY/defs.h"
 #include "PHY/extern.h"
 #include "SCHED/defs.h"
 #include "SCHED/extern.h"
+#include <sched.h>
+#include "targets/RT/USER/lte-softmodem.h"
 
 #define DEBUG_PHY_PROC
 
@@ -69,8 +73,6 @@ fifo_dump_emos_UE emos_dump_UE;
 
 #define NS_PER_SLOT 500000
 
-extern int oai_exit;
-
 extern double cpuf;
 
 
@@ -87,29 +89,29 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf
   uint8_t nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12;
 
   coded_bits_per_codeword = get_G(&ue->frame_parms,
-                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
-                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
-                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Qm,
-                                  ue->dlsch[subframe&0x1][eNB_id][0]->harq_processes[harq_pid]->Nl,
-                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm,
+                                  ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                                   proc->frame_rx,
-				  subframe,
-				  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
+          subframe,
+          ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
 
-  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
-  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[subframe&0x1][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
-  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[subframe&0x1][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1);
+  write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
   /*
     write_output("dlsch01_ch0_ext.m","dl01_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[1],300*12,1,1);
     write_output("dlsch10_ch0_ext.m","dl10_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[2],300*12,1,1);
     write_output("dlsch11_ch0_ext.m","dl11_ch0_ext",pdsch_vars[0]->dl_ch_estimates_ext[3],300*12,1,1);
     write_output("dlsch_rho.m","dl_rho",pdsch_vars[0]->rho[0],300*12,1,1);
   */
-  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[subframe&0x1][0]->rxdataF_comp0[0],300*12,1,1);
-  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[subframe&0x1][0]->llr[0],coded_bits_per_codeword,1,0);
+  write_output("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_comp0[0],300*12,1,1);
+  write_output("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->llr[0],coded_bits_per_codeword,1,0);
 
-  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0,300*12,1,1);
-  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0,300*12,1,1);
+  write_output("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_mag0,300*12,1,1);
+  write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_magb0,300*12,1,1);
 }
 
 void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe)
@@ -122,23 +124,23 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
                                   ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even,
                                   2,
                                   1,
-                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                                   proc->frame_rx,
-				  subframe,
-				  0);
+          subframe,
+          0);
   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,
-	nsymb,
+  ue->frame_parms.ofdm_symbol_size,
+  nsymb,
         ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
         ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs,
         ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb,
-        ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
         coded_bits_per_codeword);
 
   write_output("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1);
 
-  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
   write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1);
   write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1);
   /*
@@ -221,19 +223,19 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
                                   ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even,
                                   2,
                                   1,
-                                  ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+                                  ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
                                   proc->frame_rx,
-				  subframe,
-				  0);
+          subframe,
+          0);
   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,
         ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs,
         ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb,
-        ue->pdcch_vars[0&0x1][eNB_id]->num_pdcch_symbols,
+        ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols,
         coded_bits_per_codeword);
 
-  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
+  write_output("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1);
   write_output("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1);
   write_output("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1);
   /*
@@ -259,7 +261,7 @@ void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
 
   //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
-  for(int l=0; l<2; l++) {
+  for(int l=0; l<RX_NB_TH; l++) {
       for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
           for(j=0; j<2; j++) {
               //DL HARQ
@@ -323,6 +325,7 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
       PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=SCH_IDLE;
       PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0;
       PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0;
+      PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0;
     }
   }
 
@@ -370,7 +373,7 @@ 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[proc->subframe_rx & 0x1][eNB_id]->crnti,proc->frame_tx,subframe,
+        ue->Mod_id,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][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
@@ -453,9 +456,9 @@ void compute_cqi_ri_resources(PHY_VARS_UE *ue,
     }
 }
 
-void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS) 
+void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS)
 {
-  
+
   LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
   int frame_tx    = proc->frame_tx;
   int subframe_tx = proc->subframe_tx;
@@ -469,7 +472,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
   pSoundingrs_ul_config_dedicated->srsUeSubframe   = 0;
   pSoundingrs_ul_config_dedicated->srsCellSubframe = isSubframeSRS;
 
-  if (isSubframeSRS) {  
+  if (isSubframeSRS) {
     LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup);
       if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup)
       {
@@ -507,7 +510,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
 					     CC_id,
 					     frame_tx,
 					     eNB_id,
-					     ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti,
+					     ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
 					     subframe_tx); // subframe used for meas gap
 
                       if (SR_payload > 0)
@@ -517,7 +520,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id
 
               uint8_t pucch_ack_payload[2];
               if (get_ack(&ue->frame_parms,
-                      ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
                       subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0)
               {
                   is_sr_an_subframe = 1;
@@ -576,19 +579,19 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id)
       cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157;
     }
     else if (cqi_PMI_ConfigIndex > 317) {
-      
+
       if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period
-	cqirep->Npd = 32;
+  cqirep->Npd = 32;
       cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318;
       }
       else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period
-	cqirep->Npd = 64;
-	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
+  cqirep->Npd = 64;
+  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350;
       }
       else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period
-	cqirep->Npd = 128;
-	cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
-      }  
+  cqirep->Npd = 128;
+  cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414;
+      }
     }
   }
   else { // TDD
@@ -622,7 +625,8 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
                              uint8_t SR_payload,
                              uint8_t nb_cw,
                              uint8_t cqi_status,
-                             uint8_t ri_status)
+                             uint8_t ri_status,
+                             uint8_t bundling_flag)
 {
   if((cqi_status == 0) && (ri_status==0))
   {
@@ -630,10 +634,14 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
       // 1- SR only ==> PUCCH format 1
       // 2- 1bit Ack/Nack with/without SR  ==> PUCCH format 1a
       // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b
-      if(nb_cw == 1)
+      if((nb_cw == 1)&&(bundling_flag==bundling))
       {
           return pucch_format1a;
       }
+      if((nb_cw == 1)&&(bundling_flag==multiplexing))
+      {
+          return pucch_format1b;
+      }
       if(nb_cw == 2)
       {
           return pucch_format1b;
@@ -647,7 +655,7 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
           } else if (frame_type == TDD) {
               return pucch_format1b;
           } else {
-	      AssertFatal(1==0,"Unknown frame_type");
+              AssertFatal(1==0,"Unknown frame_type");
           }*/
       }
   }
@@ -681,7 +689,7 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type,
   return pucch_format1a;
 }
 uint16_t get_n1_pucch(PHY_VARS_UE *ue,
-		      UE_rxtx_proc_t *proc,
+          UE_rxtx_proc_t *proc,
                       harq_status_t *harq_ack,
                       uint8_t eNB_id,
                       uint8_t *b,
@@ -704,10 +712,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 
   if (frame_parms->frame_type == FDD ) { // FDD
     sf = (subframe<4)? subframe+6 : subframe-4;
-    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[proc->subframe_rx&0x1][eNB_id]->nCCE[sf]);
+    LOG_D(PHY,"n1_pucch_UE: subframe %d, nCCE %d\n",sf,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
 
     if (SR == 0)
-      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[sf]);
+      return(frame_parms->pucch_config_common.n1PUCCH_AN + ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[sf]);
     else
       return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex);
   } else {
@@ -716,10 +724,10 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 #ifdef DEBUG_PHY_PROC
 
     if (bundling_flag==bundling) {
-      LOG_I(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->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_I(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, multiplexing, SR %d/%d\n",ue->Mod_id,proc->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);
     }
 
@@ -770,7 +778,7 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           last_dl);
 
       // i=0
-      nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[last_dl];
+      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[last_dl];
       n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
 
       harq_ack0 = b[0];
@@ -812,18 +820,18 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
       // This is the offset for a particular subframe (2,3,4) => (0,2,4)
       last_dl = (subframe-2)<<1;
       // i=0
-      nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[5+last_dl];
+      nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+last_dl];
       n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
       // i=1
-      nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(6+last_dl)%10];
+      nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+last_dl)%10];
       n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
 
       // set ACK/NAK to values if not DTX
-      if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-        harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
+      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+        harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].ack;
 
-      if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-        harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+last_dl].ack;
+      if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+        harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].ack;
 
       LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n",
                                       proc->frame_tx%1024,
@@ -898,31 +906,32 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           //last_dl = (subframe-2)<<1;
           if (subframe == 2) {
           // i=0
-          //nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[2+subframe];
-          nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(8+subframe)%10];
+          //nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
+          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
           n1_pucch0 = 2*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=1
-          nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[2+subframe];
+          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe];
           n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=2
-          nCCE2 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(8+subframe)%10];
+          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10];
+
           n1_pucch2 = 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=3
-          //nCCE3 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(9+subframe)%10];
+          //nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(9+subframe)%10];
           //n1_pucch3 = get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
 
           // set ACK/NAK to values if not DTX
-          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(8+subframe)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-            harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(8+subframe)%10].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+            harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(8+subframe)%10].ack;
 
-          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-            harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[2+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+            harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[2+subframe].ack;
 
-          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-            harq_ack2 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[3+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+            harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].ack;
 
-          //if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-            //harq_ack3 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(9+subframe)%10].ack;
+          //if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+            //harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].ack;
           //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d cce2=%d n1_pucch2=%d\n",
           //                      proc->frame_tx%1024,
           //                      proc->subframe_tx,
@@ -931,30 +940,30 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           }else if (subframe == 3) {
           // i=0
 
-          nCCE0 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[4+subframe];
+          nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[4+subframe];
           n1_pucch0 = 3*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=1
-          nCCE1 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[5+subframe];
+          nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+subframe];
           n1_pucch1 = 2*get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=2
-          nCCE2 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(6+subframe)];
+          nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+subframe)];
           n1_pucch2 = get_Np(frame_parms->N_RB_DL,nCCE2,0) + 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN;
           // i=3
-          nCCE3 = ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->nCCE[(3+subframe)];
+          nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(3+subframe)];
           n1_pucch3 = 3*get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN;
 
           // set ACK/NAK to values if not DTX
-          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-          harq_ack0 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[4+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+          harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].ack;
 
-          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-          harq_ack1 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[5+subframe].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+          harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].ack;
 
-          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
-          harq_ack2 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(6+subframe)].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0)  // n-6 // subframe 6 is to be ACK/NAKed
+          harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].ack;
 
-          if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
-          harq_ack3 = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack[(3+subframe)].ack;
+          if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0)  // n-6 // subframe 5 is to be ACK/NAKed
+          harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].ack;
           }
 
           //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n",
@@ -965,28 +974,38 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
           //                                nCCE3, n1_pucch3, harq_ack3, bundling_flag);
 
           if ((bundling_flag==bundling)&&(SR == 0)) {  // This is for bundling without SR,
+             b[0] = 1;
+             ack_counter = 0;
+
+             if ((harq_ack3!=2) ) {
+                b[0] = b[0]&harq_ack3;
+                n1_pucch_inter = n1_pucch3;
+                ack_counter ++;
+             }
              if ((harq_ack0!=2) ) {
-                b[0] = harq_ack0;
+                b[0] = b[0]&harq_ack0;
                 n1_pucch_inter = n1_pucch0;
+                ack_counter ++;
              }
              if ((harq_ack1!=2) ) {
                 b[0] = b[0]&harq_ack1;
                 n1_pucch_inter = n1_pucch1;
+                ack_counter ++;
              }
              if ((harq_ack2!=2) ) {
                 b[0] = b[0]&harq_ack2;
                 n1_pucch_inter = n1_pucch2;
-             }
-             if ((harq_ack3!=2) ) {
-                b[0] = b[0]&harq_ack3;
-                n1_pucch_inter = n1_pucch3;
+                ack_counter ++;
              }
 
-             if (subframe == 3) {
+             if (ack_counter == 0)
+                 b[0] = 0;
+
+             /*if (subframe == 3) {
                 n1_pucch_inter = n1_pucch2;
              } else if (subframe == 2) {
-                n1_pucch_inter = n1_pucch2;
-             }
+                n1_pucch_inter = n1_pucch1;
+             }*/
 
              //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d  b[0]=%d b[1]=%d \n",
              //                                           proc->frame_tx%1024,
@@ -997,37 +1016,39 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
 
             } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1
 
+             if (subframe == 3) {
+                 LOG_I(PHY, "sbuframe=%d \n",subframe);
               if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
-                b[1] = 1;
                 b[0] = 1;
+                b[1] = 1;
                 return(n1_pucch1);
               } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                 b[0] = 1;
                 b[1] = 0;
                 return(n1_pucch1);
               } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 0) && (harq_ack3 == 2)) {
-                b[1] = 1;
                 b[0] = 1;
+                b[1] = 1;
                 return(n1_pucch2);
               } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) {
-                b[1] = 1;
-                b[0] = 0;
+                b[0] = 1;
+                b[1] = 0;
                 return(n1_pucch1);
               } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) {
-                b[1] = 1;
-                b[0] = 0;
+                b[0] = 1;
+                b[1] = 0;
                 return(n1_pucch0);
               } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
-                b[1] = 1;
-                b[0] = 0;
+                b[0] = 1;
+                b[1] = 0;
                 return(n1_pucch1);
               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) {
                 b[0] = 0;
                 b[1] = 1;
                 return(n1_pucch3);
               } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 0)) {
-                b[1] = 1;
                 b[0] = 1;
+                b[1] = 1;
                 return(n1_pucch3);
               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) {
                 b[0] = 0;
@@ -1074,9 +1095,53 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue,
                 b[1] = 0;
                 return(n1_pucch3);
                 }
+             } else if (subframe == 2) {
+                if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
+                 b[0] = 1;
+                 b[1] = 1;
+                 return(n1_pucch2);
+               } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 1;
+                 b[1] = 1;
+                 return(n1_pucch1);
+               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
+                 b[0] = 1;
+                 b[1] = 1;
+                 return(n1_pucch0);
+               } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 0;
+                 b[1] = 1;
+                 return(n1_pucch0);
+               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1)) {
+                 b[0] = 1;
+                 b[1] = 0;
+                 return(n1_pucch2);
+               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[1] = 0;
+                 b[0] = 0;
+                 return(n1_pucch1);
+               } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) {
+                 b[0] = 0;
+                 b[1] = 0;
+                 return(n1_pucch2);
+               } else if ((harq_ack0 == 2) && (harq_ack1 == 2) && (harq_ack2 == 0)) {
+                 b[0] = 0;
+                 b[1] = 1;
+                 return(n1_pucch2);
+               } else if ((harq_ack0 == 2) && (harq_ack1 == 0) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 1;
+                 b[1] = 0;
+                 return(n1_pucch1);
+               } else if ((harq_ack0 == 0) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) {
+                 b[0] = 1;
+                 b[1] = 0;
+                 return(n1_pucch0);
+               }
 
+             }
             } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213)
               // this should be number of ACKs (including
+              ack_counter = 0;
               if (harq_ack0==1)
                  ack_counter ++;
               if (harq_ack1==1)
@@ -1175,10 +1240,11 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
 #endif
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN);
-
+#if UE_TIMING_TRACE
   start_meas(&ue->ofdm_mod_stats);
+#endif
   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-
@@ -1205,14 +1271,14 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
       for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
 
           if (overflow > 0)
-		 {
-			 memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow));
-			 memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
-		 }
-		 else
-		 {
-			 memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti);
-		 }
+     {
+       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow));
+       memset(&ue->common_vars.txdata[aa][0],0,4*overflow);
+     }
+     else
+     {
+       memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti);
+     }
       }
 /*#else
       overflow = ulsch_start - 9*frame_parms->samples_per_tti;
@@ -1234,37 +1300,37 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
 
   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);
-  
-  
+    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,
+       dummy_tx_buffer,
 #else
-		   &ue->common_vars.txdata[aa][ulsch_start],
+       &ue->common_vars.txdata[aa][ulsch_start],
 #endif
-		   frame_parms->ofdm_symbol_size,
-		   nsymb,
-		   frame_parms->nb_prefix_samples,
-		   CYCLIC_PREFIX);
+       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,
+      dummy_tx_buffer,
 #else
-			&ue->common_vars.txdata[aa][ulsch_start],
+      &ue->common_vars.txdata[aa][ulsch_start],
 #endif
-			nsymb,
-			&ue->frame_parms);
-    
-    
+      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);
@@ -1272,17 +1338,17 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
     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;
@@ -1291,11 +1357,11 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
     // 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;
+  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;
+  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;
+  ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE;
     }
 #endif
 #endif
@@ -1308,10 +1374,12 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt
       write_output("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1);
     }
     */
-    
+
   } //nb_antennas_tx
-  
-  stop_meas(&ue->ofdm_mod_stats);
+
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ofdm_mod_stats);
+#endif
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT);
 
@@ -1338,6 +1406,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     // ask L2 for RACH transport
     if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
       LOG_D(PHY,"Getting PRACH resources\n");
+
       ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id,
 						ue->CC_id,
 						frame_tx,
@@ -1347,9 +1416,9 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
       LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
     }
   }
-  
+
   if (ue->prach_resources[eNB_id]!=NULL) {
-    
+
     ue->generate_prach=1;
     ue->prach_cnt=0;
 #ifdef SMBV
@@ -1358,7 +1427,6 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #ifdef OAI_EMU
     ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
 #endif
-    
     LOG_I(PHY,"mode %d\n",mode);
     
     if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
@@ -1366,7 +1434,7 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     }
     else {
       ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
-      ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;	      
+      ue->prach_resources[eNB_id]->ra_PreambleIndex = 19;
     }
     
     LOG_I(PHY,"[UE  %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d,PL %d,  P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
@@ -1387,9 +1455,11 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 					     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,
@@ -1414,32 +1484,31 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     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){
     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",
+
+  LOG_I(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 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->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt);
+
   ue->prach_cnt++;
-  
+
   if (ue->prach_cnt==3)
     ue->generate_prach=0;
 
@@ -1471,37 +1540,38 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 
   // get harq_pid from subframe relationship
   harq_pid = subframe2harq_pid(&ue->frame_parms,
-			       frame_tx,
-			       subframe_tx);
-  
-  
+             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_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);
-      
+  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);
+      Mod_id,
+      frame_tx,
+      subframe_tx,
+      harq_pid);
       Msg3_flag = 1;
     } else {
+
       
-      AssertFatal(harq_pid!=255,"[UE%d] Frame %d subframe %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, returning\n",
+      AssertFatal(harq_pid!=255,"[UE%d] Frame %d subframe %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, exiting\n",
 	      Mod_id,frame_tx, subframe_tx);
       Msg3_flag=0;
     }
   }
-  
+
   if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) {
 
     uint8_t isBad = 0;
@@ -1546,9 +1616,9 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     }
   }
   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;
     LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit);
@@ -1558,40 +1628,39 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
         ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
         ue->ulsch[eNB_id]->harq_processes[harq_pid]->round  = 0;
     }
-    
+
     ack_status_cw0 = reset_ack(&ue->frame_parms,
-            ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
             subframe_tx,
             proc->subframe_rx,
             ue->ulsch[eNB_id]->o_ACK,
             &Nbundled,
             0);
     ack_status_cw1 = reset_ack(&ue->frame_parms,
-            ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack,
+            ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
             subframe_tx,
             proc->subframe_rx,
             ue->ulsch[eNB_id]->o_ACK,
             &NbundledCw1,
             1);
 
-    //Nbundled = ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack;
+    //Nbundled = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack;
     //ue->ulsch[eNB_id]->bundling = Nbundled;
 
     first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb;
     nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb;
-    
-    
+
+
     // check Periodic CQI/RI reporting
     cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&&
         (is_cqi_TXOp(ue,proc,eNB_id)==1));
 
     ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) &&
              (is_ri_TXOp(ue,proc,eNB_id)==1));
-    
+
     // compute CQI/RI resources
     compute_cqi_ri_resources(ue, ue->ulsch[eNB_id], eNB_id, ue->ulsch[eNB_id]->rnti, P_RNTI, CBA_RNTI, cqi_status, ri_status);
 
-
     if (ack_status_cw0 > 0) {
 
       // check if we received a PDSCH at subframe_tx - 4
@@ -1606,53 +1675,55 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     if(ue->ulsch[eNB_id]->o_ACK[0])
     {
     	LOG_I(PHY,"PUSCH ACK\n");
-        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
-                      T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
+        T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
     }
     else
     {
     	LOG_I(PHY,"PUSCH NACK\n");
-        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
-                      T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
+        T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                      T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
     }
 #endif
-
-      LOG_D(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
+#ifdef UE_DEBUG_TRACE
+      LOG_I(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n",
         Mod_id,
         ue->ulsch[eNB_id]->rnti,
         frame_tx%1024,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);
+#endif
     }
 
-#ifdef DEBUG_PHY_PROC
+
+#ifdef UE_DEBUG_TRACE
         LOG_I(PHY,
               "[UE  %d][PUSCH %d] AbsSubframe %d.%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, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n",
-	  Mod_id,harq_pid,frame_tx%1024,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,
-	  ack_status_cw0,
-	  ack_status_cw1,
-	  ue->ulsch[eNB_id]->bundling, Nbundled,
-	  cqi_status,
-	  ri_status);
+          Mod_id,harq_pid,frame_tx%1024,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,
+          ack_status_cw0,
+          ack_status_cw1,
+          ue->ulsch[eNB_id]->bundling, Nbundled,
+          cqi_status,
+          ri_status);
 #endif
-    
-    
-    
-    
-    
+
+
+
+
+
     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,
@@ -1669,8 +1740,9 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 	    ue->prach_resources[eNB_id]->Msg3[6],
 	    ue->prach_resources[eNB_id]->Msg3[7],
 	    ue->prach_resources[eNB_id]->Msg3[8]);
-      
+#if UE_TIMING_TRACE
       start_meas(&ue->ulsch_encoding_stats);
+#endif
       
       AssertFatal(ulsch_encoding(ue->prach_resources[eNB_id]->Msg3,
 				 ue,
@@ -1680,9 +1752,17 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 				 ue->transmission_mode[eNB_id],0,0)==0,
 		  "ulsch_coding.c: FATAL ERROR: returning\n");
       
+#if UE_TIMING_TRACE
+      stop_meas(&ue->phy_proc_tx);
+      printf("------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0));
+#endif
+	  return;
+
+#if UE_TIMING_TRACE
       stop_meas(&ue->ulsch_encoding_stats);
-      
+#endif
       if (ue->mac_enabled == 1) {
+
 	// signal MAC that Msg3 was sent
 	Msg3_transmitted(Mod_id,
 			 CC_id,
@@ -1693,8 +1773,9 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     } // Msg3_flag==1
     else {// Msg3_flag==0
       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) {
@@ -1709,6 +1790,9 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 		     &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);
@@ -1728,39 +1812,53 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 	
       }
       
+#if UE_TIMING_TRACE
       start_meas(&ue->ulsch_encoding_stats);
+#endif
+      if (abstraction_flag==0) {
+	
+	if (ulsch_encoding(ulsch_input_buffer,
+			   ue,
+			   harq_pid,
+			   eNB_id,
+			   proc->subframe_rx,
+			   ue->transmission_mode[eNB_id],0,
+			   Nbundled)!=0) {
+	  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);
+#if UE_TIMING_TRACE
+	  stop_meas(&ue->phy_proc_tx);
+#endif
+	  return;
+	}
+      }
       
-      if (ulsch_encoding(ulsch_input_buffer,
-			 ue,
-			 harq_pid,
-			 eNB_id,
-			 proc->subframe_rx,
-			 ue->transmission_mode[eNB_id],0,
-			 Nbundled)!=0) {
-	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,proc->subframe_rx,harq_pid,0);
       }
-    } // Msg3_flag==0
-    stop_meas(&ue->ulsch_encoding_stats);
-    
-    LOG_I(PHY,"Doing ULSCH modulation\n");
-	  
-    if (ue->mac_enabled==1) {
-      pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
-      ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
-    }
-    else {
-      ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
+      
+#endif
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ulsch_encoding_stats);
+#endif
     }
-    ue->tx_total_RE[subframe_tx] = nb_rb*12;
+    
+    if (abstraction_flag == 0) {
+      if (ue->mac_enabled==1) {
+	pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag);
+	ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH;
+      }
+      else {
+	ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm;
+      }
+      ue->tx_total_RE[subframe_tx] = nb_rb*12;
       
 #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)
-    tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
-			ue->tx_power_max_dBm,
-			ue->frame_parms.N_RB_UL,
-			nb_rb);
+      tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx],
+			  ue->tx_power_max_dBm,
+			  ue->frame_parms.N_RB_UL,
+			  nb_rb);
 #else
     tx_amp = AMP;
 #endif
@@ -1768,9 +1866,15 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
     T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
       T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb));
 #endif
+
+#ifdef UE_DEBUG_TRACE
     LOG_I(PHY,"[UE  %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n",
 	  Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp);
+#endif
+#if UE_TIMING_TRACE
+    
     start_meas(&ue->ulsch_modulation_stats);
+#endif
     ulsch_modulation(ue->common_vars.txdataF,
 		     tx_amp,
 		     frame_tx,
@@ -1786,9 +1890,15 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB
 			 first_rb,
 			 nb_rb,
 			 aa);
-    
+#if UE_TIMING_TRACE
     stop_meas(&ue->ulsch_modulation_stats);
-
+#endif
+    }
+    
+    if (abstraction_flag==1) {
+      // clear SR
+      ue->sr[subframe_tx]=0;
+    }
   } // subframe_scheduling_flag==1
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_OUT);
@@ -1844,11 +1954,11 @@ void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8
 
     uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12;
     uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((subframe_tx*nsymb)+(nsymb-1));
-    generate_srs(&ue->frame_parms, 
-		 &ue->soundingrs_ul_config_dedicated[eNB_id], 
-		 &ue->common_vars.txdataF[eNB_id][symbol_offset], 
-		 tx_amp, 
-		 subframe_tx);
+    generate_srs(&ue->frame_parms,
+     &ue->soundingrs_ul_config_dedicated[eNB_id],
+     &ue->common_vars.txdataF[eNB_id][symbol_offset],
+     tx_amp,
+     subframe_tx);
   }
 }
 
@@ -1857,16 +1967,16 @@ int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) {
   if ((ue->transmission_mode[eNB_id]<4)||
       (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback
     // 4-bit CQI message
-	  /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id],
-			  ue->measurements.wideband_cqi_avg[eNB_id],
-			  sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
-			            ue->transmission_mode[eNB_id]));*/
+          /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id],
+                          ue->measurements.wideband_cqi_avg[eNB_id],
+                          sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
+                                    ue->transmission_mode[eNB_id]));*/
     *len=4;
     return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id],
-		    ue->transmission_mode[eNB_id]));
+        ue->transmission_mode[eNB_id]));
   }
   else { // Mode 1-1 feedback, later
-	  //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]);
+          //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]);
     *len=0;
     // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI)
 
@@ -1911,7 +2021,7 @@ void get_pucch_param(PHY_VARS_UE    *ue,
     {
         pucch_resource[0] = get_n1_pucch(ue,
                                          proc,
-                                         ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+                                         ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
                                          eNB_id,
                                          ack_payload,
                                          SR);
@@ -1951,7 +2061,6 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 
 
   uint8_t  pucch_ack_payload[2];
-  uint8_t  n2_pucch = -1;
   uint16_t pucch_resource;
   ANFBmode_t bundling_flag;
   PUCCH_FMT_t format;
@@ -1974,7 +2083,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   uint8_t ri_status=0;
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN);
-  
+
   SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id];
 
   // 36.213 8.2
@@ -1997,7 +2106,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission);
 
   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)))) {
@@ -2007,7 +2116,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     format = pucch_format1b;
     LOG_D(PHY,"[UE] PUCCH 1b\n");
   }
-  
+
   // Part - I
   // Collect feedback that should be transmitted at this subframe
   // - SR
@@ -2019,12 +2128,12 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   if (is_SR_TXOp(ue,proc,eNB_id)==1)
   {
       if (ue->mac_enabled==1) {
-          SR_payload = ue_get_SR(Mod_id,
-				 CC_id,
-				 frame_tx,
-				 eNB_id,
-				 ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti,
-				 subframe_tx); // subframe used for meas gap
+	SR_payload = ue_get_SR(Mod_id,
+			       CC_id,
+			       frame_tx,
+			       eNB_id,
+			       ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,
+			       subframe_tx); // subframe used for meas gap
       }
       else {
           SR_payload = 1;
@@ -2032,14 +2141,14 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   }
 
   ack_status_cw0 = get_ack(&ue->frame_parms,
-                       ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
                        subframe_tx,
                        proc->subframe_rx,
                        pucch_ack_payload,
                        0);
 
   ack_status_cw1 = get_ack(&ue->frame_parms,
-                       ue->dlsch[proc->subframe_rx&0x1][eNB_id][1]->harq_ack,
+                       ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack,
                        subframe_tx,
                        proc->subframe_rx,
                        pucch_ack_payload,
@@ -2069,7 +2178,8 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                             SR_payload,
                             nb_cw,
                             cqi_status,
-                            ri_status);
+                            ri_status,
+                            bundling_flag);
   // Determine PUCCH resources and payload: mandatory for pucch encoding
   get_pucch_param(ue,
                   proc,
@@ -2082,9 +2192,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                   (uint8_t *)&pucch_payload,
                   &len);
 
-  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
-          frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
 
+  LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n",
+	frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]);
 
   // Part - IV
   // Generate PUCCH signal
@@ -2114,13 +2224,15 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #endif
 #if T_TRACER
       T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
-              T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
 #endif
+
+#ifdef UE_DEBUG_TRACE
       if(format == pucch_format1)
       {
-          LOG_D(PHY,"[UE  %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
+          LOG_I(PHY,"[UE  %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n",
                   Mod_id,
-                  ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
+                  ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
                   frame_tx%1024, subframe_tx,
                   frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission,
                   isShortenPucch,
@@ -2130,9 +2242,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
       else
       {
           if (SR_payload>0) {
-              LOG_D(PHY,"[UE  %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
+              LOG_I(PHY,"[UE  %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n",
                       Mod_id,
-                      ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
+                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
                       frame_tx % 1024, subframe_tx,
                       (format == pucch_format1a? "1a": (
                               format == pucch_format1b? "1b" : "??")),
@@ -2143,9 +2255,9 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                               Po_PUCCH,
                               tx_amp);
           } else {
-              LOG_D(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
+              LOG_I(PHY,"[UE  %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n",
                       Mod_id,
-                      ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
+                      ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
                       frame_tx%1024, subframe_tx,ue->rx_offset_diff,
                       (format == pucch_format1a? "1a": (
                               format == pucch_format1b? "1b" : "??")),
@@ -2156,17 +2268,18 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
                               tx_amp);
           }
       }
+#endif
 
 #if T_TRACER
       if(pucch_payload[0])
       {
-          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
-                  T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
+          T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
       }
       else
       {
-          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti),
-                  T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->current_harq_pid));
+          T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(Mod_id), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti),
+                  T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid));
       }
 #endif
 
@@ -2206,18 +2319,17 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 #endif
 #if T_TRACER
       T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id),T_INT(Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]),
-              T_INT(tx_amp),T_INT(ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
+              T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id)));
 #endif
-
-      LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), n2_pucch %d, Po_PUCCH %d, isShortenPucch %d, amp %d\n",
+#ifdef UE_DEBUG_TRACE
+      LOG_I(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n",
               Mod_id,
-              ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
+              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx,
-              n2_pucch,
               Po_PUCCH,
               isShortenPucch,
               tx_amp);
-
+#endif
       generate_pucch2x(ue->common_vars.txdataF,
               &ue->frame_parms,
               ue->ncs_cell,
@@ -2229,20 +2341,20 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
               0,            // B2 not needed
               tx_amp,
               subframe_tx,
-              ue->pdcch_vars[proc->subframe_rx & 0x1][eNB_id]->crnti);
+              ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti);
   }
   break;
 
   case pucch_format2a:
       LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n",
               Mod_id,
-              ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
+              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx);
       break;
   case pucch_format2b:
       LOG_D(PHY,"[UE  %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n",
               Mod_id,
-              ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,
+              ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,
               frame_tx%1024, subframe_tx);
       break;
   default:
@@ -2254,7 +2366,7 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 }
 
 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) {
-  
+
 
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
   //int32_t ulsch_start=0;
@@ -2263,21 +2375,27 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
   unsigned int aa;
   uint8_t isSubframeSRS;
 
+  uint8_t next1_thread_id = ue->current_thread_id[proc->subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[proc->subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
 
+  LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);
 #if T_TRACER
   T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx));
 #endif
 
   ue->generate_ul_signal[eNB_id] = 0;
-
+#if UE_TIMING_TRACE
   start_meas(&ue->phy_proc_tx);
+#endif
 
 #ifdef EMOS
   //phy_procedures_emos_UE_TX(next_slot);
 #endif
 
   ue->tx_power_dBm[subframe_tx]=-127;
+
       
   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],
@@ -2295,13 +2413,14 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
     ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag);
 
   }
-  	  
+
   if (ue->UE_mode[eNB_id] == PUSCH) {
       // check if we need to use PUCCH 1a/1b
       ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag);
       // check if we need to use SRS
       ue_srs_procedures(ue,proc,eNB_id,abstraction_flag);
   } // UE_mode==PUSCH
+
 	
   	
 
@@ -2310,7 +2429,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
         
   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)) {
@@ -2321,20 +2440,27 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
   else {
     ue->generate_prach=0;
   }
-    
+
   // reset DL ACK/NACK status
   uint8_t N_bundled = 0;
-  if (ue->dlsch[proc->subframe_rx&0x1][eNB_id][0] != NULL)
+  if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0] != NULL)
   {
     reset_ack(&ue->frame_parms,
-               ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->harq_ack,
+               ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack,
+               subframe_tx,
+               proc->subframe_rx,
+               ue->ulsch[eNB_id]->o_ACK,
+               &N_bundled,
+               0);
+    reset_ack(&ue->frame_parms,
+               ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack,
                subframe_tx,
                proc->subframe_rx,
                ue->ulsch[eNB_id]->o_ACK,
                &N_bundled,
                0);
     reset_ack(&ue->frame_parms,
-               ue->dlsch[(proc->subframe_rx+1)&0x1][eNB_id][0]->harq_ack,
+               ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack,
                subframe_tx,
                proc->subframe_rx,
                ue->ulsch[eNB_id]->o_ACK,
@@ -2351,15 +2477,20 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui
              &N_bundled,
              0);
 
-      
+
+  LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx);
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
   stop_meas(&ue->phy_proc_tx);
+#endif
 }
 
 void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
 {
   int aa;//i,aa;
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
+
   
   for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
 #if defined(EXMIMO) //this is the EXPRESS MIMO case
@@ -2380,12 +2511,12 @@ void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_f
 void ue_measurement_procedures(
     uint16_t l,    // symbol index of each slot [0..6]
     PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id,
-    uint16_t slot, // slot index of each radio frame [0..19]    
+    uint16_t slot, // slot index of each radio frame [0..19]
     uint8_t abstraction_flag,runmode_t mode)
 {
+
   //LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp);
 
-  
   LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
 
   int subframe_rx = proc->subframe_rx;
@@ -2394,46 +2525,45 @@ void ue_measurement_procedures(
 
   if (l==0) {
     // UE measurements on symbol 0
+
     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),
-			(subframe_rx == 1) ? 1 : 0,
-			0,subframe_rx);
-  } else {
-    lte_ue_measurements(ue,
-			0,
-			0,
-			1,
-			subframe_rx);
-  }
+      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),
+			  (subframe_rx == 1) ? 1 : 0,
+			  0,
+			  0,
+			  subframe_rx);
+      
 #if T_TRACER
-  if(slot == 0)
-    T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
-      T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
-      T_INT((int)ue->measurements.rx_rssi_dBm[0]),
-      T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
-      T_INT((int)ue->measurements.rx_power_avg_dB[0]),
-      T_INT((int)ue->measurements.n0_power_avg_dB),
-      T_INT((int)ue->measurements.wideband_cqi_avg[0]),
-      T_INT((int)ue->common_vars.freq_offset));
+      if(slot == 0)
+	T(T_UE_PHY_MEAS, T_INT(eNB_id),  T_INT(ue->Mod_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
+	  T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)),
+	  T_INT((int)ue->measurements.rx_rssi_dBm[0]),
+	  T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)),
+	  T_INT((int)ue->measurements.rx_power_avg_dB[0]),
+	  T_INT((int)ue->measurements.n0_power_avg_dB),
+	  T_INT((int)ue->measurements.wideband_cqi_avg[0]),
+	  T_INT((int)ue->common_vars.freq_offset));
 #endif
-
+  }
 
   if (l==(6-ue->frame_parms.Ncp)) {
-	
+
     // make sure we have signal from PSS/SSS for N0 measurement
-	 // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
+         // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n");
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN);
     ue_rrc_measurements(ue,
-			slot,
-			abstraction_flag);
+      slot,
+      abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT);
 
   }
 
-  if ((subframe_rx==0) && (slot == 0) && (l==(4-frame_parms->Ncp))) {
+  // accumulate and filter timing offset estimation every subframe (instead of every frame)
+  if (( (slot%2) == 0) && (l==(4-frame_parms->Ncp))) {
 
     // AGC
 
@@ -2450,6 +2580,7 @@ void ue_measurement_procedures(
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT);
 
     eNB_id = 0;
+
     
     if (ue->no_timing_correction==0)
       lte_adjust_synch(&ue->frame_parms,
@@ -2459,13 +2590,14 @@ void ue_measurement_procedures(
 		       0,
 		       16384);
  
-
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT);
 }
 
-void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, 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;
@@ -2490,6 +2622,7 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
   for (pbch_trials=0; pbch_trials<4; pbch_trials++) {
     //for (pbch_phase=0;pbch_phase<4;pbch_phase++) {
     //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);
+
     pbch_tx_ant = rx_pbch(&ue->common_vars,
 			  ue->pbch_vars[eNB_id],
 			  &ue->frame_parms,
@@ -2498,9 +2631,6 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 			  ue->high_speed_flag,
 			  pbch_phase);
     
-
-
-    
     if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) {
       break;
     }
@@ -2539,10 +2669,11 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
     frame_tx += pbch_phase;
 
     if (ue->mac_enabled==1) {
+
       dl_phy_sync_success(ue->Mod_id,frame_rx,eNB_id,
 			  ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0);
     }
-    
+
 #ifdef EMOS
     //emos_dump_UE.frame_tx = frame_tx;
     //emos_dump_UE.mimo_mode = ue->pbch_vars[eNB_id]->decoded_output[1];
@@ -2553,39 +2684,52 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 
       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] TXPATH 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);
+
+      for(int th_id=0; th_id<RX_NB_TH; th_id++)
+      {
+        ue->proc.proc_rxtx[th_id].frame_rx = proc->frame_rx;
+        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_tx;
+
+        printf("[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,
+ 	    ue->proc.proc_rxtx[th_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_I(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);
+      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;
+      
+      for(int th_id=0; th_id<RX_NB_TH; th_id++)
+      {
+        ue->proc.proc_rxtx[th_id].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF);
+        ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_rx;
+      }
 
     }
 
 #ifdef DEBUG_PHY_PROC
+
     LOG_D(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n",
 	  ue->Mod_id,
 	  frame_rx,
@@ -2599,9 +2743,10 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 #endif
 
   } else { 
+
     /*
     LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n",
-	  ue->Mod_id,frame_rx, subframe_rx);
+    ue->Mod_id,frame_rx, subframe_rx);
 
     LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset);
 
@@ -2620,6 +2765,7 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 
     ue->pbch_vars[eNB_id]->pdu_errors_conseq++;
     ue->pbch_vars[eNB_id]->pdu_errors++;
+
     if (ue->mac_enabled == 1) rrc_out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id);
     else AssertFatal(ue->pbch_vars[eNB_id]->pdu_errors_conseq<100,
 		     "More that 100 consecutive PBCH errors! Exiting!\n");
@@ -2633,9 +2779,9 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin
 
 #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, subframe_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);
 }
@@ -2649,28 +2795,51 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
   int subframe_rx = proc->subframe_rx;
   DCI_ALLOC_t dci_alloc_rx[8];
 
+  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN);
+#if UE_TIMING_TRACE
   start_meas(&ue->dlsch_rx_pdcch_stats);
-
+#endif
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN);
   rx_pdcch(ue,
 	   proc->frame_rx,
 	   subframe_rx,
 	   eNB_id,
-	   (ue->frame_parms.nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI,
+	   ue->frame_parms.nb_antenna_ports_eNB==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);
+  
+  
+  //printf("Decode SIB frame param agregation + DCI %d %d \n",agregationLevel,dciFormat);
+  
+  //agregation level == FF means no configuration on
+  if(ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB)
+    {
+      // search all possible dcis
+      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);
+    }
+  else
+    {
+      // search only preconfigured dcis
+      // search C RNTI dci
+      dci_cnt = dci_CRNTI_decoding_procedure(ue,
+					     dci_alloc_rx,
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat,
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel,
+					     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);
   
@@ -2681,129 +2850,151 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT);
   }
   
+  uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx];
+  uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[subframe_rx];
+  uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[subframe_rx];
+  memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t));
+  memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t));
+
+  LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[subframe_rx], next1_thread_id, next2_thread_id);
 
   LOG_D(PHY,"[UE  %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n",
        ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]],
        dci_cnt,
        dci_alloc_rx[0].rnti,
-       ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
+       ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
        dci_alloc_rx[0].format );
 
-  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->dci_received += dci_cnt;
+  ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dci_received += dci_cnt;
+
   for (i=0; i<dci_cnt; i++) {
 
 
 
     if ((ue->UE_mode[eNB_id]>PRACH) &&
-	(dci_alloc_rx[i].rnti == ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti) &&
+	(dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
 	(dci_alloc_rx[i].format != format0)) {
       
-
       LOG_D(PHY,"[UE  %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n",
 	    ue->Mod_id,dci_alloc_rx[i].rnti,
 	    frame_rx%1024,subframe_rx,
 	    dci_alloc_rx[i].format,
-	    ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
-	    ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->nCCE[subframe_rx],
+	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+	    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx],
 	    get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0)));
-
-
-
-
       
       //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
+      
       if ((ue->UE_mode[eNB_id] > PRACH) &&
 	  (generate_ue_dlsch_params_from_dci(frame_rx,
 					     subframe_rx,
 					     (void *)&dci_alloc_rx[i].dci_pdu,
-					     ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
 					     dci_alloc_rx[i].format,
-					     ue->dlsch[subframe_rx&0x1][eNB_id],
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					     ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					     ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id],
 					     &ue->frame_parms,
 					     ue->pdsch_config_dedicated,
 					     SI_RNTI,
 					     0,
 					     P_RNTI,
 					     ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
-					     ue->pdcch_vars[0&0x1][eNB_id]->crnti_is_temporary? ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti: 0)==0)) {
-
-          // update TPC for PUCCH
-          if((dci_alloc_rx[i].format == format1)   ||
-              (dci_alloc_rx[i].format == format1A) ||
-              (dci_alloc_rx[i].format == format1B) ||
-              (dci_alloc_rx[i].format == format2)  ||
-              (dci_alloc_rx[i].format == format2A) ||
-              (dci_alloc_rx[i].format == format2B))
+					     ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti: 0)==0)) {
+	
+	// update TPC for PUCCH
+	if((dci_alloc_rx[i].format == format1)   ||
+	   (dci_alloc_rx[i].format == format1A) ||
+	   (dci_alloc_rx[i].format == format1B) ||
+	   (dci_alloc_rx[i].format == format2)  ||
+	   (dci_alloc_rx[i].format == format2A) ||
+	   (dci_alloc_rx[i].format == format2B))
           {
-            ue->dlsch[subframe_rx&0x1][eNB_id][0]->g_pucch += ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            //ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            int32_t delta_pucch = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH;
+            for(int th_id=0; th_id<RX_NB_TH; th_id++)
+	      {
+                ue->dlsch[th_id][eNB_id][0]->g_pucch += delta_pucch;
+	      }
+            LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid,
+		  delta_pucch,
+		  ue->dlsch[0][eNB_id][0]->g_pucch,
+		  ue->dlsch[1][eNB_id][0]->g_pucch
+		  //ue->dlsch[2][eNB_id][0]->g_pucch
+		  );
           }
-
+	
 	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\n",ue->Mod_id,subframe_rx,ue->dlsch[subframe_rx&0x1][eNB_id][0]->active);
+	LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active);
 #endif
 	
 	// 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[subframe_rx&1][eNB_id]->crnti);
+	  LOG_I(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[subframe_rx&1][eNB_id]->crnti);
 #endif
+	  
 	  //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]);
 	  ue->UE_mode[eNB_id] = PUSCH;
+	  
+	} 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]);
 	}
-      } 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]);
       }
-    }
-
-    else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
-	     ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
-
-
+      
+      else if ((dci_alloc_rx[i].rnti == SI_RNTI) &&
+	       ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) {
 
 
-      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,
-					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
-              0)==0) {
 #ifdef DEBUG_PHY_PROC
-	LOG_I(PHY,"[UE  %d] frame %d subframe %d: Found rnti %x, format 1%s, dci_cnt %d, mcs %d\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i,ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs);
+	LOG_I(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);
 #endif
-	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]);
-
+	
+	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->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					      ue->pdsch_vars_SI[eNB_id],
+					      &ue->dlsch_SI[eNB_id],
+					      &ue->frame_parms,
+					      ue->pdsch_config_dedicated,
+					      SI_RNTI,
+					      0,
+					      P_RNTI,
+					      ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
+					      0)==0) {
+	  
+	  ue->dlsch_SI_received[eNB_id]++;
+	  
+	  LOG_I(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]);
+	
+	}
       }
     }
 
     else if ((dci_alloc_rx[i].rnti == P_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);
+      LOG_I(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);
 #endif
 
 
       if (generate_ue_dlsch_params_from_dci(frame_rx,
 					    subframe_rx,
 					    (void *)&dci_alloc_rx[i].dci_pdu,
-						P_RNTI,
+					    P_RNTI,
 					    dci_alloc_rx[i].format,
+					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					    ue->pdsch_vars_p[eNB_id],
 					    &ue->dlsch_SI[eNB_id],
 					    &ue->frame_parms,
 					    ue->pdsch_config_dedicated,
@@ -2814,17 +3005,15 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
                                             0)==0) {
 
 	ue->dlsch_p_received[eNB_id]++;
- 
-
 	LOG_D(PHY,"[UE  %d] Frame %d, subframe %d : Generate UE DLSCH P_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]);
-
+	
       }
     }
 
     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_I(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);
@@ -2836,6 +3025,8 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    (DCI1A_5MHz_TDD_1_6_t *)&dci_alloc_rx[i].dci_pdu,
 					    ue->prach_resources[eNB_id]->ra_RNTI,
 					    format1A,
+					    ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id],
+					    ue->pdsch_vars_ra[eNB_id],
 					    &ue->dlsch_ra[eNB_id],
 					    &ue->frame_parms,
 					    ue->pdsch_config_dedicated,
@@ -2844,27 +3035,28 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					    P_RNTI,
 					    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id],
                                             0)==0) {
-
-	ue->dlsch_ra_received[eNB_id]++;
+	
+  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[subframe_rx & 0x1][eNB_id]->crnti) &&
+    } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) &&
 	       (dci_alloc_rx[i].format == format0)) {
-      //#ifdef DEBUG_PHY_PROC
-      LOG_I(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);
-      //#endif
+
+#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);
+#endif
 
       ue->ulsch_no_allocation_counter[eNB_id] = 0;
       //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
-
+      
       if ((ue->UE_mode[eNB_id] > PRACH) &&
 	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
-					     ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
+					     ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
 					     subframe_rx,
 					     format0,
 					     ue,
@@ -2875,7 +3067,6 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
 					     CBA_RNTI,
 					     eNB_id,
 					     0)==0)) {
-
 #if T_TRACER
     LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
     uint8_t harq_pid = subframe2harq_pid(frame_parms,
@@ -2891,20 +3082,20 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
       T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS));
 #endif
 #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
 
@@ -2912,39 +3103,41 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint
       //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]);
 
       if ((ue->UE_mode[eNB_id] > PRACH) &&
-	  (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
-					     ue->ulsch[eNB_id]->cba_rnti[0],
-					     subframe_rx,
-					     format0,
-					     ue,
-					     proc,
-					     SI_RNTI,
-					     0,
-					     P_RNTI,
-					     CBA_RNTI,
-					     eNB_id,
-					     0)==0)) {
+    (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu,
+               ue->ulsch[eNB_id]->cba_rnti[0],
+               subframe_rx,
+               format0,
+               ue,
+               proc,
+               SI_RNTI,
+               0,
+               P_RNTI,
+               CBA_RNTI,
+               eNB_id,
+               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[subframe_rx & 0x1][eNB_id]->crnti,
+      LOG_I(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[ue->current_thread_id[subframe_rx]][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
     }
 
   }
-
+#if UE_TIMING_TRACE
   stop_meas(&ue->dlsch_rx_pdcch_stats);
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT);
   return(0);
 }
@@ -2965,10 +3158,11 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
 
   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);
+    ue->Mod_id,(subframe_rx==9?-1:0)+frame_rx,subframe_rx);
 #if defined(Rel10) || defined(Rel14)
+
     pmch_mcs = ue_query_mch(ue->Mod_id,
 			    CC_id,
 			    frame_rx,
@@ -2980,10 +3174,11 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
 #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,frame_rx,subframe_rx,pmch_mcs);
       fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0);
+
       
       for (l=2; l<12; l++) {
 	
@@ -3053,6 +3248,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
 	LOG_T(PHY,"\n");
 #endif
 	
+	
 	//	if (subframe_rx==9)
 	//  mac_xface->macphy_exit("Why are we exiting here?");
       } else { // decoding successful
@@ -3078,6 +3274,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs
 	  
 	  
 	}
+
 #endif // Rel10 || Rel14
       } // decoding sucessful
     } // pmch_mcs>=0
@@ -3142,14 +3339,15 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
     if (dlsch0 && (!dlsch1))  {
       harq_pid = dlsch0->current_harq_pid;
       LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m);
-	    
-      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;
+
+      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 if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3))
       {
@@ -3158,9 +3356,9 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
           i_mod          = 0;
       }
       else {
-	dual_stream_UE = 0;
-	eNB_id_i = eNB_id+1;
-	i_mod = 0;
+        dual_stream_UE = 0;
+        eNB_id_i = eNB_id+1;
+        i_mod = 0;
       }
 
       //TM7 UE specific channel estimation here!!!
@@ -3173,13 +3371,17 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
           LOG_E(PHY,"[UE %d]Beamforming channel estimation not supported yet for TM7 extented CP.\n",ue->Mod_id);
         }
       }
-     
+
       if ((m==s0) && (m<4))
-	first_symbol_flag = 1;
+          first_symbol_flag = 1;
       else
-	first_symbol_flag = 0;
-
-      start_meas(&ue->dlsch_llr_stats);
+          first_symbol_flag = 0;
+#if UE_TIMING_TRACE
+      uint8_t slot = 0;
+      if(m >= ue->frame_parms.symbols_per_tti>>1)
+        slot = 1;
+      start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
+#endif
       // process DLSCH received in first slot
       rx_pdsch(ue,
 	       pdsch,
@@ -3192,10 +3394,23 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC
 	       dual_stream_UE,
 	       i_mod,
 	       dlsch0->current_harq_pid);
-      stop_meas(&ue->dlsch_llr_stats);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+      if(first_symbol_flag)
+      {
+          proc->first_symbol_available = 1;
+      }
     } // CRNTI active
   }
-} 
+}
 
 void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
 
@@ -3205,16 +3420,18 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
   LTE_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
   int harq_pid = 0;
   uint8_t *rar;
+  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
 
   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]);
-  
-	
+  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)) {
+    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,
@@ -3225,52 +3442,54 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
 				      frame_rx,
 				      ue->prach_resources[eNB_id]->ra_RNTI,
 				      dlsch0->harq_processes[0]->b,
-				      &ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti,
+				      &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
 				      ue->prach_resources[eNB_id]->ra_PreambleIndex,
 				      dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
       
-      ue->pdcch_vars[(subframe_rx+1) & 0x1][eNB_id]->crnti = ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti;
+      ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
+      ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti;
+
       
-	    
       if (timing_advance!=0xffff) {
-	      
-	      LOG_D(PHY,"[UE  %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n",
+
+              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[subframe_rx & 0x1][eNB_id]->crnti,
+              ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti,
               timing_advance);
+
+	      // remember this c-rnti is still a tc-rnti
 	      
-  // remember this c-rnti is still a tc-rnti
-  ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->crnti_is_temporary = 1;
+	      ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti_is_temporary = 1;
 	      
-	//timing_advance = 0;
-	process_timing_advance_rar(ue,proc,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;
-	}
+	      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,
@@ -3286,15 +3505,15 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo
   
 }
 
-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) {
+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;
@@ -3338,7 +3557,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
       pdsch_vars = ue->pdsch_vars_p[eNB_id];
       break;
     case PDSCH:
-      pdsch_vars = ue->pdsch_vars[subframe_rx&0x1][eNB_id];
+      pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id];
       break;
     case PMCH:
     case PDSCH1:
@@ -3352,128 +3571,176 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
       break;
 
     }
-
     if (frame_rx < *dlsch_errors)
       *dlsch_errors=0;
 
     if (pdsch==RA_PDSCH) {
       
-      AssertFatal(ue->prach_resources[eNB_id]!=NULL,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx);
-      dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
+      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);
+	AssertFatal(1==0,"prach_resources is NULL");
+      }
     }
-
-    // start turbo decode for CW 0
-    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[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
-						frame_rx,
-						subframe_rx,
-						ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
-    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);
-    
-    //#if 0
-    LOG_D(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, subframe_rx, harq_pid);
-    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
-    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even[0]);
-    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
-    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
-    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
-    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
-    LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
-    //#endif
     
-    start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
-    ret = dlsch_decoding(ue,
-			 pdsch_vars->llr[0],
-			 &ue->frame_parms,
+    if (abstraction_flag == 0) {
+      
+      // start turbo decode for CW 0
+      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[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+						  frame_rx,
+						  subframe_rx,
+						  ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
+#if UE_TIMING_TRACE
+      start_meas(&ue->dlsch_unscrambling_stats);
+#endif
+      dlsch_unscrambling(&ue->frame_parms,
+			 0,
 			 dlsch0,
-			 dlsch0->harq_processes[harq_pid],
-			 frame_rx,
-			 subframe_rx,
-			 harq_pid,
-			 pdsch==PDSCH?1:0,
-			 dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
-    stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
-    
-    LOG_D(PHY," --> Unscrambling for CW0 %5.3f\n",
-	  (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-    LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
-	  frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx&0x1].p_time)/(cpuf*1000.0));
-    
-    
-    if(is_cw1_active)
-      {
-	// start turbo decode for CW 1
-	dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
-						    dlsch1->harq_processes[harq_pid]->nb_rb,
-						    dlsch1->harq_processes[harq_pid]->rb_alloc_even,
-						    dlsch1->harq_processes[harq_pid]->Qm,
-						    dlsch1->harq_processes[harq_pid]->Nl,
-						    ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
-						    frame_rx,
-						    subframe_rx,
-						    ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
-	
-	start_meas(&ue->dlsch_unscrambling_stats);
-	dlsch_unscrambling(&ue->frame_parms,
-			   0,
-			   dlsch1,
-			   dlsch1->harq_processes[harq_pid]->G,
-			   pdsch_vars->llr[1],
-			   1,
-			   subframe_rx<<1);
-	stop_meas(&ue->dlsch_unscrambling_stats);
-	
+			 dlsch0->harq_processes[harq_pid]->G,
+			 pdsch_vars->llr[0],
+			 0,
+			 subframe_rx<<1);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->dlsch_unscrambling_stats);
+#endif
+      
 #if 0
-	LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb);
-	LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even);
-	LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm);
-	LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
-	LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
-	LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo);
-	LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
+      LOG_I(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d  ------  \n", frame_rx, subframe_rx, harq_pid);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->rb_alloc_even);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo);
+      LOG_I(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
 #endif
-	
-	start_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
-	
-	ret1 = dlsch_decoding(ue,
-			      pdsch_vars->llr[1],
-			      &ue->frame_parms,
-			      dlsch1,
-			      dlsch1->harq_processes[harq_pid],
-			      frame_rx,
-			      subframe_rx,
-			      harq_pid,
-			      pdsch==PDSCH?1:0,
-			      dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
-	stop_meas(&ue->dlsch_decoding_stats[subframe_rx&0x1]);
-	
-	
-	LOG_D(PHY," --> Unscrambling for CW1 %5.3f\n",
-	      (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
-	LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
-	      frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[subframe_rx&0x1].p_time)/(cpuf*1000.0));
-      }
+      
+#if UE_TIMING_TRACE
+      start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
+#endif
+      ret = dlsch_decoding(ue,
+			   pdsch_vars->llr[0],
+			   &ue->frame_parms,
+			   dlsch0,
+			   dlsch0->harq_processes[harq_pid],
+			   frame_rx,
+			   subframe_rx,
+			   harq_pid,
+			   pdsch==PDSCH?1:0,
+			   dlsch0->harq_processes[harq_pid]->TBS>256?1:0);
+      
+#if UE_TIMING_TRACE
+      stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+      printf(" --> Unscrambling for CW0 %5.3f\n",
+	     (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+      printf("AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
+	     frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
+#else
+      LOG_D(PHY, " --> Unscrambling for CW0 %5.3f\n",
+	    (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+      LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n",
+	    frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
+#endif
+      
+#endif
+      if(is_cw1_active)
+	{
+          // start turbo decode for CW 1
+          dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms,
+						      dlsch1->harq_processes[harq_pid]->nb_rb,
+						      dlsch1->harq_processes[harq_pid]->rb_alloc_even,
+						      dlsch1->harq_processes[harq_pid]->Qm,
+						      dlsch1->harq_processes[harq_pid]->Nl,
+						      ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+						      frame_rx,
+						      subframe_rx,
+						      ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]);
+#if UE_TIMING_TRACE
+          start_meas(&ue->dlsch_unscrambling_stats);
+#endif
+          dlsch_unscrambling(&ue->frame_parms,
+			     0,
+			     dlsch1,
+			     dlsch1->harq_processes[harq_pid]->G,
+			     pdsch_vars->llr[1],
+			     1,
+			     subframe_rx<<1);
+#if UE_TIMING_TRACE
+          stop_meas(&ue->dlsch_unscrambling_stats);
+#endif
+	  
+#if 0
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->rb_alloc_even);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> G  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Kmimo  %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo);
+          LOG_I(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d  --> Pdcch Sym  %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
+#endif
+	  
+#if UE_TIMING_TRACE
+          start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
+#endif
+	  
+          ret1 = dlsch_decoding(ue,
+				pdsch_vars->llr[1],
+				&ue->frame_parms,
+				dlsch1,
+				dlsch1->harq_processes[harq_pid],
+				frame_rx,
+				subframe_rx,
+				harq_pid,
+				pdsch==PDSCH?1:0,
+				dlsch1->harq_processes[harq_pid]->TBS>256?1:0);
+	  
+#if UE_TIMING_TRACE
+          stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+          printf(" --> Unscrambling for CW1 %5.3f\n",
+		 (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+          printf("AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
+		 frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
+#else
+          LOG_D(PHY, " --> Unscrambling for CW1 %5.3f\n",
+		(ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0));
+          LOG_D(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
+		frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
+#endif
+	  
+#endif
+          LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n",
+		frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
+	}
+      
+      LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, subframe_rx);
+    }
     
-    LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------  \n", frame_rx, subframe_rx);
-  
+    else {
+      LOG_D(PHY,"Calling dlsch_decoding_emul ...\n");
+#ifdef PHY_ABSTRACTION
+      ret = dlsch_decoding_emul(ue,
+				subframe_rx,
+				pdsch,
+				eNB_id);
+#endif
+    }
+    
+
     // Check CRC for CW 0
     if (ret == (1+dlsch0->max_turbo_iterations)) {
       *dlsch_errors=*dlsch_errors+1;
-      
+
       if(dlsch0->rnti != 0xffff)
       {
+
 	LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n",
 	      ue->Mod_id,dlsch0->rnti,
 	      harq_pid,frame_rx,subframe_rx,
@@ -3482,32 +3749,33 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
 	      dlsch0->harq_processes[harq_pid]->mcs,
 	      dlsch0->harq_processes[harq_pid]->TBS);
       }
-      
+
 
     } else {
         if(dlsch0->rnti != 0xffff)
         {
       LOG_D(PHY,"[UE  %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %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]->round,
-	    dlsch0->harq_processes[harq_pid]->mcs,
-	    dlsch0->harq_processes[harq_pid]->TBS);
+            ue->Mod_id,dlsch0->rnti,
+            harq_pid,frame_rx,subframe_rx,
+            dlsch0->harq_processes[harq_pid]->rvidx,
+            dlsch0->harq_processes[harq_pid]->round,
+            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,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]);
+
       LOG_T(PHY,"\n");
 #endif
 
-      
+
       if (ue->mac_enabled == 1) {
+	
 	switch (pdsch) {
 	case PDSCH:
 	  ue_send_sdu(ue->Mod_id,
@@ -3552,52 +3820,50 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
       ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] +
 	dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
     }
-  
     // Check CRC for CW 1
     if(is_cw1_active)
-    {
+      {
         if (ret1 == (1+dlsch0->max_turbo_iterations)) {
-            LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 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);
-
+	  LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 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);
+	  
         } else {
-            LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (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);
-
-
-            if (ue->mac_enabled == 1) {
-                switch (pdsch) {
-                case PDSCH:
-                    if(is_cw1_active)
-                        ue_send_sdu(ue->Mod_id,
-				    CC_id,
-				    frame_rx,
-				    subframe_rx,
-				    dlsch1->harq_processes[dlsch1->current_harq_pid]->b,
-				    dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3,
-				    eNB_id);
-                    break;
-                case SI_PDSCH:
-                case P_PDSCH:
-                case RA_PDSCH:
-                case PDSCH1:
-                case PMCH:
-                    AssertFatal(0,"exiting");
-                    break;
-                }
-            }
+	  LOG_I(PHY,"[UE  %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (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);
+	  
+	  
+	  if (ue->mac_enabled == 1) {
+	    switch (pdsch) {
+	    case PDSCH:
+	      if(is_cw1_active)
+		ue_send_sdu(ue->Mod_id,
+			    CC_id,
+			    frame_rx,
+			    subframe_rx,
+			    dlsch1->harq_processes[dlsch1->current_harq_pid]->b,
+			    dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3,
+			    eNB_id);
+	      break;
+	    case SI_PDSCH:
+	    case P_PDSCH:
+	    case RA_PDSCH:
+	    case PDSCH1:
+	    case PMCH:
+	      AssertFatal(0,"exiting");
+	      break;
+	    }
+	  }
         }
-    }
-  
-      
+      }
+    
 #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,
@@ -3618,46 +3884,873 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue,
     }
     
 #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) {
- 
-  int l,l2;
-  int pilot1;
-  int pmch_flag=0;
-  int frame_rx = proc->frame_rx;
-  int subframe_rx = proc->subframe_rx;
-
   
+  
+}
+
+/*!
+ * \brief This is the UE synchronize thread.
+ * It performs band scanning and synchonization.
+ * \param arg is a pointer to a \ref PHY_VARS_UE structure.
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+#ifdef UE_SLOT_PARALLELISATION
+#define FIFO_PRIORITY   40
+void *UE_thread_slot1_dl_processing(void *arg) {
+
+    static __thread int UE_dl_slot1_processing_retval;
+    struct rx_tx_thread_data *rtd = arg;
+    UE_rxtx_proc_t *proc = rtd->proc;
+    PHY_VARS_UE    *ue   = rtd->UE;
+
+    int frame_rx;
+    uint8_t subframe_rx;
+    uint8_t pilot0;
+    uint8_t pilot1;
+    uint8_t slot1;
+
+    uint8_t next_subframe_rx;
+    uint8_t next_subframe_slot0;
+
+    proc->instance_cnt_slot1_dl_processing=-1;
+    proc->subframe_rx=proc->sub_frame_start;
+
+    char threadname[256];
+    sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start);
+
+    cpu_set_t cpuset;
+    CPU_ZERO(&cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 )
+        CPU_SET(threads.slot1_proc_one, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 )
+        CPU_SET(threads.slot1_proc_two, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 )
+        CPU_SET(threads.slot1_proc_three, &cpuset);
+
+    init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
+                threadname);
+
+    while (!oai_exit) {
+        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE slot1 dl processing\n" );
+            exit_fun("nothing to add");
+        }
+        while (proc->instance_cnt_slot1_dl_processing < 0) {
+            // most of the time, the thread is waiting here
+            pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing );
+        }
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE slot1 dl processing \n" );
+            exit_fun("nothing to add");
+        }
+
+        /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++)
+        {
+        frame_rx    = ue->proc.proc_rxtx[0].frame_rx;
+        subframe_rx = ue->proc.proc_rxtx[0].subframe_rx;
+        printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
+        }*/
+        frame_rx    = proc->frame_rx;
+        subframe_rx = proc->subframe_rx;
+        next_subframe_rx    = (1+subframe_rx)%10;
+        next_subframe_slot0 = next_subframe_rx<<1;
+
+        slot1  = (subframe_rx<<1) + 1;
+        pilot0 = 0;
+
+        //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx);
+
+        if (ue->frame_parms.Ncp == 0) {  // normal prefix
+            pilot1 = 4;
+        } else { // extended prefix
+            pilot1 = 3;
+        }
+
+        /**** Slot1 FE Processing ****/
+#if UE_TIMING_TRACE
+        start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#endif
+        // I- start dl slot1 processing
+        // do first symbol of next downlink subframe for channel estimation
+        /*
+        // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11)
+        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
+        {
+            front_end_fft(ue,
+                    pilot0,
+                    next_subframe_slot0,
+                    0,
+                    0);
+        }
+
+        front_end_fft(ue,
+                pilot1,
+                slot1,
+                0,
+                0);
+         */
+        // 1- perform FFT
+        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
+        {
+            //if( (l != pilot0) && (l != pilot1))
+            {
+#if UE_TIMING_TRACE
+                start_meas(&ue->ofdm_demod_stats);
+#endif
+                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+                //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
+                front_end_fft(ue,
+                        l,
+                        slot1,
+                        0,
+                        0);
+                VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+                stop_meas(&ue->ofdm_demod_stats);
+#endif
+            }
+        } // for l=1..l2
+
+        if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL)
+        {
+            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
+            front_end_fft(ue,
+                    pilot0,
+                    next_subframe_slot0,
+                    0,
+                    0);
+        }
+
+        // 2- perform Channel Estimation for slot1
+        for (int l=1; l<ue->frame_parms.symbols_per_tti>>1; l++)
+        {
+            if(l == pilot1)
+            {
+                //wait until channel estimation for pilot0/slot1 is available
+                uint32_t wait = 0;
+                while(proc->chan_est_pilot0_slot1_available == 0)
+                {
+                    usleep(1);
+                    wait++;
+                }
+                //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait);
+            }
+            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l);
+            front_end_chanEst(ue,
+                    l,
+                    slot1,
+                    0);
+            ue_measurement_procedures(l-1,ue,proc,0,1+(subframe_rx<<1),0,ue->mode);
+        }
+        //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0);
+        front_end_chanEst(ue,
+                pilot0,
+                next_subframe_slot0,
+                0);
+
+        if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
+        {
+            ue_pbch_procedures(0,ue,proc,0);
+        }
+
+        proc->chan_est_slot1_available = 1;
+        //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+        //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
+
+        //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx);
+
+
+#if UE_TIMING_TRACE
+        stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#endif
+
+#endif
+
+
+    //wait until pdcch is decoded
+    uint32_t wait = 0;
+    while(proc->dci_slot0_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+    //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,subframe_rx,wait);
+
+
+    /**** Pdsch Procedure Slot1 ****/
+    // start slot1 thread for Pdsch Procedure (slot1)
+    // do procedures for C-RNTI
+    //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,subframe_rx);
+
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#endif
+    // start slave thread for Pdsch Procedure (slot1)
+    // do procedures for C-RNTI
+    uint8_t eNB_id = 0;
+    uint8_t abstraction_flag = 0;
+    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
+        //wait until first ofdm symbol is processed
+        //wait = 0;
+        //while(proc->first_symbol_available == 0)
+        //{
+        //    usleep(1);
+        //    wait++;
+        //}
+        //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,subframe_rx,wait);
+
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+        LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+        LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+    }
+
+    // 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->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+
+    // do procedures for P-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                (ue->frame_parms.symbols_per_tti>>1),
+                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->frame_parms.symbols_per_tti>>1),
+                ue->frame_parms.symbols_per_tti-1,
+                abstraction_flag);
+    }
+
+    proc->llr_slot1_available=1;
+    //printf("Set available LLR slot1 to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+        if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" );
+            exit_fun("noting to add");
+        }
+        proc->instance_cnt_slot1_dl_processing--;
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" );
+            exit_fun("noting to add");
+        }
+    }
+    // thread finished
+        free(arg);
+        return &UE_dl_slot1_processing_retval;
+}
+#endif
+
+#ifdef UE_SLOT_PARALLELISATION
+int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
+        uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
+        relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn)  {
+
+    int l,l2;
+    int pmch_flag=0;
+    int frame_rx = proc->frame_rx;
+    int subframe_rx = proc->subframe_rx;
+    uint8_t pilot0;
+    uint8_t pilot1;
+    uint8_t slot0;
+    uint8_t slot1;
+    uint8_t first_ofdm_sym;
+
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
-
 #if T_TRACER
-  T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
+    T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
+
+    T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
+            T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
+                    ue->frame_parms.samples_per_tti * 4));
+#endif
+
+    // start timers
+#ifdef UE_DEBUG_TRACE
+    LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
+    start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+
+    pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
+
+    if (do_pdcch_flag) {
+        // deactivate reception until we scan pdcch
+        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
+            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
+        if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
+            ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
+
+        if (ue->dlsch_SI[eNB_id])
+            ue->dlsch_SI[eNB_id]->active = 0;
+        if (ue->dlsch_p[eNB_id])
+            ue->dlsch_p[eNB_id]->active = 0;
+        if (ue->dlsch_ra[eNB_id])
+            ue->dlsch_ra[eNB_id]->active = 0;
+    }
+
+#ifdef DEBUG_PHY_PROC
+    LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
+            (r_type == multicast_relay) ? "RN/UE" : "UE",
+                    ue->Mod_id,frame_rx, subframe_rx);
+#endif
+
+
+
+
+    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;
+    }
+
+    int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1);
+    if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) {
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // RX processing of symbols l=0...l2
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        first_ofdm_sym = 0;
+    } else {
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch)
+        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+        first_ofdm_sym = 1;
+    }
+    slot0  = (subframe_rx<<1);
+    slot1  = (subframe_rx<<1) + 1;
+    pilot0 = 0;
+    if (ue->frame_parms.Ncp == 0) {  // normal prefix
+        pilot1 = 4;
+    } else { // extended prefix
+        pilot1 = 3;
+    }
+
+    //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+    //LOG_I(PHY,"Set available llrs slot1 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+    //LOG_I(PHY,"Set available dci info slot0 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+    proc->chan_est_pilot0_slot1_available=0;
+    proc->llr_slot1_available=0;
+    proc->dci_slot0_available=0;
+    proc->first_symbol_available=0;
+    proc->chan_est_slot1_available=0;
+    //proc->channel_level=0;
+
+    if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) {
+        LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE slot1 dl processing\n",ue->Mod_id );
+        exit_fun("nothing to add");
+    }
+
+    proc->instance_cnt_slot1_dl_processing++;
+    if (proc->instance_cnt_slot1_dl_processing == 0)
+    {
+    LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_slot1_dl_processing : %d \n", proc->instance_cnt_slot1_dl_processing );
+        if (pthread_cond_signal(&proc->cond_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE slot1 processing thread\n", ue->Mod_id);
+            exit_fun("nothing to add");
+        }
+        if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) {
+            LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE slot1 dl processing \n",ue->Mod_id );
+            exit_fun("nothing to add");
+        }
+
+    } else
+    {
+        LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_slot1_dl_processing);
+        if (proc->instance_cnt_slot1_dl_processing > 2)
+            exit_fun("instance_cnt_slot1_dl_processing > 2");
+    }
+    //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,"");
+    AssertFatal(pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) ==0,"");
+
+
+    /**** Slot0 FE Processing ****/
+    // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7
+#if UE_TIMING_TRACE
+    start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#endif
+    // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3))
+    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
+    front_end_fft(ue,
+            pilot0,
+            slot1,
+            0,
+            0);
+    //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
+    front_end_fft(ue,
+            pilot1,
+            slot0,
+            0,
+            0);
+    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1);
+    front_end_chanEst(ue,
+            pilot1,
+            slot0,
+            0);
+    //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0);
+    front_end_chanEst(ue,
+            pilot0,
+            slot1,
+            0);
+    proc->chan_est_pilot0_slot1_available = 1;
+    //printf("Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx);
+
+    // 2- perform FFT for other ofdm symbols other than pilots
+    for (l=first_ofdm_sym; l<=l2; l++)
+    {
+        if( (l != pilot0) && (l != pilot1))
+        {
+            //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
+#if UE_TIMING_TRACE
+            start_meas(&ue->ofdm_demod_stats);
+#endif
+            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+            front_end_fft(ue,
+                    l,
+                    slot0,
+                    0,
+                    0);
+            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+            stop_meas(&ue->ofdm_demod_stats);
+#endif
+        }
+    } // for l=1..l2
+
+    // 3- perform Channel Estimation for slot0
+    for (l=first_ofdm_sym; l<=l2; l++)
+    {
+        if( (l != pilot0) && (l != pilot1))
+        {
+            //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l);
+            front_end_chanEst(ue,
+                    l,
+                    slot0,
+                    0);
+        }
+        ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
+    }
+
+    if (do_pdcch_flag) {
+#if UE_TIMING_TRACE
+        start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+        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);
+#if UE_TIMING_TRACE
+            stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+            printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+            LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+            //proc->dci_slot0_available = 1;
+            return(-1);
+        }
+        //proc->dci_slot0_available=1;
+#if UE_TIMING_TRACE
+        stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+    }
+
+    //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
+
+    // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+    //wait until slot1 FE is done
+    uint32_t wait = 0;
+    while(proc->chan_est_slot1_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+    /**** End Subframe FE Processing ****/
+
+
+#if 0
+    //Trigger LLR parallelized for Slot 1
+    proc->dci_slot0_available=1;
+    printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
+#endif
+
+    /**** Pdsch Procedure Slot0 ****/
+    // start main thread for Pdsch Procedure (slot0)
+    // do procedures for C-RNTI
+    //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx);
+    //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[ue->current_thread_id[subframe_rx]][0][0]->active);
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#endif
+    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                SI_PDSCH,
+                ue->dlsch_SI[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN);
+        ue_pdsch_procedures(ue,
+                proc,
+                eNB_id,
+                RA_PDSCH,
+                ue->dlsch_ra[eNB_id],
+                NULL,
+                ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+                (ue->frame_parms.symbols_per_tti>>1)-1,
+                abstraction_flag);
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
+    }
+
+#if 1
+    // LLR linear
+    proc->dci_slot0_available=1;
+    //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx);
+#endif
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+
+    //wait until LLR Slot1 is done
+    wait = 0;
+    while(proc->llr_slot1_available == 0)
+    {
+        usleep(1);
+        wait++;
+    }
+
+
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+    printf("[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+    //printf("[slot0 dl processing] AbsSubframe %d.%d Channel Decoder Start wait %d\n",frame_rx,subframe_rx,wait);
+
+
+    //=====================================================================//
+#if UE_TIMING_TRACE
+    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#endif
+
+    LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active,
+    		ue->dlsch_SI[eNB_id]->active,
+			//ue->dlsch_p[eNB_id]->active,
+			ue->dlsch_ra[eNB_id]->active);
+    // Start Turbo decoder
+    if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                PDSCH,
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+                ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
+                &ue->dlsch_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
+    }
+
+    // do procedures for SI-RNTI
+    if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
+        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 P-RNTI
+    if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
+        ue_dlsch_procedures(ue,
+                proc,
+                eNB_id,
+                P_PDSCH,
+                ue->dlsch_p[eNB_id],
+                NULL,
+                &ue->dlsch_p_errors[eNB_id],
+                mode,
+                abstraction_flag);
+        ue->dlsch_p[eNB_id]->active = 0;
+    }
+    // do procedures for RA-RNTI
+    if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) {
+        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 UE_TIMING_TRACE
+        stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+        printf("[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+        LOG_D(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+
+#endif
+
+        // duplicate harq structure
+        uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
+        LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
+        harq_status_t    *current_harq_ack       = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
+
+        // For Debug parallelisation
+        //if (current_harq_ack->ack == 0) {
+            //printf("[slot0 dl processing][End of Channel Decoding] AbsSubframe %d.%d Decode Fail for HarqId%d Round%d\n",frame_rx,subframe_rx,current_harq_pid,current_harq_processes->round);
+        //}
+        for(uint8_t rx_th_idx=1; rx_th_idx<RX_NB_TH; rx_th_idx++)
+        {
+            LTE_DL_UE_HARQ_t *harq_processes_dest  = ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_processes[current_harq_pid];
+            harq_status_t    *harq_ack_dest        = &ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_ack[subframe_rx];
+
+            copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
+            copy_ack_struct(harq_ack_dest, current_harq_ack);
+
+        }
+    /*
+    LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
+    LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid];
+
+    harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
+    harq_status_t *harq_ack_dest    = &ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
+    harq_status_t *harq_ack_dest1    = &ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx];
+
+    copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
+    copy_ack_struct(harq_ack_dest, current_harq_ack);
+
+    copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
+    copy_ack_struct(harq_ack_dest1, current_harq_ack);
+    */
+    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_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 UE_AUTOTEST_TRACE
+        if ((frame_rx % 100 == 0)) {
+            LOG_I(PHY,"[UE  %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx);
+        }
 #endif
 
+    }
+
+#ifdef EMOS
+    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);
+
+#if UE_TIMING_TRACE
+    stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+    printf("------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+
+    LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+    return (0);
+}
+#endif
+
+
+int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,
+			 uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
+			 relaying_type_t r_type,PHY_VARS_RN *phy_vars_rn) {
+
+  int l,l2;
+  int pilot1;
+  int pmch_flag=0;
+  int frame_rx = proc->frame_rx;
+  int subframe_rx = proc->subframe_rx;
+
+  uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1);
+  uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
+
+#if T_TRACER
+  T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx));
+
   T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0),
     T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
              ue->frame_parms.samples_per_tti * 4));
+#endif
 
   // start timers
+#ifdef UE_DEBUG_TRACE
+  LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
+#endif
 
-  LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
-  start_meas(&ue->phy_proc_rx[subframe_rx&0x1]);
+#if UE_TIMING_TRACE
+  start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
   start_meas(&ue->generic_stat);
+#endif
 
   pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0;
 
-
+  if (do_pdcch_flag) {
   // deactivate reception until we scan pdcch
-  if (ue->dlsch[subframe_rx&0x1][eNB_id][0])
-    ue->dlsch[subframe_rx&0x1][eNB_id][0]->active = 0;
-  if (ue->dlsch[subframe_rx&0x1][eNB_id][1])
-    ue->dlsch[subframe_rx&0x1][eNB_id][1]->active = 0;
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0])
+    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0;
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1])
+    ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0;
 
   if (ue->dlsch_SI[eNB_id])
     ue->dlsch_SI[eNB_id]->active = 0;
@@ -3665,22 +4758,12 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     ue->dlsch_p[eNB_id]->active = 0;
   if (ue->dlsch_ra[eNB_id])
     ue->dlsch_ra[eNB_id]->active = 0;
+  }
 
-  
 #ifdef DEBUG_PHY_PROC
   LOG_D(PHY,"[%s %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n",
-	(r_type == multicast_relay) ? "RN/UE" : "UE",
-	ue->Mod_id,frame_rx, subframe_rx);
-  LOG_D(PHY,"phy_procedures_UR_RX: Frame %d, subframe %d : energy %d\n",
-	frame_rx,subframe_rx,
-	  dB_fixed(signal_energy(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],
-				 ue->frame_parms.samples_per_tti)));
-
-  /*													   
-  if ((subframe_rx == 5) && ((frame_rx &1) == 0)) {
-    write_output("rxsig5.m","rxs5",&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1);
-    exit(-1);
-    }*/
+  (r_type == multicast_relay) ? "RN/UE" : "UE",
+  ue->Mod_id,frame_rx, subframe_rx);
 #endif
 
   if (ue->frame_parms.Ncp == 0) {  // normal prefix
@@ -3688,8 +4771,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   } 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
@@ -3697,7 +4780,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   } else { // normal subframe, last symbol to be processed is the first of the second slot
     l2 = (ue->frame_parms.symbols_per_tti/2)-1;
   }
-  
+
   int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1);
   if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) {
     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -3714,33 +4797,46 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
   LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
   for (; l<=l2; l++) {
-    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),
-	     0,
-	     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 (abstraction_flag == 0) {
+#if UE_TIMING_TRACE
+        start_meas(&ue->ofdm_demod_stats);
+#endif
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN);
+      slot_fep(ue,
+         l,
+         (subframe_rx<<1),
+         0,
+         0,
+         0);
+      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+      stop_meas(&ue->ofdm_demod_stats);
+#endif
+    }
+
     ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),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);
+
+    if (do_pdcch_flag) {
+      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);
+
+	//start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
+	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);
+	}
+	//stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]);
+    //printf("subframe %d n_pdcch_sym %d pdcch procedures  %5.3f \n",
+    //        subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
+    //     (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0));
+	LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols);
       }
-      LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols);
     }
-    
+
   } // for l=1..l2
-  ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); 
-  
+  ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode);
+
   LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
     // If this is PMCH, call procedures and return
   if (pmch_flag == 1) {
@@ -3749,30 +4845,40 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   }
 
   slot_fep(ue,
-	   0,
-	   1+(subframe_rx<<1),
-	   0,
-	   0,
-	   0);
+     0,
+     1+(subframe_rx<<1),
+     0,
+     0,
+     0);
 
   // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH)
+#if UE_TIMING_TRACE
   stop_meas(&ue->generic_stat);
-  LOG_D(PHY,"[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
-  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+#if DISABLE_LOG_X
+  printf("[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
 
+#endif
+
+  LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
+#if UE_TIMING_TRACE
   start_meas(&ue->generic_stat);
+#endif
   // do procedures for C-RNTI
-  if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
 			PDSCH,
-			ue->dlsch[subframe_rx&0x1][eNB_id][0],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
 			NULL,
-			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
+
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
   }
 
@@ -3781,12 +4887,13 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN);
     ue_pdsch_procedures(ue,
+
 			proc,
 			eNB_id,
 			SI_PDSCH,
 			ue->dlsch_SI[eNB_id],
 			NULL,
-			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT);
@@ -3801,7 +4908,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 			P_PDSCH,
 			ue->dlsch_p[eNB_id],
 			NULL,
-			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT);
@@ -3816,31 +4923,36 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 			RA_PDSCH,
 			ue->dlsch_ra[eNB_id],
 			NULL,
-			ue->pdcch_vars[subframe_rx & 0x1][eNB_id]->num_pdcch_symbols,
+			ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols,
 			ue->frame_parms.symbols_per_tti>>1,
 			abstraction_flag);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
-  }    
-  
+  }
+
   LOG_D(PHY," ------ slot 1 Processing: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
   LOG_D(PHY," ------  --> FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
 
   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++) {
-      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),
-	       0,
-	       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 (abstraction_flag == 0) {
+#if UE_TIMING_TRACE
+          start_meas(&ue->ofdm_demod_stats);
+#endif
+	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),
+		 0,
+		 0,
+		 0);
+	VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->ofdm_demod_stats);
+#endif
+      }
+
       ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode);
-      
+
     } // for l=1..l2
 
     // do first symbol of next downlink subframe for channel estimation
@@ -3855,71 +4967,90 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
          0);
     }
   } // not an S-subframe
-
+#if UE_TIMING_TRACE
   stop_meas(&ue->generic_stat);
+#if DISABLE_LOG_X
+  printf("[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
+
+#endif
 
-  LOG_D(PHY,"[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0));
   LOG_D(PHY," ------  end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
 
   if ( (subframe_rx == 0) && (ue->decode_MIB == 1))
   {
     ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag);
   }
-   
+
+
+
   // do procedures for C-RNTI
   LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
-  if (ue->dlsch[subframe_rx&0x1][eNB_id][0]->active == 1) {
+  if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN);
-    start_meas(&ue->pdsch_procedures_stat);
+#if UE_TIMING_TRACE
+    start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]);
+#endif
     ue_pdsch_procedures(ue,
 			proc,
 			eNB_id,
 			PDSCH,
-			ue->dlsch[subframe_rx&0x1][eNB_id][0],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
 			NULL,
 			1+(ue->frame_parms.symbols_per_tti>>1),
 			ue->frame_parms.symbols_per_tti-1,
 			abstraction_flag);
-    stop_meas(&ue->pdsch_procedures_stat);
-
     LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
     LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------  \n", frame_rx%1024, subframe_rx);
-
-    start_meas(&ue->dlsch_procedures_stat);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+    start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#endif
     ue_dlsch_procedures(ue,
 			proc,
 			eNB_id,
 			PDSCH,
-			ue->dlsch[subframe_rx&0x1][eNB_id][0],
-			ue->dlsch[subframe_rx&0x1][eNB_id][1],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0],
+			ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1],
 			&ue->dlsch_errors[eNB_id],
 			mode,
 			abstraction_flag);
-    stop_meas(&ue->dlsch_procedures_stat);
-    LOG_D(PHY,"[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat.p_time/(cpuf*1000.0));
-    LOG_D(PHY,"[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat.p_time/(cpuf*1000.0));
+#if UE_TIMING_TRACE
+    stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+    printf("[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+    printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+    LOG_D(PHY, "[SFN %d] Slot1:       Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+    LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+
+#endif
 
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT);
 
   }
-
+#if UE_TIMING_TRACE
   start_meas(&ue->generic_stat);
+#endif
 
 #if 0
-  if(subframe_rx==5 &&  ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid]->nb_rb > 20){
+  if(subframe_rx==5 &&  ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){
        //write_output("decoder_llr.m","decllr",dlsch_llr,G,1,0);
        //write_output("llr.m","llr",  &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0);
 
-       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
-       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[(subframe_rx+1)&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       write_output("rxdataF0_current.m"    , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
 
-       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[(subframe+1)&0x1].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       //write_output("rxdataF0_previous.m"    , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
 
-       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[subframe_rx&0x1].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
-       write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[subframe_rx&0x1][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
-       write_output("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[subframe_rx&0x1][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
-       //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1);
-       //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[subframe&0x1][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
+       write_output("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1);
+       write_output("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
+       write_output("rxdataF_comp00.m","rxdataF_comp00",         &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1);
+       //write_output("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1);
+       //write_output("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1);
 
        AssertFatal (0,"");
   }
@@ -3928,89 +5059,94 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
   // 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);
+      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);
+      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 P-RNTI
   if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) {
     ue_pdsch_procedures(ue,
-			proc,
-			eNB_id,
-			P_PDSCH,
-			ue->dlsch_p[eNB_id],
-			NULL,
-			1+(ue->frame_parms.symbols_per_tti>>1),
-			ue->frame_parms.symbols_per_tti-1,
-			abstraction_flag);
+      proc,
+      eNB_id,
+      P_PDSCH,
+      ue->dlsch_p[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,
-			P_PDSCH,
-			ue->dlsch_p[eNB_id],
-			NULL,
-			&ue->dlsch_p_errors[eNB_id],
-			mode,
-			abstraction_flag);
+      proc,
+      eNB_id,
+      P_PDSCH,
+      ue->dlsch_p[eNB_id],
+      NULL,
+      &ue->dlsch_p_errors[eNB_id],
+      mode,
+      abstraction_flag);
     ue->dlsch_p[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);
+      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);
+      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;
   }
 
   // duplicate harq structure
 
-  uint8_t          current_harq_pid        = ue->dlsch[subframe_rx&0x1][eNB_id][0]->current_harq_pid;
-  LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_processes[current_harq_pid];
-  LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[(subframe_rx+1)&0x1][eNB_id][0]->harq_processes[current_harq_pid];
+  uint8_t          current_harq_pid        = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid;
+  LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid];
+  LTE_DL_UE_HARQ_t *harq_processes_dest    = ue->dlsch[next1_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
+  LTE_DL_UE_HARQ_t *harq_processes_dest1    = ue->dlsch[next2_thread_id][eNB_id][0]->harq_processes[current_harq_pid];
 
-  harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx&0x1][eNB_id][0]->harq_ack[subframe_rx];
-  harq_status_t *harq_ack_dest    = &ue->dlsch[(subframe_rx+1)&0x1][eNB_id][0]->harq_ack[subframe_rx];
+  harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx];
+  harq_status_t *harq_ack_dest    = &ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack[subframe_rx];
+  harq_status_t *harq_ack_dest1    = &ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack[subframe_rx];
 
   copy_harq_proc_struct(harq_processes_dest, current_harq_processes);
   copy_ack_struct(harq_ack_dest, current_harq_ack);
 
+  copy_harq_proc_struct(harq_processes_dest1, current_harq_processes);
+  copy_ack_struct(harq_ack_dest1, current_harq_ack);
+
   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];
@@ -4020,8 +5156,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
     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);
+    ue->Mod_id,frame_rx,ue->total_TBS[eNB_id],
+    ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0);
 
   #if UE_AUTOTEST_TRACE
     if ((frame_rx % 100 == 0)) {
@@ -4031,53 +5167,62 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
 
   }
 
+#if UE_TIMING_TRACE
   stop_meas(&ue->generic_stat);
-  //printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+  printf("after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0));
+#endif
 
 #ifdef EMOS
   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[subframe_rx&0x1]);
 
-  LOG_D(PHY,"------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[subframe_rx&0x1].p_time/(cpuf*1000.0));
+#if UE_TIMING_TRACE
+  stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]);
+#if DISABLE_LOG_X
+  printf("------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#else
+  LOG_D(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0));
+#endif
+#endif
+
   LOG_D(PHY," ****** end RX-Chain  for AbsSubframe %d.%d ******  \n", frame_rx%1024, subframe_rx);
   return (0);
 }
-   
+
 #if defined(Rel10) || defined(Rel14)
+
 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,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode,
+
+void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode,
 			   relaying_type_t r_type, PHY_VARS_RN *phy_vars_rn)
 {
 #if defined(ENABLE_ITTI)
@@ -4087,85 +5232,89 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
   unsigned int  Mod_id;
   int           result;
 #endif
-   
+
   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;
   }
-   
-   
+
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1);
-  start_meas(&ue->phy_proc);
+#if UE_TIMING_TRACE
+  start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
+#endif
 #if defined(ENABLE_ITTI)
 
   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 */
-	break;
-	 
+  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
-   
+
   for (slot=0;slot<2;slot++) {
-     
+
     if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)||
-	(ue->frame_parms.frame_type == FDD)) {
+  (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)) {
+  (ue->frame_parms.frame_type == FDD)) {
 #if defined(Rel10) || defined(Rel14)
-       
+
       if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
 #endif
-	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type,phy_vars_rn);
     }
-     
+
     if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) &&
-	(slot==1)) {
+  (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)) {
+  (slot==0)) {
 #if defined(Rel10) || defined(Rel14)
-	 
+
       if (phy_procedures_RN_UE_RX(subframe_rx, subframe_tx, r_type) != 0 )
 #endif
-	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,mode,r_type,phy_vars_rn);
+	phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode,r_type,phy_vars_rn);
     }
-       
+
     if (ue->mac_enabled==1) {
       if (slot==0) {
+
+          //LOG_I(PHY,"[UE %d] Frame %d, subframe %d, star ue_scheduler\n", ue->Mod_id,frame_rx,subframe_tx);
         ret = ue_scheduler(ue->Mod_id,
 			   frame_rx,
 			   subframe_rx,
@@ -4193,10 +5342,12 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u
 	}
       }
     }
-       
+    
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0);
-    stop_meas(&ue->phy_proc);
+#if UE_TIMING_TRACE
+    stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]);
+#endif
   } // slot
 }
- 
- 
+
+
diff --git a/openair1/SCHED/pucch_pc.c b/openair1/SCHED/pucch_pc.c
index 5186153821b507791f045f185a5bf1e1c97b825d..510d9a1401547ab1ae1106318d52f17ff818ff1e 100644
--- a/openair1/SCHED/pucch_pc.c
+++ b/openair1/SCHED/pucch_pc.c
@@ -52,7 +52,7 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u
 
   Po_PUCCH = get_PL(ue->Mod_id,ue->CC_id,eNB_id)+
     ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+
-    ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch;
+    ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch;
 
   switch (pucch_fmt) {
   case pucch_format1:
@@ -98,19 +98,19 @@ int16_t pucch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t subframe,u
   if (pucch_fmt!=pucch_format1) {
     LOG_D(PHY,"[UE  %d][PDSCH %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB, g_pucch %d dB\n",
           ue->Mod_id,
-          ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
           Po_PUCCH,
           ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
           get_PL(ue->Mod_id,ue->CC_id,eNB_id),
-          ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch);
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch);
   } else {
     LOG_D(PHY,"[UE  %d][SR %x] AbsSubframe %d.%d: Po_PUCCH %d dBm : Po_NOMINAL_PUCCH %d dBm, PL %d dB g_pucch %d dB\n",
           ue->Mod_id,
-          ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti,proc->frame_tx%1024,subframe,
           Po_PUCCH,
           ue->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
           get_PL(ue->Mod_id,ue->CC_id,eNB_id),
-          ue->dlsch[proc->subframe_rx&0x1][eNB_id][0]->g_pucch);
+          ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch);
   }
 
   return(Po_PUCCH);
diff --git a/openair1/SCHED/pusch_pc.c b/openair1/SCHED/pusch_pc.c
index f4ce761c31d3589f171a190d5f7a611a8d12c35f..8b2e19eef186416ed6e2c6a780168cd734266dba 100644
--- a/openair1/SCHED/pusch_pc.c
+++ b/openair1/SCHED/pusch_pc.c
@@ -163,6 +163,7 @@ void pusch_power_cntl(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_
 
     ue->ulsch[eNB_id]->Po_PUSCH += (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,proc->frame_tx,proc->subframe_tx,ue->ulsch[eNB_id]->Po_PUSCH,
           100*get_Po_NOMINAL_PUSCH(ue->Mod_id,0),
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c
index 951b5f75f65c9450ee6b32f54308dff21a0c8af7..02591dcc8f3ecd608372bae441b6d598c8e6cdd9 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim.c
@@ -390,10 +390,11 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           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;
+          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;
+          dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
 	  //          printf("Generating dlsch params for user %d\n",k);
@@ -530,11 +531,12 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           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;
+          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;
+          dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -699,13 +701,14 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           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;
+          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;
+          dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-          printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
+          //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],
@@ -839,14 +842,15 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           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;
+          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;
+          dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
-          printf("Generating dlsch params for user %d\n",k);
+          //printf("Generating dlsch params for user %d\n",k);
           generate_eNB_dlsch_params_from_dci(0,
 					     subframe,
                                              &DLSCH_alloc_pdu_1[0],
@@ -866,7 +870,7 @@ void fill_DCI(PHY_VARS_eNB *eNB,
 
         }
 
-        printf("Generated DCI format 2A (Transmission Mode 3)\n");
+        //printf("Generated DCI format 2A (Transmission Mode 3)\n");
         break;
 
       case 4:
@@ -1009,10 +1013,11 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           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;
+          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;
+          dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1149,11 +1154,12 @@ void fill_DCI(PHY_VARS_eNB *eNB,
           }
 
           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;
+          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;
+          dci_alloc[*num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[*num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1181,11 +1187,12 @@ void fill_DCI(PHY_VARS_eNB *eNB,
       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;
+        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;
+        dci_alloc[*num_dci].search_space = DCI_UE_SPACE;
         printf("Generating dlsch params for user %d\n",k);
         generate_eNB_dlsch_params_from_dci(0,
 					   subframe,
@@ -1224,12 +1231,10 @@ int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1;
 DCI_PDU *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframeP) {
 
   if (subframeP == subframe) {
-    DCI_pdu.Num_ue_spec_dci   = num_ue_spec_dci;
-    DCI_pdu.Num_common_dci    = num_common_dci;
+    DCI_pdu.Num_dci   = num_ue_spec_dci + num_common_dci;
     DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
   } else {
-    DCI_pdu.Num_ue_spec_dci   = 0;
-    DCI_pdu.Num_common_dci    = 0;
+    DCI_pdu.Num_dci   = 0;
     DCI_pdu.num_pdcch_symbols = num_pdcch_symbols;
   }
 
@@ -1292,7 +1297,6 @@ int main(int argc, char **argv)
   uint16_t tdd_config=3;
 
 
-
   SCM_t channel_model=Rayleigh1;
   //  unsigned char *input_data,*decoded_output;
 
@@ -1347,7 +1351,7 @@ int main(int argc, char **argv)
   // void *data;
   // int ii;
   //  int bler;
-  double blerr[4],uncoded_ber; //,avg_ber;
+  double blerr[4],uncoded_ber=0; //,avg_ber;
   short *uncoded_ber_bit=NULL;
   uint8_t N_RB_DL=25,osf=1;
   frame_t frame_type = FDD;
@@ -1366,6 +1370,7 @@ int main(int argc, char **argv)
   int rballocset=0;
   int print_perf=0;
   int test_perf=0;
+  int test_passed=0;
   int dump_table=0;
 
   double effective_rate=0.0;
@@ -1391,10 +1396,13 @@ int main(int argc, char **argv)
 
   FILE *csv_fd=NULL;
   char csv_fname[32];
-  //int dci_flag=1;
+  int dci_flag=0;
   int two_thread_flag=0;
   int DLSCH_RB_ALLOC = 0;
 
+  int log_level = LOG_ERR;
+  int dci_received;
+
 #if defined(__arm__)
   FILE    *proc_fd = NULL;
   char buf[64];
@@ -1418,15 +1426,13 @@ int main(int argc, char **argv)
   //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:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXY")) != -1) {
+  while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXYL:")) != -1) {
     switch (c) {
     case 'a':
       awgn_flag = 1;
@@ -1453,9 +1459,9 @@ int main(int argc, char **argv)
       Nid_cell = atoi(optarg);
       break;
 
-    //case 'd':
-    //  dci_flag = 1;
-    //  break;
+    case 'd':
+      dci_flag = 1;
+      break;
 
     case 'D':
       frame_type=TDD;
@@ -1482,7 +1488,7 @@ int main(int argc, char **argv)
     case 'i':
       input_fd = fopen(optarg,"r");
       input_file=1;
-      //dci_flag = 1;
+      dci_flag = 1;
       break;
 
     case 'I':
@@ -1722,7 +1728,9 @@ int main(int argc, char **argv)
       dump_table=1;
       break;
 
-
+    case 'L':
+      log_level=atoi(optarg);
+      break;
 
     case 'h':
     default:
@@ -1732,12 +1740,17 @@ int main(int argc, char **argv)
       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("-d Transmit the DCI and compute its error statistics\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("-C cell id\n");
+      printf("-S subframe\n");
+      printf("-D use TDD mode\n");
+      printf("-b TDD config\n");
+      printf("-B bandwidth configuration (in number of ressource blocks): 6, 25, 50, 100\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");
@@ -1757,6 +1770,16 @@ int main(int argc, char **argv)
     }
   }
 
+  logInit();
+  // enable these lines if you need debug info
+  set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1);
+  set_glog(log_level,LOG_HIGH);
+  // moreover you need to init itti with the following line
+  // however itti will catch all signals, so ctrl-c won't work anymore
+  // alternatively you can disable ITTI completely in CMakeLists.txt
+  //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
+
+
   if (common_flag == 0) {
     switch (N_RB_DL) {
     case 6:
@@ -1999,7 +2022,7 @@ int main(int argc, char **argv)
     }
   */
 
-  UE->pdcch_vars[subframe & 0x1][0]->crnti = n_rnti;
+  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
 
   // Fill in UL_alloc
   UL_alloc_pdu.type    = 0;
@@ -2159,7 +2182,7 @@ int main(int argc, char **argv)
 	     TPC,
 	     mcs1,
 	     mcs2,
-	     0,
+	     1,
 	     0,
 	     &num_common_dci,
 	     &num_ue_spec_dci,
@@ -2240,7 +2263,7 @@ int main(int argc, char **argv)
     }
 
     for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
-      UE->proc.proc_rxtx[subframe&1].frame_rx=0;
+      UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
       errs[0]=0;
       errs[1]=0;
       errs[2]=0;
@@ -2273,7 +2296,7 @@ int main(int argc, char **argv)
       reset_meas(&eNB->dlsch_rate_matching_stats);
       reset_meas(&eNB->dlsch_turbo_encoding_stats);
 
-      reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx
+      reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx
       reset_meas(&UE->ofdm_demod_stats);
       reset_meas(&UE->dlsch_channel_estimation_stats);
       reset_meas(&UE->dlsch_freq_offset_estimation_stats);
@@ -2309,7 +2332,7 @@ 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];
+      eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[UE->current_thread_id[subframe]];
 
       for (trials = 0; trials<n_frames; trials++) {
 	//printf("Trial %d\n",trials);
@@ -2318,10 +2341,10 @@ int main(int argc, char **argv)
 
         //if (trials%100==0)
         eNB2UE[0]->first_run = 1;
+	UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack = 0;
+	UE->dlsch[UE->current_thread_id[subframe]][eNB_id][1]->harq_ack[subframe].ack = 0;
 
-        UE->dlsch_errors[0] = 1;
-
-        while ((round < num_rounds) && (UE->dlsch_errors[0] > 0)) {
+        while ((round < num_rounds) && (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 0)) {
 	  //	  printf("Trial %d, round %d\n",trials,round);
           round_trials[round]++;
 
@@ -2361,11 +2384,12 @@ int main(int argc, char **argv)
 
                 eNB->dlsch[0][0]->harq_processes[0]->rvidx = round&3;
 
-		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);
+		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);
+			 (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++) {
 
@@ -2419,7 +2443,7 @@ int main(int argc, char **argv)
 	    proc_eNB->subframe_tx = subframe;
 	    eNB->abstraction_flag=0;
 
-	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1);
+	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,1,dci_flag);
 
 
 	    start_meas(&eNB->ofdm_mod_stats);
@@ -2455,7 +2479,7 @@ int main(int argc, char **argv)
 
 	    proc_eNB->subframe_tx = subframe+1;
 
-	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0);
+	    phy_procedures_eNB_TX(eNB,proc_eNB,no_relay,NULL,0,dci_flag);
 
 	    do_OFDM_mod_l(eNB->common_vars.txdataF[eNB_id],
 			  eNB->common_vars.txdata[eNB_id],
@@ -2493,10 +2517,10 @@ int main(int argc, char **argv)
 	  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];
+	  UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[UE->current_thread_id[subframe]];
 	  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,
@@ -2506,12 +2530,48 @@ int main(int argc, char **argv)
 		   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[subframe&0x1][0][0]->active == 0) {
+	  if (dci_flag==0) {
+	    if (n_frames==1)
+	      printf("bypassing PDCCH/DCI detection\n");
+	    if  (generate_ue_dlsch_params_from_dci(proc->frame_rx,
+						   proc->subframe_rx,
+						   (void *)&dci_alloc[0].dci_pdu,
+						   n_rnti,
+						   dci_alloc[0].format,
+						   UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
+						   UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id],
+                           UE->dlsch[UE->current_thread_id[proc->subframe_rx]][0],
+						   &UE->frame_parms,
+						   UE->pdsch_config_dedicated,
+						   SI_RNTI,
+						   0,
+						   P_RNTI,
+						   UE->transmission_mode[eNB_id]<7?0:UE->transmission_mode[eNB_id],
+						   0)==0) {
+
+		dump_dci(&UE->frame_parms, &dci_alloc[0]);
+
+		//UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][0]->active = 1;
+		//UE->dlsch[UE->current_thread_id[proc->subframe_rx]][eNB_id][1]->active = 1;
+
+		UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->num_pdcch_symbols = num_pdcch_symbols;
+
+		UE->dlsch_received[eNB_id]++;
+	    } else {
+	      LOG_E(PHY,"Problem in DCI!\n");
+	    }
+	  }
+
+	  dci_received = UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
+
+	  phy_procedures_UE_RX(UE,proc,0,0,dci_flag,normal_txrx,no_relay,NULL);
+
+	  dci_received = dci_received - UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id]->dci_received;
+
+	  if (dci_flag && (dci_received == 0)) {
 	    //printf("DCI not received\n");
 	    dci_errors[round]++;
-	    UE->dlsch_errors[0] = 1;
 
 	    /*
 	    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);
@@ -2538,35 +2598,35 @@ int main(int argc, char **argv)
 	    //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.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	    write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+	      write_output("rxsigF1.m","rxsF1", UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 	    }
 
 	    write_output("dlsch00_r0.m","dl00_r0",
-			 &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+			 &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+			   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
 			   UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
 
 	    //pdsch_vars
 
-	    dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid);
+	    dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
 
 	    write_output("dlsch_e.m","e",eNB->dlsch[0][0]->harq_processes[0]->e,coded_bits_per_codeword,1,4);
 
@@ -2582,15 +2642,15 @@ int main(int argc, char **argv)
 
 
 
-          if (UE->dlsch_errors[0] == 0) {
+          if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) {
 
-            avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt;
+            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt;
             iter_trials++;
 
             if (n_frames==1)
               printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber);
 
-            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS;
+            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS;
             TB0_active = 0;
 
 
@@ -2598,25 +2658,25 @@ int main(int argc, char **argv)
 	  else {
             errs[round]++;
 
-            avg_iter += UE->dlsch[subframe&0x1][eNB_id][0]->last_iteration_cnt-1;
+            avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt-1;
             iter_trials++;
 
             if (n_frames==1) {
               //if ((n_frames==1) || (SNR>=30)) {
               printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber);
 
-              for (s=0; s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) {
-                if (s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus)
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus;
+              for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) {
+                if (s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus)
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus;
                 else
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus;
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
 
                 Kr_bytes = Kr>>3;
 
                 printf("Decoded_output (Segment %d):\n",s);
 
                 for (i=0; i<Kr_bytes; i++)
-                  printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
+                  printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
               }
 
               sprintf(fname,"rxsig0_r%d.m",round);
@@ -2625,7 +2685,7 @@ int main(int argc, char **argv)
               sprintf(fname,"rxsigF0_r%d.m",round);
               sprintf(vname,"rxs0F_r%d",round);
 
-              write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+              write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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);
@@ -2633,20 +2693,20 @@ int main(int argc, char **argv)
                 write_output(fname,vname, UE->common_vars.rxdata[1],UE->frame_parms.samples_per_tti,1,1);
                 sprintf(fname,"rxsigF1_r%d.m",round);
                 sprintf(vname,"rxs1F_r%d.m",round);
-                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
               }
 
               sprintf(fname,"dlsch00_r%d.m",round);
               sprintf(vname,"dl00_r%d",round);
               write_output(fname,vname,
-                           &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+                           &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                            UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"dlsch01_r%d.m",round);
                 sprintf(vname,"dl01_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -2654,7 +2714,7 @@ int main(int argc, char **argv)
                 sprintf(fname,"dlsch10_r%d.m",round);
                 sprintf(vname,"dl10_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -2662,18 +2722,18 @@ int main(int argc, char **argv)
                 sprintf(fname,"dlsch11_r%d.m",round);
                 sprintf(vname,"dl11_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
               //pdsch_vars
-              dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid);
+              dump_dlsch2(UE,eNB_id,subframe,&coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
 
 
               //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[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+              //write_output("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
 	      //pdcch_vars
 	      write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[0][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[0][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
@@ -2687,7 +2747,7 @@ int main(int argc, char **argv)
             //      printf("round %d errors %d/%d\n",round,errs[round],trials);
 
             round++;
-            //      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++;
+            //      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
           }
 
 	  if (xforms==1) {
@@ -2698,7 +2758,7 @@ int main(int argc, char **argv)
 			 subframe);
 	  }
 
-	  UE->proc.proc_rxtx[subframe&1].frame_rx++;
+	  UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
 	}  //round
 
         //      printf("\n");
@@ -2709,7 +2769,7 @@ int main(int argc, char **argv)
         //len = chbch_stats_read(stats_buffer,NULL,0,4096);
         //printf("%s\n\n",stats_buffer);
 
-        if (UE->proc.proc_rxtx[subframe&1].frame_rx % 10 == 0) {
+        if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].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);
@@ -2728,10 +2788,10 @@ int main(int argc, char **argv)
         double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
 
 
-        double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
         double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
-        double t_rx_dec = (double)UE->dlsch_decoding_stats[subframe&1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx_dec = (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
 
         if (t_tx > t_tx_max)
           t_tx_max = t_tx;
@@ -2862,22 +2922,22 @@ int main(int argc, char **argv)
              errs2[0],
              round_trials[0],
              errs[1],
-             round_trials[0],
+             round_trials[1],
              errs[2],
-             round_trials[0],
+             round_trials[2],
              errs[3],
-             round_trials[0],
+             round_trials[3],
              (double)errs[0]/(round_trials[0]),
-             (double)errs[1]/(round_trials[0]),
-             (double)errs[2]/(round_trials[0]),
-             (double)errs[3]/(round_trials[0]),
+             (double)errs[1]/(round_trials[1]),
+             (double)errs[2]/(round_trials[2]),
+             (double)errs[3]/(round_trials[3]),
              dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3],
              round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3],
              (double)(dci_errors[0]+dci_errors[1]+dci_errors[2]+dci_errors[3])/(round_trials[0]+round_trials[1]+round_trials[2]+round_trials[3]),
              //rate*effective_rate,
              100*effective_rate,
              //rate,
-             //rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
+             //rate*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
              (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
@@ -2917,10 +2977,10 @@ int main(int argc, char **argv)
                eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
 
         printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
-        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                               2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2));
-        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0,
-               UE->phy_proc_rx[subframe&0x1].trials*2/3);
+        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,
+               UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3);
         printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
                rx_q1, rx_q3, n_rx_dropped);
         std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
@@ -2944,17 +3004,17 @@ int main(int argc, char **argv)
         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,
                UE->dlsch_unscrambling_stats.trials);
-        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[subframe&1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                                   2)/UE->dlsch_decoding_stats[subframe&1].trials - pow((double)UE->dlsch_decoding_stats[subframe&1].diff/UE->dlsch_decoding_stats[subframe&1].trials/cpu_freq_GHz/1000,2));
+        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials - pow((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
         printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f)    :%f us (%d trials, max %f)\n",
                eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials,
-               (double)UE->dlsch_decoding_stats[subframe&1].diff/UE->dlsch_decoding_stats[subframe&1].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[subframe&1].trials,
-               (double)UE->dlsch_decoding_stats[subframe&1].max/cpu_freq_GHz/1000.0);
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials,
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].max/cpu_freq_GHz/1000.0);
         printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
         printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
                (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
         printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
-               UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus,
+               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
                (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
         printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
                (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
@@ -3132,12 +3192,12 @@ int main(int argc, char **argv)
                 eNB->dlsch_modulation_stats.trials,
                 eNB->dlsch_scrambling_stats.trials,
                 eNB->dlsch_encoding_stats.trials,
-                UE->phy_proc_rx[subframe&0x1].trials,
+                UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
                 UE->ofdm_demod_stats.trials,
                 UE->dlsch_rx_pdcch_stats.trials,
                 UE->dlsch_llr_stats.trials,
                 UE->dlsch_unscrambling_stats.trials,
-                UE->dlsch_decoding_stats[subframe&1].trials
+                UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
                );
         fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
                 get_time_meas_us(&eNB->phy_proc_tx),
@@ -3145,12 +3205,12 @@ int main(int argc, char **argv)
                 get_time_meas_us(&eNB->dlsch_modulation_stats),
                 get_time_meas_us(&eNB->dlsch_scrambling_stats),
                 get_time_meas_us(&eNB->dlsch_encoding_stats),
-                get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]),
+                get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]),
                 nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
                 get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
                 3*get_time_meas_us(&UE->dlsch_llr_stats),
                 get_time_meas_us(&UE->dlsch_unscrambling_stats),
-                get_time_meas_us(&UE->dlsch_decoding_stats[subframe&1])
+                get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
                );
         //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
         fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped);
@@ -3185,17 +3245,19 @@ int main(int argc, char **argv)
         eNB->dlsch_modulation_stats.trials,
         eNB->dlsch_scrambling_stats.trials,
         eNB->dlsch_encoding_stats.trials,
-        UE->phy_proc_rx[subframe&0x1].trials,
+        UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
         UE->ofdm_demod_stats.trials,
         UE->dlsch_rx_pdcch_stats.trials,
         UE->dlsch_llr_stats.trials,
         UE->dlsch_unscrambling_stats.trials,
-        UE->dlsch_decoding_stats[subframe&1].trials);
+        UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials);
         */
         printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate );
+	test_passed = 1;
         break;
       } else if (test_perf !=0 ) {
         printf("[continue] effective rate : %f  (%2.1f%%,%f)): increase snr \n",rate*effective_rate, 100*effective_rate, rate);
+	test_passed = 0;
       }
 
       if (((double)errs[0]/(round_trials[0]))<(10.0/n_frames))
@@ -3243,11 +3305,13 @@ int main(int argc, char **argv)
     printf("eNB %d\n",i);
     free_eNB_dlsch(eNB->dlsch[0][i]);
     printf("UE %d\n",i);
-    free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]);
+    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
   }
 
-
-  return(0);
+  if (test_perf && !test_passed)
+    return(-1);
+  else 
+    return(0);
 }
 
 
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
index 57742c5e13e4ec8d1f7fe13e0fe069a7ce1238c4..f493336e988aa453a525609ad845d2570476c4fe 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
@@ -56,10 +56,8 @@
 
 extern unsigned int dlsch_tbs25[27][25],TBStable[27][110];
 extern unsigned char offset_mumimo_llr_drange_fix;
-
-extern uint8_t interf_unaw_shift0;
-extern uint8_t interf_unaw_shift1;
-extern uint8_t interf_unaw_shift;
+extern int16_t dlsch_demod_shift;
+extern int16_t cond_num_threshold;
 
 #include "PHY/TOOLS/lte_phy_scope.h"
 
@@ -151,6 +149,8 @@ int main(int argc, char **argv)
   double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel
   double iqim=0.0;
 
+  extern int use_sic_receiver;
+
   uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1, n_tx_phy=1, n_rx=1;
   uint16_t Nid_cell=0;
 
@@ -162,13 +162,19 @@ int main(int argc, char **argv)
   uint16_t tdd_config=3;
   uint16_t n_rnti=0x1234;
   int n_users = 1;
+  int active_tb0_sent[4]={0,0,0,0};
+  int active_tb1_sent[4]={0,0,0,0};
+  int failed_tb0[4]={0,0,0,0};
+  int failed_tb1[4]={0,0,0,0};
 
   int TB=0;
+
   RX_type_t rx_type=rx_standard;
   unsigned char  cur_harq_pid;
   int hold_rank1_precoder=0;
   int tpmi_retr=0;
   bool  is_first_time;
+  int rank_adapt =0;
   int updated_csi = 0;
 
   SCM_t channel_model=Rayleigh1;
@@ -195,6 +201,8 @@ int main(int argc, char **argv)
   char bler_fname[256];
   FILE *time_meas_fd;
   char time_meas_fname[256];
+  FILE *rankadapt_fd;
+  char rankadapt_fname[256];
 
   FILE *input_trch_fd=NULL;
   unsigned char input_trch_file=0;
@@ -251,6 +259,7 @@ int main(int argc, char **argv)
   FD_lte_phy_scope_ue *form_ue = NULL;
   char title[255];
   uint32_t DLSCH_RB_ALLOC = 0x1fff;
+  int log_level = LOG_ERR;
   int numCCE=0;
   int dci_length_bytes=0,dci_length=0;
   int common_flag=0,TPC=0;
@@ -258,6 +267,7 @@ int main(int argc, char **argv)
   double cpu_freq_GHz;
   //time_stats_t ts;//,sts,usts;
   int avg_iter[2],iter_trials[2];
+  int rank_indc[4]={0,0,0,0};
   int rballocset=0;
   int print_perf=0;
   int test_perf=0;
@@ -266,7 +276,8 @@ int main(int argc, char **argv)
 
   double effective_rate=0.0;
 
-  double thr_cw0_tm4 = 0.0;
+  double thr_cw0_tm4 = 0.0, throug_tb0=0.0, throug_tb1=0.0, throug_tb0_acc[4]={0,0,0,0}, throug_tb1_acc[4]={0,0,0,0}, throug_tb0_acc_aver[4]={0,0,0,0}, throug_tb1_acc_aver[4]={0,0,0,0};
+  double throug_tot_acc_aver[4]={0,0,0,0}, throug_tot_acc_aver_all_rounds=0;
   double thr_cw0_tm4_nonconst = 0.0;
   double thr_cw0[4]={0,0,0,0}, thr_cw1[4]={0,0,0,0}, thr_cw0_tot = 0.0, thr_cw1_tot = 0.0;
   unsigned int tbs0_init=0, tbs1_init=0;
@@ -276,6 +287,7 @@ int main(int argc, char **argv)
 
   int TB0_active = 1;
   int TB1_active = 1;
+  int decoded_tb[2]={0,0};
 
   uint32_t perfect_ce = 0;
 
@@ -322,9 +334,6 @@ int main(int argc, char **argv)
   //signal(SIGSEGV, handler);
   //signal(SIGABRT, handler);
 
-  logInit();
-  set_glog(LOG_INFO, LOG_MED);
-
   // default parameters
   n_frames = 1000;
   snr0 = 0;
@@ -332,7 +341,7 @@ int main(int argc, char **argv)
   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:XYv:W:J:K:U")) != -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:Pl:XYWv:V:J:K:UL:")) != -1) {
 
     switch (c) {
     case 'a':
@@ -397,10 +406,6 @@ int main(int argc, char **argv)
       input_trch_file=1;
       break;
 
-    case 'L':
-      llr8_flag=1;
-      break;
-
     case 'l':
       offset_mumimo_llr_drange_fix=atoi(optarg);
       break;
@@ -616,14 +621,14 @@ int main(int argc, char **argv)
       case 'Y':
         perfect_ce=1;
         break;
-      case 'V':
-        interf_unaw_shift0=atoi(optarg);
-        break;
       case 'W':
-        interf_unaw_shift1=atoi(optarg);
+        rank_adapt=1;
+        break;
+      case 'V':
+        cond_num_threshold = atoi(optarg);
         break;
       case 'J':
-        interf_unaw_shift=atoi(optarg);
+        dlsch_demod_shift = atoi(optarg);
         break;
       case 'K':
       tpmi_retr = atoi(optarg);
@@ -631,6 +636,9 @@ int main(int argc, char **argv)
       case 'U':
       updated_csi=1;
       break;
+      case 'L':
+      log_level=atoi(optarg);
+      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,3,5,6) -y TXant -z RXant -I trch_file\n",argv[0]);
@@ -664,6 +672,25 @@ int main(int argc, char **argv)
     }
   }
 
+  if (dlsch_demod_shift==0) {
+    if ((transmission_mode==3 || transmission_mode==4) && (rx_type>rx_standard)) {
+      if (mcs1<17)
+        dlsch_demod_shift=0;
+      else
+       dlsch_demod_shift=-2;
+    }
+  }
+
+
+  logInit();
+  // enable these lines if you need debug info
+  set_comp_log(PHY,LOG_DEBUG,LOG_HIGH,1);
+  set_glog(log_level,LOG_HIGH);
+  // moreover you need to init itti with the following line
+  // however itti will catch all signals, so ctrl-c won't work anymore
+  // alternatively you can disable ITTI completely in CMakeLists.txt
+  //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
+
   if (common_flag == 0) {
     switch (N_RB_DL) {
     case 6:
@@ -700,6 +727,12 @@ int main(int argc, char **argv)
     exit(-1);
   }
 
+   if (transmission_mode==4 && rx_type == rx_SIC_dual_stream )
+    use_sic_receiver = 1;
+  else if (transmission_mode==4 && rx_type < rx_SIC_dual_stream )
+    use_sic_receiver = 0;
+
+
 
   if (xforms==1) {
   fl_initialize (&argc, argv, NULL, 0, 0);
@@ -707,15 +740,20 @@ int main(int argc, char **argv)
   sprintf (title, "LTE PHY SCOPE eNB");
   fl_show_form (form_ue->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
 
-  /*
-  if (rx_type==rx_IC_single_stream) {
-    openair_daq_vars.use_ia_receiver = 1;
-    fl_set_button(form_ue->button_0,1);
-    fl_set_object_label(form_ue->button_0, "IA Receiver ON");
+
+  if (transmission_mode==4 && use_sic_receiver == 1) {
+    use_sic_receiver = 1;
+    fl_set_button(form_ue->button_0, use_sic_receiver);
+    fl_set_object_label(form_ue->button_0, "SIC Receiver ON");
     fl_set_object_color(form_ue->button_0, FL_GREEN, FL_GREEN);
+  }else if (transmission_mode==4 && use_sic_receiver == 0 ){
+    use_sic_receiver = 0;
+    fl_set_button(form_ue->button_0, use_sic_receiver);
+    fl_set_object_label(form_ue->button_0, "SIC Receiver OFF");
+    fl_set_object_color(form_ue->button_0, FL_RED, FL_RED);
   }
 
-  */
+
   }
 
   if (transmission_mode==5) {
@@ -746,9 +784,10 @@ int main(int argc, char **argv)
   printf("n_frames = %d\n",n_frames);
   printf("Transmission mode %d with %dx%d antenna configuration, Extended Prefix %d\n",transmission_mode,n_tx_phy,n_rx,extended_prefix_flag);
   printf("Using receiver type %d\n", rx_type);
-  printf("TM1 shift %d\n", interf_unaw_shift);
-  //printf("Using I_UA rec shift layer 1  %d\n", interf_unaw_shift0);
-  //printf("Using I_UA rec shift layer 2  %d\n", interf_unaw_shift1);
+  printf("dlsch_demod_shift %d\n", dlsch_demod_shift);
+  printf("rank adaptation %d\n", rank_adapt);
+  //printf("Using I_UA rec shift layer 1  %d\n", dlsch_demod_shift0);
+  //printf("Using I_UA rec shift layer 2  %d\n", dlsch_demod_shift1);
   snr1 = snr0+snr_int;
   printf("SNR0 %f, SNR1 %f\n",snr0,snr1);
 
@@ -782,29 +821,53 @@ int main(int argc, char **argv)
     sprintf(bler_fname,"bler_tx%d_rec%d_chan%d_nrx%d_mcs%d_mcsi%d_u%d_imod%d.csv",transmission_mode,rx_type,channel_model,n_rx,mcs1,mcs_i,rx_type,i_mod);
   else if (abstx == 1){
     if (perfect_ce==1)
-      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr);
+      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_pce_sh%d_rpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2,dlsch_demod_shift, tpmi_retr);
     else
-      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,interf_unaw_shift, tpmi_retr);
+      sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_ab_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model, n_frames, n_rx, num_rounds, mcs1, mcs2,dlsch_demod_shift, tpmi_retr);
   }
   else {//abstx=0
     if (perfect_ce==1){
       if (updated_csi==1){
-        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
       else{
-          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_rtpmi%d_n.csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
     }
     else{
       if (updated_csi==1){
-        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+        sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_up_rtpmi%d_n.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
       else{
-          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, interf_unaw_shift, tpmi_retr);
+          sprintf(bler_fname,"bler_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_rtpmi%csv",transmission_mode,rx_type, channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, tpmi_retr);
       }
     }
   }
 
+  if (transmission_mode==3 || transmission_mode==4){
+    if (rank_adapt==1){
+      if (perfect_ce==1)
+        sprintf(rankadapt_fname,"rank_adapt1_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+      else
+        sprintf(rankadapt_fname,"rank_adapt1_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+    } else {
+        if (perfect_ce==1)
+          sprintf(rankadapt_fname,"rank_adapt0_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+        else
+          sprintf(rankadapt_fname,"rank_adapt0_tx%d_r%d_ch%d_%d_nrx%d_rnd%d_mcs%d_mcsi%d_sh%d_connum_%d.csv",transmission_mode,rx_type,channel_model,n_frames, n_rx, num_rounds, mcs1, mcs2, dlsch_demod_shift, cond_num_threshold);
+    }
+
+  rankadapt_fd = fopen(rankadapt_fname,"w");
+    if (rankadapt_fd==NULL) {
+      fprintf(stderr,"Cannot create file %s!\n",rankadapt_fname);
+      exit(-1);
+    }
+    if (rx_type == rx_SIC_dual_stream)
+      fprintf(rankadapt_fd,"SNR; rank_adapt; clsm_counter; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+    else
+      fprintf(rankadapt_fd,"SNR; rank_adapt; clsm_counter; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+  }
+
   bler_fd = fopen(bler_fname,"w");
   if (bler_fd==NULL) {
     fprintf(stderr,"Cannot create file %s!\n",bler_fname);
@@ -812,11 +875,13 @@ int main(int argc, char **argv)
   }
 
   if ((transmission_mode != 3) && (transmission_mode != 4))
-    fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_st1; err0_st2 trials0; err1_st1; err1_st2; trials1; err2_st1; err2_st2; trials2; err3_st1; err3_st2; trials3; throug 0; throug 1; sum throug; dci_err\n");
+    fprintf(bler_fd,"SNR; MCS1; TBS1; rate 0; err0; trials0; err1;trials1; err2;trials2; err3; trials3\n");
   else if (rx_type == rx_SIC_dual_stream)
-    fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+    fprintf(bler_fd,"SNR; rank_adapt; rank; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; sic_att0; sic_suc0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; sic_att1; sic_suc1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; sic_att2; sic_suc2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; sic_att3; sic_suc3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
   else
-    fprintf(bler_fd,"SNR; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+    fprintf(bler_fd,"SNR; rank_adapt; clsm_counter; MCS1; MCS2; TBS1; TBS2; rate 0; rate 1; err0_tb0; err0_tb1; trials_tb0_r0; trials_tb1_r0; deact_tb0_r0; deact_tb1_r0; ret_both0; ret_one0; err1_tb0; err1_tb1; trials_tb0_r1; trials_tb1_r1; deact_tb0_r1; deact_tb1_r1; ret_both1; ret_one1; err2_tb0; err2_tb1; trials_tb0_r2; trials1_tb1_r2; deact_tb0_r2; deact_tb1_r2; ret_both2; ret_one2; err3_tb0; err3_tb1; trials_tb0_r3; trials_tb1_r3; th_tb0_r0; th_tb1_r0; th_sum_r0; th_tb0_r1; th_tb1_r1; th_sum_r1; th_tb0_r2; th_tb1_r2; th_sum_r2; th_tb0_r3; th_tb1_r3; th_sum_r3; tot_th\n");
+
+
 
   if (test_perf != 0) {
 
@@ -845,9 +910,9 @@ int main(int argc, char **argv)
 
     else
       if (perfect_ce==1)
-        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz);
+        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_pce_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, dlsch_demod_shift, n_ch_rlz);
       else
-        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, interf_unaw_shift, n_ch_rlz);
+        sprintf(csv_fname,"dout_tx%d_r%d_ch%d_%d_rnd%d_mcs%d_mcsi%d_sh%d_%d_csi.m",transmission_mode,rx_type, channel_model, n_frames, num_rounds, mcs1, mcs2, dlsch_demod_shift, n_ch_rlz);
 
     csv_fd = fopen(csv_fname,"w");
     fprintf(csv_fd,"data_all%d=[",mcs1);
@@ -868,7 +933,7 @@ int main(int argc, char **argv)
     //    bzero(r_im0[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double));
   }
 
-  UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti;
+  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
   UE->transmission_mode[eNB_id]=transmission_mode;
   if (UE->transmission_mode[eNB_id] !=4)
       UE->measurements.rank[eNB_id]=0;
@@ -943,6 +1008,10 @@ int main(int argc, char **argv)
     exit(-1);
   }
 
+  if ((transmission_mode == 3) && (transmission_mode == 4))
+    for (n=0; n<4; ++n)
+      rank_indc[n]=1;
+
   if ((transmission_mode == 3) || (transmission_mode==4) || (transmission_mode==8))
     Kmimo=2;
   else
@@ -981,15 +1050,15 @@ int main(int argc, char **argv)
   }
 
   for (i=0; i<2; i++) {
-    UE->dlsch[subframe&0x1][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
 
-    if (!UE->dlsch[subframe&0x1][0][i]) {
+    if (!UE->dlsch[UE->current_thread_id[subframe]][0][i]) {
 
       printf("Can't get ue dlsch structures\n");
       exit(-1);
     }
 
-    UE->dlsch[subframe&0x1][0][i]->rnti   = n_rnti;
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]->rnti   = n_rnti;
   }
 
   // structure for SIC at UE
@@ -1128,10 +1197,11 @@ int main(int argc, char **argv)
             }
           }
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
 
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
@@ -1265,11 +1335,12 @@ int main(int argc, char **argv)
             }
           }
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           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,
@@ -1427,10 +1498,11 @@ int main(int argc, char **argv)
           }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
 
@@ -1564,11 +1636,12 @@ int main(int argc, char **argv)
             }
           }
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1758,10 +1831,11 @@ int main(int argc, char **argv)
            }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
 
@@ -1895,11 +1969,12 @@ int main(int argc, char **argv)
             }
           }
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
             printf("Generating dlsch params for user %d\n",k);
@@ -1926,11 +2001,12 @@ int main(int argc, char **argv)
       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;
+        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;
+        dci_alloc[num_dci].search_space = DCI_UE_SPACE;
         printf("Generating dlsch params for user %d\n",k);
         generate_eNB_dlsch_params_from_dci(0,
                                            subframe,
@@ -2048,7 +2124,6 @@ int main(int argc, char **argv)
     }
 
     for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
-
       UE->proc.proc_rxtx[0].frame_rx=0;
       for (i=0; i<4; i++) {
         errs[0][i]=0; //CW_0
@@ -2062,6 +2137,17 @@ int main(int argc, char **argv)
         round_trials[1][i] = 0;  // CW_1
         TB0_deact[i]=0;
         TB1_deact[i]=0;
+        throug_tb0_acc[i] = 0;
+        throug_tb1_acc[i] = 0;
+        throug_tb0_acc_aver[i]=0;
+        throug_tb1_acc_aver[i]=0;
+        throug_tot_acc_aver[i]=0;
+        active_tb0_sent[i]=0;
+        active_tb1_sent[i]=0;
+        failed_tb0[i]=0;
+        failed_tb1[i]=0;
+        throug_tot_acc_aver_all_rounds=0;
+
       }
       dci_errors=0;
 
@@ -2072,6 +2158,9 @@ int main(int argc, char **argv)
       iter_trials[0]=0;
       iter_trials[1]=0;
 
+      uint32_t clsm_counter=0;
+      uint32_t two_tb_flag=0;
+
       reset_meas(&eNB->phy_proc_tx); // total eNB tx
       reset_meas(&eNB->dlsch_scrambling_stats);
       reset_meas(&UE->dlsch_unscrambling_stats);
@@ -2082,7 +2171,7 @@ int main(int argc, char **argv)
       reset_meas(&eNB->dlsch_rate_matching_stats);
       reset_meas(&eNB->dlsch_turbo_encoding_stats);
 
-      reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx
+      reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx
       reset_meas(&UE->ofdm_demod_stats);
       reset_meas(&UE->dlsch_channel_estimation_stats);
       reset_meas(&UE->dlsch_freq_offset_estimation_stats);
@@ -2128,7 +2217,7 @@ int main(int argc, char **argv)
         is_first_time = true;
 #ifdef DEBUG_HARQ
         printf("[DLSIM] TRIAL %d\n", trials);
-        printf("TPMI_retr= %d\n", tpmi_retr);
+        printf("[DLSIM] TPMI_retr= %d\n", tpmi_retr);
 #endif
 
         for (i=0; i<frame_parms->nb_antennas_tx; i++) {
@@ -2137,33 +2226,43 @@ int main(int argc, char **argv)
 
         eNB2UE[0]->first_run = 1;
 
-        ret[0] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1;
-        ret[1] = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1;
+        ret[0] = UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations+1;
+        ret[1] = UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations+1;
 
         resend_cw0_cw1=1;
         resend_cw1=0;
         TB0_active=1;
         TB1_active=1;
 
+
+        if (transmission_mode == 3 || transmission_mode == 4)
+          rank_indc[0]=1;
+
         while (((transmission_mode == 3 || transmission_mode == 4) &&
-               ((round < num_rounds) && ((ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) ||
-               (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) ||
+               ((round < num_rounds) && (((rank_indc[0] == 1) ||((rank_indc[0] == 0) && (rank_adapt==0))) &&
+                ((ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) ||
+               (ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations))||
+                (rank_indc[0] ==0 && rank_adapt==1 && ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations )))) ||
                ((transmission_mode!=4 && transmission_mode != 3) && ((round< num_rounds) &&
-               (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)))) {
+               (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations)))) {
+         // printf("ret[0] =% d UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations = %d\n", ret[0], UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations);
+         // printf("ret[1] =% d UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations = %d\n", ret[1], UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations);
+
 #ifdef DEBUG_HARQ
         printf("\n [DLSIM] On top round is %d\n", round);
 #endif
 
-
           round_trials[0][round]++;
           round_trials[1][round]++;
+          decoded_tb[0]=0;
+          decoded_tb[1]=0;
 
           //printf("Trial %d, round %d , ret[0] %d, ret[1] %d, round_trials %d\n",trials,round, ret[0], ret[1], round_trials[round]);
 
-        /*if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) {
+        /*if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) {
           round_trials[0][round]++;
           round_trials[1][round]++;
-        } else if ((ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations))
+        } else if ((ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) && (ret[0] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations))
           round_trials[1][round]++;*/
 
 
@@ -2212,9 +2311,19 @@ int main(int argc, char **argv)
                   eNB->dlsch[0][1]->harq_processes[0]->rvidx = round&3;
 
               if (round == 0) {   // First round
-                TB0_active = 1;
-                TB1_active = 1;
-
+                if ((rank_indc[0]==1) || (rank_indc[0]==0 && rank_adapt==0)) {
+                  TB0_active = 1;
+                  TB1_active = 1;
+#ifdef DEBUG_HARQ
+                  printf("Simulating HARQ both active \n");
+#endif
+                }else {
+                  TB0_active = 1;
+                  TB1_active = 0;
+#ifdef DEBUG_HARQ
+                  printf("Simulating HARQ only TB0 active \n");
+#endif
+                }
                 if (eNB->frame_parms.frame_type == TDD) {
 
                   switch (transmission_mode) {
@@ -2276,47 +2385,98 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                     case 6:
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_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(DCI2_1_5MHz_2A_TDD_t));
-                      break;
-                    case 25:
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
-                      break;
-                    case 50:
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
-                      break;
-                    case 100:
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
-                      break;
+                    if ((TB0_active == 1) && (TB1_active == 1)) {
+                        switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_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(DCI2_1_5MHz_2A_TDD_t));
+                          break;
+                        case 25:
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                          break;
+                        case 50:
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                          break;
+                        case 100:
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                          break;
+                        }
+                    } else if ((TB0_active == 1) && (TB1_active == 0)) {
+                       switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+                          break;
+                        case 25:
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                          break;
+                        case 50:
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                          break;
+                        case 100:
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                          break;
+                        }
+                        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,
+                                                         UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
+                                                         transmission_mode>=7?transmission_mode:0
+                                                         );
                     }
                     break;
                   case 5:
@@ -2326,8 +2486,7 @@ int main(int argc, char **argv)
                     memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu2_1E[0],sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
                     break;
                   }
-                }
-                else { // FDD
+                } else { // FDD
                   switch (transmission_mode) {
                     case 1:
                     case 2:
@@ -2387,49 +2546,101 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                     case 6:
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_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(DCI2_1_5MHz_2A_FDD_t));
-                      break;
-                    case 25:
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
-                      break;
-                    case 50:
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
-                      break;
-                    case 100:
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                      ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
-                      break;
+                    if ((TB0_active == 1) && (TB1_active == 1)) {
+                      switch (eNB->frame_parms.N_RB_DL) {
+                       case 6:
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_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(DCI2_1_5MHz_2A_FDD_t));
+                        break;
+                      case 25:
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+                        break;
+                      case 50:
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+                        break;
+                      case 100:
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 0;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                        ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 0;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+                        break;
+                      }
+                    } else if ((TB0_active == 1) && (TB1_active == 0)) {
+                       switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
+                          break;
+                        case 25:
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+                          break;
+                        case 50:
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+                          break;
+                        case 100:
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+                          break;
+                        }
                     }
+                    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,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
                     break;
+
                   case 5:
                   case 6:
                     DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
@@ -2557,134 +2768,179 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
-                    switch (eNB->frame_parms.N_RB_DL) {
-                    case 6:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                    if ((rank_indc[0]==1 )|| ((rank_indc[0]==0) && (rank_adapt==0))){
+                      switch (eNB->frame_parms.N_RB_DL) {
+                      case 6:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr; // you have choice
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
                         }
-                      else {  // deactivate TB1
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
-                      }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
-                      break;
-                    case 25:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-#ifdef DEBUG_HARQ
-                        printf("\n[DLSIM] Requesting only TB1 from temp DCI\n");
-#endif
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else {  // deactivate TB1
-#ifdef DEBUG_HARQ
-                        printf("\n[DLSIM] TDD Requesting only TB0 from temp DCI\n");
-#endif
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
-                      }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
-                      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,
-                                                         UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
-                                                         transmission_mode>=7?transmission_mode:0
-                                                         );
-                      break;
-                    case 50:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else {  // deactivate TB1
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
-                      }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
-                      break;
-                    case 100:
-                      if (TB0_active == 1 && TB1_active == 1) {
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else if (TB0_active == 0){  // deactivate TB0
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
-                      }
-                      else {  // deactivate TB1
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
-                        ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                          }
+                        else {  // deactivate TB1
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+                        break;
+                      case 25:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else {  // deactivate TB1
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                        break;
+                      case 50:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else {  // deactivate TB1
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                        break;
+                      case 100:
+                        if (TB0_active == 1 && TB1_active == 1) {
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = mcs1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = mcs2;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else if (TB0_active == 0){  // deactivate TB0
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi2             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
+                        }
+                        else {  // deactivate TB1
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        }
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                        break;
                       }
-                      memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
-                      break;
+                        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,
+                                                           UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
+                                                           transmission_mode>=7?transmission_mode:0
+                                                           );
+                    } else if (rank_indc[0]==0 && rank_adapt==1) {
+                      //in this case only TB0 is active for the retransmissions, deactivatiing TB1
+                        switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0; //no choice, only alamouti
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_TDD_t));
+                        break;
+                        case 25:
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_TDD_t));
+                        break;
+                        case 50:
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_TDD_t));
+                        break;
+                        case 100:
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                           memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_TDD_t));
+                        break;
                     }
+                    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,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
+                  }
                     break;
-
                   case 5:
                   case 6:
                     DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
@@ -2785,6 +3041,7 @@ int main(int argc, char **argv)
                     }
                     break;
                   case 4:
+                  if ((rank_indc[0]==1 )|| ((rank_indc[0]==0) && (rank_adapt==0))){
                     switch (eNB->frame_parms.N_RB_DL) {
                     case 6:
                       if (TB0_active == 1 && TB1_active == 1) {
@@ -2823,9 +3080,6 @@ int main(int argc, char **argv)
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
                       }
                       else if (TB0_active == 0){  // deactivate TB0
-#ifdef DEBUG_HARQ
-                        printf("\n [DLSIM] Requesting only TB1 from temp DCI\n");
-#endif
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs1             = 0;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = 1;
@@ -2833,9 +3087,6 @@ int main(int argc, char **argv)
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = round&3;
                       }
                       else {  // deactivate TB1
-#ifdef DEBUG_HARQ
-                        printf("\n[DLSIM] FDD Requesting only TB0 from temp DCI\n");
-#endif
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = tpmi_retr;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
@@ -2843,20 +3094,6 @@ int main(int argc, char **argv)
                         ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
                       }
                       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
-                      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,
-                                                         UE->dlsch[subframe&0x1][0][1]->pmi_alloc,
-                                                         transmission_mode>=7?transmission_mode:0
-                                                         );
                       break;
                     case 50:
                       if (TB0_active == 1 && TB1_active == 1) {
@@ -2911,9 +3148,72 @@ int main(int argc, char **argv)
                       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
                       break;
                     }
-                    break;
-
-
+                    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,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
+                  } else if (rank_indc[0]==0 && rank_adapt==1) {
+                      //in this case only TB0 is active for the retransmissions, deactivatiing TB1
+                        switch (eNB->frame_parms.N_RB_DL) {
+                        case 6:
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0; //no choice, only alamouti
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_1_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_1_5MHz_2A_FDD_t));
+                        break;
+                        case 25:
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                        memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_5MHz_2A_FDD_t));
+                        break;
+                        case 50:
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_10MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                          memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_10MHz_2A_FDD_t));
+                        break;
+                        case 100:
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->tpmi             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->ndi1             = trials&1;
+                          ((DCI2_20MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[0])->rv1              = round&3;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->mcs2             = 0;
+                          ((DCI2_20MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[0])->rv2              = 1;
+                           memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu_1[0],sizeof(DCI2_20MHz_2A_FDD_t));
+                        break;
+                    }
+                    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,
+                                                       UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc,
+                                                       transmission_mode>=7?transmission_mode:0
+                                                       );
+                  }
+                  break;
                   case 5:
                   case 6:
                     DLSCH_alloc_pdu2_1E[0].ndi             = trials&1;
@@ -2924,8 +3224,7 @@ int main(int argc, char **argv)
                 }
               }
             }
-            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci,
-                                                   num_common_dci,
+            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci + num_common_dci,
                                                    dci_alloc,
                                                    0,
                                                    AMP,
@@ -2985,7 +3284,7 @@ int main(int argc, char **argv)
               // use the PMI from previous trial
                 if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
                   eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
-                  UE->dlsch[subframe&0x1][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                  UE->dlsch[UE->current_thread_id[subframe]][0][0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
                   if (n_users>1)
                     eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555);
                   /*
@@ -2996,44 +3295,47 @@ int main(int argc, char **argv)
                     }
           */
                 }
+#ifdef DEBUG_HARQ
+                printf("[DLSIM] UE->dlsch[UE->current_thread_id[subframe]][0][%d]->pmi_alloc %d \n", TB, UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc);
+#endif
 
                 //if standard case when both TBs are active
                 if (transmission_mode == 4) {
                   if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 2)) && TB0_active == 1 && TB1_active == 1){
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 1\n");
+                      printf ("[DLSIM] I am calling from the eNode B 1\n");
 #endif
 
                     eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 2\n");
+                      printf ("[DLSIM] I am calling from the eNode B 2\n");
 #endif
 
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
                   }
 
                   else if (updated_csi == 0){
 
                     if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 5))){
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 1\n");
+                      printf ("[DLSIM] I am calling from the eNode B 1\n");
 #endif
                       eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,5,eNB->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 2\n");
+                      printf ("[DLSIM] I am calling from the eNode B 2\n");
 #endif
-                      UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
+                      UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
                     }
 
                     else if (hold_rank1_precoder == 0 && ((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 1\n");
+                      printf ("[DLSIM] I am calling from the eNode B 1\n");
 #endif
                       eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc = pmi_convert_rank1_from_rank2(eNB->dlsch[0][TB]->harq_processes[0]->pmi_alloc,6,eNB->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
-                      printf ("[DLSIM] I am calling from the  eNode B 2\n");
+                      printf ("[DLSIM] I am calling from the eNode B 2\n");
 #endif
-                      UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
+                      UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
                     }
                   } else if (updated_csi == 1){
 
@@ -3052,11 +3354,11 @@ int main(int argc, char **argv)
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I quantize from ENodeB 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,5,UE->frame_parms.N_RB_DL);
                   }
                   else if (((((DCI2_5MHz_2A_TDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6) ||(((DCI2_5MHz_2A_FDD_t *)&DLSCH_alloc_pdu_1[k])->tpmi == 6))){
 #ifdef DEBUG_HARQ
@@ -3072,15 +3374,18 @@ int main(int argc, char **argv)
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I quantize from ENodeB 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
 #ifdef DEBUG_HARQ
                       printf ("[DLSIM] I convert pmi to rank1 eNode B 2\n");
 #endif
-                    UE->dlsch[subframe&0x1][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[subframe&0x1][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc = pmi_convert_rank1_from_rank2(UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc,6,UE->frame_parms.N_RB_DL);
                   }
 
                 }
             }
+#ifdef DEBUG_HARQ
+            printf("[DLSIM 2 ] UE->dlsch[UE->current_thread_id[subframe]][0][%d]->pmi_alloc %d \n", TB, UE->dlsch[UE->current_thread_id[subframe]][0][TB]->pmi_alloc);
+#endif
 
                 start_meas(&eNB->dlsch_encoding_stats);
                 if (dlsch_encoding(eNB,
@@ -3165,7 +3470,7 @@ int main(int argc, char **argv)
                           (subframe*2)+2,
                           &eNB->frame_parms);
 
-            if (n_frames==1) {
+            if (n_frames==2) {
               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);
               if (eNB->frame_parms.nb_antennas_tx>1)
                 write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
@@ -3179,7 +3484,7 @@ int main(int argc, char **argv)
             }
             tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
 
-            if (n_frames==1) {
+            if (n_frames==2) {
               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);
               if (eNB->frame_parms.nb_antennas_tx>1)
                 write_output("txsigF1.m","txsF1", &eNB->common_vars.txdataF[eNB_id][1][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],nsymb*eNB->frame_parms.ofdm_symbol_size,1,1);
@@ -3310,13 +3615,23 @@ int main(int argc, char **argv)
         }
 
         //AWGN
-	// tx_lev is the average energy over the whole subframe
-	// but SNR should be better defined wrt the energy in the reference symbols
-	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;
+  // tx_lev is the average energy over the whole subframe
+  // but SNR should be better defined wrt the energy in the reference symbols
+  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;
         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<10*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*i] =
+              (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+            ((short*) UE->common_vars.rxdata[aa])[2*i+1] =
+              (short) (sqrt(sigma2/2)*gaussdouble(0.0,1.0));
+          }
+        }
+
         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]);
@@ -3365,12 +3680,12 @@ int main(int argc, char **argv)
           pilot3 = 9;
         }
 
-        start_meas(&UE->phy_proc_rx[subframe&0x1]);
+        start_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
         // Inner receiver scheduling for 3 slots
           for (Ns=(2*subframe);Ns<((2*subframe)+3);Ns++) {
             for (l=0;l<pilot2;l++) {
               if (n_frames==1)
-          printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
+         // printf("Ns %d, l %d, l2 %d\n",Ns, l, l+(Ns%2)*pilot2);
               /*
           This function implements the OFDM front end processor (FEP).
 
@@ -3401,9 +3716,9 @@ int main(int argc, char **argv)
                     for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
                       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                         for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
                           (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=
                           (int16_t)(eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
                         }
                       }
@@ -3412,21 +3727,21 @@ int main(int argc, char **argv)
               }else {
                 if (transmission_mode==4) {
                   for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP);
-                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][0])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][0])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][1])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][1])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][2])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][2])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][3])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=-(short)(AMP);
+                    ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][3])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0;
                   }
                 } else {
                     for(aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
                       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                         for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
                         }
                        }
                     }
@@ -3435,11 +3750,19 @@ int main(int argc, char **argv)
               }
 
               if ((Ns==((2*subframe))) && (l==0)) {
+                /*ue_rrc_measurements(UE,
+                                    0,
+                                    0);*/
                 lte_ue_measurements(UE,
                                     subframe*UE->frame_parms.samples_per_tti,
                                     1,
                                     0,
+                                    rank_adapt,
                                     subframe);
+
+                if ((transmission_mode == 3) || (transmission_mode == 4))
+                  rank_indc[round] = UE->measurements.rank[0];
+
                 //printf ("Trial %d, Measurements are done \n", trials);
                       /*
                         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",
@@ -3500,7 +3823,7 @@ int main(int argc, char **argv)
 
                   stop_meas(&UE->dlsch_rx_pdcch_stats);
                   // overwrite number of pdcch symbols
-                  UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols;
+                  UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols = num_pdcch_symbols;
 
                   dci_cnt = dci_decoding_procedure(UE,
                                                    dci_alloc_rx,1,
@@ -3525,10 +3848,10 @@ int main(int argc, char **argv)
                     //printf("Generating dlsch parameters for RNTI %x\n",dci_alloc_rx[i].rnti);
 
                      if (round == 0) {
-                        UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx=1;
                       }
                       if ((transmission_mode == 3 || transmission_mode ==4) && (round == 0)) {
-                        UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->first_tx=1;
                       }
 
                     if ((dci_alloc_rx[i].rnti == n_rnti) &&
@@ -3537,40 +3860,42 @@ int main(int argc, char **argv)
                                                            dci_alloc_rx[i].dci_pdu,
                                                            dci_alloc_rx[i].rnti,
                                                            dci_alloc_rx[i].format,
-                                                           UE->dlsch[subframe&0x1][0],
+                                                           UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->dlsch[UE->current_thread_id[subframe]][0],
                                                            &UE->frame_parms,
                                                            UE->pdsch_config_dedicated,
                                                            SI_RNTI,
                                                            0,
                                                            P_RNTI,
                                                            transmission_mode<7?0:transmission_mode,
-                                                           UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0)==0)) {
+                                                           UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0)==0)) {
                       dump_dci(&UE->frame_parms,&dci_alloc_rx[i]);
                       coded_bits_per_codeword[0]= get_G(&eNB->frame_parms,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even,
-                                                      get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl,
-                                                      UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->nb_rb,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->rb_alloc_even,
+                                                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->Nl,
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols,
                                                       0,
                                                       subframe,
                                                       transmission_mode>=7?transmission_mode:0);
                       if (transmission_mode == 3 || transmission_mode == 4) {
                         coded_bits_per_codeword[1]= get_G(&eNB->frame_parms,
-                                                      UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb,
-                                                      UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even,
-                                                      get_Qm(UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
-                                                      UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl,
-                                                      UE->pdcch_vars[subframe&0x1][1]->num_pdcch_symbols,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->nb_rb,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->rb_alloc_even,
+                                                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->Nl,
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][1]->num_pdcch_symbols,
                                                       0,
                                                       subframe,
                                                       transmission_mode>=7?transmission_mode:0);
                       }
                       /*
-                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword);
-                      rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs);
+                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs)][UE->dlsch[UE->current_thread_id[subframe]][0][0]->nb_rb-1]/(coded_bits_per_codeword);
+                      rate*=get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs);
                       */
-                      printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS);
+                      printf("num_pdcch_symbols %d, G %d, TBS %d\n",UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols,coded_bits_per_codeword [0],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->TBS);
 
                       dlsch_active = 1; // what does it indicates???
                     } else {
@@ -3591,12 +3916,24 @@ int main(int argc, char **argv)
                       }
                   }
                   } else { //dci_flag == 0
-                      UE->pdcch_vars[subframe&0x1][0]->crnti = n_rnti;
-                      UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols = num_pdcch_symbols;
+                      UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti = n_rnti;
+                      UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols = num_pdcch_symbols;
                       if (round == 0) {
-                        UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1;
-                        UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx=1;
+                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->first_tx=1;
                       }
+#ifdef DEBUG_HARQ
+                   printf("[DLSIM 3 ] UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc %d \n", UE->dlsch[UE->current_thread_id[subframe]][0][1]->pmi_alloc);
+#endif
+
+                   if (transmission_mode==4 && use_sic_receiver==1){
+                    if (rx_type>rx_IC_single_stream)
+                      rx_type=rx_SIC_dual_stream;
+                  }
+                  else if (transmission_mode==4 && use_sic_receiver==0){
+                    if (rx_type>rx_IC_single_stream)
+                      rx_type=rx_IC_dual_stream;
+                }
 
                       switch (transmission_mode) {
                       case 1:
@@ -3606,33 +3943,37 @@ int main(int argc, char **argv)
                                                           &DLSCH_alloc_pdu_1[0],
                                                           (common_flag==0)? C_RNTI : SI_RNTI,
                                                           (common_flag==0)? format1 : format1A,
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
                         break;
                       case 3:
 
-                        //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                        //printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
 
                         generate_ue_dlsch_params_from_dci(0,
                                                           subframe,
                                                           &DLSCH_alloc_pdu_1[0],
                                                           (common_flag==0)? C_RNTI : SI_RNTI,
                                                           (common_flag==0)? format2A : format1A,
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
-                        //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
+                        //printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
                         break;
                       case 4:
                         generate_ue_dlsch_params_from_dci(0,
@@ -3640,15 +3981,16 @@ int main(int argc, char **argv)
                                                           &DLSCH_alloc_pdu_1[0],
                                                           (common_flag==0)? C_RNTI : SI_RNTI,
                                                           (common_flag==0)? format2 : format1A,//format1A only for a codeblock
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
-
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
                         break;
                       case 5:
                       case 6:
@@ -3657,14 +3999,16 @@ int main(int argc, char **argv)
                                                           &DLSCH_alloc_pdu2_1E[0],
                                                           C_RNTI,
                                                           format1E_2A_M10PRB,
-                                                          UE->dlsch[subframe&0x1][0],
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                          UE->dlsch[UE->current_thread_id[subframe]][0],
                                                           &UE->frame_parms,
                                                           UE->pdsch_config_dedicated,
                                                           SI_RNTI,
                                                           0,
                                                           P_RNTI,
                                                           transmission_mode<7?0:transmission_mode,
-                                                          UE->pdcch_vars[subframe&0x1][0]->crnti_is_temporary? UE->pdcch_vars[subframe&0x1][0]->crnti: 0);
+                                                          UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti_is_temporary? UE->pdcch_vars[UE->current_thread_id[subframe]][0]->crnti: 0);
                         break;
                       }
                       dlsch_active = 1;
@@ -3673,13 +4017,13 @@ int main(int argc, char **argv)
 
               if (dlsch_active == 1) {
                 if (TB0_active==1)
-                  cur_harq_pid =UE->dlsch[subframe&0x1][0][0]->current_harq_pid;
+                  cur_harq_pid =UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid;
                 else
-                  cur_harq_pid =UE->dlsch[subframe&0x1][0][1]->current_harq_pid;
+                  cur_harq_pid =UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid;
 
                 if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix
               /*    if (transmission_mode == 5) {
-                    if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) &&
+                    if ((UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[cur_harq_pid]->dl_power_off==0) &&
                         (openair_daq_vars.use_ia_receiver ==1)) {
                       rx_type = rx_IC_single_stream;
                     } else {
@@ -3690,7 +4034,7 @@ int main(int argc, char **argv)
 
                   start_meas(&UE->dlsch_llr_stats);
 
-                  for (m=UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols; m<pilot2; m++) {
+                  for (m=UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols; m<pilot2; m++) {
                     if (rx_pdsch(UE,
                                  PDSCH,
                                  eNB_id,
@@ -3698,10 +4042,10 @@ int main(int argc, char **argv)
                                  0,
                                  subframe,
                                  m,
-                                 (m==UE->pdcch_vars[subframe&0x1][0]->num_pdcch_symbols)?1:0,
+                                 (m==UE->pdcch_vars[UE->current_thread_id[subframe]][0]->num_pdcch_symbols)?1:0,
                                  rx_type,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1){
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1){
                       dlsch_active = 0;
                       break;
                     }
@@ -3760,7 +4104,7 @@ int main(int argc, char **argv)
             if (trials==0 && round==0 && transmission_mode>=4){
               for (iii=0; iii<NB_RB; iii++){
                 //fprintf(csv_fd, "%d, %d", (UE->pdsch_vars[eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id_i]->pmi_ext[iii]));
-                fprintf(csv_fd,"%x,",(UE->pdsch_vars[subframe&0x1][eNB_id]->pmi_ext[iii]));
+                fprintf(csv_fd,"%x,",(UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->pmi_ext[iii]));
                 //printf("%x ",(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
               }
             }
@@ -3775,20 +4119,19 @@ int main(int argc, char **argv)
               printf("[DLSIM] Skip TB0 \n");
 #endif
               TB++;
-
             }
 #ifdef DEBUG_HARQ
-            printf("[DLSIM] process TB %d \n", TB);
+            printf("[DLSIM] process TB %d Kmimo %d \n", TB, Kmimo);
 #endif
 
             if (TB==1 && TB1_active == 0){
 #ifdef DEBUG_HARQ
-              printf("[DLSIM] Skip TB1 \n");
+              printf("[DLSIM] Skip TB1 round %d\n", round);
 #endif
               break;
             }
 
-            UE->dlsch[subframe&0x1][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+            UE->dlsch[UE->current_thread_id[subframe]][0][TB]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
             coded_bits_per_codeword[TB] = get_G(&eNB->frame_parms,
                                             eNB->dlsch[0][TB]->harq_processes[0]->nb_rb,
                                             eNB->dlsch[0][TB]->harq_processes[0]->rb_alloc,
@@ -3798,12 +4141,12 @@ int main(int argc, char **argv)
                                             0,subframe,
                                             transmission_mode>=7?transmission_mode:0);
 
-            UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB];
-            UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs);
+            UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->G = coded_bits_per_codeword[TB];
+            UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs);
 
             if (n_frames==2) {
               printf("Kmimo=%d, TB=%d, G=%d, TBS=%d\n",Kmimo,TB,coded_bits_per_codeword[TB],
-                     UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->TBS);
+                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->TBS);
 
               // calculate uncoded BER
               uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[TB]);
@@ -3812,7 +4155,7 @@ int main(int argc, char **argv)
 
               sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round, TB);
               sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, TB);
-              write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0);
+              write_output(fname,vname, UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->codeword],coded_bits_per_codeword[TB],1,0);
               sprintf(fname,"dlsch_cw%d_e.m", TB);
               sprintf(vname,"dlschcw%d_e", TB);
               write_output(fname, vname,eNB->dlsch[0][TB]->harq_processes[0]->e,coded_bits_per_codeword[TB],1,4);
@@ -3820,7 +4163,7 @@ int main(int argc, char **argv)
               printf("trials=%d\n", trials);
 
               for (i=0;i<coded_bits_per_codeword[TB];i++)
-                if (eNB->dlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword][i]<0)) {
+                if (eNB->dlsch[0][TB]->harq_processes[0]->e[i] != (UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->codeword][i]<0)) {
                   uncoded_ber_bit[i] = 1;
                   uncoded_ber++;
                 }
@@ -3842,34 +4185,39 @@ int main(int argc, char **argv)
             start_meas(&UE->dlsch_unscrambling_stats);
             dlsch_unscrambling(&UE->frame_parms,
                                0,
-                               UE->dlsch[subframe&0x1][0][TB],
+                               UE->dlsch[UE->current_thread_id[subframe]][0][TB],
                                coded_bits_per_codeword[TB],
-                               UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],
+                               UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[TB],
                                TB,
                                subframe<<1);
             stop_meas(&UE->dlsch_unscrambling_stats);
 
-            start_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+            start_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
+#ifdef DEBUG_HARQ
+            //printf("non-SIC decoding TB %d LLR is %d\n", TB, UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid]->codeword);
+#endif
             ret[TB] = dlsch_decoding(UE,
-                                     UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid]->codeword],
+                                     UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[TB],
                                      &UE->frame_parms,
-                                     UE->dlsch[subframe&0x1][0][TB],
-                                     UE->dlsch[subframe&0x1][0][TB]->harq_processes[UE->dlsch[subframe&0x1][0][TB]->current_harq_pid],
+                                     UE->dlsch[UE->current_thread_id[subframe]][0][TB],
+                                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid],
                                      0,
-                                    subframe,
-                                    UE->dlsch[subframe&0x1][0][TB]->current_harq_pid,
-                                    1,llr8_flag);
-            stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+                                     subframe,
+                                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->current_harq_pid,
+                                     1,
+                                     llr8_flag);
+            stop_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
 #ifdef DEBUG_HARQ
             printf("[DLSIM] ret[%d] = %d\n", TB, ret[TB]);
 #endif
 
             //printf("retr cw 0 = %d\n", ret[0]);
-            //printf("current round = %d\n", UE->dlsch[subframe&0x1][0][cw_non_sic]->harq_processes[UE->dlsch[subframe&0x1][0][cw_non_sic]->current_harq_pid]->round);
+            //printf("current round = %d\n", UE->dlsch[UE->current_thread_id[subframe]][0][cw_non_sic]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][cw_non_sic]->current_harq_pid]->round);
 
 
 
-            if (ret[TB] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1
+            if (ret[TB] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations ) { //if CW0 is decoded, approach CW1
+              decoded_tb[TB]=1;
 #ifdef DEBUG_HARQ
             printf("[DLSIM] TB%d is decoded\n", TB);
 #endif
@@ -3877,36 +4225,36 @@ int main(int argc, char **argv)
                 /*avg_iter[TB] += ret[TB];
                 iter_trials[TB]++;*/
 
-              if (n_frames==2) {
+              if (n_frames==1) {
                 printf("cw non sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber);
 #ifdef PRINT_BYTES
-                for (s=0;s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) {
-                  if (s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus)
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus;
+                for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->C;s++) {
+                  if (s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Cminus)
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kminus;
                   else
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus;
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kplus;
 
                   Kr_bytes = Kr>>3;
 
                   printf("Decoded_output (Segment %d):\n",s);
                   for (i=0;i<Kr_bytes;i++)
-                    printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i],
-                           UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
+                    printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i],
+                           UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
                 }
 #endif
               }
 
-              UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][TB]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][TB]->current_harq_pid]->TBS;
+              UE->total_TBS[eNB_id] = UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][TB]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][TB]->current_harq_pid]->TBS;
 
               // If the  receiver is NOT SIC, Here we are done with both CW, now only to calculate BLER
               //If the receiver IS SIC, we are done only with CW0, CW1 was only compensated by this moment (y1' obtained)
-              if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
+              if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
               /*
-              //for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) {
+              //for (round = 0 ; round < UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round ; round++) {
               // we assume here that the second stream has a lower MCS and is thus more likely to be decoded
               // re-encoding of second stream
-              dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
-              dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
+              dlsch0_ue_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
+              dlsch0_eNB_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
 
               dlsch0_eNB_harq->mimo_mode    = LARGE_CDD;
               dlsch0_eNB_harq->rb_alloc[0]  = dlsch0_ue_harq->rb_alloc[0];
@@ -3920,14 +4268,14 @@ int main(int argc, char **argv)
               dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
               dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
 
-              UE->dlsch[subframe&0x1][eNB_id]->active       = UE->dlsch[subframe&0x1][eNB_id][0]->active;
-              UE->dlsch[subframe&0x1][eNB_id]->rnti         = UE->dlsch[subframe&0x1][eNB_id][0]->rnti;
-              UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid         = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->active       = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->active;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->rnti         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->rnti;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
 
-              dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b,
+              dlsch_encoding(UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->b,
                  &UE->frame_parms,
                  num_pdcch_symbols,
-                 UE->dlsch[subframe&0x1][eNB_id],
+                 UE->dlsch[UE->current_thread_id[subframe]][eNB_id],
                  0,subframe,
                  &UE->dlsch_rate_matching_stats,
                  &UE->dlsch_turbo_encoding_stats,
@@ -3935,10 +4283,10 @@ int main(int argc, char **argv)
                  );
 
               coded_bits_per_codeword = get_G(&UE->frame_parms,
-                      UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->nb_rb,
-                      UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->rb_alloc,
-                      get_Qm(UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->mcs),
-                      UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id]->current_harq_pid]->Nl,
+                      UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->nb_rb,
+                      UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->rb_alloc,
+                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->mcs),
+                      UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->current_harq_pid]->Nl,
                       num_pdcch_symbols,
                       0,subframe);
 
@@ -3946,7 +4294,7 @@ int main(int argc, char **argv)
               //scrambling
               dlsch_scrambling(&UE->frame_parms,
                    0,
-                   UE->dlsch[subframe&0x1][eNB_id],
+                   UE->dlsch[UE->current_thread_id[subframe]][eNB_id],
                    coded_bits_per_codeword,
                    0,
                    subframe<<1);
@@ -3958,7 +4306,7 @@ int main(int argc, char **argv)
                       subframe,
                       &UE->frame_parms,
                       num_pdcch_symbols,
-                      &UE->dlsch[subframe&0x1][0][0],
+                      &UE->dlsch[UE->current_thread_id[subframe]][0][0],
                       NULL);
               // sic_buffer is a vector of size nb_antennas_tx, but both contain the same signal, since we do modulation without precoding
               // precoding is contained in effective channel estimate
@@ -3998,17 +4346,15 @@ int main(int argc, char **argv)
               }
 
 
-             if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
-                  (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) &&
+             if ((UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+                  (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) && (TB0_active == 1) &&
                   (rx_type==rx_SIC_dual_stream)) {
 #ifdef DEBUG_HARQ
                 printf("[DLSIM] Starting SIC procedure\n");
+                printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round);
+                printf("\n CW 0 is decoded, i go for , round %d\n", round);
+                printf("\n ret[TB0] = %d  round %d\n", ret[TB], round);
 #endif
-               // printf("current round = %d\n", PHY_vars_UE->dlsch_ue[eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->round);
-
-
-              //printf("\n CW 0 is decoded, i go for , round %d\n", round);
-              //printf("\n ret[TB0] = %d  round %d\n", ret[TB], round);
                 sic_attempt[round]++;
 
                 for (round_sic = 0 ; round_sic < (round +1); round_sic++) {
@@ -4018,45 +4364,36 @@ int main(int argc, char **argv)
 #endif
                 //printf("I enter round_sic loop \n");
                 //printf("round_sic= %d\n", round_sic);
-                dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
-                dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
+                dlsch0_ue_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
+                dlsch0_eNB_harq = UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
 
-                dlsch0_eNB_harq->mimo_mode    = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode;
+                dlsch0_eNB_harq->mimo_mode    = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode;
                 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->rvidx        = round_sic;//dlsch0_ue_harq->rvidx;
+                //printf("dlsch0_eNB_harq->rvidx = %d \n", dlsch0_eNB_harq->rvidx);
                 dlsch0_eNB_harq->Nl           = dlsch0_ue_harq->Nl;
-                dlsch0_eNB_harq->round        = dlsch0_ue_harq->round;
+                dlsch0_eNB_harq->round        = round_sic; //dlsch0_ue_harq->round;
                 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;
 
-                if (round_sic == 0){
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 0;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=0;
-                }
-                  else if (round_sic == 1){
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 1;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=1;
-                }
-                  else if (round_sic == 2){
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 2;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=2;
-                }
-                  else{
-                  UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][1]->current_harq_pid]->rvidx        = 3;
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->rvidx=3;
-                }
-
-                UE->dlsch_eNB[eNB_id]->active                   = UE->dlsch[subframe&0x1][eNB_id][0]->active;
-                UE->dlsch_eNB[eNB_id]->rnti                     = UE->dlsch[subframe&0x1][eNB_id][0]->rnti;
-                UE->dlsch_eNB[eNB_id]->current_harq_pid         = UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid;
+                UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->rvidx = round_sic;
+                UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->rvidx=round_sic;
+                UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round = round_sic;
+                UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->round=round_sic;
 
+                UE->dlsch_eNB[eNB_id]->active                   = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->active;
+                UE->dlsch_eNB[eNB_id]->rnti                     = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->rnti;
+                UE->dlsch_eNB[eNB_id]->current_harq_pid         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid;
+#ifdef DEBUG_HARQ
+                printf("UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round = %d\n", UE->dlsch_eNB[eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round);
+#endif
                 dlsch_encoding_SIC(UE,
-                               input_buffer0[0], //UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,,
+                               input_buffer0[0], //UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[PHY_vars_UE->dlsch_ue[eNB_id][0]->current_harq_pid]->b,,
                                num_pdcch_symbols,
-                               UE->dlsch_eNB[eNB_id],
+                               &UE->dlsch_eNB[0][0],
                                0,
                                subframe,
                                &UE->dlsch_rate_matching_stats,
@@ -4076,7 +4413,7 @@ int main(int argc, char **argv)
 
                 dlsch_scrambling(&UE->frame_parms,
                                  0,
-                                 UE->dlsch_eNB[eNB_id],
+                                 &UE->dlsch_eNB[0][0],
                                  coded_bits_per_codeword[0],
                                  0,
                                  subframe<<1);
@@ -4089,8 +4426,8 @@ int main(int argc, char **argv)
                                                     coded_bits_per_codeword[0]);
 
                // write_output("sic_buffer.m","sic", *sic_buffer,re_allocated,1,1);
-               // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1);
-               // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round],14*12*25,1,1);
+               // write_output("rxdataF_comp1.m","rxF_comp1", *UE->pdsch_vars[eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid][round],14*12*25,1,1);
+               // write_output("rxdataF_rho.m","rho", *UE->pdsch_vars[eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid][round],14*12*25,1,1);
 
 
                 switch  (get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)){
@@ -4100,58 +4437,55 @@ int main(int argc, char **argv)
                   case 2:
 
                     dlsch_qpsk_llr_SIC(&UE->frame_parms,
-                                       UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                       UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                        sic_buffer,
-                                       UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
-                                       UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                       UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                       UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                        num_pdcch_symbols,
                                        dlsch0_eNB_harq->nb_rb,
                                        subframe,
-                                       dlsch0_eNB_harq->rb_alloc[0],
                                        get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
-                                       UE->dlsch[subframe&0x1][eNB_id][0]);
+                                       dlsch0_eNB_harq->rb_alloc[0]);
                   break;
 
                   case 4:
 
                     dlsch_16qam_llr_SIC(&UE->frame_parms,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         sic_buffer,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                         num_pdcch_symbols,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         dlsch0_eNB_harq->nb_rb,
                                         subframe,
-                                        dlsch0_eNB_harq->rb_alloc[0],
-                                        get_Qm(eNB->dlsch[0][TB]->harq_processes[0]->mcs),
-                                        UE->dlsch[subframe&0x1][eNB_id][0]);
+                                        get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
+                                        dlsch0_eNB_harq->rb_alloc[0]);
                   break;
                   case 6:
                     dlsch_64qam_llr_SIC(&UE->frame_parms,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->rxdataF_comp1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         sic_buffer,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_rho_ext[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_rho_ext[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                         num_pdcch_symbols,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_mag1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->dl_ch_magb1[UE->dlsch[subframe&0x1][0][0]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_mag1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->dl_ch_magb1[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid][round_sic],
                                         dlsch0_eNB_harq->nb_rb,
                                         subframe,
-                                        dlsch0_eNB_harq->rb_alloc[0],
                                         get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs),
-                                        UE->dlsch[subframe&0x1][eNB_id][TB]);
+                                        dlsch0_eNB_harq->rb_alloc[0]);
                   break;
                     }
                   //}// rouns sic
 #ifdef DEBUG_HARQ
-                  printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword);
+                  printf("[DLSIM] TB1 is mapped into CW%d\n", UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->codeword);
 #endif
 
                     //  write_output("rxdata_llr1.m","llr1", UE->pdsch_vars[eNB_id]->llr[1],re_allocated*2,1,0);
 
                   // replace cw_sic with TB+1
-                  UE->dlsch[subframe&0x1][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+                  UE->dlsch[UE->current_thread_id[subframe]][0][1]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
                   coded_bits_per_codeword[1]= get_G(&eNB->frame_parms,
                                                     eNB->dlsch[0][1]->harq_processes[0]->nb_rb,
                                                     eNB->dlsch[0][1]->harq_processes[0]->rb_alloc,
@@ -4162,26 +4496,26 @@ int main(int argc, char **argv)
                                                     subframe,
                                                     transmission_mode>=7?transmission_mode:0);
 
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1];
-                  UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs);
+                  UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->G = coded_bits_per_codeword[1];
+                  UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->Qm = get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs);
 
-                  if (n_frames==2) {
+                  if (n_frames==1) {
                     printf("Kmimo=%d, cw=%d, G=%d, TBS=%d\n",Kmimo,1,coded_bits_per_codeword[1],
-                    UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->TBS);
+                    UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->TBS);
 
                   // calculate uncoded BER
                     uncoded_ber_bit = (short*) malloc(sizeof(short)*coded_bits_per_codeword[1]);
                     AssertFatal(uncoded_ber_bit, "uncoded_ber_bit==NULL");
                     sprintf(fname,"dlsch%d_rxF_r%d_cw%d_llr.m",eNB_id,round,1);
                     sprintf(vname,"dl%d_r%d_cw%d_llr",eNB_id,round, 1);
-                    write_output(fname,vname, UE->pdsch_vars[subframe&0x1][0]->llr[1],coded_bits_per_codeword[1],1,0);
+                    write_output(fname,vname, UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[1],coded_bits_per_codeword[1],1,0);
                     sprintf(fname,"dlsch_cw%d_e.m", 1);
                     sprintf(vname,"dlschcw%d_e", 1);
                     write_output(fname, vname,eNB->dlsch[0][1]->harq_processes[0]->e,coded_bits_per_codeword[1],1,4);
                     uncoded_ber=0;
                     printf("trials=%d\n", trials);
                     for (i=0;i<coded_bits_per_codeword[1];i++)
-                    if (eNB->dlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword][i]<0)) {
+                    if (eNB->dlsch[0][1]->harq_processes[0]->e[i] != (UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->codeword][i]<0)) {
                       uncoded_ber_bit[i] = 1;
                       uncoded_ber++;
                     }
@@ -4201,25 +4535,25 @@ int main(int argc, char **argv)
                 start_meas(&UE->dlsch_unscrambling_stats);
                 dlsch_unscrambling(&UE->frame_parms,
                                    0,
-                                   UE->dlsch[subframe&0x1][0][1],
+                                   UE->dlsch[UE->current_thread_id[subframe]][0][1],
                                    coded_bits_per_codeword[1],
-                                   UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                   UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                    1,
                                    subframe<<1);
                 stop_meas(&UE->dlsch_unscrambling_stats);
 
-                start_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+                start_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
 
                 ret[1] = dlsch_decoding(UE,
-                                        UE->pdsch_vars[subframe&0x1][eNB_id]->llr[UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid]->codeword],
+                                        UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[1],
                                         &UE->frame_parms,
-                                        UE->dlsch[subframe&0x1][0][1],
-                                        UE->dlsch[subframe&0x1][0][1]->harq_processes[UE->dlsch[subframe&0x1][0][1]->current_harq_pid],
+                                        UE->dlsch[UE->current_thread_id[subframe]][0][1],
+                                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid],
                                         0,
                                         subframe,
-                                        UE->dlsch[subframe&0x1][0][1]->current_harq_pid,
+                                        UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid,
                                         1,llr8_flag);
-                stop_meas(&UE->dlsch_decoding_stats[subframe&0x1]);
+                stop_meas(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]);
 
 #ifdef DEBUG_HARQ
                 printf("[DLSIM] Decoding TB1 in SIC: ret[1] = %d,  round sic %d\n", ret[1], round_sic);
@@ -4227,7 +4561,8 @@ int main(int argc, char **argv)
 
                 //printf("ret TB 1 = %d round %d \n", ret[1], round);
 
-                if (ret[1] <=UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ) {
+                if (ret[1] <=UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations ) {
+                  decoded_tb[1]=1;
                   decoded_in_sic[round]++;
                   round_sic = round+1; // to exit round_sic
 #ifdef DEBUG_HARQ
@@ -4237,23 +4572,23 @@ int main(int argc, char **argv)
                   iter_trials[1]++;
 
 
-                  if (n_frames==2) {
+                  if (n_frames==1) {
                     printf("cw sic %d, round %d: No DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber);
 
                     #ifdef PRINT_BYTES
-                    for (s=0;s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) {
-                    if (s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus)
-                      Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus;
+                    for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->C;s++) {
+                    if (s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Cminus)
+                      Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kminus;
                     else
-                      Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus;
+                      Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kplus;
 
                     Kr_bytes = Kr>>3;
 
                     printf("Decoded_output (Segment %d):\n",s);
 
                     for (i=0;i<Kr_bytes;i++)
-                      printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i],
-                      UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
+                      printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i],
+                      UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
                     }
                     #endif
                   }
@@ -4261,7 +4596,8 @@ int main(int argc, char **argv)
               } //round_sic
 
 
-            if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations ){
+            if (ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations ){
+              decoded_tb[1]=0;
               errs[1][round]++;
 #ifdef DEBUG_HARQ
                   printf("[DLSIM] TB1 is not decoded in SIC loop, errs[TB1][round %d] = %d\n",round, errs[1][round]);
@@ -4272,30 +4608,34 @@ int main(int argc, char **argv)
                   avg_iter[1] += ret[1]-1;
                   iter_trials[1]++;
 
-                  if (n_frames==2) {
+                  if (n_frames==1) {
                     //if ((n_frames==1) || (SNR>=30)) {
                     printf("cw sic %d, round %d: DLSCH errors found, uncoded ber %f\n",1,round,uncoded_ber);
 #ifdef PRINT_BYTES
-                    for (s=0;s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->C;s++) {
-                      if (s<UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Cminus)
-                        Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kminus;
+                    for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->C;s++) {
+                      if (s<UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Cminus)
+                        Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kminus;
                       else
-                        Kr = UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->Kplus;
+                        Kr = UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->Kplus;
 
                       Kr_bytes = Kr>>3;
 
                       printf("Decoded_output (Segment %d):\n",s);
                       for (i=0;i<Kr_bytes;i++)
-                        printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i],
-                         UE->dlsch[subframe&0x1][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
+                        printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i],
+                         UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[0]->c[s][i]^eNB->dlsch[0][1]->harq_processes[0]->c[s][i]);
                     }
 #endif
                   } //n_frames==1
                  // exit(0);
-              } //if (ret > UE->dlsch[subframe&0x1][0][1]->max_turbo_iterations )
+              } //if (ret > UE->dlsch[UE->current_thread_id[subframe]][0][1]->max_turbo_iterations )
             }//if SIC
           } else {
 
+            if (TB0_active && TB1_active)
+              UE->dlsch[UE->current_thread_id[subframe]][0][1]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][1]->current_harq_pid]->round++;
+
+            decoded_tb[TB]=0;
             errs[TB][round]++;
 #ifdef DEBUG_HARQ
             printf("[DLSIM] TB%d is not decoded outside SIC loop, errs[TB%d][round %d] = %d\n", TB, TB, round, errs[TB][round]);
@@ -4307,8 +4647,8 @@ int main(int argc, char **argv)
           iter_trials[0]++;
               }*/
 
-            if ((UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
-              (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) &&
+            if ((UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode >=DUALSTREAM_UNIFORM_PRECODING1) &&
+              (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode <=DUALSTREAM_PUSCH_PRECODING) &&
                 (rx_type==rx_SIC_dual_stream) && (TB0_active ==1)) {
                 errs[1][round]++;
 #ifdef DEBUG_HARQ
@@ -4323,22 +4663,22 @@ int main(int argc, char **argv)
               }*/
 
 
-              if (n_frames==2) {
+              if (n_frames==1) {
           //if ((n_frames==1) || (SNR>=30)) {
                 printf("cw %d, round %d: DLSCH errors found, uncoded ber %f\n",TB,round,uncoded_ber);
 #ifdef PRINT_BYTES
-                for (s=0;s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->C;s++) {
-                  if (s<UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Cminus)
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kminus;
+                for (s=0;s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->C;s++) {
+                  if (s<UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Cminus)
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kminus;
                   else
-                    Kr = UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->Kplus;
+                    Kr = UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->Kplus;
 
                   Kr_bytes = Kr>>3;
 
                   printf("Decoded_output (Segment %d):\n",s);
                   for (i=0;i<Kr_bytes;i++)
-                    printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i],
-                     UE->dlsch[subframe&0x1][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
+                    printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i],
+                     UE->dlsch[UE->current_thread_id[subframe]][0][TB]->harq_processes[0]->c[s][i]^eNB->dlsch[0][TB]->harq_processes[0]->c[s][i]);
                 }
 #endif
               }
@@ -4347,9 +4687,9 @@ int main(int argc, char **argv)
             TB++; // to terminate the loop over TB
           }
 
-          stop_meas(&UE->phy_proc_rx[subframe&0x1]);
+          stop_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
 
-          if (n_frames==1) {
+          if (n_frames==4) {
 
             //rxsig
             sprintf(fname,"rxsig0_r%d.m",round);
@@ -4357,14 +4697,14 @@ int main(int argc, char **argv)
             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.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+            write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
             if (UE->frame_parms.nb_antennas_rx>1) {
               sprintf(fname,"rxsig1_r%d.m",round);
               sprintf(vname,"rxs1_r%d",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(vname,"rxs1F_r%d",round);
-              write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+              write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
             }
 
             //channel
@@ -4386,44 +4726,44 @@ int main(int argc, char **argv)
             sprintf(fname,"dlsch00_r%d.m",round);
             sprintf(vname,"dl00_r%d",round);
             write_output(fname,vname,
-              &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+              &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
              UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
             if (UE->frame_parms.nb_antennas_rx>1) {
               sprintf(fname,"dlsch01_r%d.m",round);
               sprintf(vname,"dl01_r%d",round);
               write_output(fname,vname,
-               &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+               &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
             }
             if (eNB->frame_parms.nb_antennas_tx>1) {
               sprintf(fname,"dlsch10_r%d.m",round);
               sprintf(vname,"dl10_r%d",round);
               write_output(fname,vname,
-               &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+               &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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)) {
               sprintf(fname,"dlsch11_r%d.m",round);
               sprintf(vname,"dl11_r%d",round);
               write_output(fname,vname,
-               &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+               &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
             }
             //pdsch_vars
-            dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[subframe&0x1][0][0]->current_harq_pid);
+            dump_dlsch2(UE,eNB_id,subframe,coded_bits_per_codeword,round, UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid);
             /*
               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_eNB_w.m","w",eNB->dlsch[0][0]->harq_processes[0]->w[0],3*(tbs+64),1,4);
-              write_output("dlsch_UE_w.m","w",UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+              write_output("dlsch_UE_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
             */
 
             //pdcch_vars
-            write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[subframe&0x1][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[subframe&0x1][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
+            write_output("pdcchF0_ext.m","pdcchF_ext", UE->pdcch_vars[UE->current_thread_id[subframe]][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[UE->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],300*3,1,1);
 
-            write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[subframe&0x1][eNB_id]->rxdataF_comp[0],4*300,1,1);
-            write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[subframe&0x1][eNB_id]->llr,2400,1,4);
+            write_output("pdcch_rxF_comp0.m","pdcch0_rxF_comp0",UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id]->rxdataF_comp[0],4*300,1,1);
+            write_output("pdcch_rxF_llr.m","pdcch_llr",UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id]->llr,2400,1,4);
 
             if (round == 3) exit(-1);
           }
@@ -4439,71 +4779,144 @@ int main(int argc, char **argv)
           printf("[DLSIM] Errors errs[TB0][round %d] = %d, errs[TB1][round %d] = %d\n ", round, errs[0][round], round, errs[1][round]);
 #endif
 
-          if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)){
+          if ((transmission_mode != 3) && (transmission_mode !=4) && (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations)){
             //printf("flag 1 \n");
             round++;
           }
 
+         /* if ((rank_indc[0]==0) && (rank_adapt==1))
+            errs[1][0]++;*/
+
 
           if (transmission_mode == 3 || transmission_mode == 4 ) {
-            if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations &&
-               ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
-              resend_both[round]++;
-              round++;
-              resend_cw0_cw1=1;  //resend both cws
-              resend_cw1=0;
-              TB0_active=1;
-              TB1_active=1;
-            }
-            else if (ret[1] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations &&
-                     ret[0] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
-              resend_one[round]++;
-              resend_cw0_cw1=0;
-              TB0_active=0;
-              TB1_active=1;
-              if (rx_type == rx_IC_dual_stream)
-                TB0_deact[round]++;
-              if(is_first_time) {
-                hold_rank1_precoder = 0;
-                is_first_time = false;
+
+              if (TB0_active==1)
+                active_tb0_sent[round]++;
+
+              if (TB1_active==1)
+                active_tb1_sent[round]++;
+
+              if (TB0_active==1 && decoded_tb[0]==0)
+                failed_tb0[round]++;
+
+              if (TB1_active==1 && decoded_tb[1]==0)
+                failed_tb1[round]++;
+
+              if (round==0){
+                if (rank_adapt==1){
+                  if (rank_indc[0]==1)
+                    clsm_counter++;
+                  }
               }
-              else
-                hold_rank1_precoder = 1;
 
+            if (rank_indc[0]==1 || (rank_indc[0]==0 && rank_adapt==0)){
+              if ((TB0_active==1) && (decoded_tb[0]==1)){
+                throug_tb0=rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/(round+1);
 #ifdef DEBUG_HARQ
-            printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
-            printf("[DLSIM] TB0 deactivated\n");
+                printf("rank 2 round %d, TB0 contributes to throughput throug_tb0 %f \n", round, throug_tb0 );
 #endif
-            round++;
-            }
-            else if (ret[0] > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations &&
-                     ret[1] <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations){
-              resend_one[round]++;
-              resend_cw0_cw1=0;
-              TB0_active=1;
-              TB1_active=0;
-              if (rx_type == rx_IC_dual_stream)
-                TB1_deact[round]++;
-              if(is_first_time) {
-                hold_rank1_precoder = 0;
-                is_first_time = false;
+              } else if (((TB0_active==1) && (decoded_tb[0]==0)) || (TB0_active==0)){
+                throug_tb0=0;
+              }
+              throug_tb0_acc[round]+=throug_tb0;
+            } else if ((rank_indc[0]==0) && (rank_adapt==1)){
+                if ((TB0_active==1) && (decoded_tb[0]==1)){
+                  throug_tb0=rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)/(round+1);
+#ifdef DEBUG_HARQ
+                  printf("rank 1 round %d, TB0 contributes to throughput throug_tb0 %f \n", round, throug_tb0 );
+#endif
+                } else if (((TB0_active==1) && (decoded_tb[0]==0)) || (TB0_active==0)){
+                  throug_tb0=0;
+                }
+                throug_tb0_acc[round]+=throug_tb0;
               }
-              else
-                hold_rank1_precoder = 1;
 
+            if (rank_indc[0]==1 || (rank_indc[0]==0 && rank_adapt==0)){
+              if ((TB1_active==1) && (decoded_tb[1]==1)){
+                throug_tb1=rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/(round+1);
 #ifdef DEBUG_HARQ
-            printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
-            printf("[DLSIM] TB1 deactivated\n");
+                printf("rank 2 round %d, TB1 contributes to throughput throug_tb1 %f \n", round, throug_tb1 );
 #endif
-            round++;
+              } else if (((TB1_active==1) && (decoded_tb[1]==0)) || (TB1_active==0)){
+                throug_tb1=0;
+              }
+              throug_tb1_acc[round]+=throug_tb1;
+              }
+
+            if (rank_indc[0] == 1 || (rank_indc[0] == 0 && rank_adapt==0)) {
+              if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations &&
+                 ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
+                resend_both[round]++;
+                round++;
+                resend_cw0_cw1=1;  //resend both cws
+                resend_cw1=0;
+                TB0_active=1;
+                TB1_active=1;
+              }
+              else if (ret[1] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations &&
+                       ret[0] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
+                resend_one[round]++;
+                resend_cw0_cw1=0;
+                TB0_active=0;
+                TB1_active=1;
+                if (rx_type == rx_IC_dual_stream)
+                  TB0_deact[round]++;
+                if(is_first_time) {
+                  hold_rank1_precoder = 0;
+                  is_first_time = false;
+                }
+                else
+                  hold_rank1_precoder = 1;
+
+#ifdef DEBUG_HARQ
+              printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
+              printf("[DLSIM] TB0 deactivated\n");
+#endif
+              round++;
+              }
+              else if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations &&
+                       ret[1] <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
+                resend_one[round]++;
+                resend_cw0_cw1=0;
+                TB0_active=1;
+                TB1_active=0;
+                if (rx_type == rx_IC_dual_stream)
+                  TB1_deact[round]++;
+                if(is_first_time) {
+                  hold_rank1_precoder = 0;
+                  is_first_time = false;
+                }
+                else
+                  hold_rank1_precoder = 1;
+
+  #ifdef DEBUG_HARQ
+              printf("[DLSIM] ret[TB0] =%d, ret[TB1] =%d, trial %d \n", ret[0], ret[1], trials);
+              printf("[DLSIM] TB1 deactivated\n");
+  #endif
+                round++;
+              }
+            } else if (rank_indc[0] == 0 && rank_adapt == 1){
+#ifdef DEBUG_HARQ
+              printf("I am in case rank_indc[0] == 0 && rank_adapt == 1, decoded_tb[0] = %d\n", decoded_tb[0]);
+#endif
+                if (ret[0] > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations){
+                  resend_one[round]++;
+                  round++;
+                  resend_cw0_cw1=0;  //resend both cws
+                  resend_cw1=0;
+                  TB0_active=1;
+                  TB1_active=0;
+                }
             }
+
           }
 
+
 #ifdef DEBUG_HARQ
           printf("[DLSIM] Now round is %d, trial %d\n" , round, trials);
 #endif
-        }
 
+        }
 
         if(transmission_mode != 3 && transmission_mode !=4 ){
           if ((errs[0][0]>=n_frames/10) && (trials>(n_frames/2)) )
@@ -4531,10 +4944,10 @@ int main(int argc, char **argv)
         double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
 
 
-        double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
         double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
-        double t_rx_dec = (double)UE->dlsch_decoding_stats[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx_dec = (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
 
 
               if (t_tx > t_tx_max)
@@ -4561,9 +4974,9 @@ int main(int argc, char **argv)
               push_front(&time_vector_rx_demod, t_rx_demod);
               push_front(&time_vector_rx_dec, t_rx_dec);
 
-
             }   //trials
 
+
 #ifdef DEBUG_HARQ
         printf("\n both failed round 0 = %d, both failed round 1 = %d, both failed round 2 = %d, both failed round 3 = %d\n", resend_both[0], resend_both[1], resend_both[2], resend_both[3]);
         printf(" only one failed round 0  = %d, only one failed round 1  = %d, only one failed round 2  = %d, only one failed round 3  = %d\n", resend_one[0], resend_one[1], resend_one[2], resend_one[3]);
@@ -4680,6 +5093,31 @@ int main(int argc, char **argv)
       */
 
       if (transmission_mode == 3 || transmission_mode == 4) {
+
+          throug_tb0_acc_aver[0]=throug_tb0_acc[0]/(double)round_trials[1][0];//active_tb0_sent[0];
+
+          throug_tb0_acc_aver[1]=throug_tb0_acc[1]/(double)round_trials[1][0];//active_tb0_sent[1];
+
+          throug_tb0_acc_aver[2]=throug_tb0_acc[2]/(double)round_trials[1][0];//active_tb0_sent[2];
+
+          throug_tb0_acc_aver[3]=throug_tb0_acc[3]/(double)round_trials[1][0];//active_tb0_sent[3];
+
+          throug_tb1_acc_aver[0]=throug_tb1_acc[0]/(double)round_trials[1][0];//active_tb1_sent[0];
+
+          throug_tb1_acc_aver[1]=throug_tb1_acc[1]/(double)round_trials[1][0];//active_tb1_sent[1];
+
+          throug_tb1_acc_aver[2]=throug_tb1_acc[2]/(double)round_trials[1][0];//active_tb1_sent[2];
+
+          throug_tb1_acc_aver[3]=throug_tb1_acc[3]/(double)round_trials[1][0];//active_tb1_sent[3];
+
+          throug_tot_acc_aver[0]= throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0];
+          throug_tot_acc_aver[1]= throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1];
+          throug_tot_acc_aver[2]= throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2];
+          throug_tot_acc_aver[3]= throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3];
+          throug_tot_acc_aver_all_rounds= throug_tot_acc_aver[0]+throug_tot_acc_aver[1]+throug_tot_acc_aver[2]+throug_tot_acc_aver[3];
+
+
+
         // FOR CW0
         thr_cw0[0] = rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs)*(1-((double)errs[0][0]/(double)round_trials[0][0]));
         if (num_rounds > 1)
@@ -4698,17 +5136,25 @@ int main(int argc, char **argv)
 #ifdef PRINT_THROUGHPUT
         printf("rate  %f \n", rate0_init);
         printf("rate*mod_order  %f \n", rate0_init*get_Qm(eNB->dlsch[0][0]->harq_processes[0]->mcs));
-        printf("Probability  %f \n", (1-((double)errs[0][0]/(double)round_trials[0][0])));
         printf("Throughput cw0 sum =  %f \n", thr_cw0_tot);
         printf("Throughput cw0 round 0 =  %f \n", thr_cw0[0]);
         printf("Throughput cw0 round 1 =  %f \n", thr_cw0[1]);
         printf("Throughput cw0 round 2 =  %f \n", thr_cw0[2]);
         printf("Throughput cw0 round 3 =  %f \n", thr_cw0[3]);
+        printf("Accumulated throughput  TB0 round 0 =  %f \n", throug_tb0_acc_aver[0]);
+        printf("Accumulated throughput  TB0 round 1 =  %f \n", throug_tb0_acc_aver[1]);
+        printf("Accumulated throughput  TB0 round 2 =  %f \n", throug_tb0_acc_aver[2]);
+        printf("Accumulated throughput  TB0 round 3 =  %f \n", throug_tb0_acc_aver[3]);
+        printf("Accumulated throughput  TB1 round 0 =  %f \n", throug_tb1_acc_aver[0]);
+        printf("Accumulated throughput  TB1 round 1 =  %f \n", throug_tb1_acc_aver[1]);
+        printf("Accumulated throughput  TB1 round 2 =  %f \n", throug_tb1_acc_aver[2]);
+        printf("Accumulated throughput  TB1 round 3 =  %f \n", throug_tb1_acc_aver[3]);
         printf("round_trials =  %d, errs[0][0] = %d, round_trials[0][1] = %d, errs[0][1] = %d, round_trials[0][2] = %d, errs[0][2] = %d, \
         round_trials[0][3] = %d, errs[0][3] = %d \n", round_trials[0][0], errs[0][0],round_trials[0][1], errs[0][1], round_trials[0][2], \
         errs[0][2], round_trials[0][3], errs[0][3]);
 #endif
 
+
         thr_cw1[0] = rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)*(1-((double)errs[1][0]/(double)round_trials[1][0]));
         if (num_rounds > 1)
           thr_cw1[1] = (rate1_init*get_Qm(eNB->dlsch[0][1]->harq_processes[0]->mcs)/2)*(((double)errs[1][0] - (double)errs[1][1])/(double)round_trials[1][0]);
@@ -4796,7 +5242,7 @@ int main(int argc, char **argv)
          rate[0]*effective_rate,
          100*effective_rate,
          rate[0],
-         rate[0]*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
+         rate[0]*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
          (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])+
           4.0*(round_trials[0][3]-errs[0][3]))/((double)round_trials[0][0])/(double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
          (1.0*(round_trials[0][0]-errs[0][0])+2.0*(round_trials[0][1]-errs[0][1])+3.0*(round_trials[0][2]-errs[0][2])
@@ -4806,7 +5252,7 @@ int main(int argc, char **argv)
          thr_cw0_tot + thr_cw1_tot,
          rate[0],
          rate[1]);
-      }else{
+      }else if (((transmission_mode==3) || (transmission_mode==4)) && (rank_adapt==0)){
         printf("Errors (%d(%d)/%d %d(%d)/%d %d(%d)/%d %d(%d)/%d),"
                 "dci_errors %d/%d, thr TB0 = %f , thr TB1 = %f, overall thr = %f , rate 0 = %f , rate 1 = %f \n",
          errs[0][0],
@@ -4828,6 +5274,29 @@ int main(int argc, char **argv)
          thr_cw0_tot + thr_cw1_tot,
          rate0_init,
          rate1_init);
+      } else{
+         printf("Errors: r0 TB0 %d/%d TB1 %d/%d, r1 TB0 %d/%d TB1 %d/%d, r2 TB0 %d/%d TB1 %d/%d, r3 TB0 %d/%d TB1 %d/%d,"
+                "Through tot: TB0 = %f, TB1 = %f, overall thr = %f, clsm applied %d times\n",
+         failed_tb0[0],
+         active_tb0_sent[0],
+         failed_tb1[0],
+         active_tb1_sent[0],
+         failed_tb0[1],
+         active_tb0_sent[1],
+         failed_tb1[1],
+         active_tb1_sent[1],
+         failed_tb0[2],
+         active_tb0_sent[2],
+         failed_tb1[2],
+         active_tb1_sent[2],
+         failed_tb0[3],
+         active_tb0_sent[3],
+         failed_tb1[3],
+         active_tb1_sent[3],
+         throug_tb0_acc_aver[0]+throug_tb0_acc_aver[1]+throug_tb0_acc_aver[2]+throug_tb0_acc_aver[3],
+         throug_tb1_acc_aver[0]+throug_tb1_acc_aver[1]+throug_tb1_acc_aver[2]+throug_tb1_acc_aver[3],
+         throug_tot_acc_aver_all_rounds,
+         clsm_counter);
       }
 
       if (print_perf==1) {
@@ -4864,10 +5333,10 @@ int main(int argc, char **argv)
                eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
 
         printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
-        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                               2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2));
-        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0,
-               UE->phy_proc_rx[subframe&0x1].trials*2/3);
+        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,
+               UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3);
         printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
                rx_q1, rx_q3, n_rx_dropped);
         std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
@@ -4891,17 +5360,17 @@ int main(int argc, char **argv)
         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,
                UE->dlsch_unscrambling_stats.trials);
-        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                                   2)/UE->dlsch_decoding_stats[subframe&0x1].trials - pow((double)UE->dlsch_decoding_stats[subframe&0x1].diff/UE->dlsch_decoding_stats[subframe&0x1].trials/cpu_freq_GHz/1000,2));
+        std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                                   2)/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials - pow((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
         printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f)    :%f us (%d trials, max %f)\n",
                eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter[0]/iter_trials[0],
-               (double)UE->dlsch_decoding_stats[subframe&0x1].diff/UE->dlsch_decoding_stats[subframe&0x1].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[subframe&0x1].trials,
-               (double)UE->dlsch_decoding_stats[subframe&0x1].max/cpu_freq_GHz/1000.0);
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials,
+               (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].max/cpu_freq_GHz/1000.0);
         printf("|__ Statistcs                           std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3);
         printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
                (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
         printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
-               UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus,
+               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
                (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
         printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
                (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
@@ -4934,7 +5403,7 @@ int main(int argc, char **argv)
       }
 
       if ((transmission_mode != 3) && (transmission_mode != 4)) {
-        fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d\n",
+        fprintf(bler_fd,"%f;%d;%d;%f;%d;%d;%d;%d;%d;%d;%d;%d\n",
                 SNR,
                 mcs1,
                 eNB->dlsch[0][0]->harq_processes[0]->TBS,
@@ -4946,112 +5415,225 @@ int main(int argc, char **argv)
                 errs[0][2],
                 round_trials[0][2],
                 errs[0][3],
-                round_trials[0][3],
-                dci_errors);
-      }
-      else if ( rx_type== rx_SIC_dual_stream) {
-        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                round_trials[0][3]);
+      } else if(rx_type== rx_SIC_dual_stream){
+                fprintf(bler_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
                 SNR,
+                rank_adapt,
+                clsm_counter,
                 mcs1,
                 mcs2,
                 tbs0_init,
                 tbs1_init,
                 rate0_init,
                 rate1_init,
-                errs[0][0],
-                errs[1][0],
-                round_trials[0][0],
-                round_trials[1][0],
+                failed_tb0[0],
+                failed_tb1[0],
+                active_tb0_sent[0],
+                active_tb1_sent[0],
                 sic_attempt[0],
                 decoded_in_sic[0],
                 resend_both[0],
                 resend_one[0],
-                errs[0][1],
-                errs[1][1],
-                round_trials[0][1],
-                round_trials[1][1],
+                failed_tb0[1],
+                failed_tb1[1],
+                active_tb0_sent[1],
+                active_tb1_sent[1],
                 sic_attempt[1],
                 decoded_in_sic[1],
                 resend_both[1],
                 resend_one[1],
-                errs[0][2],
-                errs[1][2],
-                round_trials[0][2],
-                round_trials[1][2],
+                failed_tb0[2],
+                failed_tb1[2],
+                active_tb0_sent[2],
+                active_tb1_sent[2],
                 sic_attempt[2],
                 decoded_in_sic[2],
                 resend_both[2],
                 resend_one[2],
-                errs[0][3],
-                errs[1][3],
-                round_trials[0][3],
-                round_trials[1][3],
+                failed_tb0[3],
+                failed_tb1[3],
+                active_tb0_sent[3],
+                active_tb1_sent[3],
                 sic_attempt[3],
                 decoded_in_sic[3],
-                thr_cw0[0],
-                thr_cw1[0],
-                thr_cw0[0]+thr_cw1[0],
-                thr_cw0[1],
-                thr_cw1[1],
-                thr_cw0[1]+thr_cw1[1],
-                thr_cw0[2],
-                thr_cw1[2],
-                thr_cw0[2]+thr_cw1[2],
-                thr_cw0[3],
-                thr_cw1[3],
-                thr_cw0[3]+thr_cw1[3],
-                thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]);
-            }
-      else{
-        fprintf(bler_fd,"%f;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                throug_tb0_acc_aver[0],
+                throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[1],
+                throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[2],
+                throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[3],
+                throug_tb1_acc_aver[3],
+                throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                throug_tot_acc_aver_all_rounds);
+        } else if ((rx_type!= rx_SIC_dual_stream)){
+              fprintf(bler_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                  SNR,
+                  rank_adapt,
+                  clsm_counter,
+                  mcs1,
+                  mcs2,
+                  tbs0_init,
+                  tbs1_init,
+                  rate0_init,
+                  rate1_init,
+                  failed_tb0[0],
+                  failed_tb1[0],
+                  active_tb0_sent[0],
+                  active_tb1_sent[0],
+                  TB0_deact[0],
+                  TB1_deact[0],
+                  resend_both[0],
+                  resend_one[0],
+                  failed_tb0[1],
+                  failed_tb1[1],
+                  active_tb0_sent[1],
+                  active_tb1_sent[1],
+                  TB0_deact[1],
+                  TB1_deact[1],
+                  resend_both[1],
+                  resend_one[1],
+                  failed_tb0[2],
+                  failed_tb1[2],
+                  active_tb0_sent[2],
+                  active_tb1_sent[2],
+                  TB0_deact[2],
+                  TB1_deact[2],
+                  resend_both[2],
+                  resend_one[2],
+                  failed_tb0[3],
+                  failed_tb1[3],
+                  active_tb0_sent[3],
+                  active_tb1_sent[3],
+                  throug_tb0_acc_aver[0],
+                  throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[1],
+                  throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[2],
+                  throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[3],
+                  throug_tb1_acc_aver[3],
+                  throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                  throug_tot_acc_aver_all_rounds);
+
+        }
+
+       if (transmission_mode==3 || transmission_mode==4){
+        if (rx_type== rx_SIC_dual_stream){
+         fprintf(rankadapt_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
                 SNR,
+                rank_adapt,
+                clsm_counter,
                 mcs1,
                 mcs2,
                 tbs0_init,
                 tbs1_init,
                 rate0_init,
                 rate1_init,
-                errs[0][0],
-                errs[1][0],
-                round_trials[0][0],
-                round_trials[1][0],
-                TB0_deact[0],
-                TB1_deact[0],
+                failed_tb0[0],
+                failed_tb1[0],
+                active_tb0_sent[0],
+                active_tb1_sent[0],
+                sic_attempt[0],
+                decoded_in_sic[0],
                 resend_both[0],
                 resend_one[0],
-                errs[0][1],
-                errs[1][1],
-                round_trials[0][1],
-                round_trials[1][1],
-                TB0_deact[1],
-                TB1_deact[1],
+                failed_tb0[1],
+                failed_tb1[1],
+                active_tb0_sent[1],
+                active_tb1_sent[1],
+                sic_attempt[1],
+                decoded_in_sic[1],
                 resend_both[1],
                 resend_one[1],
-                errs[0][2],
-                errs[1][2],
-                round_trials[0][2],
-                round_trials[1][2],
-                TB0_deact[2],
-                TB1_deact[2],
+                failed_tb0[2],
+                failed_tb1[2],
+                active_tb0_sent[2],
+                active_tb1_sent[2],
+                sic_attempt[2],
+                decoded_in_sic[2],
                 resend_both[2],
                 resend_one[2],
-                errs[0][3],
-                errs[1][3],
-                round_trials[0][3],
-                round_trials[1][3],
-                thr_cw0[0],
-                thr_cw1[0],
-                thr_cw0[0]+thr_cw1[0],
-                thr_cw0[1],
-                thr_cw1[1],
-                thr_cw0[1]+thr_cw1[1],
-                thr_cw0[2],
-                thr_cw1[2],
-                thr_cw0[2]+thr_cw1[2],
-                thr_cw0[3],
-                thr_cw1[3],
-                thr_cw0[3]+thr_cw1[3],
-                thr_cw0[0]+thr_cw0[1]+thr_cw0[2]+thr_cw0[3]+thr_cw1[0]+thr_cw1[1]+thr_cw1[2]+ thr_cw1[3]);
+                failed_tb0[3],
+                failed_tb1[3],
+                active_tb0_sent[3],
+                active_tb1_sent[3],
+                sic_attempt[3],
+                decoded_in_sic[3],
+                throug_tb0_acc_aver[0],
+                throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                throug_tb0_acc_aver[1],
+                throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                throug_tb0_acc_aver[2],
+                throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                throug_tb0_acc_aver[3],
+                throug_tb1_acc_aver[3],
+                throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                throug_tot_acc_aver_all_rounds);
+        }
+       else{
+          fprintf(rankadapt_fd,"%f;%d;%d;%d;%d;%d;%d;%f;%f;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f\n",
+                  SNR,
+                  rank_adapt,
+                  clsm_counter,
+                  mcs1,
+                  mcs2,
+                  tbs0_init,
+                  tbs1_init,
+                  rate0_init,
+                  rate1_init,
+                  failed_tb0[0],
+                  failed_tb1[0],
+                  active_tb0_sent[0],
+                  active_tb1_sent[0],
+                  TB0_deact[0],
+                  TB1_deact[0],
+                  resend_both[0],
+                  resend_one[0],
+                  failed_tb0[1],
+                  failed_tb1[1],
+                  active_tb0_sent[1],
+                  active_tb1_sent[1],
+                  TB0_deact[1],
+                  TB1_deact[1],
+                  resend_both[1],
+                  resend_one[1],
+                  failed_tb0[2],
+                  failed_tb1[2],
+                  active_tb0_sent[2],
+                  active_tb1_sent[2],
+                  TB0_deact[2],
+                  TB1_deact[2],
+                  resend_both[2],
+                  resend_one[2],
+                  failed_tb0[3],
+                  failed_tb1[3],
+                  active_tb0_sent[3],
+                  active_tb1_sent[3],
+                  throug_tb0_acc_aver[0],
+                  throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[0]+throug_tb1_acc_aver[0],
+                  throug_tb0_acc_aver[1],
+                  throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[1]+throug_tb1_acc_aver[1],
+                  throug_tb0_acc_aver[2],
+                  throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[2]+throug_tb1_acc_aver[2],
+                  throug_tb0_acc_aver[3],
+                  throug_tb1_acc_aver[3],
+                  throug_tb0_acc_aver[3]+throug_tb1_acc_aver[3],
+                  throug_tot_acc_aver_all_rounds);
+       }
       }
 
 
@@ -5189,12 +5771,12 @@ int main(int argc, char **argv)
     eNB->dlsch_modulation_stats.trials,
     eNB->dlsch_scrambling_stats.trials,
     eNB->dlsch_encoding_stats.trials,
-    UE->phy_proc_rx[subframe&0x1].trials,
+    UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
     UE->ofdm_demod_stats.trials,
     UE->dlsch_rx_pdcch_stats.trials,
     UE->dlsch_llr_stats.trials,
     UE->dlsch_unscrambling_stats.trials,
-    UE->dlsch_decoding_stats[subframe&0x1].trials
+    UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials
     );
   fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;%f;",
     get_time_meas_us(&eNB->phy_proc_tx),
@@ -5202,12 +5784,12 @@ int main(int argc, char **argv)
     get_time_meas_us(&eNB->dlsch_modulation_stats),
     get_time_meas_us(&eNB->dlsch_scrambling_stats),
     get_time_meas_us(&eNB->dlsch_encoding_stats),
-    get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]),
+    get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]),
     nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
     get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
     3*get_time_meas_us(&UE->dlsch_llr_stats),
     get_time_meas_us(&UE->dlsch_unscrambling_stats),
-    get_time_meas_us(&UE->dlsch_decoding_stats[subframe&0x1])
+    get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]])
     );
   //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n");
   fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped);
@@ -5247,7 +5829,7 @@ int main(int argc, char **argv)
     UE->dlsch_rx_pdcch_stats.trials,
     UE->dlsch_llr_stats.trials,
     UE->dlsch_unscrambling_stats.trials,
-    UE->dlsch_decoding_stats[subframe&0x1].trials);
+    UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials);
     */
     printf("[passed] effective rate : %f  (%2.1f%%,%f)): log and break \n",rate[0]*effective_rate, 100*effective_rate, rate[0]);
     break;
@@ -5281,7 +5863,7 @@ int main(int argc, char **argv)
 
   }
 
-      if (n_frames==1)
+      if (n_frames==2)
   break;
 
       }// SNR
@@ -5326,7 +5908,7 @@ int main(int argc, char **argv)
 
     free_eNB_dlsch(eNB->dlsch[0][i]);
     printf("UE %d\n",i);
-    free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]);
+    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
   }
 
 
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
index 3055e99b07272a4d318787f4b6830b772efd88d8..b257b1561b533b104a05fe76d704e66a46b4167c 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -953,14 +953,14 @@ int main(int argc, char **argv)
   }
 
   for (i=0; i<2; i++) {
-    UE->dlsch[subframe&0x1][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]  = new_ue_dlsch(Kmimo,8,Nsoft,MAX_TURBO_ITERATIONS,N_RB_DL,0);
 
-    if (!UE->dlsch[subframe&0x1][0][i]) {
+    if (!UE->dlsch[UE->current_thread_id[subframe]][0][i]) {
       printf("Can't get ue dlsch structures\n");
       exit(-1);
     }
 
-    UE->dlsch[subframe&0x1][0][i]->rnti   = n_rnti;
+    UE->dlsch[UE->current_thread_id[subframe]][0][i]->rnti   = n_rnti;
   }
 
   // structure for SIC at UE
@@ -1112,10 +1112,11 @@ int main(int argc, char **argv)
           }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1255,11 +1256,12 @@ int main(int argc, char **argv)
           }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1424,10 +1426,11 @@ int main(int argc, char **argv)
           }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d / format 2A (%d)\n",k,format2A);
@@ -1564,11 +1567,12 @@ int main(int argc, char **argv)
           }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1734,10 +1738,11 @@ int main(int argc, char **argv)
           }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_UE_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1874,11 +1879,12 @@ int main(int argc, char **argv)
           }
 
           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;
+          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;
+          dci_alloc[num_dci].search_space = DCI_COMMON_SPACE;
           dump_dci(&eNB->frame_parms,&dci_alloc[num_dci]);
 
           printf("Generating dlsch params for user %d\n",k);
@@ -1906,11 +1912,12 @@ int main(int argc, char **argv)
       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;
+        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;
+        dci_alloc[num_dci].search_space = DCI_UE_SPACE;
         printf("Generating dlsch params for user %d\n",k);
         generate_eNB_dlsch_params_from_dci(0,
 					   subframe,
@@ -2039,7 +2046,7 @@ int main(int argc, char **argv)
     }
 
     for (SNR=snr0; SNR<snr1; SNR+=snr_step) {
-      UE->proc.proc_rxtx[subframe&1].frame_rx=0;
+      UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx=0;
       errs[0]=0;
       errs[1]=0;
       errs[2]=0;
@@ -2069,7 +2076,7 @@ int main(int argc, char **argv)
       reset_meas(&eNB->dlsch_rate_matching_stats);
       reset_meas(&eNB->dlsch_turbo_encoding_stats);
 
-      reset_meas(&UE->phy_proc_rx[subframe&0x1]); // total UE rx
+      reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx
       reset_meas(&UE->ofdm_demod_stats);
       reset_meas(&UE->dlsch_channel_estimation_stats);
       reset_meas(&UE->dlsch_freq_offset_estimation_stats);
@@ -2112,9 +2119,9 @@ int main(int argc, char **argv)
         //if (trials%100==0)
         eNB2UE[0]->first_run = 1;
 
-        ret = UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations+1;
+        ret = UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations+1;
 
-        while ((round < num_rounds) && (ret > UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations)) {
+        while ((round < num_rounds) && (ret > UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations)) {
               //printf("Trial %d, round %d\n",trials,round);
           round_trials[round]++;
 
@@ -2556,8 +2563,7 @@ PMI_FEEDBACK:
               }
             }
 	    
-            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci,
-                                                   num_common_dci,
+            num_pdcch_symbols_2 = generate_dci_top(num_ue_spec_dci + num_common_dci,
                                                    dci_alloc,
                                                    0,
                                                    AMP,
@@ -2601,7 +2607,7 @@ PMI_FEEDBACK:
                 // use the PMI from previous trial
                 if (DLSCH_alloc_pdu2_1E[0].tpmi == 5) {
                   eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,eNB->frame_parms.N_RB_DL);
-                  UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
+                  UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->pmi_alloc = quantize_subband_pmi(&UE->measurements,0,UE->frame_parms.N_RB_DL);
 
                   if (n_users>1)
                     eNB->dlsch[1][0]->harq_processes[0]->pmi_alloc = (eNB->dlsch[0][0]->harq_processes[0]->pmi_alloc ^ 0x1555);
@@ -3059,7 +3065,7 @@ PMI_FEEDBACK:
           }
           
 
-          start_meas(&UE->phy_proc_rx[subframe&0x1]);
+          start_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
 
           // Inner receiver scheduling for 3 slots
         
@@ -3096,24 +3102,24 @@ PMI_FEEDBACK:
                     for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
                       for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                         for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
                                 eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
                           //printf("x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[k][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(int16_t)(
                                 eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
 
                           if (transmission_mode == 7){
 			    //this should include the BF weights! Will not work for a random channel
                             if (UE->high_speed_flag==0) {
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
                               //printf("**,x=%d,AMP=%d\n",eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x,AMP);
                             } else  {
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].x*AMP);
-                              ((int16_t *)UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
+                              ((int16_t *)UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(int16_t)(
                                   eNB2UE[round]->chF[aarx+(aa*frame_parms->nb_antennas_rx)][i].y*AMP);
                                 
                             }
@@ -3126,15 +3132,15 @@ PMI_FEEDBACK:
                   for(aa=0; aa<frame_parms->nb_antenna_ports_eNB; aa++) {
                     for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
                       for (i=0; i<frame_parms->N_RB_DL*12; i++) {
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
-                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=(short)(AMP);
+                          ((int16_t *) UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[0][(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size+LTE_CE_FILTER_LENGTH)*2]=0/2;
                         if (transmission_mode == 7) {
                           if (UE->high_speed_flag==0){
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(short)(AMP);
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=0/2;
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i]=(short)(AMP);
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1]=0/2;
                           } else {
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(short)(AMP);
-                            ((int16_t *) UE->pdsch_vars[subframe&0x1][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=0/2;
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=(short)(AMP);
+                            ((int16_t *) UE->pdsch_vars[UE->current_thread_id[subframe]][0]->dl_bf_ch_estimates[(aa<<1)+aarx])[2*i+1+((l+(Ns%2)*pilot2)*frame_parms->ofdm_symbol_size)*2]=0/2;
                           }
                         }
                       }
@@ -3227,7 +3233,7 @@ PMI_FEEDBACK:
 
                   for (i=0; i<dci_cnt; i++) {
                     //        printf("Generating dlsch parameters for RNTI %x\n",dci_alloc_rx[i].rnti);
-                    if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->first_tx=1;
+                    if (round == 0) UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->first_tx=1;
 
                     if ((dci_alloc_rx[i].rnti == n_rnti) &&
                         (generate_ue_dlsch_params_from_dci(0,
@@ -3235,7 +3241,9 @@ PMI_FEEDBACK:
                                                            dci_alloc_rx[i].dci_pdu,
                                                            dci_alloc_rx[i].rnti,
                                                            dci_alloc_rx[i].format,
-                                                           UE->dlsch[subframe&0x1][0],
+                                                           UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                           UE->dlsch[UE->current_thread_id[subframe]][0],
                                                            &UE->frame_parms,
                                                            UE->pdsch_config_dedicated,
                                                            SI_RNTI,
@@ -3244,23 +3252,23 @@ PMI_FEEDBACK:
                                                            transmission_mode<7?0:transmission_mode))) {
                       //dump_dci(&UE->frame_parms,&dci_alloc_rx[i]);
                       coded_bits_per_codeword = get_G(&eNB->frame_parms,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->nb_rb,
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->rb_alloc_even,
-                                                      get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
-                                                      UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->Nl,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->nb_rb,
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->rb_alloc_even,
+                                                      get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->Nl,
                                                       UE->pdcch_vars[0]->num_pdcch_symbols,
                                                       0,
 						      subframe,
 						      (transmission_mode<7?0:transmission_mode));
           	    /*if (transmission_mode==7 && common_flag==0)
-       	    	      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7; */
+       	    	      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7; */
 
                       /*
-                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs)][UE->dlsch[subframe&0x1][0][0]->nb_rb-1]/(coded_bits_per_codeword);
-                      rate*=get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs);
+                      rate = (double)dlsch_tbs25[get_I_TBS(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs)][UE->dlsch[UE->current_thread_id[subframe]][0][0]->nb_rb-1]/(coded_bits_per_codeword);
+                      rate*=get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][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[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->TBS);
+                             UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->TBS);
 
                       dlsch_active = 1;
                     } else {
@@ -3288,7 +3296,7 @@ PMI_FEEDBACK:
                   UE->pdcch_vars[0]->crnti = n_rnti;
                   UE->pdcch_vars[0]->num_pdcch_symbols = num_pdcch_symbols;
 
-                  if (round == 0) UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx=1;
+                  if (round == 0) UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx=1;
 
                   switch (transmission_mode) {
                   case 1:
@@ -3299,7 +3307,9 @@ PMI_FEEDBACK:
                                                       &DLSCH_alloc_pdu_1[0],
                                                       (common_flag==0)? C_RNTI : SI_RNTI,
                                                       (common_flag==0)? format1 : format1A,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
@@ -3307,24 +3317,24 @@ PMI_FEEDBACK:
                                                       P_RNTI,
                                                       transmission_mode<7?0:transmission_mode);
           	    /*if(transmission_mode==7 && common_flag==0)
-       	    	      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->mimo_mode = TM7;*/
+       	    	      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->mimo_mode = TM7;*/
                     break;
 
                   case 3:
-                    //        printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                    //        printf("Rate: TM3 (before) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
                     generate_ue_dlsch_params_from_dci(0,
 						      subframe,
                                                       &DLSCH_alloc_pdu_1[0],
                                                       (common_flag==0)? C_RNTI : SI_RNTI,
                                                       (common_flag==0)? format2A : format1A,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
                                                       0,
                                                       P_RNTI,
                                                       0);
-                    //        printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->first_tx);
+                    //        printf("Rate: TM3 (after) round %d (%d) first_tx %d\n",round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->first_tx);
                     break;
 
                   case 4:
@@ -3333,7 +3343,9 @@ PMI_FEEDBACK:
                                                       &DLSCH_alloc_pdu_1[0],
                                                       (common_flag==0)? C_RNTI : SI_RNTI,
                                                       (common_flag==0)? format2 : format1A,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      UE->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
@@ -3349,7 +3361,9 @@ PMI_FEEDBACK:
                                                       &DLSCH_alloc_pdu2_1E[0],
                                                       C_RNTI,
                                                       format1E_2A_M10PRB,
-                                                      UE->dlsch[subframe&0x1][0],
+                                                      ue->pdcch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      ue->pdsch_vars[UE->current_thread_id[subframe]][eNB_id],
+                                                      UE->dlsch[UE->current_thread_id[subframe]][0],
                                                       &UE->frame_parms,
                                                       UE->pdsch_config_dedicated,
                                                       SI_RNTI,
@@ -3381,7 +3395,7 @@ PMI_FEEDBACK:
                 if ((Ns==(1+(2*subframe))) && (l==0)) {// process PDSCH symbols 1,2,3,4,5,(6 Normal Prefix)
 
                   if ((transmission_mode == 5) &&
-                      (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->dl_power_off==0) &&
+                      (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->dl_power_off==0) &&
                       (UE->use_ia_receiver ==1)) {
                     dual_stream_UE = 1;
                   } else {
@@ -3404,7 +3418,7 @@ PMI_FEEDBACK:
                                  (m==UE->pdcch_vars[0]->num_pdcch_symbols)?1:0,
                                  dual_stream_UE,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) {
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1) {
                       dlsch_active = 0;
                       break;
                     }
@@ -3430,7 +3444,7 @@ PMI_FEEDBACK:
                                  0,
                                  dual_stream_UE,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) {
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1) {
                       dlsch_active=0;
                       break;
                     }
@@ -3456,7 +3470,7 @@ PMI_FEEDBACK:
                                  0,
                                  dual_stream_UE,
                                  i_mod,
-                                 UE->dlsch[subframe&0x1][0][0]->current_harq_pid)==-1) {
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid)==-1) {
                       dlsch_active=0;
                       break;
                     }
@@ -3477,30 +3491,30 @@ PMI_FEEDBACK:
                     //write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][0],10*UE->frame_parms.samples_per_tti,1,1);
                     write_output("rxsig0.m","rxs0", &UE->common_vars.rxdata[0][subframe*UE->frame_parms.samples_per_tti],UE->frame_parms.samples_per_tti,1,1);
                     //write_output("rxsigF0.m","rxsF0", &UE->common_vars.rxdataF[0][subframe*nsymb*eNB->frame_parms.ofdm_symbol_size],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
-                    write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                    write_output("rxsigF0.m","rxsF0", &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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..common_vars_rx_data_per_thread[subframe&0x1]rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
+                      write_output("rxsigF1.m","rxsF1", UE->common_vars..common_vars_rx_data_per_thread[UE->current_thread_id[subframe]]rxdataF[1],UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
                     }
 
                     write_output("dlsch00_r0.m","dl00_r0",
-                                 &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+                                 &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+                                   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+                                   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].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.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+                                   &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                                    UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
 
                     //pdsch_vars
@@ -3527,14 +3541,14 @@ PMI_FEEDBACK:
             if (trials==0 && round==0 && transmission_mode>=5 && transmission_mode<7) {
               for (iii=0; iii<NB_RB; iii++) {
                 //fprintf(csv_fd, "%d, %d", (UE->pdsch_vars[eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id_i]->pmi_ext[iii]));
-                fprintf(csv_fd,"%x,%x,",(UE->pdsch_vars[subframe&0x1][eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
-                printf("%x ",(UE->pdsch_vars[subframe&0x1][eNB_id]->pmi_ext[iii]));
+                fprintf(csv_fd,"%x,%x,",(UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->pmi_ext[iii]),(UE->pdsch_vars[eNB_id]->pmi_ext[iii]));
+                printf("%x ",(UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->pmi_ext[iii]));
               }
             }
           }
 
           for (int cw=Kmimo-1; cw>=0; cw--) {
-            UE->dlsch[subframe&0x1][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
+            UE->dlsch[UE->current_thread_id[subframe]][0][cw]->rnti = (common_flag==0) ? n_rnti: SI_RNTI;
             coded_bits_per_codeword = get_G(&eNB->frame_parms,
                                             eNB->dlsch[0][cw]->harq_processes[0]->nb_rb,
                                             eNB->dlsch[0][cw]->harq_processes[0]->rb_alloc,
@@ -3545,14 +3559,14 @@ PMI_FEEDBACK:
 					    subframe,
 					    (transmission_mode<7?0:transmission_mode));
 
-            UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid]->G = coded_bits_per_codeword;
+            UE->dlsch[UE->current_thread_id[subframe]][0][cw]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][cw]->current_harq_pid]->G = coded_bits_per_codeword;
 
 
 	                
             // calculate uncoded BLER
             uncoded_ber=0;
             for (i=0;i<coded_bits_per_codeword;i++)
-              if (eNB->dlsch[0][0]->harq_processes[0]->e[i] != (UE->pdsch_vars[subframe&0x1][0]->llr[0][i]<0)) {
+              if (eNB->dlsch[0][0]->harq_processes[0]->e[i] != (UE->pdsch_vars[UE->current_thread_id[subframe]][0]->llr[0][i]<0)) {
                 uncoded_ber_bit[i] = 1;
                 uncoded_ber++;
               }
@@ -3569,26 +3583,26 @@ PMI_FEEDBACK:
             start_meas(&UE->dlsch_unscrambling_stats);
             dlsch_unscrambling(&UE->frame_parms,
                                0,
-                               UE->dlsch[subframe&0x1][0][cw],
+                               UE->dlsch[UE->current_thread_id[subframe]][0][cw],
                                coded_bits_per_codeword,
-                               UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw],
+                               UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[cw],
                                0,
                                subframe<<1);
             stop_meas(&UE->dlsch_unscrambling_stats);
 
             start_meas(&UE->dlsch_decoding_stats);
             ret = dlsch_decoding(UE,
-                                 UE->pdsch_vars[subframe&0x1][eNB_id]->llr[cw],
+                                 UE->pdsch_vars[UE->current_thread_id[subframe]][eNB_id]->llr[cw],
                                  &UE->frame_parms,
-                                 UE->dlsch[subframe&0x1][0][cw],
-                                 UE->dlsch[subframe&0x1][0][cw]->harq_processes[UE->dlsch[subframe&0x1][0][cw]->current_harq_pid],
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][cw],
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][cw]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][cw]->current_harq_pid],
                                  subframe,
-                                 UE->dlsch[subframe&0x1][0][cw]->current_harq_pid,
+                                 UE->dlsch[UE->current_thread_id[subframe]][0][cw]->current_harq_pid,
                                  1,llr8_flag);
             stop_meas(&UE->dlsch_decoding_stats);
 
             if (cw==1) {
-              if (ret <= UE->dlsch[subframe&0x1][0][cw]->max_turbo_iterations) {
+              if (ret <= UE->dlsch[UE->current_thread_id[subframe]][0][cw]->max_turbo_iterations) {
               } else {
                 errs2[round]++;
               }
@@ -3596,10 +3610,10 @@ PMI_FEEDBACK:
           }
 
 
-          stop_meas(&UE->phy_proc_rx[subframe&0x1]);
+          stop_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]);
 
 
-          if (ret <= UE->dlsch[subframe&0x1][0][0]->max_turbo_iterations) {
+          if (ret <= UE->dlsch[UE->current_thread_id[subframe]][0][0]->max_turbo_iterations) {
 
             avg_iter += ret;
             iter_trials++;
@@ -3607,15 +3621,15 @@ PMI_FEEDBACK:
             if (n_frames==1)
               printf("No DLSCH errors found (round %d),uncoded ber %f\n",round,uncoded_ber);
 
-            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->TBS;
+            UE->total_TBS[eNB_id] =  UE->total_TBS[eNB_id] + UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->TBS;
             TB0_active = 0;
 
-            if (UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
+            if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->mimo_mode == LARGE_CDD) {   //try to decode second stream using SIC
               /*
-              for (round = 0 ; round < UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->round ; round++) {
+              for (round = 0 ; round < UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->round ; round++) {
               // re-encoding of first stream
-              dlsch0_ue_harq = UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
-              dlsch0_eNB_harq = UE->dlsch[subframe&0x1][eNB_id]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid];
+              dlsch0_ue_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid];
+              dlsch0_eNB_harq = UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][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;
@@ -3627,13 +3641,13 @@ PMI_FEEDBACK:
               dlsch0_eNB_harq->dl_power_off = dlsch0_ue_harq->dl_power_off;
               dlsch0_eNB_harq->status       = dlsch0_ue_harq->status;
 
-              UE->dlsch[subframe&0x1][eNB_id]->active       = UE->dlsch[subframe&0x1][eNB_id][0]->active;
-              UE->dlsch[subframe&0x1][eNB_id]->rnti         = UE->dlsch[subframe&0x1][eNB_id][0]->rnti;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->active       = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->active;
+              UE->dlsch[UE->current_thread_id[subframe]][eNB_id]->rnti         = UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->rnti;
 
-              dlsch_encoding(UE->dlsch[subframe&0x1][eNB_id][0]->harq_processes[UE->dlsch[subframe&0x1][eNB_id][0]->current_harq_pid]->b,
+              dlsch_encoding(UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->current_harq_pid]->b,
                    &UE->frame_parms,
                    num_pdcch_symbols,
-                   UE->dlsch[subframe&0x1][0],
+                   UE->dlsch[UE->current_thread_id[subframe]][0],
                    0,subframe,
                    &UE->dlsch_rate_matching_stats,
                    &UE->dlsch_turbo_encoding_stats,
@@ -3660,18 +3674,18 @@ PMI_FEEDBACK:
               //if ((n_frames==1) || (SNR>=30)) 
               printf("DLSCH errors found (round %d), uncoded ber %f\n",round,uncoded_ber);
 
-              for (s=0; s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->C; s++) {
-                if (s<UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus)
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus;
+              for (s=0; s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->C; s++) {
+                if (s<UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus)
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus;
                 else
-                  Kr = UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus;
+                  Kr = UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus;
 
                 Kr_bytes = Kr>>3;
 
                 printf("Decoded_output (Segment %d):\n",s);
 
                 for (i=0; i<Kr_bytes; i++)
-                  printf("%d : %x (%x)\n",i,UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i],UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
+                  printf("%d : %x (%x)\n",i,UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i],UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->c[s][i]^eNB->dlsch[0][0]->harq_processes[0]->c[s][i]);
               }
 
               sprintf(fname,"rxsig0_r%d.m",round);
@@ -3679,7 +3693,7 @@ 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.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+              write_output(fname,vname, &UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[0][0],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
 	     
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"rxsig1_r%d.m",round);
@@ -3687,20 +3701,20 @@ PMI_FEEDBACK:
                 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(vname,"rxs1F_r%d.m",round);
-                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
+                write_output(fname,vname, UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].rxdataF[1],2*UE->frame_parms.ofdm_symbol_size*nsymb,2,1);
               }
 
               sprintf(fname,"dlsch00_r%d.m",round);
               sprintf(vname,"dl00_r%d",round);
               write_output(fname,vname,
-                           &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][0][0]),
+                           &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
                            UE->frame_parms.ofdm_symbol_size*nsymb,1,1);
 
               if (UE->frame_parms.nb_antennas_rx>1) {
                 sprintf(fname,"dlsch01_r%d.m",round);
                 sprintf(vname,"dl01_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][1][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][1][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -3708,7 +3722,7 @@ PMI_FEEDBACK:
                 sprintf(fname,"dlsch10_r%d.m",round);
                 sprintf(vname,"dl10_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][2][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][2][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -3716,7 +3730,7 @@ PMI_FEEDBACK:
                 sprintf(fname,"dlsch11_r%d.m",round);
                 sprintf(vname,"dl11_r%d",round);
                 write_output(fname,vname,
-                             &(UE->common_vars.common_vars_rx_data_per_thread[subframe&0x1].dl_ch_estimates[eNB_id][3][0]),
+                             &(UE->common_vars.common_vars_rx_data_per_thread[UE->current_thread_id[subframe]].dl_ch_estimates[eNB_id][3][0]),
                              UE->frame_parms.ofdm_symbol_size*nsymb/2,1,1);
               }
 
@@ -3726,7 +3740,7 @@ PMI_FEEDBACK:
               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[subframe&0x1][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
+              write_output("dlsch_w.m","w",UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->w[0],3*(tbs+64),1,0);
               */
 
               if (round == 3) exit(-1);
@@ -3735,7 +3749,7 @@ PMI_FEEDBACK:
             //      printf("round %d errors %d/%d\n",round,errs[round],trials);
 
             round++;
-            //      UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->round++;
+            //      UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->round++;
           }
 
 	  if (xforms==1) {
@@ -3756,7 +3770,7 @@ PMI_FEEDBACK:
         //len = chbch_stats_read(stats_buffer,NULL,0,4096);
         //printf("%s\n\n",stats_buffer);
 
-        if (UE->proc.proc_rxtx[subframe&1].frame_rx % 10 == 0) {
+        if (UE->proc.proc_rxtx[UE->current_thread_id[subframe]].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);
@@ -3764,7 +3778,7 @@ PMI_FEEDBACK:
         }
 
 
-        UE->proc.proc_rxtx[subframe&1].frame_rx++;
+        UE->proc.proc_rxtx[UE->current_thread_id[subframe]].frame_rx++;
 
         /* calculate the total processing time for each packet,
          * get the max, min, and number of packets that exceed t>2000us
@@ -3775,7 +3789,7 @@ PMI_FEEDBACK:
         double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0;
 
 
-        double t_rx = (double)UE->phy_proc_rx[subframe&0x1].p_time/cpu_freq_GHz/1000.0;
+        double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0;
         double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0;
         double t_rx_dec = (double)UE->dlsch_decoding_stats.p_time/cpu_freq_GHz/1000.0;
@@ -3925,7 +3939,7 @@ PMI_FEEDBACK:
              rate*effective_rate,
              100*effective_rate,
              rate,
-             rate*get_Qm(UE->dlsch[subframe&0x1][0][0]->harq_processes[UE->dlsch[subframe&0x1][0][0]->current_harq_pid]->mcs),
+             rate*get_Qm(UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[UE->dlsch[UE->current_thread_id[subframe]][0][0]->current_harq_pid]->mcs),
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])/
              (double)eNB->dlsch[0][0]->harq_processes[0]->TBS,
              (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0]));
@@ -3964,10 +3978,10 @@ PMI_FEEDBACK:
                eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials);
 
         printf("\n\nUE RX function statistics (per 1ms subframe)\n\n");
-        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[subframe&0x1].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
-                               2)/UE->phy_proc_rx[subframe&0x1].trials - pow((double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000,2));
-        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[subframe&0x1].diff/UE->phy_proc_rx[subframe&0x1].trials/cpu_freq_GHz/1000.0,
-               UE->phy_proc_rx[subframe&0x1].trials*2/3);
+        std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000,
+                               2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2));
+        printf("Total PHY proc rx                                   :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,
+               UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3);
         printf("|__Statistcs                                            std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median,
                rx_q1, rx_q3, n_rx_dropped);
         std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000,
@@ -4001,7 +4015,7 @@ PMI_FEEDBACK:
         printf("|__ DLSCH Rate Unmatching                               :%f us (%d trials)\n",
                (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials);
         printf("|__ DLSCH Turbo Decoding(%d bits)                       :%f us (%d trials)\n",
-               UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Cminus ? UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kminus : UE->dlsch[subframe&0x1][0][0]->harq_processes[0]->Kplus,
+               UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus,
                (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials);
         printf("    |__ init                                            %f us (cycles/iter %f, %d trials)\n",
                (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0,
@@ -4179,7 +4193,7 @@ PMI_FEEDBACK:
                 eNB->dlsch_modulation_stats.trials,
                 eNB->dlsch_scrambling_stats.trials,
                 eNB->dlsch_encoding_stats.trials,
-                UE->phy_proc_rx[subframe&0x1].trials,
+                UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
                 UE->ofdm_demod_stats.trials,
                 UE->dlsch_rx_pdcch_stats.trials,
                 UE->dlsch_llr_stats.trials,
@@ -4192,7 +4206,7 @@ PMI_FEEDBACK:
                 get_time_meas_us(&eNB->dlsch_modulation_stats),
                 get_time_meas_us(&eNB->dlsch_scrambling_stats),
                 get_time_meas_us(&eNB->dlsch_encoding_stats),
-                get_time_meas_us(&UE->phy_proc_rx[subframe&0x1]),
+                get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]),
                 nsymb*get_time_meas_us(&UE->ofdm_demod_stats),
                 get_time_meas_us(&UE->dlsch_rx_pdcch_stats),
                 3*get_time_meas_us(&UE->dlsch_llr_stats),
@@ -4232,7 +4246,7 @@ PMI_FEEDBACK:
         eNB->dlsch_modulation_stats.trials,
         eNB->dlsch_scrambling_stats.trials,
         eNB->dlsch_encoding_stats.trials,
-        UE->phy_proc_rx[subframe&0x1].trials,
+        UE->phy_proc_rx[UE->current_thread_id[subframe]].trials,
         UE->ofdm_demod_stats.trials,
         UE->dlsch_rx_pdcch_stats.trials,
         UE->dlsch_llr_stats.trials,
@@ -4290,7 +4304,7 @@ PMI_FEEDBACK:
     printf("eNB %d\n",i);
     free_eNB_dlsch(eNB->dlsch[0][i]);
     printf("UE %d\n",i);
-    free_ue_dlsch(UE->dlsch[subframe&0x1][0][i]);
+    free_ue_dlsch(UE->dlsch[UE->current_thread_id[subframe]][0][i]);
   }
 
 
diff --git a/openair1/SIMULATION/LTE_PHY/framegen.c b/openair1/SIMULATION/LTE_PHY/framegen.c
index d056bea5d0eaad6fe28fe807658167d3ef60d748..9719aeb9e52c0be1cc4544325d5d59b81ea4984f 100644
--- a/openair1/SIMULATION/LTE_PHY/framegen.c
+++ b/openair1/SIMULATION/LTE_PHY/framegen.c
@@ -66,8 +66,7 @@ DCI_PDU *get_dci(uint8_t Mod_id, uint8_t frame, uint8_t subframe)
   int dci_length_bytes,dci_length;
   int BCCH_pdu_size_bits, BCCH_pdu_size_bytes;
 
-  DCI_pdu.Num_ue_spec_dci = 0;
-  DCI_pdu.Num_common_dci = 0;
+  DCI_pdu.Num_dci = 0;
 
   if (subframe_select(&PHY_vars_eNB_g[0]->lte_frame_parms, subframe) == SF_S) {
     return (&DCI_pdu);
@@ -281,28 +280,30 @@ DCI_PDU *get_dci(uint8_t Mod_id, uint8_t frame, uint8_t subframe)
     }
 
     // add common dci
-    DCI_pdu.dci_alloc[0].dci_length = BCCH_pdu_size_bits;
-    DCI_pdu.dci_alloc[0].L          = 2;
-    DCI_pdu.dci_alloc[0].rnti       = SI_RNTI;
-    DCI_pdu.dci_alloc[0].format     = format1A;
-    DCI_pdu.dci_alloc[0].ra_flag    = 0;
+    DCI_pdu.dci_alloc[0].dci_length   = BCCH_pdu_size_bits;
+    DCI_pdu.dci_alloc[0].L            = 2;
+    DCI_pdu.dci_alloc[0].rnti         = SI_RNTI;
+    DCI_pdu.dci_alloc[0].format       = format1A;
+    DCI_pdu.dci_alloc[0].ra_flag      = 0;
+    DCI_pdu.dci_alloc[0].search_space = DCI_COMMON_SPACE;
     memcpy((void*)&DCI_pdu.dci_alloc[0].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes);
-    DCI_pdu.Num_common_dci++;
+    DCI_pdu.Num_dci++;
 
     // add ue specific dci
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].dci_length = dci_length;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].L          = 0;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].rnti       = n_rnti+k;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].format     = format1;
-    DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].ra_flag    = 0;
-    memcpy((void*)&DCI_pdu.dci_alloc[k+DCI_pdu.Num_common_dci].dci_pdu[0], &DLSCH_alloc_pdu_1[k], dci_length_bytes);
-    DCI_pdu.Num_ue_spec_dci++;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].dci_length   = dci_length;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].L            = 0;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].rnti         = n_rnti+k;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].format       = format1;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].ra_flag      = 0;
+    DCI_pdu.dci_alloc[DCI_pdu.Num_dci].search_space = DCI_UE_SPACE;
+    memcpy((void*)&DCI_pdu.dci_alloc[DCI_pdu.Num_dci].dci_pdu[0], &DLSCH_alloc_pdu_1[k], dci_length_bytes);
+    DCI_pdu.Num_dci++;
 
   }
 
   DCI_pdu.nCCE = 0;
 
-  for (i=0; i<DCI_pdu.Num_common_dci+DCI_pdu.Num_ue_spec_dci; i++) {
+  for (i=0; i<DCI_pdu.Num_dci; i++) {
     DCI_pdu.nCCE += (1<<(DCI_pdu.dci_alloc[i].L));
   }
 
diff --git a/openair1/SIMULATION/LTE_PHY/pbchsim.c b/openair1/SIMULATION/LTE_PHY/pbchsim.c
index f117879d6b49fd43f390d3c9999dae237bc3a492..687e7219e82b55cd1c01863fa69a4667ad99c924 100644
--- a/openair1/SIMULATION/LTE_PHY/pbchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pbchsim.c
@@ -570,7 +570,6 @@ int main(int argc, char **argv)
 
     /*
     num_pdcch_symbols = generate_dci_top(1,
-           0,
            dci_alloc,
            0,
            1024,
@@ -937,6 +936,7 @@ int main(int argc, char **argv)
                                 0,
                                 1,
                                 0,
+                                0,
                                 0);
             /*
              if (trial%100 == 0) {
diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
index 2b13449c6172498a3ee2c07fd49ec41e2fb9b7e5..1102d4be3800ba2515669dfb2020aab0604741ab 100644
--- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c
@@ -66,8 +66,7 @@ DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2
   int UL_pdu_size_bits=0, UL_pdu_size_bytes=0;
   int mcs = 3;
 
-  DCI_pdu.Num_ue_spec_dci = 0;
-  DCI_pdu.Num_common_dci = 0;
+  DCI_pdu.Num_dci = 0;
 
   if (lte_frame_parms->frame_type == TDD) {
     switch (lte_frame_parms->N_RB_DL) {
@@ -358,35 +357,38 @@ DCI_PDU *get_dci(LTE_DL_FRAME_PARMS *lte_frame_parms,uint8_t log2L, uint8_t log2
   for (ind = 0; ind<num_dci; ind++) {
     if (format_selector[ind]==format1A) {
       // add common dci
-      DCI_pdu.dci_alloc[ind].dci_length = BCCH_pdu_size_bits;
-      DCI_pdu.dci_alloc[ind].L          = log2Lcommon;
-      DCI_pdu.dci_alloc[ind].rnti       = SI_RNTI;
-      DCI_pdu.dci_alloc[ind].format     = format1A;
-      DCI_pdu.dci_alloc[ind].ra_flag    = 0;
-      memcpy((void*)&DCI_pdu.dci_alloc[0].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes);
-      DCI_pdu.Num_common_dci++;
+      DCI_pdu.dci_alloc[ind].dci_length   = BCCH_pdu_size_bits;
+      DCI_pdu.dci_alloc[ind].L            = log2Lcommon;
+      DCI_pdu.dci_alloc[ind].rnti         = SI_RNTI;
+      DCI_pdu.dci_alloc[ind].format       = format1A;
+      DCI_pdu.dci_alloc[ind].ra_flag      = 0;
+      DCI_pdu.dci_alloc[ind].search_space = DCI_COMMON_SPACE;
+      memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &BCCH_alloc_pdu[0], BCCH_pdu_size_bytes);
+      DCI_pdu.Num_dci++;
       printf("Added common dci (%d) for rnti %x\n",ind,SI_RNTI);
     }
     
 
     if (format_selector[ind]==format1) {
-      DCI_pdu.dci_alloc[ind].dci_length = dci_length;
-      DCI_pdu.dci_alloc[ind].L          = log2L;
-      DCI_pdu.dci_alloc[ind].rnti       = rnti;
-      DCI_pdu.dci_alloc[ind].format     = format1;
-      DCI_pdu.dci_alloc[ind].ra_flag    = 0;
+      DCI_pdu.dci_alloc[ind].dci_length   = dci_length;
+      DCI_pdu.dci_alloc[ind].L            = log2L;
+      DCI_pdu.dci_alloc[ind].rnti         = rnti;
+      DCI_pdu.dci_alloc[ind].format       = format1;
+      DCI_pdu.dci_alloc[ind].ra_flag      = 0;
+      DCI_pdu.dci_alloc[ind].search_space = DCI_UE_SPACE;
       memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &DLSCH_alloc_pdu[0], dci_length_bytes);
-      DCI_pdu.Num_ue_spec_dci++;
+      DCI_pdu.Num_dci++;
     }
     
     if (format_selector[ind]==format0) {
-      DCI_pdu.dci_alloc[ind].dci_length = UL_pdu_size_bits;
-      DCI_pdu.dci_alloc[ind].L          = log2L;
-      DCI_pdu.dci_alloc[ind].rnti       = rnti;
-      DCI_pdu.dci_alloc[ind].format     = format0;
-      DCI_pdu.dci_alloc[ind].ra_flag    = 0;
+      DCI_pdu.dci_alloc[ind].dci_length   = UL_pdu_size_bits;
+      DCI_pdu.dci_alloc[ind].L            = log2L;
+      DCI_pdu.dci_alloc[ind].rnti         = rnti;
+      DCI_pdu.dci_alloc[ind].format       = format0;
+      DCI_pdu.dci_alloc[ind].ra_flag      = 0;
+      DCI_pdu.dci_alloc[ind].search_space = DCI_UE_SPACE;
       memcpy((void*)&DCI_pdu.dci_alloc[ind].dci_pdu[0], &UL_alloc_pdu[0], UL_pdu_size_bytes);
-      DCI_pdu.Num_ue_spec_dci++;
+      DCI_pdu.Num_dci++;
     }
   }
   
@@ -849,20 +851,20 @@ int main(int argc, char **argv)
 	    n_trials_dl++;
 	  }
 	}
-        num_pdcch_symbols = get_num_pdcch_symbols(DCI_pdu.Num_common_dci+DCI_pdu.Num_ue_spec_dci,
+        num_pdcch_symbols = get_num_pdcch_symbols(DCI_pdu.Num_dci,
                             DCI_pdu.dci_alloc, frame_parms, subframe);
 	numCCE = get_nCCE(num_pdcch_symbols,&eNB->frame_parms,get_mi(&eNB->frame_parms,subframe));
 
         if (n_frames==1) {
           printf("num_dci %d, num_pddch_symbols %d, nCCE %d\n",
-                 DCI_pdu.Num_common_dci+DCI_pdu.Num_ue_spec_dci,
+                 DCI_pdu.Num_dci,
                  num_pdcch_symbols,numCCE);
         }
 
         // apply RNTI-based nCCE allocation
 	memset(CCE_table,0,800*sizeof(int));
 
-        for (i = 0; i < DCI_pdu.Num_common_dci + DCI_pdu.Num_ue_spec_dci; i++) {
+        for (i = 0; i < DCI_pdu.Num_dci; i++) {
           // SI RNTI
           if (DCI_pdu.dci_alloc[i].rnti == SI_RNTI) {
             DCI_pdu.dci_alloc[i].firstCCE = get_nCCE_offset_l1(CCE_table,
@@ -899,8 +901,7 @@ int main(int argc, char **argv)
             exit(-1);
         }
 
-        num_pdcch_symbols = generate_dci_top(DCI_pdu.Num_ue_spec_dci,
-                                             DCI_pdu.Num_common_dci,
+        num_pdcch_symbols = generate_dci_top(DCI_pdu.Num_dci,
                                              DCI_pdu.dci_alloc,
                                              0,
                                              AMP,
diff --git a/openair1/SIMULATION/LTE_PHY/pucchsim.c b/openair1/SIMULATION/LTE_PHY/pucchsim.c
index 3869851f712d875c09f6c8bbd82db821eda52fb7..9deff20d350dcfc11f876486bb0b7e5306cd42ee 100644
--- a/openair1/SIMULATION/LTE_PHY/pucchsim.c
+++ b/openair1/SIMULATION/LTE_PHY/pucchsim.c
@@ -297,7 +297,7 @@ int main(int argc, char **argv)
   }
 
   logInit();
-  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
+  //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL);
   g_log->log_component[PHY].level = LOG_DEBUG;
   g_log->log_component[PHY].flag = LOG_HIGH;
 
diff --git a/openair1/SIMULATION/LTE_PHY/scansim.c b/openair1/SIMULATION/LTE_PHY/scansim.c
index 20c3f374d0b8c1ac52995b351b1cb9999f006058..ba355bbbebb113131761b93eaedb75288a811188 100644
--- a/openair1/SIMULATION/LTE_PHY/scansim.c
+++ b/openair1/SIMULATION/LTE_PHY/scansim.c
@@ -493,7 +493,6 @@ int main(int argc, char **argv)
 
 
      num_pdcch_symbols = generate_dci_top(1,
-     0,
      dci_alloc,
      0,
      1024,
diff --git a/openair1/SIMULATION/LTE_PHY/syncsim.c b/openair1/SIMULATION/LTE_PHY/syncsim.c
index 97a94a1a4323f3bda14401c39425b1c761b6db3b..58e96a9abef054cdb198e7ec5bd8824349a0cc02 100644
--- a/openair1/SIMULATION/LTE_PHY/syncsim.c
+++ b/openair1/SIMULATION/LTE_PHY/syncsim.c
@@ -1101,11 +1101,12 @@ int main(int argc, char **argv)
       ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->mcs             = 0;
       ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->ndi             = 1;
       ((DCI1_5MHz_FDD_t*)&DLSCH_alloc_pdu)->rv              = 0;
-      dci_alloc[0].dci_length = sizeof_DCI1_5MHz_FDD_t;
+      dci_alloc[0].dci_length   = sizeof_DCI1_5MHz_FDD_t;
       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu,sizeof(DCI1_5MHz_FDD_t));
-      dci_alloc[0].L          = 2;
-      dci_alloc[0].rnti       = n_rnti;
-      dci_alloc[0].format     = format1;
+      dci_alloc[0].L            = 2;
+      dci_alloc[0].rnti         = n_rnti;
+      dci_alloc[0].format       = format1;
+      dci_alloc[0].search_space = DCI_UE_SPACE;
     } else {
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rah             = 0;
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rballoc         = DLSCH_RB_ALLOC;
@@ -1117,15 +1118,15 @@ int main(int argc, char **argv)
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->rv              = 0;
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->tpmi            = (transmission_mode>=5 ? 5 : 0);  // precoding
       ((DCI1E_5MHz_2A_M10PRB_TDD_t*)&DLSCH_alloc_pdu)->dl_power_off    = (transmission_mode==5 ? 0 : 1);
-      dci_alloc[0].dci_length = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
+      dci_alloc[0].dci_length   = sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t;
       memcpy(&dci_alloc[0].dci_pdu[0],&DLSCH_alloc_pdu,sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t));
-      dci_alloc[0].L          = 2;
-      dci_alloc[0].rnti       = n_rnti;
-      dci_alloc[0].format     = format1E_2A_M10PRB;
+      dci_alloc[0].L            = 2;
+      dci_alloc[0].rnti         = n_rnti;
+      dci_alloc[0].format       = format1E_2A_M10PRB;
+      dci_alloc[0].search_space = DCI_UE_SPACE;
     }
 
     num_pdcch_symbols = generate_dci_top(1,
-                                         0,
                                          dci_alloc,
                                          0,
                                          AMP,
@@ -1134,7 +1135,6 @@ int main(int argc, char **argv)
                                          subframe);
     /*
     num_pdcch_symbols = generate_dci_top(1,
-           0,
            dci_alloc,
            0,
            AMP,
diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c
index dbce85851695fb10b49f1a655221806ac2b93a02..03c736ecd3f3475bfcbd7a1c22f899701235795c 100644
--- a/openair1/SIMULATION/LTE_PHY/ulsim.c
+++ b/openair1/SIMULATION/LTE_PHY/ulsim.c
@@ -175,7 +175,7 @@ int main(int argc, char **argv)
 
   int aarx,aatx;
   double channelx,channely;
-  double sigma2, sigma2_dB=10,SNR,SNR2,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0;
+  double sigma2, sigma2_dB=10,SNR,SNR2=0,snr0=-2.0,snr1,SNRmeas,rate,saving_bler=0;
   double input_snr_step=.2,snr_int=30;
   double blerr;
 
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
index 51ae7112770a701d9212ebc2801e3fb6f8753322..7b392b6b3bbc7a89049fc5ae5708026d68064dc4 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";'
+syntax = "proto2";
 package protocol;
 
 //
diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
index 441e193569343b1b3a619ce3e97da437d55bc9d1..ac939b828cc13399511a808a92159919285b7d39 100644
--- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";'
+syntax = "proto2";
 package protocol;
 
 import "config_common.proto";
diff --git a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto
index 3a5efaf7d40d427d6b1fa3185eba77f36d460ff2..0f7e34de156599a448265e2846b9b69c83aea5c6 100644
--- a/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/control_delegation.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";'
+syntax = "proto2";
 package protocol;
 
 enum flex_control_delegation_type {
diff --git a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto
index cbec332b304085d4389d7b3498556fc29a9803dd..c92f171b0ee9e21d163633b86c021e74aa47b641 100644
--- a/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/controller_commands.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 import "mac_primitives.proto";
diff --git a/openair2/ENB_APP/MESSAGES/V2/flexran.proto b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
index 3a1d40bca69479daaafa42f055e690add87426ef..8c0c300efea152c1b5a3943807504d5d1295bfaf 100644
--- a/openair2/ENB_APP/MESSAGES/V2/flexran.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/flexran.proto
@@ -1,4 +1,4 @@
-//'syntax = "proto2";' 
+syntax = "proto2";
 package protocol;
 
 import "stats_messages.proto";
@@ -40,7 +40,7 @@ enum flexran_direction {
 }
 	
 enum flexran_err {
-        option allow_alias = true;
+        //option allow_alias = true;
 	// message errors
 	NO_ERR = 0;	
 	MSG_DEQUEUING = -1;
diff --git a/openair2/ENB_APP/MESSAGES/V2/header.proto b/openair2/ENB_APP/MESSAGES/V2/header.proto
index dfd5ea6c9951ef2b266677413a4aec128c839b24..939429f51fe134c644d14dce5097154bea17e280 100644
--- a/openair2/ENB_APP/MESSAGES/V2/header.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/header.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 message flex_header {
diff --git a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto
index be7c72ab7b07a4dd69bc99d5f7c4b9765d79c1c9..89b8f0e380605a12077aae640728b7fbf25fcc47 100644
--- a/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/mac_primitives.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 //
diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto
index 080883ea97997ace22b23e96f5643b59a25e8776..fa985bf9cc4af4cdfa8318d640239364aac58af2 100644
--- a/openair2/ENB_APP/MESSAGES/V2/stats_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/stats_common.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 //
diff --git a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto
index 1b1567dda1e4b87b9f5b41bcdd05d0d2badf8af7..d8c0651fa16962a0f26e9c2c922cf0e9dbbd02c9 100644
--- a/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/stats_messages.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 //import "header.proto";
diff --git a/openair2/ENB_APP/MESSAGES/V2/time_common.proto b/openair2/ENB_APP/MESSAGES/V2/time_common.proto
index 30a56bb776957d245e673ac44e8e2ca255408c71..8bd2497443daaed136dc55b39740c66776d95795 100644
--- a/openair2/ENB_APP/MESSAGES/V2/time_common.proto
+++ b/openair2/ENB_APP/MESSAGES/V2/time_common.proto
@@ -1,3 +1,4 @@
+syntax = "proto2";
 package protocol;
 
 enum flex_harq_status {
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index 59eb6a0b01c3891bb19e9d6009fd5329bf74f398..4e2491fe8576950c784d2c37b4667243bcbeeb8c 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -637,20 +637,11 @@ void Eurecom_RCconfig_macrlc() {
 int Eurecom_RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
   config_t          cfg;
   config_setting_t *setting                       = NULL;
-  config_setting_t *subsetting                    = NULL;
   config_setting_t *setting_component_carriers    = NULL;
   config_setting_t *component_carrier             = NULL;
   config_setting_t *setting_srb1                  = NULL;
-  config_setting_t *setting_mme_addresses         = NULL;
-  config_setting_t *setting_mme_address           = NULL;
-  config_setting_t *setting_ru                    = NULL;
-  config_setting_t *setting_enb                   = NULL;
-  config_setting_t *setting_otg                   = NULL;
-  config_setting_t *subsetting_otg                = NULL;
-  int               parse_errors                  = 0;
+  config_setting_t *setting_enb                  = NULL;
   int               num_enbs                      = 0;
-  int               num_mme_address               = 0;
-  int               num_otg_elements              = 0;
   int               num_component_carriers        = 0;
   int               j                             = 0;
   libconfig_int     enb_id                        = 0;
@@ -683,10 +674,6 @@ int Eurecom_RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
   libconfig_int     Nid_cell_mbsfn                = 0;
   libconfig_int     N_RB_DL                       = 0;
   libconfig_int     nb_antenna_ports              = 0;
-  libconfig_int     nb_antennas_tx                = 0;
-  libconfig_int     nb_antennas_rx                = 0;
-  libconfig_int     tx_gain                       = 0;
-  libconfig_int     rx_gain                       = 0;
   libconfig_int     prach_root                    = 0;
   libconfig_int     prach_config_index            = 0;
   const char*            prach_high_speed         = NULL;
@@ -760,38 +747,8 @@ int Eurecom_RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 
 
   const char*       active_enb[MAX_ENB];
-  char*             enb_interface_name_for_S1U    = NULL;
-  char*             enb_ipv4_address_for_S1U      = NULL;
-  libconfig_int     enb_port_for_S1U              = 0;
-  char*             enb_interface_name_for_S1_MME = NULL;
-  char*             enb_ipv4_address_for_S1_MME   = NULL;
-  char             *address                       = NULL;
-  char             *cidr                          = NULL;
   char             *astring                       = NULL;
-  char*             flexran_agent_interface_name      = NULL;
-  char*             flexran_agent_ipv4_address        = NULL;
-  libconfig_int     flexran_agent_port                = 0;
-  char*             flexran_agent_cache               = NULL;
-  libconfig_int     otg_ue_id                     = 0;
-  char*             otg_app_type                  = NULL;
-  char*             otg_bg_traffic                = NULL;
-  char*             glog_level                    = NULL;
-  char*             glog_verbosity                = NULL;
-  char*             hw_log_level                  = NULL;
-  char*             hw_log_verbosity              = NULL;
-  char*             phy_log_level                 = NULL;
-  char*             phy_log_verbosity             = NULL;
-  char*             mac_log_level                 = NULL;
-  char*             mac_log_verbosity             = NULL;
-  char*             rlc_log_level                 = NULL;
-  char*             rlc_log_verbosity             = NULL;
-  char*             pdcp_log_level                = NULL;
-  char*             pdcp_log_verbosity            = NULL;
-  char*             rrc_log_level                 = NULL;
-  char*             rrc_log_verbosity             = NULL;
-  char*             udp_log_verbosity             = NULL;
-  char*             osa_log_level                 = NULL;
-  char*             osa_log_verbosity             = NULL;
+
 
   // for no gcc warnings 
   (void)astring;
@@ -886,6 +843,7 @@ int Eurecom_RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
       if (strcmp(tr_s_preference, "local_mac") == 0) {
 
 
+
       }
       else if (strcmp(tr_s_preference, "cudu") == 0) {
 	if (  !(config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_LOCAL_S_IF_NAME,        (const char **)&if_name_s)
@@ -2429,7 +2387,6 @@ int Eurecom_RCconfig_gtpu() {
   config_setting_t *subsetting                    = NULL;
   config_setting_t *setting_enb                   = NULL;
   int               num_enbs                      = 0;
-  libconfig_int     enb_id                        = 0;
 
 
 
@@ -2513,16 +2470,10 @@ int Eurecom_RCconfig_S1(MessageDef *msg_p, uint32_t i) {
   config_setting_t *setting_mme_addresses         = NULL;
   config_setting_t *setting_mme_address           = NULL;
   config_setting_t *setting_enb                   = NULL;
-  config_setting_t *setting_otg                   = NULL;
-  config_setting_t *subsetting_otg                = NULL;
-  int               parse_errors                  = 0;
-  int               num_enbs                      = 0;
   int               num_mme_address               = 0;
-  int               num_otg_elements              = 0;
-  int               num_component_carriers        = 0;
   int               j                             = 0;
   libconfig_int     enb_id                        = 0;
-
+  int               num_enbs                      = 0;
 
   const char*       cell_type                     = NULL;
   const char*       tac                           = 0;
@@ -2533,17 +2484,10 @@ int Eurecom_RCconfig_S1(MessageDef *msg_p, uint32_t i) {
   libconfig_int     my_int;
 
 
-  char*             if_name                       = NULL;
   char*             ipv4                          = NULL;
-  char*             ipv4_remote                   = NULL;
   char*             ipv6                          = NULL;
-  char*             local_rf                      = NULL;
   char*             preference                    = NULL;
   char*             active                        = NULL;
-
-  char*             tr_preference                 = NULL;
-  libconfig_int     local_port                    = 0;
-  libconfig_int     remote_port                   = 0;
   const char*       active_enb[MAX_ENB];
   char*             enb_interface_name_for_S1U    = NULL;
   char*             enb_ipv4_address_for_S1U      = NULL;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 8f879d8859362c88af00a6e0afe1a9cfd7c8c104..e3a221dd94cb83327d8da99ab310fe62f5f03a94 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -223,6 +223,7 @@ void schedule_SR(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) {
   int CC_id,UE_id;  
   SchedulingRequestConfig_t      *SRconfig;
 
+
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
     for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
@@ -522,10 +523,12 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
   schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
 
   // Allocate CCEs for good after scheduling is done
+
   for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) allocate_CCEs(module_idP,CC_id,subframeP,0);
   
 
   stop_meas(&RC.mac[module_idP]->eNB_scheduler);
+
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
 
 }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
old mode 100755
new mode 100644
index f8717641fc90d325ca0240a781cd42b4c303f45f..6df032b0cab2f3c60297aeed5221006927f58994
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -423,6 +423,7 @@ schedule_ue_spec(
 //------------------------------------------------------------------------------
 {
 
+
   uint8_t                        CC_id;
   int                            UE_id;
   unsigned char                  aggregation;
@@ -501,6 +502,7 @@ schedule_ue_spec(
    
     }
   }
+
   //weight = get_ue_weight(module_idP,UE_id);
   aggregation = 2; 
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
@@ -534,7 +536,6 @@ schedule_ue_spec(
   stop_meas(&eNB->schedule_dlsch_preprocessor);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT);
 
-
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id);
 
@@ -607,6 +608,21 @@ schedule_ue_spec(
         continue;
       }
 
+#warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed
+#if 0
+      /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */
+      /* if we don't add it, next allocations may succeed but overall allocations may fail */
+      /* will be removed at the end of this function */
+      add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu,
+                      &(char[]){0},
+                      rnti,
+                      1,
+                      aggregation,
+                      1,
+                      format1,
+                      0);
+#endif
+
       nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
 
       if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
@@ -670,6 +686,7 @@ schedule_ue_spec(
 
             while((nb_rb_temp > 0) && (j<N_RBG[CC_id])) {
               if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) {
+                if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) printf("WARN: rballoc_subband not free for retrans?\n");
                 UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
 
                 if((j == N_RBG[CC_id]-1) &&
@@ -771,6 +788,7 @@ schedule_ue_spec(
 	    }
 	  }
 
+
 	  add_ue_dlsch_info(module_idP,
 			    CC_id,
 			    UE_id,
@@ -1282,6 +1300,7 @@ schedule_ue_spec(
     } // UE_id loop
   }  // CC_id loop
 
+
      
   fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_flag);
 
@@ -1424,6 +1443,7 @@ void update_ul_dci(module_id_t module_idP,
   COMMON_channels_t    *cc                     = &RC.mac[module_idP]->common_channels[CC_idP];
   int i;
 
+
   if (cc->tdd_Config != NULL) { // TDD 
     for (i=0; i<HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_dci; i++) {
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index dc45eeefd1177ab4f7cd2b83c90141ca3bd0e8d1..824ea61185cdbe1199565827cac40ef384a28995 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -56,6 +56,8 @@
 # include "intertask_interface.h"
 #endif
 
+#include "T.h"
+
 #define ENABLE_MAC_PAYLOAD_DEBUG
 #define DEBUG_eNB_SCHEDULER 1
 
@@ -2077,8 +2079,6 @@ void swap_UEs(UE_list_t *listP,int nodeiP, int nodejP, int ul_flag)
   #endif
  */
 
-
-
 // This has to be updated to include BSR information
 uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
 {
@@ -2512,7 +2512,8 @@ int get_nCCE_offset(int *CCE_table,
       search_space_free = 1;
 
       for (l=0; l<L; l++) {
-        if (CCE_table[(((Yk+m)%(nCCE/L))*L) + l] == 1) {
+        int cce = (((Yk+m)%(nCCE/L))*L) + l;
+        if (cce >= nCCE || CCE_table[cce] == 1) {
           search_space_free = 0;
           break;
         }
@@ -2713,6 +2714,7 @@ int allocate_CCEs(int module_idP,
   int i,j,idci;
   int nCCE=0;
 
+
   LOG_D(MAC,"Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n",subframeP,test_onlyP,DL_req->number_pdu,DL_req->number_dci,HI_DCI0_req->number_of_dci);
   DL_req->number_pdcch_ofdm_symbols=1;
 
@@ -2720,6 +2722,7 @@ try_again:
   init_CCE_table(module_idP,CC_idP);
   nCCE=0;
 
+
   for (i=0,idci=0;i<DL_req->number_pdu;i++) {
     // allocate DL common DCIs first
     if ((dl_config_pdu[i].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)&&
@@ -2899,6 +2902,7 @@ try_again:
 
   return 0;
 
+
  failed:
   return -1;
 }
@@ -2988,6 +2992,7 @@ nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,ui
 }
  
 boolean_t CCE_allocation_infeasible(int module_idP,
+
 				    int CC_idP,
 				    int format_flag,
 				    int subframe,
@@ -3002,6 +3007,7 @@ boolean_t CCE_allocation_infeasible(int module_idP,
   int ret;
   boolean_t res=FALSE;
 
+
   if (format_flag!=2) { // DL DCI
     dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti              = rnti;
     dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation;
@@ -3021,6 +3027,7 @@ boolean_t CCE_allocation_infeasible(int module_idP,
     HI_DCI0_req->number_of_dci--;
   }
   return(res);
+
 }
 
 void extract_harq(module_id_t mod_idP,int CC_idP,int UE_id,frame_t frameP,sub_frame_t subframeP,void *harq_indication,int format) {
@@ -3588,6 +3595,7 @@ void cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t
 
 void SR_indication(module_id_t mod_idP, int cc_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, uint8_t ul_cqi)
 {
+  T(T_ENB_MAC_SCHEDULING_REQUEST, T_INT(mod_idP), T_INT(cc_idP), T_INT(frameP), T_INT(subframeP), T_INT(rntiP));
  
   int UE_id = find_UE_id(mod_idP, rntiP);
   UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 520497cdb4cc2efe767fbc70d1b22915c55d02c9..10cbce6d19c621cda1758980a10b6bd5230519e0 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -812,7 +812,6 @@ void schedule_ulsch(module_id_t module_idP,
 
   schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb);
 
-
   stop_meas(&eNB->schedule_ulsch);
 
 }
@@ -946,6 +945,13 @@ abort();
         continue; // break;
       } 
 
+      /* be sure that there are some free RBs */
+      if (first_rb[CC_id] >= N_RB_UL-1) {
+	LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
+	      module_idP,frameP,subframeP,UE_id,rnti,CC_id);
+        continue;
+      }
+
 
 
       //      if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
@@ -1036,6 +1042,7 @@ abort();
 	    
             UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid];
 	    //            buffer_occupancy = UE_template->ul_total_buffer;
+
 	    
             while (((rb_table[rb_table_index]>(N_RB_UL-1-first_rb[CC_id])) ||
 		    (rb_table[rb_table_index]>45)) &&
@@ -1148,6 +1155,7 @@ abort();
 	    
 	    LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id);
 
+
             // increment first rb for next UE allocation
             first_rb[CC_id]+=rb_table[rb_table_index];
 	    
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index 0aeeeb8d351ecdc1f356a688210add47449bf7a5..ce680273e032ec8bababbb4ca6e3b3a3c61dc04b 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -606,7 +606,7 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
       }
 
 
-      // hypotetical assignement
+      // hypothetical assignment
       /*
        * If schedule is enabled and if the priority of the UEs is modified
        * The average rbs per logical channel per user will depend on the level of
@@ -640,9 +640,12 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
 
     for (ii=0; ii<UE_num_active_CC(UE_list,i); ii++) {
       CC_id = UE_list->ordered_CCids[ii][i];
+      ue_sched_ctl = &UE_list->UE_sched_ctrl[i];
+      round    = ue_sched_ctl->round[CC_id][harq_pid];
 
-      // control channel
-      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED) {
+      // control channel or retransmission
+      /* TODO: do we have to check for retransmission? */
+      if (mac_eNB_get_rrc_status(Mod_id,rnti) < RRC_RECONFIGURED || round > 0) {
         nb_rbs_required_remaining_1[CC_id][i] = nb_rbs_required[CC_id][i];
       } else {
         nb_rbs_required_remaining_1[CC_id][i] = cmin(average_rbs_per_user[CC_id],nb_rbs_required[CC_id][i]);
@@ -664,6 +667,7 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
           nb_rbs_required_remaining[CC_id][i] = nb_rbs_required_remaining_1[CC_id][i];
         } else { // rb required based only on the buffer - rb allloctaed in the 1st round + extra reaming rb form the 1st round
           nb_rbs_required_remaining[CC_id][i] = nb_rbs_required[CC_id][i]-nb_rbs_required_remaining_1[CC_id][i]+nb_rbs_required_remaining[CC_id][i];
+if (nb_rbs_required_remaining[CC_id][i]<0) abort();
         }
 
         if (nb_rbs_required[CC_id][i]> 0 )
@@ -863,7 +867,7 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
   }
 }
 
-#define SF05_LIMIT 1
+#define SF0_LIMIT 1
 
 void dlsch_scheduler_pre_processor_reset (int module_idP,
 					  int UE_id,
@@ -881,12 +885,12 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
   UE_list_t *UE_list=&RC.mac[module_idP]->UE_list;
   UE_sched_ctrl *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
   rnti_t rnti = UE_RNTI(module_idP,UE_id);
+
   uint8_t *vrb_map = RC.mac[module_idP]->common_channels[CC_id].vrb_map;
   int N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth);
-  int RBGsize = N_RB_DL/N_RBG;
-#ifdef SF05_LIMIT
-  //int subframe05_limit=0;
-  int sf05_upper=-1,sf05_lower=-1;
+  int RBGsize = N_RB_DL/N_RBG,RBGsize_last;
+#ifdef SF0_LIMIT
+  int sf0_upper=-1,sf0_lower=-1;
 #endif
 
 
@@ -955,45 +959,61 @@ void dlsch_scheduler_pre_processor_reset (int module_idP,
   ue_sched_ctl->pre_nb_available_rbs[CC_id] = 0;
   ue_sched_ctl->dl_pow_off[CC_id] = 2;
   nb_rbs_required_remaining[CC_id][UE_id] = 0;
-
-#ifdef SF05_LIMIT  
+  
+  switch (N_RB_DL) {
+  case 6:   RBGsize = 1; RBGsize_last = 1; break;
+  case 15:  RBGsize = 2; RBGsize_last = 1; break;
+  case 25:  RBGsize = 2; RBGsize_last = 1; break;
+  case 50:  RBGsize = 3; RBGsize_last = 2; break;
+  case 75:  RBGsize = 4; RBGsize_last = 3; break;
+  case 100: RBGsize = 4; RBGsize_last = 4; break;
+  default: AssertFatal(1==0,"unsupported RBs (%d)\n", N_RB_DL);
+  }
+  
+#ifdef SF0_LIMIT
   switch (N_RBG) {
   case 6:
-    sf05_lower=0;
-    sf05_upper=5;
+    sf0_lower=0;
+    sf0_upper=5;
     break;
   case 8:
-    sf05_lower=2;
-    sf05_upper=5;
+    sf0_lower=2;
+    sf0_upper=5;
     break;
   case 13:
-    sf05_lower=4;
-    sf05_upper=7;
+    sf0_lower=4;
+    sf0_upper=7;
     break;
   case 17:
-    sf05_lower=7;
-    sf05_upper=9;
+    sf0_lower=7;
+    sf0_upper=9;
     break;
   case 25:
-    sf05_lower=11;
-    sf05_upper=13;
+    sf0_lower=11;
+    sf0_upper=13;
     break;
+  default: AssertFatal(1==0,"unsupported RBs (%d)\n", N_RB_DL);
   }
 #endif
   // Initialize Subbands according to VRB map
   for (i=0; i<N_RBG; i++) {
+    int rb_size = i==N_RBG-1 ? RBGsize_last : RBGsize;
+
     ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 0;
     rballoc_sub[CC_id][i] = 0;
-#ifdef SF05_LIMIT
-    // for avoiding 6+ PRBs around DC in subframe 0-5 (avoid excessive errors)
-
-    if ((subframeP==0 || subframeP==5) && 
-	(i>=sf05_lower && i<=sf05_upper))
+#ifdef SF0_LIMIT
+    // for avoiding 6+ PRBs around DC in subframe 0 (avoid excessive errors)
+    /* TODO: make it proper - allocate those RBs, do not "protect" them, but
+     * compute number of available REs and limit MCS according to the
+     * TBS table 36.213 7.1.7.2.1-1 (can be done after pre-processor)
+     */
+    if (subframeP==0 &&
+	i >= sf0_lower && i <= sf0_upper)
       rballoc_sub[CC_id][i]=1;
 #endif
     // for SI-RNTI,RA-RNTI and P-RNTI allocations
-    for (j=0;j<RBGsize;j++) {
-      if (vrb_map[j+(i*RBGsize)]!=0)  {
+    for (j = 0; j < rb_size; j++) {
+      if (vrb_map[j+(i*RBGsize)] != 0)  {
 	rballoc_sub[CC_id][i] = 1;
 	LOG_D(MAC,"Frame %d, subframe %d : vrb %d allocated\n",frameP,subframeP,j+(i*RBGsize));
 	break;
@@ -1033,14 +1053,16 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
       if (ue_sched_ctl->dl_pow_off[CC_id] != 0 )  {
 
 	if ((i == N_RBG-1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) {
-	  rballoc_sub[CC_id][i] = 1;
-	  ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
-	  MIMO_mode_indicator[CC_id][i] = 1;
-	  if (transmission_mode == 5 ) {
-	    ue_sched_ctl->dl_pow_off[CC_id] = 1;
-	  }   
-	  nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
-          ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
+	  if (nb_rbs_required_remaining[CC_id][UE_id] >=  min_rb_unit-1){
+            rballoc_sub[CC_id][i] = 1;
+            ue_sched_ctl->rballoc_sub_UE[CC_id][i] = 1;
+            MIMO_mode_indicator[CC_id][i] = 1;
+            if (transmission_mode == 5 ) {
+              ue_sched_ctl->dl_pow_off[CC_id] = 1;
+            }
+            nb_rbs_required_remaining[CC_id][UE_id] = nb_rbs_required_remaining[CC_id][UE_id] - min_rb_unit+1;
+            ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1;
+          }
         } else {
 	  if (nb_rbs_required_remaining[CC_id][UE_id] >=  min_rb_unit){
 	    rballoc_sub[CC_id][i] = 1;
@@ -1056,7 +1078,6 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
       } // dl_pow_off[CC_id][UE_id] ! = 0
     }
   }
-
 }
 
 
@@ -1301,7 +1322,10 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
       // if this UE has UL traffic
       if (UE_template->ul_total_buffer > 0 ) {
 
+
         tbs = get_TBS_UL(mcs,3)<<3;  // 1 or 2 PRB with cqi enabled does not work well!
+        rb_table_index = 2;
+
         // fixme: set use_srs flag
         tx_power= estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,Ncp,0);
 
@@ -1344,8 +1368,15 @@ void assign_max_mcs_min_rb(module_id_t module_idP,int frameP, sub_frame_t subfra
               UE_template->pre_allocated_nb_rb_ul,
               UE_template->phr_info,tx_power);
       } else {
-        UE_template->pre_allocated_rb_table_index_ul=-1;
-        UE_template->pre_allocated_nb_rb_ul=0;
+        /* if UE has pending scheduling request then pre-allocate 3 RBs */
+        //if (UE_template->ul_active == 1 && UE_template->ul_SR == 1) {
+        if (UE_is_to_be_scheduled(module_idP, CC_id, i)) {
+          UE_template->pre_allocated_rb_table_index_ul = 2;
+          UE_template->pre_allocated_nb_rb_ul          = 3;
+        } else {
+          UE_template->pre_allocated_rb_table_index_ul=-1;
+          UE_template->pre_allocated_nb_rb_ul=0;
+        }
       }
     }
   }
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 3d9cc64f246ff6d971642f3d3e2ff342599c308e..3c2faf725acd9841d43332de161a36e42f1f1045 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -341,8 +341,9 @@ ue_send_sdu(
   unsigned char rx_lcids[NB_RB_MAX];
   unsigned short rx_lengths[NB_RB_MAX];
   unsigned char *tx_sdu;
-
+#if UE_TIMING_TRACE
   start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
 
   LOG_T(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]);
@@ -500,13 +501,16 @@ ue_send_sdu(
   } // end if (payload_ptr != NULL)
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
   stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
+#endif
 }
 
 void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len)
 {
-
-  start_meas(&UE_mac_inst[module_idP].rx_si);
+#if UE_TIMING_TRACE
+    start_meas(&UE_mac_inst[module_idP].rx_si);
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN);
 
   LOG_D(MAC,"[UE %d] Frame %d Sending SI to RRC (LCID Id %d,len %d)\n",module_idP,frameP,BCCH,len);
@@ -522,7 +526,9 @@ void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_i
                    eNB_index,
                    0);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
   stop_meas(&UE_mac_inst[module_idP].rx_si);
+#endif
   if (opt_enabled == 1) {
     trace_pdu(0,
 	      (uint8_t *)pdu,
@@ -541,8 +547,9 @@ void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_i
 
 void ue_decode_p(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len)
 {
-
-  start_meas(&UE_mac_inst[module_idP].rx_p);
+#if UE_TIMING_TRACE
+    start_meas(&UE_mac_inst[module_idP].rx_p);
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_IN);
 
   LOG_D(MAC,"[UE %d] Frame %d Sending Paging message to RRC (LCID Id %d,len %d)\n",module_idP,frameP,PCCH,len);
@@ -558,7 +565,9 @@ void ue_decode_p(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_in
                    eNB_index,
                    0);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
   stop_meas(&UE_mac_inst[module_idP].rx_p);
+#endif
   if (opt_enabled == 1) {
     trace_pdu(0,
 	      (uint8_t *)pdu,
@@ -632,8 +641,9 @@ void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint
   unsigned char num_sdu, i, *payload_ptr;
   unsigned char rx_lcids[NB_RB_MAX];
   unsigned short rx_lengths[NB_RB_MAX];
-
+#if UE_TIMING_TRACE
   start_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN);
 
   LOG_D(MAC,"[UE %d] Frame %d : process the mch PDU for sync area %d \n",module_idP,frameP, sync_area);
@@ -692,7 +702,9 @@ void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
   stop_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
+#endif
 }
 
 int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_area, unsigned char eNB_index)
@@ -717,9 +729,13 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
   int mbsfn_period = 0;// 1<<(UE_mac_inst[module_idP].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
   int mcch_period = 0;// 32<<(UE_mac_inst[module_idP].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
   int mch_scheduling_period = -1;
+
   int frame_FDD=1;
 
+
+#if UE_TIMING_TRACE
   start_meas(&UE_mac_inst[module_idP].ue_query_mch);
+#endif
 
   if (UE_mac_inst[module_idP].pmch_Config[0]) {
     mch_scheduling_period = 8<<(UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9);
@@ -976,8 +992,9 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
       }
     }
   } // end of for
-
+#if UE_TIMING_TRACE
   stop_meas(&UE_mac_inst[module_idP].ue_query_mch);
+#endif
 
   if ( (mcch_flag==1)) { // || (msi_flag==1))
     *mcch_active=1;
@@ -1295,9 +1312,13 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
   LOG_D(MAC,"[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n",
                         module_idP, frameP, subframe, buflen);
 
+
   AssertFatal(CC_id==0,
 	      "Transmission on secondary CCs is not supported yet\n");
+
+#if UE_TIMING_TRACE
   start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_IN);
 
 #ifdef CBA
@@ -1779,7 +1800,9 @@ for (lcid=DCCH; (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE) ; lcid
   }
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
   stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
+#endif
   
   if (opt_enabled) {
     trace_pdu(0, ulsch_buffer, buflen, module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0);
@@ -1823,7 +1846,9 @@ ue_scheduler(
   instance_t    instance;
   int           result;
 #endif
+#if UE_TIMING_TRACE
   start_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#endif
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_IN);
 
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO, UE_mac_inst[module_idP].crnti, txFrameP, txSubframeP,eNB_indexP);
@@ -1883,14 +1908,18 @@ ue_scheduler(
   case RRC_ConnSetup_failed:
     LOG_E(MAC,"RRCConnectionSetup failed, returning to IDLE state\n");
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
     stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#endif
     return(CONNECTION_LOST);
     break;
 
   case RRC_PHY_RESYNCH:
     LOG_E(MAC,"RRC Loss of synch, returning PHY_RESYNCH\n");
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
     stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#endif
     return(PHY_RESYNCH);
 
   case RRC_Handover_failed:
@@ -1903,7 +1932,9 @@ ue_scheduler(
   case RRC_HO_STARTED:
     LOG_I(MAC,"RRC handover, Instruct PHY to start the contention-free PRACH and synchronization\n");
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
     stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#endif
     return(PHY_HO_PRACH);
 
   default:
@@ -1920,8 +1951,13 @@ ue_scheduler(
     } else {
       LOG_E(MAC,"FATAL: radioResourceConfigCommon is NULL!!!\n");
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
+
       stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
       AssertFatal(1==0,"");
+
+#if UE_TIMING_TRACE
+      stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#endif
       //return(RRC_OK);
     }
 
@@ -2005,7 +2041,9 @@ ue_scheduler(
     UE_mac_inst[module_idP].ul_active=0;
     LOG_T(MAC,"[UE %d] Release all SRs \n", module_idP);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
+#if UE_TIMING_TRACE
     stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#endif
     return(CONNECTION_OK);
   }
 
@@ -2053,7 +2091,9 @@ ue_scheduler(
 
   //If the UE has UL resources allocated for new transmission for this TTI here:
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
-  stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#if UE_TIMING_TRACE
+    stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
+#endif
   return(CONNECTION_OK);
 }
 
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
index f80a46695d21baef203f4eaa59ec03b8267358ae..06ad9a3b05ace2ccbaeff4fe42a5d6a040254181 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c
@@ -206,23 +206,28 @@ boolean_t rlc_am_nack_pdu (
 void rlc_am_ack_pdu (
   const protocol_ctxt_t* const  ctxt_pP,
   rlc_am_entity_t *const rlc_pP,
-  const rlc_sn_t snP)
+  const rlc_sn_t snP,
+  boolean_t free_pdu)
 {
   mem_block_t* mb_p         = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block;
   rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE];
 
   tx_data_pdu_buffer->flags.retransmit = 0;
 
-  if ((tx_data_pdu_buffer->flags.ack == 0) && (mb_p != NULL)) {
-    //if (mb_pP != NULL) {
+  if (mb_p != NULL) {
+    if (free_pdu) {
     free_mem_block(mb_p, __func__);
     tx_data_pdu_buffer->mem_block = NULL;
     LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[ACK-PDU] ACK PDU SN %05d previous retx_count %d \n",
           PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
           snP,
 		  tx_data_pdu_buffer->retx_count);
+    }
 
     if (tx_data_pdu_buffer->retx_payload_size) {
+    	AssertFatal (tx_data_pdu_buffer->flags.ack == 0,
+    			"RLC AM Rx Status Report sn=%d acked twice but is pending for Retx vtA=%d vtS=%d LcId=%d\n",
+				snP, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
       rlc_pP->retrans_num_bytes_to_retransmit -= tx_data_pdu_buffer->retx_payload_size;
       tx_data_pdu_buffer->retx_payload_size = 0;
       tx_data_pdu_buffer->num_holes = 0;
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h
index 338bc791968565aba6640d19f2e6dc181c30695c..7224d39bf96b90b11562fb4be5eb47c74daeca41 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h
@@ -74,12 +74,14 @@ protected_rlc_am_retransmit(boolean_t         rlc_am_nack_pdu (
 * \param[in]  ctxtP        Running context.
 * \param[in]  rlcP         RLC AM protocol instance pointer.
 * \param[in]  snP          Sequence number of the PDU that is acknowledged.
+* \param[in]  free_pdu     Boolean indicating that the PDU can be freed because smaller than new vtA.
 * \note                    Depending on the state of the retransmission buffer, positive confirmation can be sent to higher layers about the receiving by the peer RLC AM instance of a particular SDU.
 */
 protected_rlc_am_retransmit(void         rlc_am_ack_pdu (
                               const protocol_ctxt_t* const  ctxt_pP,
                               rlc_am_entity_t *const rlcP,
-                              const rlc_sn_t snP);)
+                              const rlc_sn_t snP,
+							  boolean_t free_pdu);)
 
 /*! \fn mem_block_t* rlc_am_retransmit_get_copy (const protocol_ctxt_t* const  ctxt_pP, rlc_am_entity_t *rlcP, rlc_sn_t snP)
 * \brief      The RLC AM PDU which have the sequence number snP is marked ACKed.
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
index c07e9cd6f3fbd65f51ec07a584784bb6b799ad3d..a5c15a5262a15bcb154c9c013765ebeb8f5645db 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c
@@ -318,7 +318,7 @@ rlc_am_receive_process_control_pdu(
     {
       if (rlc_pP->control_pdu_info.num_nack == 0) {
         while (sn_cursor != ack_sn) {
-          rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor);
+          rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE);
           sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
         }
 
@@ -330,7 +330,7 @@ rlc_am_receive_process_control_pdu(
         prev_nack_sn = 0x3FFF;
 
         while (sn_cursor != nack_sn) {
-            rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor);
+            rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE);
             sn_cursor = RLC_AM_NEXT_SN(sn_cursor);
         }
 
@@ -354,7 +354,8 @@ rlc_am_receive_process_control_pdu(
           if (sn_cursor != nack_sn) {
             rlc_am_ack_pdu(ctxt_pP,
                            rlc_pP,
-                           sn_cursor);
+                           sn_cursor,
+						   FALSE);
           } else {
         	status = rlc_am_nack_pdu (ctxt_pP,
                              rlc_pP,
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c
index 2dfa472523f5a536f7515ccaaa8d1fbbc218168b..3edb09d22815ca0053af0aecf9aed40f1f53e8a7 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c
@@ -88,8 +88,8 @@ rlc_am_check_timer_poll_retransmit(
           /* Look for the first retransmittable PDU starting from vtS - 1 */
 		  while (sn != sn_end) {
 			tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE];
-			AssertFatal (tx_data_pdu_buffer_p->mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d is empty vtA=%d vtS=%d LcId=%d\n",
-					sn, rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+			AssertFatal (tx_data_pdu_buffer_p->mem_block != NULL, "RLC AM Tpoll Retx expiry sn=%d ack=%d is empty vtA=%d vtS=%d LcId=%d\n",
+					sn, tx_data_pdu_buffer_p->flags.ack,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
 		    if ((tx_data_pdu_buffer_p->flags.ack == 0) && (tx_data_pdu_buffer_p->flags.max_retransmit == 0)) {
 		    	tx_data_pdu_buffer_p->flags.retransmit = 1;
 		    	tx_data_pdu_buffer_p->retx_payload_size = tx_data_pdu_buffer_p->payload_size;
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index 762ba78b495d10dff720ce00e636596aad0ec982..c378e4766375827068e564774ab585e8ef3d4d29 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -1555,7 +1555,7 @@ do_RRCConnectionSetup(
   // SchedulingRequestConfig
 
   physicalConfigDedicated2->schedulingRequestConfig->present = SchedulingRequestConfig_PR_setup;
-  physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 3;//ue_context_pP->local_uid;
+  physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid;
 
   if (carrier->sib1->tdd_Config == NULL) { // FDD
     physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5+(ue_context_pP->local_uid%10);  // Isr = 5 (every 10 subframes, offset=2+UE_id mod3)
diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h
index 5140a08dbd4489b77c7ca86b5aeb2383a82277b7..86abb5eab60e71315524ad3432ab193f44522a0c 100644
--- a/openair2/UTIL/LOG/log.h
+++ b/openair2/UTIL/LOG/log.h
@@ -45,6 +45,9 @@
 #include <stdarg.h>
 #include <time.h>
 #include <stdint.h>
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
 #include <inttypes.h>
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
@@ -315,16 +318,29 @@ void *log_thread_function(void * list);
 #    define LOG_N(c, x...) /* */
 #    define LOG_F(c, x...) /* */
 #  else /* T_TRACER */
-#    define LOG_G(c, x...) logIt(c, LOG_EMERG, x)
-#    define LOG_A(c, x...) logIt(c, LOG_ALERT, x)
-#    define LOG_C(c, x...) logIt(c, LOG_CRIT,  x)
-#    define LOG_E(c, x...) logIt(c, LOG_ERR, x)
-#    define LOG_W(c, x...) logIt(c, LOG_WARNING, x)
-#    define LOG_N(c, x...) logIt(c, LOG_NOTICE, x)
-#    define LOG_I(c, x...) logIt(c, LOG_INFO, x)
-#    define LOG_D(c, x...) logIt(c, LOG_DEBUG, x)
-#    define LOG_F(c, x...) logIt(c, LOG_FILE, x)  // log to a file, useful for the MSC chart generation
-#    define LOG_T(c, x...) logIt(c, LOG_TRACE, x)
+#    if DISABLE_LOG_X
+#        define LOG_I(c, x...) /* */
+#        define LOG_W(c, x...) /* */
+#        define LOG_E(c, x...) /* */
+#        define LOG_D(c, x...) /* */
+#        define LOG_T(c, x...) /* */
+#        define LOG_G(c, x...) /* */
+#        define LOG_A(c, x...) /* */
+#        define LOG_C(c, x...) /* */
+#        define LOG_N(c, x...) /* */
+#        define LOG_F(c, x...) /* */
+#    else  /*DISABLE_LOG_X*/
+#        define LOG_G(c, x...) logIt(c, LOG_EMERG, x)
+#        define LOG_A(c, x...) logIt(c, LOG_ALERT, x)
+#        define LOG_C(c, x...) logIt(c, LOG_CRIT,  x)
+#        define LOG_E(c, x...) logIt(c, LOG_ERR, x)
+#        define LOG_W(c, x...) logIt(c, LOG_WARNING, x)
+#        define LOG_N(c, x...) logIt(c, LOG_NOTICE, x)
+#        define LOG_I(c, x...) logIt(c, LOG_INFO, x)
+#        define LOG_D(c, x...) logIt(c, LOG_DEBUG, x)
+#        define LOG_F(c, x...) logIt(c, LOG_FILE, x)  // log to a file, useful for the MSC chart generation
+#        define LOG_T(c, x...) logIt(c, LOG_TRACE, x)
+#    endif /*DISABLE_LOG_X*/
 #  endif /* T_TRACER */
 #else /* USER_MODE */
 #  define LOG_G(c, x...) printk(x)
@@ -408,7 +424,11 @@ static inline void printMeas(char * txt, Meas *M, int period) {
                 M->iterations,
                 M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], 
                 M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
-        LOG_W(PHY,"%s",txt2);
+#if DISABLE_LOG_X
+        printf("%s",txt2);
+#else
+        LOG_W(PHY, "%s",txt2);
+#endif
     }
 }
 
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.c b/openair2/UTIL/LOG/vcd_signal_dumper.c
index 88c6c6b8b57f4d3e02ea404fc807504d56eaa5cf..665e5b4384b30364e8df83f40e875e0bc874b2ab 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.c
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.c
@@ -185,16 +185,16 @@ const char* eurecomVariablesNames[] = {
   "ue0_SFN5",
   "ue0_SFN6",
   "ue0_SFN7",
+  "send_if4_symbol",
+  "recv_if4_symbol",
+  "send_if5_pkt_id",
+  "recv_if5_pkt_id",
   "ue_pdcp_flush_size",
   "ue_pdcp_flush_err",
   "ue0_trx_read_ns",
   "ue0_trx_write_ns",
   "ue0_trx_read_ns_missing",
-  "ue0_trx_write_ns_missing"
-  "send_if4_symbol",
-  "recv_if4_symbol",
-  "send_if5_pkt_id",
-  "recv_if5_pkt_id"
+  "ue0_trx_write_ns_missing",
 };
 
 const char* eurecomFunctionsNames[] = {
@@ -398,10 +398,10 @@ const char* eurecomFunctionsNames[] = {
   "recv_if5",
 
   "compress_if",
-  "decompress_if"
+  "decompress_if",
 };
 
-struct vcd_module_s vcd_modules[VCD_SIGNAL_DUMPER_MODULE_END] = {
+struct vcd_module_s vcd_modules[] = {
   { "variables", VCD_SIGNAL_DUMPER_VARIABLES_END, eurecomVariablesNames, VCD_WIRE, 64 },
   { "functions", VCD_SIGNAL_DUMPER_FUNCTIONS_END, eurecomFunctionsNames, VCD_WIRE, 1 },
   //    { "ue_procedures_functions", VCD_SIGNAL_DUMPER_UE_PROCEDURES_FUNCTIONS_END, eurecomUEFunctionsNames, VCD_WIRE, 1 },
@@ -702,7 +702,7 @@ void vcd_signal_dumper_create_header(void)
       fprintf(vcd_fd, "$timescale 1 ns $end\n");
 
       /* Initialize each module definition */
-      for(i = 0; i < VCD_SIGNAL_DUMPER_MODULE_END; i++) {
+      for(i = 0; i < sizeof(vcd_modules) / sizeof(struct vcd_module_s); i++) {
         struct vcd_module_s *module;
         module = &vcd_modules[i];
         fprintf(vcd_fd, "$scope module %s $end\n", module->name);
@@ -727,7 +727,7 @@ void vcd_signal_dumper_create_header(void)
       /* Init variables and functions to 0 */
       fprintf(vcd_fd, "$dumpvars\n");
 
-      for(i = 0; i < VCD_SIGNAL_DUMPER_MODULE_END; i++) {
+      for(i = 0; i < sizeof(vcd_modules) / sizeof(struct vcd_module_s); i++) {
         struct vcd_module_s *module;
         module = &vcd_modules[i];
 
diff --git a/openair2/UTIL/LOG/vcd_signal_dumper.h b/openair2/UTIL/LOG/vcd_signal_dumper.h
index 85e536fac16bd119c31e85f6636caf6a6e50d95e..d777236b34d6585fbb9f40ef6d60206f5df5e478 100644
--- a/openair2/UTIL/LOG/vcd_signal_dumper.h
+++ b/openair2/UTIL/LOG/vcd_signal_dumper.h
@@ -167,8 +167,7 @@ typedef enum {
   VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS,
   VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_READ_NS_MISSING,
   VCD_SIGNAL_DUMPER_VARIABLES_UE0_TRX_WRITE_NS_MISSING,
-  VCD_SIGNAL_DUMPER_VARIABLES_LAST,
-  VCD_SIGNAL_DUMPER_VARIABLES_END = VCD_SIGNAL_DUMPER_VARIABLES_LAST,
+  VCD_SIGNAL_DUMPER_VARIABLES_END
 } vcd_signal_dump_variables;
 
 typedef enum {
@@ -377,8 +376,7 @@ typedef enum {
   VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_COMPR_IF,
   VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_DECOMPR_IF,
 
-  VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
-  VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
+  VCD_SIGNAL_DUMPER_FUNCTIONS_END
 } vcd_signal_dump_functions;
 
 typedef enum {
@@ -387,8 +385,6 @@ typedef enum {
   VCD_SIGNAL_DUMPER_MODULE_VARIABLES,
   VCD_SIGNAL_DUMPER_MODULE_FUNCTIONS,
   //     VCD_SIGNAL_DUMPER_MODULE_UE_PROCEDURES_FUNCTIONS,
-  VCD_SIGNAL_DUMPER_MODULE_LAST,
-  VCD_SIGNAL_DUMPER_MODULE_END = VCD_SIGNAL_DUMPER_MODULE_LAST,
 } vcd_signal_dumper_modules;
 
 typedef enum {
diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
index 84ec59a36bcb9906c8f9010a7dabfbfb2e62412e..33405805a6b6a480c684a98a7c5ea12e4075b68b 100644
--- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
+++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
@@ -87,8 +87,8 @@ UE0:
 
     SIM: {
         MSIN="0100001111";
-        USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f";
-        OPC="C42449363BBAD02B66D16BC975D77CC1";
+        USIM_API_K="8baf473f2f8fd09487cccbd7097c6862";
+        OPC="e734f8734007d6c5ce7a0508809e7e9c";
         MSISDN="33611123456";
     };
 
diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
index d70abbd9f118887daa19ecc563766f4af6f75418..ccc559231c2557d259a3b1482cca9e983bf202fe 100644
--- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
+++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
@@ -82,6 +82,48 @@ openair0_timestamp trx_get_timestamp(openair0_device *device, bladerf_module mod
  * \returns 0 on success
  */
 int trx_brf_start(openair0_device *device) {
+  brf_state_t *brf = (brf_state_t*)device->priv;
+  int status;
+
+  brf->meta_tx.flags = 0;
+
+  if ((status = bladerf_sync_config(brf->dev,
+          BLADERF_MODULE_TX,
+          BLADERF_FORMAT_SC16_Q11_META,
+          brf->num_buffers,
+          brf->buffer_size,
+          brf->num_transfers,
+          100/*brf->tx_timeout_ms*/)) != 0 ) {
+    fprintf(stderr,"Failed to configure TX sync interface: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status = bladerf_sync_config(brf->dev,
+          BLADERF_MODULE_RX,
+          BLADERF_FORMAT_SC16_Q11_META,
+          brf->num_buffers,
+          brf->buffer_size,
+          brf->num_transfers,
+          100/*brf->rx_timeout_ms*/)) != 0 ) {
+    fprintf(stderr,"Failed to configure RX sync interface: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, true)) != 0) {
+    fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, true)) != 0) {
+    fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+
+  if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_TX)) != 0) {
+    fprintf(stderr,"Failed to calibrate TX DC: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_RX)) != 0) {
+    fprintf(stderr,"Failed to calibrate RX DC: %s\n", bladerf_strerror(status));
+    abort();
+  }
 
   return 0;
 }
@@ -133,7 +175,7 @@ static int trx_brf_write(openair0_device *device,openair0_timestamp ptimestamp,
   brf->tx_count++;
   
 
-  return(0);
+  return nsamps; //brf->meta_tx.actual_count;
 }
 
 /*! \brief Receive samples from hardware.
@@ -155,6 +197,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
   // BRF has only one rx/tx chain
   int16_t *samples = (int16_t*)buff[0];
   
+  brf->meta_rx.actual_count = 0;
   brf->meta_rx.flags = BLADERF_META_FLAG_RX_NOW;
   status = bladerf_sync_rx(brf->dev, samples, (unsigned int) nsamps, &brf->meta_rx, 2*brf->rx_timeout_ms);
   
@@ -170,6 +213,10 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
 	   brf->num_overflows,brf->meta_rx.timestamp,  brf->meta_rx.actual_count, nsamps);
   } 
 
+  if (brf->meta_rx.actual_count != nsamps) {
+    printf("RX bad samples count, wanted %d, got %d\n", nsamps, brf->meta_rx.actual_count);
+  }
+
   //printf("Current RX timestampe  %u\n",  brf->meta_rx.timestamp);
   //printf("[BRF] (buff %p) ts=0x%"PRIu64" %s\n",samples, brf->meta_rx.timestamp,bladerf_strerror(status));
   brf->rx_current_ts=brf->meta_rx.timestamp;
@@ -180,7 +227,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
   
   *ptimestamp = brf->meta_rx.timestamp;
  
-  return brf->meta_rx.actual_count;
+  return nsamps; //brf->meta_rx.actual_count;
 
 }
 
@@ -188,6 +235,7 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp,
  * \param device the hardware to use
  */
 void trx_brf_end(openair0_device *device) {
+abort();
 
   int status;
   brf_state_t *brf = (brf_state_t*)device->priv;
@@ -1081,6 +1129,15 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
 
   //  memcpy((void*)&device->openair0_cfg,(void*)&openair0_cfg[0],sizeof(openair0_config_t));
 
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_TX, false)) != 0) {
+    fprintf(stderr,"Failed to enable TX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+  if ((status=bladerf_enable_module(brf->dev, BLADERF_MODULE_RX, false)) != 0) {
+    fprintf(stderr,"Failed to enable RX module: %s\n", bladerf_strerror(status));
+    abort();
+  }
+
   return 0;
 }
 
diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h
index c59488261f83aae9bb2ec6c6671bd63f6b7c9e76..2603aa9b511e8bc5c81b69fbb43e09e4ca416a81 100644
--- a/targets/ARCH/COMMON/common_lib.h
+++ b/targets/ARCH/COMMON/common_lib.h
@@ -140,7 +140,9 @@ typedef enum {
   //! This tells the underlying hardware to use the internal reference
   internal=0,
   //! This tells the underlying hardware to use the external reference
-  external=1
+  external=1,
+  //! This tells the underlying hardware to use the gpsdo reference
+  gpsdo=2
 } clock_source_t;
 
 /*! \brief RF frontend parameters set by application */
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index 4710439f6b9f4adef82196835d1509610a4a0ceb..a01a955844721481a9c8b3cdcfe5dce6967dcd82 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -33,6 +33,8 @@
 #include <uhd/version.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string.hpp>
+#include <boost/thread.hpp>
+#include <boost/format.hpp>
 #include <iostream>
 #include <complex>
 #include <fstream>
@@ -92,12 +94,181 @@ typedef struct {
     int num_seq_errors;
     int64_t tx_count;
     int64_t rx_count;
+    int wait_for_first_pps;
+    int use_gps;
     //! timestamp of RX packet
     openair0_timestamp rx_timestamp;
 
 } usrp_state_t;
 
+//void print_notes(void)
+//{
+    // Helpful notes
+  //  std::cout << boost::format("**************************************Helpful Notes on Clock/PPS Selection**************************************\n");
+  //  std::cout << boost::format("As you can see, the default 10 MHz Reference and 1 PPS signals are now from the GPSDO.\n");
+  //  std::cout << boost::format("If you would like to use the internal reference(TCXO) in other applications, you must configure that explicitly.\n");
+  //  std::cout << boost::format("You can no longer select the external SMAs for 10 MHz or 1 PPS signaling.\n");
+  //  std::cout << boost::format("****************************************************************************************************************\n");
+//}
+
+static int sync_to_gps(openair0_device *device)
+{
+    uhd::set_thread_priority_safe();
+
+    //std::string args;
+
+    //Set up program options
+    //po::options_description desc("Allowed options");
+    //desc.add_options()
+    //("help", "help message")
+    //("args", po::value<std::string>(&args)->default_value(""), "USRP device arguments")
+    //;
+    //po::variables_map vm;
+    //po::store(po::parse_command_line(argc, argv, desc), vm);
+    //po::notify(vm);
+
+    //Print the help message
+    //if (vm.count("help"))
+    //{
+      //  std::cout << boost::format("Synchronize USRP to GPS %s") % desc << std::endl;
+      // return EXIT_FAILURE;
+    //}
+
+    //Create a USRP device
+    //std::cout << boost::format("\nCreating the USRP device with: %s...\n") % args;
+    //uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(args);
+    //std::cout << boost::format("Using Device: %s\n") % usrp->get_pp_string();
+ 
+    usrp_state_t *s = (usrp_state_t*)device->priv;    
+
+    try
+    {
+        size_t num_mboards = s->usrp->get_num_mboards();
+        size_t num_gps_locked = 0;
+        for (size_t mboard = 0; mboard < num_mboards; mboard++)
+        {
+            std::cout << "Synchronizing mboard " << mboard << ": " << s->usrp->get_mboard_name(mboard) << std::endl;
+
+            //Set references to GPSDO
+            s->usrp->set_clock_source("gpsdo", mboard);
+            s->usrp->set_time_source("gpsdo", mboard);
+
+            //std::cout << std::endl;
+            //print_notes();
+            //std::cout << std::endl;
+
+            //Check for 10 MHz lock
+            std::vector<std::string> sensor_names = s->usrp->get_mboard_sensor_names(mboard);
+            if(std::find(sensor_names.begin(), sensor_names.end(), "ref_locked") != sensor_names.end())
+            {
+                std::cout << "Waiting for reference lock..." << std::flush;
+                bool ref_locked = false;
+                for (int i = 0; i < 30 and not ref_locked; i++)
+                {
+                    ref_locked = s->usrp->get_mboard_sensor("ref_locked", mboard).to_bool();
+                    if (not ref_locked)
+                    {
+                        std::cout << "." << std::flush;
+                        boost::this_thread::sleep(boost::posix_time::seconds(1));
+                    }
+                }
+                if(ref_locked)
+                {
+                    std::cout << "LOCKED" << std::endl;
+                } else {
+                    std::cout << "FAILED" << std::endl;
+                    std::cout << "Failed to lock to GPSDO 10 MHz Reference. Exiting." << std::endl;
+                    exit(EXIT_FAILURE);
+                }
+            }
+            else
+            {
+                std::cout << boost::format("ref_locked sensor not present on this board.\n");
+            }
+
+            //Wait for GPS lock
+            bool gps_locked = s->usrp->get_mboard_sensor("gps_locked", mboard).to_bool();
+            if(gps_locked)
+            {
+                num_gps_locked++;
+                std::cout << boost::format("GPS Locked\n");
+            }
+            else
+            {
+                std::cerr << "WARNING:  GPS not locked - time will not be accurate until locked" << std::endl;
+            }
+
+            //Set to GPS time
+            uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int()));
+            //s->usrp->set_time_next_pps(gps_time+1.0, mboard);
+            s->usrp->set_time_next_pps(uhd::time_spec_t(0.0));
+
+            //Wait for it to apply
+            //The wait is 2 seconds because N-Series has a known issue where
+            //the time at the last PPS does not properly update at the PPS edge
+            //when the time is actually set.
+            boost::this_thread::sleep(boost::posix_time::seconds(2));
+
+            //Check times
+            gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int()));
+            uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(mboard);
+            std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl;
+            std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl;
+            //if (gps_time.get_real_secs() == time_last_pps.get_real_secs())
+            //    std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl;
+            //else
+            //    std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl;
+        }
+
+        if (num_gps_locked == num_mboards and num_mboards > 1)
+        {
+            //Check to see if all USRP times are aligned
+            //First, wait for PPS.
+            uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps();
+            while (time_last_pps == s->usrp->get_time_last_pps())
+            {
+                boost::this_thread::sleep(boost::posix_time::milliseconds(1));
+            }
+
+            //Sleep a little to make sure all devices have seen a PPS edge
+            boost::this_thread::sleep(boost::posix_time::milliseconds(200));
+
+            //Compare times across all mboards
+            bool all_matched = true;
+            uhd::time_spec_t mboard0_time = s->usrp->get_time_last_pps(0);
+            for (size_t mboard = 1; mboard < num_mboards; mboard++)
+            {
+                uhd::time_spec_t mboard_time = s->usrp->get_time_last_pps(mboard);
+                if (mboard_time != mboard0_time)
+                {
+                    all_matched = false;
+                    std::cerr << (boost::format("ERROR: Times are not aligned: USRP 0=%0.9f, USRP %d=%0.9f")
+                                  % mboard0_time.get_real_secs()
+                                  % mboard
+                                  % mboard_time.get_real_secs()) << std::endl;
+                }
+            }
+            if (all_matched)
+            {
+                std::cout << "SUCCESS: USRP times aligned" << std::endl << std::endl;
+            } else {
+                std::cout << "ERROR: USRP times are not aligned" << std::endl << std::endl;
+            }
+        }
+    }
+    catch (std::exception& e)
+    {
+        std::cout << boost::format("\nError: %s") % e.what();
+        std::cout << boost::format("This could mean that you have not installed the GPSDO correctly.\n\n");
+        std::cout << boost::format("Visit one of these pages if the problem persists:\n");
+        std::cout << boost::format(" * N2X0/E1X0: http://files.ettus.com/manual/page_gpsdo.html");
+        std::cout << boost::format(" * X3X0: http://files.ettus.com/manual/page_gpsdo_x3x0.html\n\n");
+        std::cout << boost::format(" * E3X0: http://files.ettus.com/manual/page_usrp_e3x0.html#e3x0_hw_gps\n\n");
+        exit(EXIT_FAILURE);
+    }
 
+    return EXIT_SUCCESS;
+}
 
 /*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
     @param device pointer to the device structure specific to the RF hardware target
@@ -106,9 +277,31 @@ static int trx_usrp_start(openair0_device *device) {
 
     usrp_state_t *s = (usrp_state_t*)device->priv;
 
+
+  // setup GPIO for TDD, GPIO(4) = ATR_RX
+  //set data direction register (DDR) to output
+    s->usrp->set_gpio_attr("FP0", "DDR", 0x1f, 0x1f);
+  
+  //set control register to ATR
+    s->usrp->set_gpio_attr("FP0", "CTRL", 0x1f,0x1f);
+  
+  //set ATR register
+    s->usrp->set_gpio_attr("FP0", "ATR_RX", 1<<4, 0x1f);
+
     // init recv and send streaming
     uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);
-    cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05);
+    LOG_I(PHY,"Time in secs now: %llu \n", s->usrp->get_time_now().to_ticks(s->sample_rate));
+    LOG_I(PHY,"Time in secs last pps: %llu \n", s->usrp->get_time_last_pps().to_ticks(s->sample_rate));
+
+    if (s->use_gps == 1) {
+      s->wait_for_first_pps = 1;
+      cmd.time_spec = s->usrp->get_time_last_pps() + uhd::time_spec_t(1.0);    
+    }
+    else {
+      s->wait_for_first_pps = 0; 
+      cmd.time_spec = s->usrp->get_time_now() + uhd::time_spec_t(0.05);
+    }
+
     cmd.stream_now = false; // start at constant delay
     s->rx_stream->issue_stream_cmd(cmd);
 
@@ -256,9 +449,11 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
             while (samples_received != nsamps) {
                 samples_received += s->rx_stream->recv(buff_tmp[0]+samples_received,
                                                        nsamps-samples_received, s->rx_md);
-                if (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE)
+                if  ((s->wait_for_first_pps == 0) && (s->rx_md.error_code!=uhd::rx_metadata_t::ERROR_CODE_NONE))
                     break;
+	        if ((s->wait_for_first_pps == 1) && (samples_received != nsamps)) { printf("sleep...\n");} //usleep(100); 
             }
+	    if (samples_received == nsamps) s->wait_for_first_pps=0;
         }
         // bring RX data into 12 LSBs for softmodem RX
         for (int i=0; i<cc; i++) {
@@ -497,6 +692,10 @@ extern "C" {
     int device_init(openair0_device* device, openair0_config_t *openair0_cfg) {
         uhd::set_thread_priority_safe(1.0);
         usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1);
+        
+	if (openair0_cfg[0].clock_source==gpsdo)        
+	    s->use_gps =1;
+
         // Initialize USRP device
         device->openair0_cfg = openair0_cfg;
 
@@ -590,10 +789,13 @@ extern "C" {
             // set master clock rate and sample rate for tx & rx for streaming
 
             // lock mboard clocks
-            if (openair0_cfg[0].clock_source == internal)
-                s->usrp->set_clock_source("internal");
-            else
+            if (openair0_cfg[0].clock_source == internal){
+	        s->usrp->set_clock_source("internal");
+            }
+            else{
                 s->usrp->set_clock_source("external");
+		s->usrp->set_time_source("external");
+            }	
 
             device->type = USRP_B200_DEV;
             if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) {
@@ -714,8 +916,6 @@ extern "C" {
         for(int i=0; i<s->usrp->get_rx_num_channels() && i<openair0_cfg[0].rx_num_channels; i++)
             s->usrp->set_rx_bandwidth(openair0_cfg[0].rx_bw,i);
 
-        s->usrp->set_time_now(uhd::time_spec_t(0.0));
-
         for (int i=0; i<openair0_cfg[0].rx_num_channels; i++) {
             LOG_I(PHY,"RX Channel %d\n",i);
             LOG_I(PHY,"  Actual RX sample rate: %fMSps...\n",s->usrp->get_rx_rate(i)/1e6);
@@ -757,6 +957,14 @@ extern "C" {
             s->tx_forward_nsamps = 90;
         if(is_equal(s->sample_rate, (double)7.68e6))
             s->tx_forward_nsamps = 50;
+
+        if (s->use_gps == 1) {
+	   if (sync_to_gps(device)) {
+		 LOG_I(PHY,"USRP fails to sync with GPS...\n");
+            exit(0);   
+           } 
+        }
+ 
         return 0;
     }
 }
diff --git a/targets/ARCH/mobipass/interface.c b/targets/ARCH/mobipass/interface.c
new file mode 100644
index 0000000000000000000000000000000000000000..780dd4fbc3445fe7da5f5037699618055d64c065
--- /dev/null
+++ b/targets/ARCH/mobipass/interface.c
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include <arpa/inet.h>
+#include <linux/if_packet.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/ether.h>
+#include <unistd.h>
+#include <errno.h>
+#include <linux/sysctl.h>
+#include <sys/sysctl.h>
+
+#include "common_lib.h"
+#include "ethernet_lib.h"
+
+#include "mobipass.h"
+#include "queues.h"
+
+struct mobipass_header {
+  uint16_t flags;
+  uint16_t fifo_status;
+  unsigned char seqno;
+  unsigned char ack;
+  uint32_t word0;
+  uint32_t timestamp;
+} __attribute__((__packed__));
+
+int mobipass_start(openair0_device *device) { init_mobipass(device->priv); return 0; }
+int mobipass_request(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; }
+int mobipass_reply(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; }
+int mobipass_get_stats(openair0_device* device) { return 0; }
+int mobipass_reset_stats(openair0_device* device) { return 0; }
+void mobipass_end(openair0_device *device) {}
+int mobipass_stop(openair0_device *device) { return 0; }
+int mobipass_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; }
+int mobipass_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { return 0; }
+
+int mobipass_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
+  mobipass_state_t *mobi = device->priv;
+  struct mobipass_header *mh = (struct mobipass_header *)(((char *)buff[0]) + 14);
+  mobi->mobipass_write_last_timestamp += 640;
+  mobi->mobipass_write_last_timestamp %= mobi->samples_per_1024_frames;
+  mh->timestamp = htonl(ntohl(mh->timestamp) % mobi->samples_per_1024_frames);
+  if (mobi->mobipass_write_last_timestamp != ntohl(mh->timestamp))
+    { printf("mobipass: ERROR: bad timestamp wanted %d got %d\n", mobi->mobipass_write_last_timestamp, ntohl(mh->timestamp)); exit(1); }
+//printf("__write nsamps %d timestamps %ld seqno %d (packet timestamp %d)\n", nsamps, timestamp, mh->seqno, ntohl(mh->timestamp));
+  if (nsamps != 640) abort();
+  enqueue_to_mobipass(mobi->qstate, buff[0]);
+  return nsamps;
+}
+
+int mobipass_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) {
+  mobipass_state_t *mobi = device->priv;
+//printf("__read nsamps %d return timestamp %d\n", nsamps, ts);
+  *timestamp = htonl(mobi->mobipass_read_ts);
+  mobi->mobipass_read_ts += nsamps;
+  mobi->mobipass_read_ts %= mobi->samples_per_1024_frames;
+  if (nsamps != 640) { printf("mobipass: ERROR: bad nsamps %d, should be 640\n", nsamps); fflush(stdout); abort(); }
+
+  dequeue_from_mobipass(mobi->qstate, ntohl(*timestamp), buff[0]);
+
+#if 1
+  struct mobipass_header *mh = (struct mobipass_header *)(((char *)buff[0]) + 14);
+  mh->flags = 0;
+  mh->fifo_status = 0;
+  mh->seqno = mobi->mobipass_read_seqno++;
+  mh->ack = 0;
+  mh->word0 = 0;
+  mh->timestamp = htonl(mobi->mobipass_read_ts);
+#endif
+
+  return nsamps;
+}
+
+/* this is the only function in the library that is visible from outside
+ * because in CMakeLists.txt we use -fvisibility=hidden
+ */
+__attribute__((__visibility__("default")))
+int transport_init(openair0_device *device, openair0_config_t *openair0_cfg,
+        eth_params_t * eth_params )
+{
+  //init_mobipass();
+
+  mobipass_state_t *mobi = (mobipass_state_t*)malloc(sizeof(mobipass_state_t));
+  memset(mobi, 0, sizeof(mobipass_state_t));
+
+  if (eth_params->transp_preference != 4) goto err;
+  if (eth_params->if_compress != 0) goto err;
+
+  /* only 50 PRBs handled for the moment */
+  if (openair0_cfg[0].sample_rate != 15360000) {
+    printf("mobipass: ERROR: only 50 PRBs supported\n");
+    exit(1);
+  }
+
+  mobi->eth.flags = ETH_RAW_IF5_MOBIPASS;
+  mobi->eth.compression = NO_COMPRESS;
+  device->Mod_id           = 0;//num_devices_eth++;
+  device->transp_type      = ETHERNET_TP;
+
+  device->trx_start_func   = mobipass_start;
+  device->trx_request_func = mobipass_request;
+  device->trx_reply_func   = mobipass_reply;
+  device->trx_get_stats_func   = mobipass_get_stats;
+  device->trx_reset_stats_func = mobipass_reset_stats;
+  device->trx_end_func         = mobipass_end;
+  device->trx_stop_func        = mobipass_stop;
+  device->trx_set_freq_func = mobipass_set_freq;
+  device->trx_set_gains_func = mobipass_set_gains;
+  device->trx_write_func   = mobipass_write;
+  device->trx_read_func    = mobipass_read;
+
+  device->priv = mobi;
+
+  mobi->eth.if_name = strdup(eth_params->local_if_name);
+  if (mobi->eth.if_name == NULL) abort();
+
+  if (sscanf(eth_params->my_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+          &mobi->eth_local[0],
+          &mobi->eth_local[1],
+          &mobi->eth_local[2],
+          &mobi->eth_local[3],
+          &mobi->eth_local[4],
+          &mobi->eth_local[5]) != 6) {
+    printf("mobipass: ERROR: bad local ethernet address '%s', check configuration file\n",
+           eth_params->my_addr);
+    exit(1);
+  }
+
+  if (sscanf(eth_params->remote_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+          &mobi->eth_remote[0],
+          &mobi->eth_remote[1],
+          &mobi->eth_remote[2],
+          &mobi->eth_remote[3],
+          &mobi->eth_remote[4],
+          &mobi->eth_remote[5]) != 6) {
+    printf("mobipass: ERROR: bad remote ethernet address '%s', check configuration file\n",
+           eth_params->remote_addr);
+    exit(1);
+  }
+
+  /* note: this only works for 50 PRBs */
+  mobi->samples_per_1024_frames = 7680*2*10*1024;
+
+  /* TX starts at subframe 4, let's pretend we are at the right position */
+  /* note: this only works for 50 PRBs */
+  mobi->mobipass_write_last_timestamp = 4*7680*2-640;
+
+  /* device specific */
+  openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
+  openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift
+  openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance;
+
+  /* this is useless, I think */
+  if (device->host_type == BBU_HOST) {
+    /*Note scheduling advance values valid only for case 7680000 */    
+    switch ((int)openair0_cfg[0].sample_rate) {
+    case 30720000:
+      openair0_cfg[0].samples_per_packet    = 3840;     
+      break;
+    case 23040000:     
+      openair0_cfg[0].samples_per_packet    = 2880;
+      break;
+    case 15360000:
+      openair0_cfg[0].samples_per_packet    = 1920;      
+      break;
+    case 7680000:
+      openair0_cfg[0].samples_per_packet    = 960;     
+      break;
+    case 1920000:
+      openair0_cfg[0].samples_per_packet    = 240;     
+      break;
+    default:
+      printf("mobipass: ERROR: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
+      exit(-1);
+      break;
+    }
+  }
+
+  device->openair0_cfg=&openair0_cfg[0];
+
+  return 0;
+
+err:
+  printf("mobipass: ERROR: bad configuration file?\n");
+  exit(1);
+}
diff --git a/targets/ARCH/mobipass/mobipass.c b/targets/ARCH/mobipass/mobipass.c
new file mode 100644
index 0000000000000000000000000000000000000000..b0a9d345223898ee5fa619536576b29564b4a479
--- /dev/null
+++ b/targets/ARCH/mobipass/mobipass.c
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <linux/if_packet.h>
+#include <netinet/ether.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include "queues.h"
+#include "mobipass.h"
+
+/******************************************************************/
+/* time begin                                                     */
+/******************************************************************/
+
+#include <time.h>
+
+static void init_time(mobipass_state_t *mobi)
+{
+  struct timespec now;
+  if (clock_gettime(CLOCK_MONOTONIC_RAW, &now)) abort();
+  mobi->t0 = (uint64_t)now.tv_sec * (uint64_t)1000000000 + (uint64_t)now.tv_nsec;
+}
+
+/* called before sending data to mobipass
+ * waits if called too early with respect to system clock
+ * does not wait more than 1ms in any case
+ */
+static void synch_time(mobipass_state_t *mobi, uint32_t ts)
+{
+  if (ts < mobi->synch_time_last_ts) mobi->synch_time_mega_ts++;
+  mobi->synch_time_last_ts = ts;
+
+  struct timespec now;
+  if (clock_gettime(CLOCK_MONOTONIC_RAW, &now)) abort();
+
+  uint64_t tnow;
+  tnow = (uint64_t)now.tv_sec * (uint64_t)1000000000 + (uint64_t)now.tv_nsec;
+
+  uint64_t cur = tnow - mobi->t0;
+
+  /* 15360000 samples/second, in nanoseconds:
+   *  = 15360000 / 1000000000 = 1536 / 100000 = 48 / 3125*/
+
+  uint64_t ts_ns = ((uint64_t)ts + mobi->synch_time_mega_ts * (uint64_t)mobi->samples_per_1024_frames) * (uint64_t)3125 / (uint64_t)48;
+
+  /* TODO: if cur is way higher than ts_ns, we are very late, log something? */
+  if (cur >= ts_ns) return;
+
+  uint64_t delta = ts_ns - cur;
+  /* don't sleep more than 1 ms */
+  if (delta > 1000*1000) delta = 1000*1000;
+  delta = delta/1000;
+  if (delta) usleep(delta);
+}
+
+/******************************************************************/
+/* time end                                                       */
+/******************************************************************/
+
+struct ethernet_header {
+  unsigned char dst[6];
+  unsigned char src[6];
+  uint16_t packet_type;
+} __attribute__((__packed__));
+
+struct mobipass_header {
+  uint16_t flags;
+  uint16_t fifo_status;
+  unsigned char seqno;
+  unsigned char ack;
+  uint32_t word0;
+  uint32_t timestamp;
+} __attribute__((__packed__));
+
+static void do_receive(mobipass_state_t *mobi, unsigned char *b)
+{
+  if (recv(mobi->sock, b, 14+14+1280, 0) != 14+14+1280) { perror("recv"); exit(1); }
+  struct mobipass_header *mh = (struct mobipass_header *)(b+14);
+  mh->timestamp = htonl((ntohl(mh->timestamp)-45378/*40120*/) % mobi->samples_per_1024_frames);
+//printf("recv timestamp %u\n", ntohl(mh->timestamp));
+}
+
+/* receiver thread */
+static void *receiver(void *_mobi)
+{
+  mobipass_state_t *mobi = _mobi;
+  unsigned char receive_packet[14 + 14 + 1280];
+  while (1) {
+    do_receive(mobi, receive_packet);
+    enqueue_from_mobipass(mobi->qstate, receive_packet);
+  }
+  return 0;
+}
+
+static void do_send(mobipass_state_t *mobi, int seqno, uint32_t ts,
+    unsigned char *packet)
+{
+  struct ethernet_header *eh = (struct ethernet_header *)packet;
+  struct mobipass_header *mh = (struct mobipass_header *)(packet+14);
+
+  ts %= mobi->samples_per_1024_frames;
+//printf("SEND seqno %d ts %d\n", seqno, ts);
+
+  memcpy(eh->dst, mobi->eth_remote, 6);
+  memcpy(eh->src, mobi->eth_local, 6);
+
+  eh->packet_type = htons(0xbffe);
+
+  mh->flags = 0;
+  mh->fifo_status = 0;
+  mh->seqno = seqno;
+  mh->ack = 0;
+  mh->word0 = 0;
+  mh->timestamp = htonl(ts);
+
+  synch_time(mobi, ts);
+
+  if (send(mobi->sock, packet, 14+14+1280, 0) != 14+14+1280) { perror("send"); exit(1); }
+}
+
+/* sender thread */
+static void *sender(void *_mobi)
+{
+  mobipass_state_t *mobi = _mobi;
+  unsigned char packet[14 + 14 + 1280];
+  uint32_t ts = 0;
+  unsigned char seqno = 0;
+  while (1) {
+    dequeue_to_mobipass(mobi->qstate, ts, packet);
+    do_send(mobi, seqno, ts, packet);
+    seqno++;
+    ts += 640;
+    ts %= mobi->samples_per_1024_frames;
+  }
+  return 0;
+}
+
+static void new_thread(void *(*f)(void *), void *data)
+{
+  pthread_t t;
+  pthread_attr_t att;
+
+  if (pthread_attr_init(&att))
+    { fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
+  if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
+    { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
+  if (pthread_attr_setstacksize(&att, 10000000))
+    { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); }
+  if (pthread_create(&t, &att, f, data))
+    { fprintf(stderr, "pthread_create err\n"); exit(1); }
+  if (pthread_attr_destroy(&att))
+    { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
+}
+
+void init_mobipass(mobipass_state_t *mobi)
+{
+  int i;
+  unsigned char data[14+14+640];
+  memset(data, 0, 14+14+640);
+
+  init_time(mobi);
+
+  mobi->qstate = init_queues(mobi->samples_per_1024_frames);
+
+  for (i = 0; i < 24*4; i++) {
+    uint32_t timestamp = i*640;
+    unsigned char seqno = i;
+    struct mobipass_header *mh = (struct mobipass_header *)(data+14);
+    mh->seqno = seqno;
+    mh->timestamp = htonl(timestamp);
+    enqueue_to_mobipass(mobi->qstate, data);
+  }
+
+  mobi->sock = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
+  if (mobi->sock == -1) { perror("socket"); exit(1); }
+
+  /* get if index */
+  struct ifreq if_index;
+  memset(&if_index, 0, sizeof(struct ifreq));
+  strcpy(if_index.ifr_name, mobi->eth.if_name);
+  if (ioctl(mobi->sock, SIOCGIFINDEX, &if_index)<0) {perror("SIOCGIFINDEX");exit(1);}
+
+  struct sockaddr_ll local_addr;
+  local_addr.sll_family   = AF_PACKET;
+  local_addr.sll_ifindex  = if_index.ifr_ifindex;
+  local_addr.sll_protocol = htons(0xbffe);
+  local_addr.sll_halen    = ETH_ALEN;
+  local_addr.sll_pkttype  = PACKET_OTHERHOST;
+
+  if (bind(mobi->sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_ll))<0)
+    { perror("bind"); exit(1); }
+
+  new_thread(receiver, mobi);
+  new_thread(sender, mobi);
+}
diff --git a/targets/ARCH/mobipass/mobipass.h b/targets/ARCH/mobipass/mobipass.h
new file mode 100644
index 0000000000000000000000000000000000000000..aeaa94838ba520a3691bfabd558110a84c47107d
--- /dev/null
+++ b/targets/ARCH/mobipass/mobipass.h
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef _MOBIPASS_H_
+#define _MOBIPASS_H_
+
+#include <stdint.h>
+#include "ethernet_lib.h"
+
+typedef struct {
+  /* this has to come first */
+  eth_state_t eth;
+
+  void *qstate;
+
+  uint8_t eth_local[6];
+  uint8_t eth_remote[6];
+
+  int samples_per_1024_frames;
+
+  /* variables used by the function interface.c:mobipass_read */
+  uint32_t mobipass_read_ts;
+  unsigned char mobipass_read_seqno;
+
+  /* variables used by the function interface.c:mobipass_write */
+  uint32_t mobipass_write_last_timestamp;
+
+  /* variables used by the function mobipass.c:[init_time|synch_time] */
+  uint64_t t0;
+
+  /* variables used by the function mobipass.c:synch_time */
+  uint32_t synch_time_last_ts;
+  uint64_t synch_time_mega_ts;
+
+  /* sock is used in mobipass.c */
+  int sock;
+} mobipass_state_t;
+
+void init_mobipass(mobipass_state_t *mobi);
+
+#endif /* _MOBIPASS_H_ */
diff --git a/targets/ARCH/mobipass/queues.c b/targets/ARCH/mobipass/queues.c
new file mode 100644
index 0000000000000000000000000000000000000000..d38969616f991b2103883ab98020fb5a69cf6f46
--- /dev/null
+++ b/targets/ARCH/mobipass/queues.c
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#include "queues.h"
+#include "mobipass.h"
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#define QSIZE 10000
+
+struct mobipass_header {
+  uint16_t flags;
+  uint16_t fifo_status;
+  unsigned char seqno;
+  unsigned char ack;
+  uint32_t word0;
+  uint32_t timestamp;
+} __attribute__((__packed__));
+
+struct queue {
+  unsigned char buf[QSIZE][14+14+640*2];
+  volatile int start;
+  volatile int len;
+  pthread_mutex_t mutex;
+  pthread_cond_t cond;
+};
+
+typedef struct {
+  struct queue to_mobipass;
+  struct queue from_mobipass;
+  int samples_per_1024_frames;
+
+  /* variables used by dequeue_from_mobipass */
+  int dequeue_from_mobipass_seqno;
+
+  /* variables used to manage logging of "missing samples"
+   * coming from mobipass. (Yes, this can happen, mostly
+   * at startup.)
+   * This idea is to print some logs, but not too much to
+   * flood stdout. (This is already a bad idea to call
+   * printf in a 'realtime' thread.)
+   */
+  int no_sample_log_running;
+  uint32_t no_sample_log_start_sample;
+  uint32_t no_sample_log_next_sample;
+} queue_state_t;
+
+static void enqueue(void *data, struct queue *q)
+{
+  int pos;
+
+  if (pthread_mutex_lock(&q->mutex)) abort();
+  if (q->len == QSIZE) {
+    printf("mobipass: WARNING: enqueue: full\n");
+    goto done;
+  }
+
+  pos = (q->start + q->len) % QSIZE;
+  memcpy(q->buf[pos], data, 14+14+640*2);
+  q->len++;
+
+done:
+  if (pthread_cond_signal(&q->cond)) abort();
+  if (pthread_mutex_unlock(&q->mutex)) abort();
+}
+
+void enqueue_to_mobipass(void *_qstate, void *data)
+{
+  queue_state_t *qstate = _qstate;
+  enqueue(data, &qstate->to_mobipass);
+}
+
+void dequeue_to_mobipass(void *_qstate, uint32_t timestamp, void *data)
+{
+  queue_state_t *qstate = _qstate;
+  if (pthread_mutex_lock(&qstate->to_mobipass.mutex)) abort();
+  while (qstate->to_mobipass.len == 0) {
+    if (pthread_cond_wait(&qstate->to_mobipass.cond, &qstate->to_mobipass.mutex)) abort();
+  }
+
+  memcpy(data, qstate->to_mobipass.buf[qstate->to_mobipass.start], 14+14+640*2);
+  qstate->to_mobipass.len--;
+  qstate->to_mobipass.start = (qstate->to_mobipass.start + 1) % QSIZE;
+
+  if (pthread_mutex_unlock(&qstate->to_mobipass.mutex)) abort();
+}
+
+void enqueue_from_mobipass(void *_qstate, void *data)
+{
+  queue_state_t *qstate = _qstate;
+  struct mobipass_header *mh = (struct mobipass_header *)((char*)data+14);
+  mh->timestamp = htonl(ntohl(mh->timestamp) % qstate->samples_per_1024_frames);
+//printf("from mobipass! timestamp %u seqno %d\n", ntohl(mh->timestamp), mh->seqno);
+  enqueue(data, &qstate->from_mobipass);
+}
+
+static int cmp_timestamps(uint32_t a, uint32_t b, int samples_per_1024_frames)
+{
+  if (a == b) return 0;
+  if (a < b) {
+    if (b-a > samples_per_1024_frames/2) return 1;
+    return -1;
+  }
+  if (a-b > samples_per_1024_frames/2) return -1;
+  return 1;
+}
+
+/*************************************************/
+/* missing samples logging management begin      */
+/*************************************************/
+
+static void log_flush(queue_state_t *qstate)
+{
+  /* print now if there is something to print */
+  if (qstate->no_sample_log_running == 0)
+    return;
+  qstate->no_sample_log_running = 0;
+  printf("mobipass: WARNING: missing samples [%u-%u]\n",
+      qstate->no_sample_log_start_sample,
+      (uint32_t)(qstate->no_sample_log_next_sample-1));
+}
+
+static void log_missed_sample(queue_state_t *qstate, uint32_t timestamp)
+{
+  /* collect data, print if there is a discontinuity */
+  if (qstate->no_sample_log_running == 0 ||
+      timestamp != qstate->no_sample_log_next_sample) {
+    log_flush(qstate);
+    qstate->no_sample_log_start_sample = timestamp;
+  }
+
+  qstate->no_sample_log_next_sample = timestamp+1;
+  qstate->no_sample_log_running = 1;
+}
+
+static void log_flush_if_old(queue_state_t *qstate, uint32_t timestamp)
+{
+  /* log every second (more or less), if we have to */
+  /* note that if mobipass stopped, it may take much more
+   * than one second to log, due to the sleeps done while
+   * waiting for samples (that never come)
+   */
+  if (qstate->no_sample_log_running == 1 &&
+      labs(timestamp-qstate->no_sample_log_start_sample) > qstate->samples_per_1024_frames/10)
+    log_flush(qstate);
+}
+
+/*************************************************/
+/* missing samples logging management end        */
+/*************************************************/
+
+/* to be called with lock on */
+static void get_sample_from_mobipass(queue_state_t *qstate, char *I, char *Q, uint32_t timestamp)
+{
+  unsigned char *b = NULL;
+  unsigned char *data = NULL;
+  struct mobipass_header *mh = NULL;
+  uint32_t packet_timestamp = 0;
+
+#if 0
+uint32_t old_start = qstate->from_mobipass.start;
+uint32_t old_len = qstate->from_mobipass.len;
+b = qstate->from_mobipass.buf[qstate->from_mobipass.start];
+mh = (struct mobipass_header *)(b+14);
+uint32_t old_pts = qstate->from_mobipass.len ? ntohl(mh->timestamp) : -1;
+b=NULL;
+mh=NULL;
+#endif
+
+  while (qstate->from_mobipass.len) {
+    b = qstate->from_mobipass.buf[qstate->from_mobipass.start];
+    mh = (struct mobipass_header *)(b+14);
+    data = b + 14*2;
+    packet_timestamp = ntohl(mh->timestamp);
+    if (cmp_timestamps(timestamp, packet_timestamp, qstate->samples_per_1024_frames) < 0) goto nodata;
+    if (cmp_timestamps(timestamp, (packet_timestamp+640) % qstate->samples_per_1024_frames, qstate->samples_per_1024_frames) < 0) break;
+    qstate->from_mobipass.len--;
+    qstate->from_mobipass.start = (qstate->from_mobipass.start+1) % QSIZE;
+  }
+
+  if (qstate->from_mobipass.len == 0) goto nodata;
+
+  if (timestamp == (packet_timestamp + 639) % qstate->samples_per_1024_frames) {
+    qstate->from_mobipass.len--;
+    qstate->from_mobipass.start = (qstate->from_mobipass.start+1) % QSIZE;
+  }
+
+  if (timestamp < packet_timestamp) timestamp += qstate->samples_per_1024_frames;
+
+  *I = data[(timestamp - packet_timestamp) * 2];
+  *Q = data[(timestamp - packet_timestamp) * 2 + 1];
+
+  return;
+
+nodata:
+  *I = 0;
+  *Q = 0;
+
+  log_missed_sample(qstate, timestamp);
+
+#if 0
+printf("no sample timestamp %u pt %u start %d old_start %d old_pt %u len %d old len %d\n", timestamp, packet_timestamp, qstate->from_mobipass.start, old_start, old_pts, qstate->from_mobipass.len, old_len);
+#endif
+}
+
+/* doesn't work with delay more than 1s */
+static void wait_for_data(pthread_cond_t *cond, pthread_mutex_t *mutex, int delay_us)
+{
+  struct timeval now;
+  struct timespec target;
+  gettimeofday(&now, NULL);
+  target.tv_sec = now.tv_sec;
+  target.tv_nsec = (now.tv_usec + delay_us) * 1000;
+  if (target.tv_nsec >= 1000 * 1000 * 1000) { target.tv_nsec -= 1000 * 1000 * 1000; target.tv_sec++; }
+  int err = pthread_cond_timedwait(cond, mutex, &target);
+  if (err != 0 && err != ETIMEDOUT) { printf("mobipass: ERROR: pthread_cond_timedwait: err (%d) %s\n", err, strerror(err)); abort(); }
+}
+
+/* don't block infinitely when waiting for data
+ * if waiting for too long, just return some zeros
+ */
+void dequeue_from_mobipass(void *_qstate, uint32_t timestamp, void *data)
+{
+  queue_state_t *qstate = _qstate;
+  int i;
+//  int ts = timestamp;
+  int waiting_allowed;
+
+  if (pthread_mutex_lock(&qstate->from_mobipass.mutex)) abort();
+
+  if (qstate->from_mobipass.len == 0) {
+//printf("sleep 1\n");
+    wait_for_data(&qstate->from_mobipass.cond, &qstate->from_mobipass.mutex, 2000); //1000/3);
+  }
+
+  waiting_allowed = qstate->from_mobipass.len != 0;
+
+  for (i = 0; i < 640*2; i+=2) {
+    if (qstate->from_mobipass.len == 0 && waiting_allowed) {
+//printf("sleep 2\n");
+      wait_for_data(&qstate->from_mobipass.cond, &qstate->from_mobipass.mutex, 2000); //1000/3);
+      waiting_allowed = qstate->from_mobipass.len != 0;
+    }
+
+    get_sample_from_mobipass(qstate, (char*)data + 14*2 + i, (char*)data + 14*2 + i+1, timestamp % qstate->samples_per_1024_frames);
+    timestamp++;
+  }
+
+  log_flush_if_old(qstate, timestamp);
+
+  if (pthread_mutex_unlock(&qstate->from_mobipass.mutex)) abort();
+
+  struct mobipass_header *mh = (struct mobipass_header *)(((char *)data) + 14);
+  mh->flags = 0;
+  mh->fifo_status = 0;
+  mh->seqno = qstate->dequeue_from_mobipass_seqno++;
+  mh->ack = 0;
+  mh->word0 = 0;
+  mh->timestamp = htonl(timestamp);
+}
+
+void *init_queues(int samples_per_1024_frames)
+{
+  queue_state_t *q;
+  q = malloc(sizeof(queue_state_t));
+  if (q == NULL) abort();
+  memset(q, 0, sizeof(queue_state_t));
+
+  if (pthread_mutex_init(&q->to_mobipass.mutex, NULL)) abort();
+  if (pthread_mutex_init(&q->from_mobipass.mutex, NULL)) abort();
+  if (pthread_cond_init(&q->to_mobipass.cond, NULL)) abort();
+  if (pthread_cond_init(&q->from_mobipass.cond, NULL)) abort();
+
+  q->samples_per_1024_frames = samples_per_1024_frames;
+
+  return q;
+}
diff --git a/targets/ARCH/mobipass/queues.h b/targets/ARCH/mobipass/queues.h
new file mode 100644
index 0000000000000000000000000000000000000000..714cf506e5fa8ff90f8bff757127ff5dde65bdcd
--- /dev/null
+++ b/targets/ARCH/mobipass/queues.h
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+#ifndef _QUEUES_H_
+#define _QUEUES_H_
+
+#include <stdint.h>
+
+void enqueue_to_mobipass(void *qstate, void *data);
+void dequeue_to_mobipass(void *qstate, uint32_t timestamp, void *data);
+
+void enqueue_from_mobipass(void *qstate, void *receive_packet);
+void dequeue_from_mobipass(void *qstate, uint32_t timestamp, void *data);
+
+/* returns a queue state type, as opaque data structure */
+void *init_queues(int samples_per_1024_frames);
+
+#endif /* _QUEUES_H_ */
diff --git a/targets/COMMON/threads_t.h b/targets/COMMON/threads_t.h
index c9ba9fea1a4bf97d2c0c8134fd404e541f330245..ddc060e8c331328b9b8a3a564940df4fba896e80 100644
--- a/targets/COMMON/threads_t.h
+++ b/targets/COMMON/threads_t.h
@@ -3,8 +3,12 @@
 
 typedef struct threads_s {
     int iq;
-    int odd;
-    int even;
+    int one;
+    int two;
+    int three;
+    int slot1_proc_one;
+    int slot1_proc_two;
+    int slot1_proc_three;
 } threads_t;
 
 #endif /* _THREADS_T_H_ */
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.generic.oaisim.local_no_mme.conf
index 8a7a694ece58fa811b80b828139d007fda664a14..e97e2d42d1be8498d285a6b11e4bc1c612278758 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.generic.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.generic.oaisim.local_no_mme.conf
@@ -118,7 +118,7 @@ eNBs =
 
         ENB_INTERFACE_NAME_FOR_S1U               = "none";
         ENB_IPV4_ADDRESS_FOR_S1U                 = "0.0.0.0/24";
-        ENB_PORT_FOR_S1U                         = 2153; # Spec 2152
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     log_config :
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.generic.oaisim.local_no_mme.conf
index bfd24f2032eadc12b51bf4c933df6616bcc7b110..532e75d61e55e4f4df0a474596b6170ac372daac 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.generic.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.generic.oaisim.local_no_mme.conf
@@ -119,7 +119,7 @@ eNBs =
 
         ENB_INTERFACE_NAME_FOR_S1U               = "none";
         ENB_IPV4_ADDRESS_FOR_S1U                 = "0.0.0.0/24";
-        ENB_PORT_FOR_S1U                         = 2153; # Spec 2152
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     log_config :
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.100PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.100PRB.usrpb210.conf
new file mode 100644
index 0000000000000000000000000000000000000000..9ede18f6af6fcd210cf92b23a8faab91ac920b16
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.100PRB.usrpb210.conf
@@ -0,0 +1,175 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+
+    mobile_country_code =  "208";
+
+    mobile_network_code =  "94";
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+      {
+        node_function                                         = "eNodeB_3GPP";
+	node_timing                                           = "synch_to_ext_device";
+	node_synch_ref                                        = 0;
+        frame_type					      = "TDD";
+        tdd_config 					      = 3;
+        tdd_config_s            			      = 5;
+        prefix_type             			      = "NORMAL";
+        eutra_band              			      = 40;
+        downlink_frequency      			      = 2350000000L;
+        uplink_frequency_offset 			      = 0;
+        Nid_cell					      = 0;
+        N_RB_DL                 			      = 100;
+        Nid_cell_mbsfn          			      = 0;
+        nb_antenna_ports          			      = 1;
+        nb_antennas_tx          			      = 1;
+        nb_antennas_rx          			      = 1;
+        tx_gain                                            = 90;
+        rx_gain                                            = 125;
+        prach_root              			      = 0;
+        prach_config_index      			      = 0;
+        prach_high_speed        			      = "DISABLE";
+        prach_zero_correlation  			      = 1;
+        prach_freq_offset       			      = 2;
+        pucch_delta_shift       			      = 1;
+        pucch_nRB_CQI           			      = 1;
+        pucch_nCS_AN            			      = 0;
+        pucch_n1_AN             			      = 32;
+        pdsch_referenceSignalPower 			      = -24;
+        pdsch_p_b                  			      = 0;
+        pusch_n_SB                 			      = 1;
+        pusch_enable64QAM          			      = "DISABLE";
+        pusch_hoppingMode                                  = "interSubFrame";
+        pusch_hoppingOffset                                = 0;
+        pusch_groupHoppingEnabled  			      = "ENABLE";
+        pusch_groupAssignment      			      = 0;
+        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+        pusch_nDMRS1                                       = 1;
+        phich_duration                                     = "NORMAL";
+        phich_resource                                     = "ONESIXTH";
+        srs_enable                                         = "DISABLE";
+        /*  srs_BandwidthConfig                                =;
+        srs_SubframeConfig                                 =;
+        srs_ackNackST                                      =;
+        srs_MaxUpPts                                       =;*/
+
+        pusch_p0_Nominal                                   = -96;
+        pusch_alpha                                        = "AL1";
+        pucch_p0_Nominal                                   = -103;
+        msg3_delta_Preamble                                = 6;
+        pucch_deltaF_Format1                               = "deltaF2";
+        pucch_deltaF_Format1b                              = "deltaF3";
+        pucch_deltaF_Format2                               = "deltaF0";
+        pucch_deltaF_Format2a                              = "deltaF0";
+        pucch_deltaF_Format2b		    	      = "deltaF0";
+
+        rach_numberOfRA_Preambles                          = 64;
+        rach_preamblesGroupAConfig                         = "DISABLE";
+        /*
+        rach_sizeOfRA_PreamblesGroupA                      = ;
+        rach_messageSizeGroupA                             = ;
+        rach_messagePowerOffsetGroupB                      = ;
+        */
+        rach_powerRampingStep                              = 4;
+        rach_preambleInitialReceivedTargetPower            = -104;
+        rach_preambleTransMax                              = 10;
+        rach_raResponseWindowSize                          = 10;
+        rach_macContentionResolutionTimer                  = 48;
+        rach_maxHARQ_Msg3Tx                                = 4;
+
+        pcch_default_PagingCycle                           = 128;
+        pcch_nB                                            = "oneT";
+        bcch_modificationPeriodCoeff			      = 2;
+        ue_TimersAndConstants_t300			      = 1000;
+        ue_TimersAndConstants_t301			      = 1000;
+        ue_TimersAndConstants_t310			      = 1000;
+        ue_TimersAndConstants_t311			      = 10000;
+        ue_TimersAndConstants_n310			      = 20;
+        ue_TimersAndConstants_n311			      = 1;
+
+	ue_TransmissionMode				      = 1;
+      }
+    );
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+    ////////// MME parameters:
+
+    mme_ip_address      = ( { ipv4       = "127.0.0.3";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.2/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.4/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+    log_config :
+    {
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="info";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+   };
+  }
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.25PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.25PRB.usrpb210.conf
new file mode 100644
index 0000000000000000000000000000000000000000..c5200f0d798d208f1357d5c4b827d43339dce4b8
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.25PRB.usrpb210.conf
@@ -0,0 +1,175 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+
+    mobile_country_code =  "208";
+
+    mobile_network_code =  "94";
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+      {
+        node_function                                         = "eNodeB_3GPP";
+	node_timing                                           = "synch_to_ext_device";
+	node_synch_ref                                        = 0;
+        frame_type					      = "TDD";
+        tdd_config 					      = 3;
+        tdd_config_s            			      = 5;
+        prefix_type             			      = "NORMAL";
+        eutra_band              			      = 40;
+        downlink_frequency      			      = 2350000000L;
+        uplink_frequency_offset 			      = 0;
+        Nid_cell					      = 0;
+        N_RB_DL                 			      = 25;
+        Nid_cell_mbsfn          			      = 0;
+        nb_antenna_ports          			      = 1;
+        nb_antennas_tx          			      = 1;
+        nb_antennas_rx          			      = 1;
+        tx_gain                                            = 90;
+        rx_gain                                            = 125;
+        prach_root              			      = 0;
+        prach_config_index      			      = 0;
+        prach_high_speed        			      = "DISABLE";
+        prach_zero_correlation  			      = 1;
+        prach_freq_offset       			      = 2;
+        pucch_delta_shift       			      = 1;
+        pucch_nRB_CQI           			      = 1;
+        pucch_nCS_AN            			      = 0;
+        pucch_n1_AN             			      = 32;
+        pdsch_referenceSignalPower 			      = -24;
+        pdsch_p_b                  			      = 0;
+        pusch_n_SB                 			      = 1;
+        pusch_enable64QAM          			      = "DISABLE";
+        pusch_hoppingMode                                  = "interSubFrame";
+        pusch_hoppingOffset                                = 0;
+        pusch_groupHoppingEnabled  			      = "ENABLE";
+        pusch_groupAssignment      			      = 0;
+        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+        pusch_nDMRS1                                       = 1;
+        phich_duration                                     = "NORMAL";
+        phich_resource                                     = "ONESIXTH";
+        srs_enable                                         = "DISABLE";
+        /*  srs_BandwidthConfig                                =;
+        srs_SubframeConfig                                 =;
+        srs_ackNackST                                      =;
+        srs_MaxUpPts                                       =;*/
+
+        pusch_p0_Nominal                                   = -96;
+        pusch_alpha                                        = "AL1";
+        pucch_p0_Nominal                                   = -103;
+        msg3_delta_Preamble                                = 6;
+        pucch_deltaF_Format1                               = "deltaF2";
+        pucch_deltaF_Format1b                              = "deltaF3";
+        pucch_deltaF_Format2                               = "deltaF0";
+        pucch_deltaF_Format2a                              = "deltaF0";
+        pucch_deltaF_Format2b		    	      = "deltaF0";
+
+        rach_numberOfRA_Preambles                          = 64;
+        rach_preamblesGroupAConfig                         = "DISABLE";
+        /*
+        rach_sizeOfRA_PreamblesGroupA                      = ;
+        rach_messageSizeGroupA                             = ;
+        rach_messagePowerOffsetGroupB                      = ;
+        */
+        rach_powerRampingStep                              = 4;
+        rach_preambleInitialReceivedTargetPower            = -104;
+        rach_preambleTransMax                              = 10;
+        rach_raResponseWindowSize                          = 10;
+        rach_macContentionResolutionTimer                  = 48;
+        rach_maxHARQ_Msg3Tx                                = 4;
+
+        pcch_default_PagingCycle                           = 128;
+        pcch_nB                                            = "oneT";
+        bcch_modificationPeriodCoeff			      = 2;
+        ue_TimersAndConstants_t300			      = 1000;
+        ue_TimersAndConstants_t301			      = 1000;
+        ue_TimersAndConstants_t310			      = 1000;
+        ue_TimersAndConstants_t311			      = 10000;
+        ue_TimersAndConstants_n310			      = 20;
+        ue_TimersAndConstants_n311			      = 1;
+
+	ue_TransmissionMode				      = 1;
+      }
+    );
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+    ////////// MME parameters:
+
+    mme_ip_address      = ( { ipv4       = "127.0.0.3";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.2/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.4/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+    log_config :
+    {
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="info";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+   };
+  }
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.50PRB.usrpb210.conf
new file mode 100644
index 0000000000000000000000000000000000000000..f4143f77f0e836160c52ca1aed22433d24f9640d
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band40.tm1.TDD3SS5.50PRB.usrpb210.conf
@@ -0,0 +1,175 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+
+    mobile_country_code =  "208";
+
+    mobile_network_code =  "94";
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+      {
+        node_function                                         = "eNodeB_3GPP";
+	node_timing                                           = "synch_to_ext_device";
+	node_synch_ref                                        = 0;
+        frame_type					      = "TDD";
+        tdd_config 					      = 3;
+        tdd_config_s            			      = 5;
+        prefix_type             			      = "NORMAL";
+        eutra_band              			      = 40;
+        downlink_frequency      			      = 2350000000L;
+        uplink_frequency_offset 			      = 0;
+        Nid_cell					      = 0;
+        N_RB_DL                 			      = 50;
+        Nid_cell_mbsfn          			      = 0;
+        nb_antenna_ports          			      = 1;
+        nb_antennas_tx          			      = 1;
+        nb_antennas_rx          			      = 1;
+        tx_gain                                            = 90;
+        rx_gain                                            = 125;
+        prach_root              			      = 0;
+        prach_config_index      			      = 0;
+        prach_high_speed        			      = "DISABLE";
+        prach_zero_correlation  			      = 1;
+        prach_freq_offset       			      = 2;
+        pucch_delta_shift       			      = 1;
+        pucch_nRB_CQI           			      = 1;
+        pucch_nCS_AN            			      = 0;
+        pucch_n1_AN             			      = 32;
+        pdsch_referenceSignalPower 			      = -24;
+        pdsch_p_b                  			      = 0;
+        pusch_n_SB                 			      = 1;
+        pusch_enable64QAM          			      = "DISABLE";
+        pusch_hoppingMode                                  = "interSubFrame";
+        pusch_hoppingOffset                                = 0;
+        pusch_groupHoppingEnabled  			      = "ENABLE";
+        pusch_groupAssignment      			      = 0;
+        pusch_sequenceHoppingEnabled		   	      = "DISABLE";
+        pusch_nDMRS1                                       = 1;
+        phich_duration                                     = "NORMAL";
+        phich_resource                                     = "ONESIXTH";
+        srs_enable                                         = "DISABLE";
+        /*  srs_BandwidthConfig                                =;
+        srs_SubframeConfig                                 =;
+        srs_ackNackST                                      =;
+        srs_MaxUpPts                                       =;*/
+
+        pusch_p0_Nominal                                   = -96;
+        pusch_alpha                                        = "AL1";
+        pucch_p0_Nominal                                   = -103;
+        msg3_delta_Preamble                                = 6;
+        pucch_deltaF_Format1                               = "deltaF2";
+        pucch_deltaF_Format1b                              = "deltaF3";
+        pucch_deltaF_Format2                               = "deltaF0";
+        pucch_deltaF_Format2a                              = "deltaF0";
+        pucch_deltaF_Format2b		    	      = "deltaF0";
+
+        rach_numberOfRA_Preambles                          = 64;
+        rach_preamblesGroupAConfig                         = "DISABLE";
+        /*
+        rach_sizeOfRA_PreamblesGroupA                      = ;
+        rach_messageSizeGroupA                             = ;
+        rach_messagePowerOffsetGroupB                      = ;
+        */
+        rach_powerRampingStep                              = 4;
+        rach_preambleInitialReceivedTargetPower            = -104;
+        rach_preambleTransMax                              = 10;
+        rach_raResponseWindowSize                          = 10;
+        rach_macContentionResolutionTimer                  = 48;
+        rach_maxHARQ_Msg3Tx                                = 4;
+
+        pcch_default_PagingCycle                           = 128;
+        pcch_nB                                            = "oneT";
+        bcch_modificationPeriodCoeff			      = 2;
+        ue_TimersAndConstants_t300			      = 1000;
+        ue_TimersAndConstants_t301			      = 1000;
+        ue_TimersAndConstants_t310			      = 1000;
+        ue_TimersAndConstants_t311			      = 10000;
+        ue_TimersAndConstants_n310			      = 20;
+        ue_TimersAndConstants_n311			      = 1;
+
+	ue_TransmissionMode				      = 1;
+      }
+    );
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+    ////////// MME parameters:
+
+    mme_ip_address      = ( { ipv4       = "127.0.0.3";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.2/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.4/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+    log_config :
+    {
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="info";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+   };
+  }
+);
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.oaisim.local_no_mme.conf
index ca36fab45578ff31fd382ad0f30fdb29503220ad..188144754143a5bba4176096d6f1b06fbb372320 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.flexran.oaisim.local_no_mme.conf
@@ -121,7 +121,7 @@ eNBs =
 
         ENB_INTERFACE_NAME_FOR_S1U               = "none";
         ENB_IPV4_ADDRESS_FOR_S1U                 = "0.0.0.0/24";
-        ENB_PORT_FOR_S1U                         = 2153; # Spec 2152
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     NETWORK_CONTROLLER :
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf
index 20589158d77d2ef8a0c18c2152267dead376a1e3..4eacf1f8de58630796fdeb0e8d8071dccfdc4a1a 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_mme.conf
@@ -17,7 +17,7 @@ eNBs =
 
     mobile_country_code =  "208";
 
-    mobile_network_code =  "10";
+    mobile_network_code =  "93";
 
        ////////// Physical parameters:
 
@@ -138,7 +138,7 @@ eNBs =
     };
     
     ////////// MME parameters:
-    mme_ip_address      = ( { ipv4       = "192.188.2.2";
+    mme_ip_address      = ( { ipv4       = "10.0.1.2";
                               ipv6       = "192:168:30::17";
                               active     = "yes";
                               preference = "ipv4";
@@ -147,12 +147,12 @@ eNBs =
 
     NETWORK_INTERFACES :
     {
-        ENB_INTERFACE_NAME_FOR_S1_MME            = "tun2";
-        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.188.2.2/24";
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "10.0.1.1/24";
 
-        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
-        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.1/8";
-        ENB_PORT_FOR_S1U                         = 2153; # Spec 2152
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "10.0.1.1/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     log_config :
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf
index 5445e35656a88b0ab2365ef1c16af56a9e61c511..e1587e5ceba3b73eaedeeb5240d91757dcf3f396 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.generic.oaisim.local_no_mme.conf
@@ -121,7 +121,7 @@ eNBs =
 
         ENB_INTERFACE_NAME_FOR_S1U               = "none";
         ENB_IPV4_ADDRESS_FOR_S1U                 = "0.0.0.0/24";
-        ENB_PORT_FOR_S1U                         = 2153; # Spec 2152
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     log_config :
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_mme.conf
index 495675c8711bcd37eebb034b2ff4e15d0e003495..f7e1ff1e6a46a4a239c40a656ba5aebe9645e4c6 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_mme.conf
@@ -151,7 +151,7 @@ eNBs =
 
         ENB_INTERFACE_NAME_FOR_S1U               = "lo";
         ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.1/8";
-        ENB_PORT_FOR_S1U                         = 2153; # Spec 2152
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     log_config :
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
index 140d215b9cb680169243ca15f277f206b7e592bf..eb85b65afba41273baf0a3f884fe29aa262cf977 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.generic.oaisim.local_no_mme.conf
@@ -121,7 +121,7 @@ eNBs =
 
         ENB_INTERFACE_NAME_FOR_S1U               = "none";
         ENB_IPV4_ADDRESS_FOR_S1U                 = "0.0.0.0/24";
-        ENB_PORT_FOR_S1U                         = 2153; # Spec 2152
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
     log_config :
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/mobipass-standalone.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/mobipass-standalone.conf
new file mode 100644
index 0000000000000000000000000000000000000000..595a4639bd5e4f124aad78af24511142ff32b4ef
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/mobipass-standalone.conf
@@ -0,0 +1,200 @@
+Active_eNBs = ( "eNB_Eurecom_LTEBox");
+# Asn1_verbosity, choice in: none, info, annoying
+Asn1_verbosity = "none";
+
+eNBs =
+(
+ {
+    ////////// Identification parameters:
+    eNB_ID    =  0xe00;
+
+    cell_type =  "CELL_MACRO_ENB";
+
+    eNB_name  =  "eNB_Eurecom_LTEBox";
+
+    // Tracking area code, 0x0000 and 0xfffe are reserved values
+    tracking_area_code  =  "1";
+
+    mobile_country_code =  "208";
+
+    mobile_network_code =  "92";
+
+       ////////// Physical parameters:
+
+    component_carriers = (
+      // second carrier-> for ERCOM
+      {
+      node_function             = "eNodeB_3GPP_BBU" # should be verified
+      //node_function             = "NGFI_RCC_IF5"  # should be verified
+      node_timing               = "synch_to_mobipass_standalone";
+      //node_timing               = "synch_to_ext_device";
+      node_synch_ref            = 0; #should 
+      frame_type                                              = "FDD";
+      tdd_config                                              = 3;
+      tdd_config_s                                    = 0;
+      prefix_type                                     = "NORMAL";
+      eutra_band                                      = 7;
+      downlink_frequency                              = 2660000000L;
+      uplink_frequency_offset                         = -120000000;
+      Nid_cell                                        = 0;
+      N_RB_DL                                         = 50;
+      Nid_cell_mbsfn                                  = 0;
+      nb_antenna_ports                               = 1;
+      nb_antennas_tx                                  = 1;
+      nb_antennas_rx                                  = 1;
+      tx_gain                                            = 90;
+      rx_gain                                            = 125;
+      prach_root                                      = 0;
+      prach_config_index                              = 0;
+      prach_high_speed                                = "DISABLE";
+      prach_zero_correlation                          = 3;
+      prach_freq_offset                               = 2;
+      pucch_delta_shift                               = 1;
+      pucch_nRB_CQI                                   = 0;
+      pucch_nCS_AN                                    = 0;
+      pucch_n1_AN                                     = 32;
+      pdsch_referenceSignalPower                              = -29;
+      pdsch_p_b                                               = 0;
+      pusch_n_SB                                              = 1;
+      pusch_enable64QAM                                       = "DISABLE";
+      pusch_hoppingMode                                  = "interSubFrame";
+      pusch_hoppingOffset                                = 0;
+      pusch_groupHoppingEnabled                               = "ENABLE";
+      pusch_groupAssignment                                   = 0;
+      pusch_sequenceHoppingEnabled                            = "DISABLE";
+      pusch_nDMRS1                                       = 1;
+      phich_duration                                     = "NORMAL";
+      phich_resource                                     = "ONESIXTH";
+      srs_enable                                         = "DISABLE";
+      /*  srs_BandwidthConfig                                =;
+      srs_SubframeConfig                                 =;
+      srs_ackNackST                                      =;
+      srs_MaxUpPts                                       =;*/
+
+      pusch_p0_Nominal                                   = -96;
+      pusch_alpha                                        = "AL1";
+      pucch_p0_Nominal                                   = -100;
+      msg3_delta_Preamble                                = 6;
+      pucch_deltaF_Format1                               = "deltaF2";
+      pucch_deltaF_Format1b                              = "deltaF3";
+      pucch_deltaF_Format2                               = "deltaF0";
+      pucch_deltaF_Format2a                              = "deltaF0";
+      pucch_deltaF_Format2b                           = "deltaF0";
+
+      rach_numberOfRA_Preambles                          = 64;
+      rach_preamblesGroupAConfig                         = "DISABLE";
+      /*
+      rach_sizeOfRA_PreamblesGroupA                      = ;
+      rach_messageSizeGroupA                             = ;
+      rach_messagePowerOffsetGroupB                      = ;
+      */
+      rach_powerRampingStep                              = 4;
+      rach_preambleInitialReceivedTargetPower            = -108;
+      rach_preambleTransMax                              = 10;
+      rach_raResponseWindowSize                          = 10;
+      rach_macContentionResolutionTimer                  = 48;
+      rach_maxHARQ_Msg3Tx                                = 4;
+
+      pcch_default_PagingCycle                           = 128;
+      pcch_nB                                            = "oneT";
+      bcch_modificationPeriodCoeff                            = 2;
+      ue_TimersAndConstants_t300                              = 1000;
+      ue_TimersAndConstants_t301                              = 1000;
+      ue_TimersAndConstants_t310                              = 1000;
+      ue_TimersAndConstants_t311                              = 10000;
+      ue_TimersAndConstants_n310                              = 20;
+      ue_TimersAndConstants_n311                              = 1;
+
+      ue_TransmissionMode                                     = 1;
+      }
+    );
+
+
+    srb1_parameters :
+    {
+        # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
+        timer_poll_retransmit    = 80;
+
+        # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
+        timer_reordering         = 35;
+
+        # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
+        timer_status_prohibit    = 0;
+
+        # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
+        poll_pdu                 =  4;
+
+        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
+        poll_byte                =  99999;
+
+        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
+        max_retx_threshold       =  4;
+    }
+
+    # ------- SCTP definitions
+    SCTP :
+    {
+        # Number of streams to use in input/output
+        SCTP_INSTREAMS  = 2;
+        SCTP_OUTSTREAMS = 2;
+    };
+
+
+    ////////// MME parameters:
+    mme_ip_address      = ( { ipv4       = "127.0.0.3";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "127.0.0.2/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.4/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+
+
+    rrh_gw_config = (
+    //second config for Ercom
+    {
+        local_if_name = "eth1.300";
+        remote_address = "00:21:5e:91:5c:7e"; # should be updated with ERCOM's MAC 
+        local_address = "f0:1f:af:db:b9:c8";
+        local_port = 50000;     #for raw option local port must be the same to remote          
+        remote_port = 50000;
+        rrh_gw_active = "yes";
+        tr_preference = "raw_if5_mobipass";
+        rf_preference = "usrp_b200";
+        iq_txshift = 0;
+        tx_sample_advance = 80;
+        tx_scheduling_advance = 9;
+        if_compression = "None"
+    }
+    );
+
+    log_config :
+    {
+      global_log_level                      ="info";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="info";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="info";
+      mac_log_verbosity                     ="high";
+      rlc_log_level                         ="info";
+      rlc_log_verbosity                     ="medium";
+      pdcp_log_level                        ="info";
+      pdcp_log_verbosity                    ="medium";
+      rrc_log_level                         ="info";
+      rrc_log_verbosity                     ="medium";
+   };
+  }
+);
+
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf
index ca17b85c0b926bb9ef5b04a4d95c0a2f36cbd813..c3aceeb97960fd57be7a1257920454239c5e337e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.if4p5-ercom.conf
@@ -48,7 +48,7 @@ eNBs =
       prach_zero_correlation                          = 1;
       prach_freq_offset                               = 2;
       pucch_delta_shift                               = 1;
-      pucch_nRB_CQI                                   = 1;
+      pucch_nRB_CQI                                   = 0;
       pucch_nCS_AN                                    = 0;
       pucch_n1_AN                                     = 32;
       pdsch_referenceSignalPower                              = -29;
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index ad99793c954f8696d72e9768d663996643bb83e3..0673c87be1132d2769628a4942bbe59cf6b761a9 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -145,6 +145,7 @@ void exit_fun(const char* s);
 void init_eNB(int,int);
 void stop_eNB(int nb_inst);
 
+
 void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
 #ifdef Rel14
 void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe);
@@ -519,11 +520,12 @@ static void* eNB_thread_prach( void* param ) {
 
   thread_top_init("eNB_thread_prach",1,500000L,1000000L,20000000L);
 
+
   while (!oai_exit) {
     
     if (oai_exit) break;
-    
 
+    
     if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break;
 
     LOG_D(PHY,"Running eNB prach procedures\n");
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index e60caa0709ba1f1d85fea942d46850dc7e912638..b78e989b3af3f88c76be9d93731079d8b5cab8a4 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -171,6 +171,9 @@ int chain_offset=0;
 int phy_test = 0;
 uint8_t usim_test = 0;
 
+uint8_t dci_Format = 0;
+uint8_t agregation_Level =0xFF;
+
 uint8_t nb_antenna_tx = 1;
 uint8_t nb_antenna_rx = 1;
 
@@ -240,7 +243,7 @@ extern char uecap_xer[1024];
 char uecap_xer_in=0;
 
 int oaisim_flag=0;
-threads_t threads= {-1,-1,-1};
+threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
 
 /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
  * this is very hackish - find a proper solution
@@ -323,58 +326,6 @@ void signal_handler(int sig) {
 #define KBLU  "\x1B[34m"
 #define RESET "\033[0m"
 
-void help (void) {
-  printf (KGRN "Usage:\n");
-  printf("  sudo -E lte-softmodem [options]\n");
-  printf("  sudo -E ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.openEPC.conf -S -V -m 26 -t 16 -x 1 --ulsch-max-errors 100 -W\n\n");
-  printf("Options:\n");
-  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
-  printf("  --ulsch-max-errors set the max ULSCH erros\n");
-  printf("  --calib-ue-rx set UE RX calibration\n");
-  printf("  --calib-ue-rx-med \n");
-  printf("  --calib-ue-rxbyp\n");
-  printf("  --debug-ue-prach run normal prach power ramping, but don't continue random-access\n");
-  printf("  --calib-prach-tx run normal prach with maximum power, but don't continue random-access\n");
-  printf("  --no-L2-connect bypass L2 and upper layers\n");
-  printf("  --ue-rxgain set UE RX gain\n");
-  printf("  --ue-rxgain-off external UE amplifier offset\n");
-  printf("  --ue-txgain set UE TX gain\n");
-  printf("  --ue-nb-ant-rx  set UE number of rx antennas\n");
-  printf("  --ue-scan-carrier set UE to scan around carrier\n");
-  printf("  --dlsch-demod-shift dynamic shift for LLR compuation for TM3/4 (default 0)\n");
-  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
-  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
-  printf("  --external-clock tells hardware to use an external clock reference\n");
-  printf("  --usim-test use XOR autentication algo in case of test usim mode\n"); 
-  printf("  --single-thread-disable. Disables single-thread mode in lte-softmodem\n"); 
-  printf("  -A Set timing_advance\n");
-  printf("  -C Set the downlink frequency for all component carriers\n");
-  printf("  -d Enable soft scope and L1 and L2 stats (Xforms)\n");
-  printf("  -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n");
-  printf("  -g Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n");
-  printf("  -G Set the global log verbosity \n");
-  printf("  -h provides this help message!\n");
-  printf("  -K Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n");
-  printf("  -m Set the maximum downlink MCS\n");
-  printf("  -O eNB configuration file (located in targets/PROJECTS/GENERIC-LTE-EPC/CONF\n");
-  printf("  -q Enable processing timing measurement of lte softmodem on per subframe basis \n");
-  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
-  printf("  -S Skip the missed slots/subframes \n");    
-  printf("  -t Set the maximum uplink MCS\n");
-  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
-  printf("  -U Set the lte softmodem as a UE\n");
-  printf("  -W Enable L2 wireshark messages on localhost \n");
-  printf("  -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n");
-  printf("  -x Set the transmission mode, valid options: 1 \n");
-  printf("  -E Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n");
-#if T_TRACER
-  printf("  --T_port [port]    use given port\n");
-  printf("  --T_nowait         don't wait for tracer, start immediately\n");
-  printf("  --T_dont_fork      to ease debugging with gdb\n");
-#endif
-  printf(RESET);
-  fflush(stdout);
-}
 
 
 void exit_fun(const char* s)
@@ -624,6 +575,7 @@ void *l2l1_task(void *arg) {
 }
 #endif
 
+
 static void get_options(void) {
   int CC_id;
   int clock_src;
@@ -719,485 +671,20 @@ static void get_options(void) {
     if (UE_flag == 0) {
       memset((void*)&RC,0,sizeof(RC));
       /* Read RC configuration file */
-      RCConfig(NULL);
+      RCConfig();
       NB_eNB_INST = RC.nb_inst;
       NB_RU	  = RC.nb_RU;
       printf("Configuration: nb_inst %d, nb_ru %d\n",NB_eNB_INST,NB_RU);
-
-      
-    } else if (UE_flag == 1) {
-      if (conf_config_file_name != NULL) {
-  	
-  	// Here the configuration file is the XER encoded UE capabilities
-  	// Read it in and store in asn1c data structures
-  	strcpy(uecap_xer,conf_config_file_name);
-  	uecap_xer_in=1;
-
-      }
     }
-  } /* CONFIG_ABORT not set */
+  } else if (UE_flag == 1 && (CONFIG_GETCONFFILE != NULL)) {
+    // Here the configuration file is the XER encoded UE capabilities
+    // Read it in and store in asn1c data structures
+    strcpy(uecap_xer,CONFIG_GETCONFFILE);
+    uecap_xer_in=1;
+  } /* UE with config file  */
 }
 
 
-static void old_get_options (int argc, char **argv) {
-  int c;
-  //  char                          line[1000];
-  //  int                           l;
-  int i;
-#if defined(OAI_USRP) || defined(CPRIGW)
-  int clock_src;
-#endif
-  int CC_id;
-
-
-
-  enum long_option_e {
-    LONG_OPTION_START = 0x100, /* Start after regular single char options */
-    LONG_OPTION_RF_CONFIG_FILE,
-    LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS,
-    LONG_OPTION_CALIB_UE_RX,
-    LONG_OPTION_CALIB_UE_RX_MED,
-    LONG_OPTION_CALIB_UE_RX_BYP,
-    LONG_OPTION_DEBUG_UE_PRACH,
-    LONG_OPTION_NO_L2_CONNECT,
-    LONG_OPTION_CALIB_PRACH_TX,
-    LONG_OPTION_RXGAIN,
-    LONG_OPTION_RXGAINOFF,
-    LONG_OPTION_TXGAIN,
-    LONG_OPTION_NBRXANT,
-    LONG_OPTION_NBTXANT,
-    LONG_OPTION_SCANCARRIER,
-    LONG_OPTION_MAXPOWER,
-    LONG_OPTION_DUMP_FRAME,
-    LONG_OPTION_LOOPMEMORY,
-    LONG_OPTION_PHYTEST,
-    LONG_OPTION_USIMTEST,
-    LONG_OPTION_MMAPPED_DMA,
-    LONG_OPTION_EXTERNAL_CLOCK,
-    LONG_OPTION_WAIT_FOR_SYNC,
-    LONG_OPTION_SINGLE_THREAD_DISABLE,
-    LONG_OPTION_THREADIQ,
-    LONG_OPTION_THREADODDSUBFRAME,
-    LONG_OPTION_THREADEVENSUBFRAME,
-    LONG_OPTION_DEMOD_SHIFT,
-#if T_TRACER
-    LONG_OPTION_T_PORT,
-    LONG_OPTION_T_NOWAIT,
-    LONG_OPTION_T_DONT_FORK,
-#endif
-
-  };
-
-  static const struct option long_options[] = {
-    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
-    {"ulsch-max-errors",required_argument,  NULL, LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS},
-    {"calib-ue-rx",     required_argument,  NULL, LONG_OPTION_CALIB_UE_RX},
-    {"calib-ue-rx-med", required_argument,  NULL, LONG_OPTION_CALIB_UE_RX_MED},
-    {"calib-ue-rx-byp", required_argument,  NULL, LONG_OPTION_CALIB_UE_RX_BYP},
-    {"debug-ue-prach",  no_argument,        NULL, LONG_OPTION_DEBUG_UE_PRACH},
-    {"no-L2-connect",   no_argument,        NULL, LONG_OPTION_NO_L2_CONNECT},
-    {"calib-prach-tx",   no_argument,        NULL, LONG_OPTION_CALIB_PRACH_TX},
-    {"ue-rxgain",   required_argument,  NULL, LONG_OPTION_RXGAIN},
-    {"ue-rxgain-off",   required_argument,  NULL, LONG_OPTION_RXGAINOFF},
-    {"ue-txgain",   required_argument,  NULL, LONG_OPTION_TXGAIN},
-    {"ue-nb-ant-rx", required_argument,  NULL, LONG_OPTION_NBRXANT},
-    {"ue-nb-ant-tx", required_argument,  NULL, LONG_OPTION_NBTXANT},
-    {"ue-scan-carrier",   no_argument,  NULL, LONG_OPTION_SCANCARRIER},
-    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
-    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
-    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
-    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
-    {"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST},
-    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
-    {"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK},
-    {"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC},
-    {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE},
-    {"threadIQ",  required_argument, NULL, LONG_OPTION_THREADIQ},
-    {"threadOddSubframe",  required_argument, NULL, LONG_OPTION_THREADODDSUBFRAME},
-    {"threadEvenSubframe",  required_argument, NULL, LONG_OPTION_THREADEVENSUBFRAME},
-    {"dlsch-demod-shift", required_argument,  NULL, LONG_OPTION_DEMOD_SHIFT},
-#if T_TRACER
-    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
-    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
-    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
-#endif
-    {NULL, 0, NULL, 0}
-  };
-
-  while ((c = getopt_long (argc, argv, "A:a:C:dEK:g:F:G:hqO:m:SUVRM:r:P:Ws:t:Tx:",long_options,NULL)) != -1) {
-    switch (c) {
-    case LONG_OPTION_RF_CONFIG_FILE:
-      if ((strcmp("null", optarg) == 0) || (strcmp("NULL", optarg) == 0)) {
-	printf("no configuration filename is provided\n");
-      }
-      else if (strlen(optarg)<=1024){
-	strcpy(rf_config_file,optarg);
-      }else {
-	printf("Configuration filename is too long\n");
-	exit(-1);   
-      }
-      break;
-    case LONG_OPTION_MAXPOWER:
-      tx_max_power[0]=atoi(optarg);
-      for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++)
-	tx_max_power[CC_id]=tx_max_power[0];
-      break;
-    case LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS:
-      ULSCH_max_consecutive_errors = atoi(optarg);
-      printf("Set ULSCH_max_consecutive_errors = %d\n",ULSCH_max_consecutive_errors);
-      break;
-
-    case LONG_OPTION_CALIB_UE_RX:
-      mode = rx_calib_ue;
-      rx_input_level_dBm = atoi(optarg);
-      printf("Running with UE calibration on (LNA max), input level %d dBm\n",rx_input_level_dBm);
-      break;
-
-    case LONG_OPTION_CALIB_UE_RX_MED:
-      mode = rx_calib_ue_med;
-      rx_input_level_dBm = atoi(optarg);
-      printf("Running with UE calibration on (LNA med), input level %d dBm\n",rx_input_level_dBm);
-      break;
-
-    case LONG_OPTION_CALIB_UE_RX_BYP:
-      mode = rx_calib_ue_byp;
-      rx_input_level_dBm = atoi(optarg);
-      printf("Running with UE calibration on (LNA byp), input level %d dBm\n",rx_input_level_dBm);
-      break;
-
-    case LONG_OPTION_DEBUG_UE_PRACH:
-      mode = debug_prach;
-      break;
-
-    case LONG_OPTION_NO_L2_CONNECT:
-      mode = no_L2_connect;
-      break;
-
-    case LONG_OPTION_CALIB_PRACH_TX:
-      mode = calib_prach_tx;
-      printf("Setting mode to calib_prach_tx (%d)\n",mode);
-      break;
-
-    case LONG_OPTION_RXGAIN:
-      for (i=0; i<4; i++)
-	rx_gain[0][i] = atof(optarg);
-
-      break;
-
-    case LONG_OPTION_RXGAINOFF:
-      rx_gain_off = atof(optarg);
-      break;
-
-    case LONG_OPTION_TXGAIN:
-      for (i=0; i<4; i++)
-	tx_gain[0][i] = atof(optarg);
-
-      break;
-    case LONG_OPTION_NBRXANT:
-      nb_antenna_rx = atof(optarg);
-      break;
-    case LONG_OPTION_NBTXANT:
-      nb_antenna_tx = atof(optarg);
-      break;
-    case LONG_OPTION_SCANCARRIER:
-      UE_scan_carrier=1;
-
-      break;
-
-    case LONG_OPTION_LOOPMEMORY:
-      mode=loop_through_memory;
-      input_fd = fopen(optarg,"r");
-      AssertFatal(input_fd != NULL,"Please provide an input file\n");
-      break;
-
-    case LONG_OPTION_DUMP_FRAME:
-      mode = rx_dump_frame;
-      break;
-      
-    case LONG_OPTION_PHYTEST:
-      phy_test = 1;
-      break;
-
-    case LONG_OPTION_USIMTEST:
-      usim_test = 1;
-      break;
-    case LONG_OPTION_MMAPPED_DMA:
-      mmapped_dma = 1;
-      break;
-
-    case LONG_OPTION_SINGLE_THREAD_DISABLE:
-      single_thread_flag = 0;
-      break;
-
-    case LONG_OPTION_EXTERNAL_CLOCK:
-      clock_source = external;
-      break;
-
-    case LONG_OPTION_WAIT_FOR_SYNC:
-      wait_for_sync = 1;
-      break;
-
-    case LONG_OPTION_THREADIQ:
-      threads.iq=atoi(optarg);
-      break;
-    case LONG_OPTION_THREADODDSUBFRAME:
-      threads.odd=atoi(optarg);
-      break;
-    case LONG_OPTION_THREADEVENSUBFRAME:
-      threads.even=atoi(optarg);
-      break;
-    case LONG_OPTION_DEMOD_SHIFT: {
-      extern int16_t dlsch_demod_shift;
-      dlsch_demod_shift = atof(optarg);
-      break;
-    }
-#if T_TRACER
-    case LONG_OPTION_T_PORT: {
-      extern int T_port;
-      if (optarg == NULL) abort();  /* should not happen */
-      T_port = atoi(optarg);
-      break;
-    }
-
-    case LONG_OPTION_T_NOWAIT: {
-      extern int T_wait;
-      T_wait = 0;
-      break;
-    }
-
-    case LONG_OPTION_T_DONT_FORK: {
-      extern int T_dont_fork;
-      T_dont_fork = 1;
-      break;
-    }
-#endif
-
-    case 'A':
-      timing_advance = atoi (optarg);
-      break;
-
-    case 'C':
-      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-	downlink_frequency[CC_id][0] = atof(optarg); // Use float to avoid issue with frequency over 2^31.
-	downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
-	downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
-	downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
-	printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
-      }
-
-      UE_scan=0;
-
-      break;
-
-    case 'a':
-      chain_offset = atoi(optarg);
-      break;
-
-    case 'd':
-#ifdef XFORMS
-      do_forms=1;
-      printf("Running with XFORMS!\n");
-#endif
-      break;
-
-    case 'E':
-      threequarter_fs=1;
-      break;
-
-    case 'K':
-#if defined(ENABLE_ITTI)
-      itti_dump_file = strdup(optarg);
-#else
-      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
-#endif
-      break;
-
-    case 'O':
-      conf_config_file_name = optarg;
-      break;
-
-    case 'U':
-      UE_flag = 1;
-      break;
-
-    case 'm':
-      target_dl_mcs = atoi (optarg);
-      break;
-
-    case 't':
-      target_ul_mcs = atoi (optarg);
-      break;
-
-    case 'W':
-      opt_enabled=1;
-      opt_type = OPT_WIRESHARK;
-      strncpy(in_ip, "127.0.0.1", sizeof(in_ip));
-      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);
-	}
-      */
-      break;
-
-    case 'P':
-      opt_type = OPT_PCAP;
-      opt_enabled=1;
-
-      if (optarg == NULL) {
-	strncpy(in_path, "/tmp/oai_opt.pcap", sizeof(in_path));
-	in_path[sizeof(in_path) - 1] = 0; // terminate string
-	printf("Enabling OPT for PCAP with the following path /tmp/oai_opt.pcap");
-      } else {
-	strncpy(in_path, optarg, sizeof(in_path));
-	in_path[sizeof(in_path) - 1] = 0; // terminate string
-	printf("Enabling OPT for PCAP  with the following file %s \n",in_path);
-      }
-
-      break;
-
-    case 'V':
-      ouput_vcd = 1;
-      break;
-
-    case  'q':
-      opp_enabled = 1;
-      break;
-
-    case  'R' :
-      online_log_messages =1;
-      break;
-
-    case 'r':
-      UE_scan = 0;
-
-      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-	switch(atoi(optarg)) {
-	case 6:
-	  frame_parms[CC_id]->N_RB_DL=6;
-	  frame_parms[CC_id]->N_RB_UL=6;
-	  break;
-
-	case 25:
-	  frame_parms[CC_id]->N_RB_DL=25;
-	  frame_parms[CC_id]->N_RB_UL=25;
-	  break;
-
-	case 50:
-	  frame_parms[CC_id]->N_RB_DL=50;
-	  frame_parms[CC_id]->N_RB_UL=50;
-	  break;
-
-	case 100:
-	  frame_parms[CC_id]->N_RB_DL=100;
-	  frame_parms[CC_id]->N_RB_UL=100;
-	  break;
-
-	default:
-	  printf("Unknown N_RB_DL %d, switching to 25\n",atoi(optarg));
-	  break;
-	}
-      }
-
-      break;
-
-    case 's':
-#if defined(OAI_USRP) || defined(CPRIGW)
-
-      clock_src = atoi(optarg);
-
-      if (clock_src == 0) {
-	//  char ref[128] = "internal";
-	//strncpy(uhd_ref, ref, strlen(ref)+1);
-      } else if (clock_src == 1) {
-	//char ref[128] = "external";
-	//strncpy(uhd_ref, ref, strlen(ref)+1);
-      }
-
-#else
-      printf("Note: -s not defined for ExpressMIMO2\n");
-#endif
-      break;
-
-    case 'g':
-      glog_level=atoi(optarg); // value between 1 - 9
-      break;
-
-    case 'G':
-      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
-      break;
-
-    case 'S':
-      exit_missed_slots=0;
-      printf("Skip exit for missed slots\n");
-      break;
-
-    case 'F':
-      break;
-
-    case 'x':
-      printf("Transmission mode should be set in config file now\n");
-      exit(-1);
-      /*
-	transmission_mode = atoi(optarg);
-
-	if (transmission_mode > 7) {
-	printf("Transmission mode %d not supported for the moment\n",transmission_mode);
-	exit(-1);
-	}
-      */
-      break;
-
-    case 'T':
-      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
-	frame_parms[CC_id]->frame_type = TDD;
-      break;
-
-    case 'h':
-      help ();
-      exit (-1);
-       
-    default:
-      help ();
-      exit (-1);
-      break;
-    }
-  }
-
-  if (UE_flag == 0)
-    AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n");
-
-  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
-
-
-    memset((void*)&RC,0,sizeof(RC));
-
-    /* Read RC configuration file */
-    RCConfig(conf_config_file_name);
-    
-    NB_eNB_INST = RC.nb_inst;
-    NB_RU       = RC.nb_RU;
-
-    printf("Read in %s : nb_inst %d, nb_ru %d\n",conf_config_file_name,NB_eNB_INST,NB_RU);
-
-    
-  } else if (UE_flag == 1) {
-    if (conf_config_file_name != NULL) {
-      
-      // Here the configuration file is the XER encoded UE capabilities
-      // Read it in and store in asn1c data structures
-      strcpy(uecap_xer,conf_config_file_name);
-      uecap_xer_in=1;
-
-    }
-  }
-}
   
 #if T_TRACER
 int T_wait = 1;       /* by default we wait for the tracer */
@@ -1205,6 +692,7 @@ int T_port = 2021;    /* default port to listen to to wait for the tracer */
 int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
 #endif
 
+
 void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
 void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
 
@@ -1428,18 +916,8 @@ int main( int argc, char **argv )
   // get options and fill parameters from configuration file
   // temporary test to allow legacy config or config module */
   
-  if ( CONFIG_ISFLAGSET(CONFIG_LEGACY) == 0) {
-      printf("configuration via the configuration module \n");
-      get_options (); 
-       if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
-           fprintf(stderr,"Getting configuration failed\n");
-	   exit(-1);
-       }
-  } else {
-      printf("Legacy configuration mode \n");
-      old_get_options (argc,argv);
-  }
-
+  get_options (); 
+  
 
 #if T_TRACER
   T_init(T_port, T_wait, T_dont_fork);
@@ -1576,8 +1054,10 @@ int main( int argc, char **argv )
 
 
 
+
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
+
     if (UE_flag==1) {     
       NB_UE_INST=1;     
       NB_INST=1;     
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index 6fba60968945d1bb9ad9b784e4419b4485334b03..676908d423135294a0c5567f3af0c71c1497dd01 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -149,8 +149,11 @@ extern int16_t dlsch_demod_shift;
 {"wait-for-sync",         	 NULL,  		PARAMFLAG_BOOL,   iptr:&wait_for_sync,  		defintval:0,			   TYPE_INT,	  0},			   \
 {"single-thread-disable", 	 CONFIG_HLP_NOSNGLT,	PARAMFLAG_BOOL,   iptr:&single_thread_flag,		defintval:1,			   TYPE_INT,	  0},			   \
 {"threadIQ",              	 NULL,  		0,		  iptr:&(threads.iq),			defintval:1,			   TYPE_INT,	  0},			   \
-{"threadOddSubframe",     	 NULL,  		0,		  iptr:&(threads.odd),  		defintval:1,			   TYPE_INT,	  0},			   \
-{"threadEvenSubframe",    	 NULL,  		0,		  iptr:&(threads.even), 		defintval:1,			   TYPE_INT,	  0},			   \
+{"threadOneSubframe",     	 NULL,  		0,		  iptr:&(threads.one),  		defintval:1,			   TYPE_INT,	  0},			   \
+{"threadTwoSubframe",    	 NULL,  		0,		  iptr:&(threads.two),  		defintval:1,			   TYPE_INT,	  0},			   \
+{"threadThreeSubframe",    	 NULL,  		0,		  iptr:&(threads.three),  		defintval:1,			   TYPE_INT,	  0},			   \
+{"threadSlot1ProcOne",     	 NULL,  		0,		  iptr:&(threads.slot1_proc_one),      	defintval:1,			   TYPE_INT,	  0},			   \
+{"threadSlot1ProcTwo",    	 NULL,  		0,		  iptr:&(threads.slot1_proc_two),      	defintval:1,			   TYPE_INT,	  0},			   \
 {"dlsch-demod-shift",     	 CONFIG_HLP_DLSHIFT,	0,		  iptr:(int32_t *)&dlsch_demod_shift,	defintval:0,			   TYPE_INT,	  0},			   \
 {"A" ,  		  	 CONFIG_HLP_TADV,	0,		  uptr:&timing_advance, 		defintval:0,			   TYPE_UINT,	  0},			   \
 {"C" ,  		  	 CONFIG_HLP_DLF,	0,		  uptr:&(downlink_frequency[0][0]),	defuintval:2680000000,  	   TYPE_UINT,	  0},			   \
@@ -231,7 +234,10 @@ extern void init_RU(const char*);
 // In lte-ue.c
 extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
 extern void fill_ue_band_info(void);
+
 extern void init_UE(int,int,int);
+extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char * name);
+
 extern void reset_opp_meas(void);
 extern void print_opp_meas(void);
 
diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
index d23a7d2ffab2429efcd9bdead92d04ee418febd2..eb0b112b9bf13ee866abbf2a30226ed2661e100f 100644
--- a/targets/RT/USER/lte-ue.c
+++ b/targets/RT/USER/lte-ue.c
@@ -141,7 +141,6 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
 
 {
 
-  int i,j;
   PHY_VARS_UE* ue;
 
   if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
@@ -381,178 +380,176 @@ static void *UE_thread_synch(void *arg)
                 if (UE->UE_scan_carrier) {
                     openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
                 }
-
-	
 	    }
 
 	    break;
  
     case pbch:
 
-      LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
-
-
-      LOG_I(PHY,"[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
-      if (initial_sync( UE, UE->mode ) == 0) {
-	
-	hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti;
-	LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
-	       hw_slot_offset,
-	       freq_offset,
-	       UE->rx_total_gain_dB,
-	       downlink_frequency[0][0]+freq_offset,
-	       downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
-	       UE->UE_scan_carrier );
-	
-	
-	// rerun with new cell parameters and frequency-offset
-	for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
-	  openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
-	  if (UE->UE_scan_carrier == 1) {
-	    if (freq_offset >= 0)
-	      openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
-	    else
-	      openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
-	    openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
-	      openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
-	    downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
-	    freq_offset=0;
-	  }
-	  
-	}	  
-	// reconfigure for potentially different bandwidth
-	switch(UE->frame_parms.N_RB_DL) {
-	case 6:
-	  openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
-	  openair0_cfg[UE->rf_map.card].rx_bw          =.96e6;
-	  openair0_cfg[UE->rf_map.card].tx_bw          =.96e6;
-	  //            openair0_cfg[0].rx_gain[0] -= 12;
-	  break;
-	case 25:
-	  openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
-	  openair0_cfg[UE->rf_map.card].rx_bw          =2.5e6;
-	  openair0_cfg[UE->rf_map.card].tx_bw          =2.5e6;
-	  //            openair0_cfg[0].rx_gain[0] -= 6;
-	  break;
-	case 50:
-	  openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
-	  openair0_cfg[UE->rf_map.card].rx_bw          =5.0e6;
-	  openair0_cfg[UE->rf_map.card].tx_bw          =5.0e6;
-	  //            openair0_cfg[0].rx_gain[0] -= 3;
-	  break;
-	case 100:
-	  openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
-	  openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
-	  openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
-	  //            openair0_cfg[0].rx_gain[0] -= 0;
-	  break;
-	}
-	
-	UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
-	//UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
-	//UE->rfdevice.trx_stop_func(&UE->rfdevice);
-	sleep(1);
-	init_frame_parms(&UE->frame_parms,1);
-	/*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
-	  LOG_E(HW,"Could not start the device\n");
-	  oai_exit=1;
-	  }*/
-	
-	if (UE->UE_scan_carrier == 1) {
-	  
-	  UE->UE_scan_carrier = 0;
-	} else {
-	  AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
-	  UE->is_synchronized = 1;
-	  AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
-	  
-	  if( UE->mode == rx_dump_frame ) {
-	    FILE *fd;
-	    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),
-		       10*UE->frame_parms.samples_per_tti,
-		       fd);
-		LOG_I(PHY,"Dummping Frame ... bye bye \n");
-		fclose(fd);
-		exit(0);
-	      } else {
-		LOG_E(PHY,"Cannot open file for writing\n");
-		exit(0);
-	      }
-	    } else {
-	      AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
-	      UE->is_synchronized = 0;
-	      AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
-	      
-	    }
-	  }
-	}
-      } else {
-	// initial sync failed
-	// calculate new offset and try again
-	if (UE->UE_scan_carrier == 1) {
-	  if (freq_offset >= 0)
-	    freq_offset += 100;
-	  freq_offset *= -1;
-	  
-	  if (abs(freq_offset) > 7500) {
-	    LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
-	    FILE *fd;
-	    if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
-	      fwrite((void*)&UE->common_vars.rxdata[0][0],
-		     sizeof(int32_t),
-		     10*UE->frame_parms.samples_per_tti,
-		     fd);
-	      LOG_I(PHY,"Dummping Frame ... bye bye \n");
-	      fclose(fd);
-	      exit(0);
-	    }
-	    exit_fun("No cell synchronization found, abandoning");
-	    return &UE_thread_synch_retval; // not reached
+#if DISABLE_LOG_X
+            printf("[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
+#else
+            LOG_I(PHY, "[UE thread Synch] Running Initial Synch (mode %d)\n",UE->mode);
+#endif
+            if (initial_sync( UE, UE->mode ) == 0) {
+
+                hw_slot_offset = (UE->rx_offset<<1) / UE->frame_parms.samples_per_tti;
+                LOG_I( HW, "Got synch: hw_slot_offset %d, carrier off %d Hz, rxgain %d (DL %u, UL %u), UE_scan_carrier %d\n",
+                       hw_slot_offset,
+                       freq_offset,
+                       UE->rx_total_gain_dB,
+                       downlink_frequency[0][0]+freq_offset,
+                       downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset,
+                       UE->UE_scan_carrier );
+
+
+                    // rerun with new cell parameters and frequency-offset
+                    for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
+                        openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
+			if (UE->UE_scan_carrier == 1) {
+                        if (freq_offset >= 0)
+                            openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] += abs(UE->common_vars.freq_offset);
+                        else
+                            openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] -= abs(UE->common_vars.freq_offset);
+                        openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] =
+                            openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i]+uplink_frequency_offset[CC_id][i];
+                        downlink_frequency[CC_id][i] = openair0_cfg[CC_id].rx_freq[i];
+                        freq_offset=0;
+                    }
 	  }
-	}
-	LOG_I( PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
-	       freq_offset,
-	       UE->rx_total_gain_dB,
-	       downlink_frequency[0][0]+freq_offset,
-	       downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
-	
-	for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
-	  openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
-	  openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
-	  openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
-	  if (UE->UE_scan_carrier==1)
-	    openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
-	}
-	UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
-      }// initial_sync=0
-      break;
-    case si:
-    default:
-      break;
-    }
-    
-    AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
-    // indicate readiness
-    UE->proc.instance_cnt_synch--;
-    AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
-    
-    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
-  }  // while !oai_exit
-  
-  return &UE_thread_synch_retval;
-}
 
+                    // reconfigure for potentially different bandwidth
+                    switch(UE->frame_parms.N_RB_DL) {
+                    case 6:
+                        openair0_cfg[UE->rf_map.card].sample_rate =1.92e6;
+                        openair0_cfg[UE->rf_map.card].rx_bw          =.96e6;
+                        openair0_cfg[UE->rf_map.card].tx_bw          =.96e6;
+                        //            openair0_cfg[0].rx_gain[0] -= 12;
+                        break;
+                    case 25:
+                        openair0_cfg[UE->rf_map.card].sample_rate =7.68e6;
+                        openair0_cfg[UE->rf_map.card].rx_bw          =2.5e6;
+                        openair0_cfg[UE->rf_map.card].tx_bw          =2.5e6;
+                        //            openair0_cfg[0].rx_gain[0] -= 6;
+                        break;
+                    case 50:
+                        openair0_cfg[UE->rf_map.card].sample_rate =15.36e6;
+                        openair0_cfg[UE->rf_map.card].rx_bw          =5.0e6;
+                        openair0_cfg[UE->rf_map.card].tx_bw          =5.0e6;
+                        //            openair0_cfg[0].rx_gain[0] -= 3;
+                        break;
+                    case 100:
+                        openair0_cfg[UE->rf_map.card].sample_rate=30.72e6;
+                        openair0_cfg[UE->rf_map.card].rx_bw=10.0e6;
+                        openair0_cfg[UE->rf_map.card].tx_bw=10.0e6;
+                        //            openair0_cfg[0].rx_gain[0] -= 0;
+                        break;
+                    }
 
-/* this structure is used to pass both UE phy vars and
- * proc to the function UE_thread_rxn_txnp4
- */
-struct rx_tx_thread_data {
-  PHY_VARS_UE    *UE;
-  UE_rxtx_proc_t *proc;
-};
+                    UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
+                    //UE->rfdevice.trx_set_gains_func(&openair0,&openair0_cfg[0]);
+                    //UE->rfdevice.trx_stop_func(&UE->rfdevice);
+                    sleep(1);
+                    init_frame_parms(&UE->frame_parms,1);
+                    /*if (UE->rfdevice.trx_start_func(&UE->rfdevice) != 0 ) {
+                        LOG_E(HW,"Could not start the device\n");
+                        oai_exit=1;
+                    }*/
+
+		if (UE->UE_scan_carrier == 1) {
+
+		  UE->UE_scan_carrier = 0;
+                } else {
+                    AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
+                    UE->is_synchronized = 1;
+                    AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
+
+                    if( UE->mode == rx_dump_frame ) {
+                        FILE *fd;
+                        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),
+                                       10*UE->frame_parms.samples_per_tti,
+                                       fd);
+                                LOG_I(PHY,"Dummping Frame ... bye bye \n");
+                                fclose(fd);
+                                exit(0);
+                            } else {
+                                LOG_E(PHY,"Cannot open file for writing\n");
+                                exit(0);
+                            }
+                        } else {
+                            AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
+                            UE->is_synchronized = 0;
+                            AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
+
+                        }
+                    }
+                }
+            } else {
+                // initial sync failed
+                // calculate new offset and try again
+                if (UE->UE_scan_carrier == 1) {
+                    if (freq_offset >= 0)
+                        freq_offset += 100;
+                    freq_offset *= -1;
+
+                    if (abs(freq_offset) > 7500) {
+                        LOG_I( PHY, "[initial_sync] No cell synchronization found, abandoning\n" );
+                        FILE *fd;
+                        if ((fd = fopen("rxsig_frame0.dat","w"))!=NULL) {
+                            fwrite((void*)&UE->common_vars.rxdata[0][0],
+                                   sizeof(int32_t),
+                                   10*UE->frame_parms.samples_per_tti,
+                                   fd);
+                            LOG_I(PHY,"Dummping Frame ... bye bye \n");
+                            fclose(fd);
+                            exit(0);
+                        }
+                        AssertFatal(1==0,"No cell synchronization found, abandoning");
+                        return &UE_thread_synch_retval; // not reached
+                    }
+                }
+#if DISABLE_LOG_X
+                printf("[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
+                       freq_offset,
+                       UE->rx_total_gain_dB,
+                       downlink_frequency[0][0]+freq_offset,
+                       downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
+#else
+                LOG_I(PHY, "[initial_sync] trying carrier off %d Hz, rxgain %d (DL %u, UL %u)\n",
+                       freq_offset,
+                       UE->rx_total_gain_dB,
+                       downlink_frequency[0][0]+freq_offset,
+                       downlink_frequency[0][0]+uplink_frequency_offset[0][0]+freq_offset );
+#endif
+
+                for (i=0; i<openair0_cfg[UE->rf_map.card].rx_num_channels; i++) {
+                    openair0_cfg[UE->rf_map.card].rx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+freq_offset;
+                    openair0_cfg[UE->rf_map.card].tx_freq[UE->rf_map.chain+i] = downlink_frequency[CC_id][i]+uplink_frequency_offset[CC_id][i]+freq_offset;
+                    openair0_cfg[UE->rf_map.card].rx_gain[UE->rf_map.chain+i] = UE->rx_total_gain_dB;//-USRP_GAIN_OFFSET;
+                    if (UE->UE_scan_carrier==1)
+                        openair0_cfg[UE->rf_map.card].autocal[UE->rf_map.chain+i] = 1;
+                }
+                UE->rfdevice.trx_set_freq_func(&UE->rfdevice,&openair0_cfg[0],0);
+            }// initial_sync=0
+            break;
+        case si:
+        default:
+            break;
+        }
+
+        AssertFatal ( 0== pthread_mutex_lock(&UE->proc.mutex_synch), "");
+        // indicate readiness
+        UE->proc.instance_cnt_synch--;
+        AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
+
+        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_SYNCH, 0 );
+    }  // while !oai_exit
+
+    return &UE_thread_synch_retval;
+}
 
 /*!
  * \brief This is the UE thread for RX subframe n and TX subframe n+4.
@@ -576,10 +573,14 @@ static void *UE_thread_rxn_txnp4(void *arg) {
     sprintf(threadname,"UE_%d_proc_%d", UE->Mod_id, proc->sub_frame_start);
     cpu_set_t cpuset;
     CPU_ZERO(&cpuset);
-    if ( (proc->sub_frame_start+1)%2 == 0 && threads.even != -1 )
-        CPU_SET(threads.even, &cpuset);
-    if ( (proc->sub_frame_start+1)%2 == 1 && threads.odd != -1 )
-        CPU_SET(threads.odd, &cpuset);
+
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.one != -1 )
+        CPU_SET(threads.one, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.two != -1 )
+        CPU_SET(threads.two, &cpuset);
+    if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.three != -1 )
+        CPU_SET(threads.three, &cpuset);
+            //CPU_SET(threads.three, &cpuset);
     init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset,
                 threadname);
 
@@ -624,11 +625,16 @@ static void *UE_thread_rxn_txnp4(void *arg) {
                        (sf_type==SF_UL? "SF_UL" :
                         (sf_type==SF_S ? "SF_S"  : "UNKNOWN_SF_TYPE"))));
             }
-            phy_procedures_UE_RX( UE, proc, 0, 0, UE->mode, no_relay, NULL );
+#ifdef UE_SLOT_PARALLELISATION
+            phy_procedures_slot_parallelization_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
+#else
+            phy_procedures_UE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
+#endif
         }
 
+#if UE_TIMING_TRACE
         start_meas(&UE->generic_stat);
-
+#endif
         if (UE->mac_enabled==1) {
 
             ret = ue_scheduler(UE->Mod_id,
@@ -658,8 +664,9 @@ static void *UE_thread_rxn_txnp4(void *arg) {
                        UE->Mod_id, proc->frame_rx, proc->subframe_tx,txt );
             }
         }
-
+#if UE_TIMING_TRACE
         stop_meas(&UE->generic_stat);
+#endif
 
 
         // Prepare the future Tx data
@@ -713,6 +720,9 @@ void *UE_thread(void *arg) {
     void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
     int start_rx_stream = 0;
     int i;
+    int th_id;
+
+    static uint8_t thread_idx = 0;
 
     cpu_set_t cpuset;
     CPU_ZERO(&cpuset);
@@ -760,6 +770,10 @@ void *UE_thread(void *arg) {
                 }
 		AssertFatal ( 0== pthread_mutex_unlock(&UE->proc.mutex_synch), "");
             } else {
+#if OAISIM
+              (void)dummy_rx; /* avoid gcc warnings */
+              usleep(500);
+#else
                 // grab 10 ms of signal into dummy buffer
                 if (UE->mode != loop_through_memory) {
                     for (int i=0; i<UE->frame_parms.nb_antennas_rx; i++)
@@ -772,6 +786,7 @@ void *UE_thread(void *arg) {
                                               UE->frame_parms.samples_per_tti,
                                               UE->frame_parms.nb_antennas_rx);
                 }
+#endif
             }
 
         } // UE->is_synchronized==0
@@ -789,8 +804,12 @@ void *UE_thread(void *arg) {
                                                                UE->frame_parms.nb_antennas_rx),"");
                     }
                     UE->rx_offset=0;
-                    UE->proc.proc_rxtx[0].frame_rx++;
-                    UE->proc.proc_rxtx[1].frame_rx++;
+                    UE->time_sync_cell=0;
+                    //UE->proc.proc_rxtx[0].frame_rx++;
+                    //UE->proc.proc_rxtx[1].frame_rx++;
+                    for (th_id=0; th_id < RX_NB_TH; th_id++) {
+                        UE->proc.proc_rxtx[th_id].frame_rx++;
+                    }
 
                     // read in first symbol
                     AssertFatal (UE->frame_parms.ofdm_symbol_size+UE->frame_parms.nb_prefix_samples0 ==
@@ -807,7 +826,16 @@ void *UE_thread(void *arg) {
             } else {
                 sub_frame++;
                 sub_frame%=10;
-                UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[sub_frame&1];
+                UE_rxtx_proc_t *proc = &UE->proc.proc_rxtx[thread_idx];
+                // update thread index for received subframe
+                UE->current_thread_id[sub_frame] = thread_idx;
+
+                LOG_D(PHY,"Process Subframe %d thread Idx %d \n", sub_frame, UE->current_thread_id[sub_frame]);
+
+                thread_idx++;
+                if(thread_idx>=RX_NB_TH)
+                    thread_idx = 0;
+
 
                 if (UE->mode != loop_through_memory) {
                     for (i=0; i<UE->frame_parms.nb_antennas_rx; i++)
@@ -874,11 +902,17 @@ void *UE_thread(void *arg) {
                     // operate on thread sf mod 2
                     AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
                     if(sub_frame == 0) {
-                        UE->proc.proc_rxtx[0].frame_rx++;
-                        UE->proc.proc_rxtx[1].frame_rx++;
+                        //UE->proc.proc_rxtx[0].frame_rx++;
+                        //UE->proc.proc_rxtx[1].frame_rx++;
+                        for (th_id=0; th_id < RX_NB_TH; th_id++) {
+                            UE->proc.proc_rxtx[th_id].frame_rx++;
+                        }
+                    }
+                    //UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
+                    //UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
+                    for (th_id=0; th_id < RX_NB_TH; th_id++) {
+                        UE->proc.proc_rxtx[th_id].gotIQs=readTime(gotIQs);
                     }
-                    UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
-                    UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
                     proc->subframe_rx=sub_frame;
                     proc->subframe_tx=(sub_frame+4)%10;
                     proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
@@ -887,6 +921,7 @@ void *UE_thread(void *arg) {
                                          UE->frame_parms.ofdm_symbol_size-UE->frame_parms.nb_prefix_samples0;
 
                     proc->instance_cnt_rxtx++;
+                    LOG_D( PHY, "[SCHED][UE %d] UE RX instance_cnt_rxtx %d subframe %d !!\n", UE->Mod_id, proc->instance_cnt_rxtx,proc->subframe_rx);
                     if (proc->instance_cnt_rxtx == 0) {
                       if (pthread_cond_signal(&proc->cond_rxtx) != 0) {
                         LOG_E( PHY, "[SCHED][UE %d] ERROR pthread_cond_signal for UE RX thread\n", UE->Mod_id);
@@ -922,6 +957,10 @@ void *UE_thread(void *arg) {
  * - UE_thread_rxtx0
  * - UE_thread_rxtx1
  * - UE_thread_synch
+ * - UE_thread_fep_slot0
+ * - UE_thread_fep_slot1
+ * - UE_thread_dlsch_proc_slot0
+ * - UE_thread_dlsch_proc_slot1
  * and the locking between them.
  */
 void init_UE_threads(int inst) {
@@ -940,20 +979,32 @@ void init_UE_threads(int inst) {
     pthread_cond_init(&UE->proc.cond_synch,NULL);
 
     // the threads are not yet active, therefore access is allowed without locking
-    int nb_threads=2;
+    int nb_threads=RX_NB_TH;
     for (int i=0; i<nb_threads; i++) {
         rtd = calloc(1, sizeof(struct rx_tx_thread_data));
         if (rtd == NULL) abort();
         rtd->UE = UE;
         rtd->proc = &UE->proc.proc_rxtx[i];
+
         pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL);
         pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL);
         UE->proc.proc_rxtx[i].sub_frame_start=i;
         UE->proc.proc_rxtx[i].sub_frame_step=nb_threads;
+        printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i);
         pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_thread_rxn_txnp4, rtd);
+
+#ifdef UE_SLOT_PARALLELISATION
+        //pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot0_dl_processing,NULL);
+        //pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot0_dl_processing,NULL);
+        //pthread_create(&UE->proc.proc_rxtx[i].pthread_slot0_dl_processing,NULL,UE_thread_slot0_dl_processing, rtd);
+
+        pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_slot1_dl_processing,NULL);
+        pthread_cond_init(&UE->proc.proc_rxtx[i].cond_slot1_dl_processing,NULL);
+        pthread_create(&UE->proc.proc_rxtx[i].pthread_slot1_dl_processing,NULL,UE_thread_slot1_dl_processing, rtd);
+#endif
+
     }
     pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE);
-
 }
 
 
diff --git a/targets/SIMU/USER/init_lte.c b/targets/SIMU/USER/init_lte.c
index 80d9e0598fbfd1ac85dc81924339bc132de3a775..9f59a116a0f31f027807a710e4a41c099460414d 100644
--- a/targets/SIMU/USER/init_lte.c
+++ b/targets/SIMU/USER/init_lte.c
@@ -149,6 +149,7 @@ PHY_VARS_eNB* init_lte_eNB(LTE_DL_FRAME_PARMS *frame_parms,
 }
 */
 
+
 /*
 
 PHY_VARS_RN* init_lte_RN(LTE_DL_FRAME_PARMS *frame_parms,
diff --git a/targets/SIMU/USER/oaisim.c b/targets/SIMU/USER/oaisim.c
index 5f9b5fb53579d50b01599e0cb201640e62802867..6490448927c85188f28de7c4762b82ce6065e96b 100644
--- a/targets/SIMU/USER/oaisim.c
+++ b/targets/SIMU/USER/oaisim.c
@@ -183,7 +183,7 @@ extern uint16_t Nid_cell;
 
 double cpuf;
 #include "threads_t.h"
-threads_t threads= {-1,-1,-1};
+threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
 
 //#ifdef XFORMS
 int otg_enabled;
@@ -1457,7 +1457,8 @@ reset_opp_meas_oaisim (void)
   reset_meas (&ul_chan_stats);
 
   for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
-    reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc);
+    reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[0]);
+    reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[1]);
     reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[0]);
     reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_rx[1]);
     reset_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc_tx);
@@ -1626,7 +1627,9 @@ print_opp_meas_oaisim (void)
   }
 
   for (UE_id = 0; UE_id < NB_UE_INST; UE_id++) {
-    print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc, "[UE][total_phy_proc]",
+    print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[0], "[UE][total_phy_proc[0]]",
+                &oaisim_stats, &oaisim_stats_f);
+    print_meas (&PHY_vars_UE_g[UE_id][0]->phy_proc[1], "[UE][total_phy_proc[1]]",
                 &oaisim_stats, &oaisim_stats_f);