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 bc9824c98ec79301f7717f5693f26bed7431c1a7..ba3e11ab6c6dda0cbe2ad6e35980b0b03b5dc895 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -238,6 +238,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")
 
@@ -500,6 +503,10 @@ set (CONFIG_LIBCONFIG_SOURCES
    )   
 add_library(params_libconfig MODULE ${CONFIG_LIBCONFIG_SOURCES} )
 target_link_libraries(params_libconfig config)  
+# shared library loader
+set (SHLIB_LOADER_SOURCES
+    ${OPENAIR_DIR}/common/utils/load_module_shlib.c
+)
 # include RF devices / transport protocols library modules
 ######################################################################
 
@@ -543,6 +550,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")
 
 ##########################################################
 
@@ -1738,9 +1758,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()
@@ -1828,6 +1864,7 @@ add_executable(lte-softmodem
   ${XFORMS_SOURCE_SOFTMODEM}
   ${T_SOURCE}
   ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
   )
 
 target_link_libraries (lte-softmodem
@@ -1864,6 +1901,8 @@ add_executable(lte-softmodem-nos1
   ${XFORMS_SOURCE}
   ${XFORMS_SOURCE_SOFTMODEM}
   ${T_SOURCE}
+  ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
   )
 target_link_libraries (lte-softmodem-nos1
   -Wl,--start-group
@@ -1951,6 +1990,8 @@ add_executable(oaisim
   ${OPENAIR_TARGETS}/COMMON/create_tasks.c
   ${XFORMS_SOURCE}
   ${T_SOURCE}
+  ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
 )
 
 #add_library( imp_nfapi STATIC IMPORTED)
@@ -2016,6 +2057,8 @@ add_executable(oaisim_nos1
   ${OPENAIR_DIR}/common/utils/system.c
   ${XFORMS_SOURCE}
   ${T_SOURCE}
+  ${CONFIG_SOURCES}
+  ${SHLIB_LOADER_SOURCES}
 )
 target_include_directories(oaisim_nos1 PUBLIC  ${OPENAIR_TARGETS}/SIMU/USER)
 target_link_libraries (oaisim_nos1
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 2877133306447530ea33812699242a0ffa2579b5..986128af342d97bae5c7c0450e364d2726d426e5 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"
@@ -324,7 +345,11 @@ function main() {
             BUILD_ECLIPSE=1
             CMAKE_CMD="$CMAKE_CMD"' -DCMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT=TRUE -G"Eclipse CDT4 - Unix Makefiles"'
             echo_info "Enabling build eclipse project support"
-            shift 1;;			
+            shift 1;;
+       --build-telnetsrv)
+            BUILD_TELNETSRV=1
+            echo_info "Build embedded telnet server"
+            shift ;;			
         -h | --help)
             print_help
             exit 1;;
@@ -448,6 +473,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 +537,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
@@ -782,7 +815,22 @@ function main() {
 	 rrh_gw $dbin/rrh_gw
 
   fi
-  
+  # Telnet server compilation
+  #####################
+  if [ "$BUILD_TELNETSRV" = "1" ] ; then
+
+     telnetsrv_build_dir=telnetsrv
+     mkdir -p $DIR/$telnetsrv_build_dir/build
+     cd $DIR/$telnetsrv_build_dir/build   
+     echo_info "Compiling telnet server library ..."
+    
+     [ "$CLEAN" = "1" ] && rm -rf $DIR/$telnetsrv_build_dir 
+     cmake_file=$OPENAIR_DIR/common/utils/$telnetsrv_build_dir/CMakeLists.txt   
+     cd $DIR/$telnetsrv_build_dir/build
+     eval  "$CMAKE_CMD $OPENAIR_DIR/common/utils/$telnetsrv_build_dir/"
+     make
+
+  fi  
   # build RF device and transport protocol libraries
   #####################################
   if [ "$eNB" = "1" -o "$UE" = "1" -o  "$RRH" = "1" ] ; then
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 8157d8b705bfbbe3ad36179de24463a10fa35680..56be4f8e0614bf014748d61dccfe6c3489256677 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
@@ -215,7 +240,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
@@ -226,27 +273,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() {
@@ -269,8 +361,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 \
@@ -299,13 +392,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"
     (
@@ -316,6 +469,7 @@ check_install_additional_tools (){
     $SUDO python setup.py install
     cd -
     ) >& $log_netiface
+  fi
 }
 
 check_install_oai_software() {
@@ -324,16 +478,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
@@ -396,73 +551,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_cmdline.c b/common/config/config_cmdline.c
index b7885ce456f8962f50ca13586e608593463e77d7..42ea7259c31963ff871c201b8215745086532223 100644
--- a/common/config/config_cmdline.c
+++ b/common/config/config_cmdline.c
@@ -37,43 +37,71 @@
 
 int processoption(paramdef_t *cfgoptions, char *value)
 {
-int ret = 0;
+char *tmpval = value;
+int optisset=0;
+char defbool[2]="1";
 
+     if ( value == NULL) {
+        if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */
+	    fprintf(stderr,"[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname);
+	    return 0;
+        } else {        /* boolean value option without argument, set value to true*/
+            tmpval = defbool;
+        }
+     }
      switch(cfgoptions->type)
        {
        	case TYPE_STRING:
-           check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *));
-           check_valptr(cfgoptions, cfgoptions->strptr, strlen(value+1));
-           sprintf(*(cfgoptions->strptr), "%s",value);
-           printf_cmdl("[LIBCONFIG] %s set to  %s from command line\n", cfgoptions->optname, value);
-           ret++;
-       break;
-       case TYPE_STRINGLIST:
-
-       break;
+           config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *));
+           config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval+1));
+           sprintf(*(cfgoptions->strptr), "%s",tmpval);
+           printf_cmdl("[CONFIG] %s set to  %s from command line\n", cfgoptions->optname, tmpval);
+	   optisset=1;
+        break;
 	
-       	case TYPE_UINT:
-       	case TYPE_INT:
+        case TYPE_STRINGLIST:
+        break;
+        case TYPE_UINT32:
+       	case TYPE_INT32:
+        case TYPE_UINT16:
+       	case TYPE_INT16:
+	case TYPE_UINT8:
+       	case TYPE_INT8:	
+           config_check_valptr(cfgoptions, (char **)&(cfgoptions->iptr),sizeof(int32_t));
+	   config_assign_int(cfgoptions,cfgoptions->optname,(int32_t)strtol(tmpval,NULL,0));  
+	   optisset=1;
+        break;  	
        	case TYPE_UINT64:
        	case TYPE_INT64:
-           check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(uint64_t)); 
-           *(cfgoptions->uptr) =strtol(value,NULL,0);  
-           printf_cmdl("[LIBCONFIG] %s set to  %lli from command line\n", cfgoptions->optname, (long long)*(cfgoptions->i64ptr));
-           ret++; 
+           config_check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(uint64_t));
+	   *(cfgoptions->i64ptr)=strtoll(tmpval,NULL,0);  
+           printf_cmdl("[CONFIG] %s set to  %lli from command line\n", cfgoptions->optname, (long long)*(cfgoptions->i64ptr));
+	   optisset=1;
         break;        
        	case TYPE_UINTARRAY:
        	case TYPE_INTARRAY:
 
         break;
+        case TYPE_DOUBLE:
+           config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double)); 
+           *(cfgoptions->dblptr) = strtof(tmpval,NULL);  
+           printf_cmdl("[CONFIG] %s set to  %lf from command line\n", cfgoptions->optname, *(cfgoptions->dblptr));
+	   optisset=1; 
+        break; 
+
        	case TYPE_IPV4ADDR:
 
         break;
 
        default:
-            fprintf(stderr,"[LIBCONFIG] command line, %s type %i  not supported\n",cfgoptions->optname, cfgoptions->type);
+            fprintf(stderr,"[CONFIG] command line, %s type %i  not supported\n",cfgoptions->optname, cfgoptions->type);
        break;
        } /* switch on param type */
-    return ret;
+       if (optisset == 1) {
+          cfgoptions->paramflags = cfgoptions->paramflags |  PARAMFLAG_PARAMSET;
+       }
+       
+    return optisset;
 }
 
 int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
@@ -81,6 +109,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix)
 char **p = config_get_if()->argv;
 int c = config_get_if()->argc;
 int j;
+char *pp;
 char *cfgpath; 
  
   j = (prefix ==NULL) ? 0 : strlen(prefix); 
@@ -93,22 +122,35 @@ char *cfgpath;
   j=0;
   p++;
   c--;
-    while (c >= 0 && *p != NULL) {
+    while (c > 0 && *p != NULL) {
         if (strcmp(*p, "-h") == 0 || strcmp(*p, "--help") == 0 ) {
             config_printhelp(cfgoptions,numoptions);
         }
-        for(int i=0;i<numoptions;i++) {
-            if ( ( cfgoptions[i].paramflags & PARAMFLAG_DISABLECMDLINE) != 0) {
-              continue;
-             }
-            sprintf(cfgpath,"%s.%s",prefix,cfgoptions[i].optname);
-            if ( strcmp(*p + 1,cfgoptions[i].shortopt) == 0  || 
-                 strcmp(*p + 2,cfgpath ) == 0 ) {
-               p++;
-               j =+ processoption(&(cfgoptions[i]), *p);
-               c--;
-            }
-         }   	     
+
+        if (*p[0] == '-') {        
+    	    for(int i=0;i<numoptions;i++) {
+    		if ( ( cfgoptions[i].paramflags & PARAMFLAG_DISABLECMDLINE) != 0) {
+    		  continue;
+    		 }
+    		if (prefix != NULL) {
+    		   sprintf(cfgpath,"%s.%s",prefix,cfgoptions[i].optname);
+    		} else {
+    		   sprintf(cfgpath,"%s",cfgoptions[i].optname);
+    		}
+
+    		if ( ((strlen(*p) == 2) && (strcmp(*p + 1,cfgpath) == 0))  || 
+    		     ((strlen(*p) > 2) && (strcmp(*p + 2,cfgpath ) == 0 )) ) {
+    		   pp = *(p+1);
+    		   if ( ( pp != NULL ) && (c>1) &&  (pp[0]!= '-') ) {
+    		
+    		      j += processoption(&(cfgoptions[i]), pp);
+    		   } else {
+    		      j += processoption(&(cfgoptions[i]), NULL);
+    		   }
+                   break;
+    		}
+    	     } /* for */
+         } /* if (*p[0] == '-') */  	     
    	 p++;
          c--;  
     }   /* fin du while */
diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c
index cec08b7e450c09fe0665c763925702e368f59c25..8351d4d82c143bf05601638fcebe4e80e1f02039 100644
--- a/common/config/config_load_configmodule.c
+++ b/common/config/config_load_configmodule.c
@@ -42,7 +42,7 @@
 #include "config_userapi.h"
 #define CONFIG_SHAREDLIBFORMAT "libparams_%s.so"
 
-int load_config_sharedlib(char *cfgmode, char *cfgP[], int numP, configmodule_interface_t *cfgptr)
+int load_config_sharedlib(configmodule_interface_t *cfgptr)
 {
 void *lib_handle;
 char fname[128];
@@ -50,46 +50,46 @@ char libname[FILENAME_MAX];
 int st;
 
    st=0;  
-   sprintf(libname,CONFIG_SHAREDLIBFORMAT,cfgmode);
+   sprintf(libname,CONFIG_SHAREDLIBFORMAT,cfgptr->cfgmode);
 
    lib_handle = dlopen(libname,RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE);
    if (!lib_handle) {
       fprintf(stderr,"[CONFIG] %s %d Error calling dlopen(%s): %s\n",__FILE__, __LINE__, libname,dlerror());
       st = -1;
    } else { 
-      sprintf (fname,"config_%s_init",cfgmode);
+      sprintf (fname,"config_%s_init",cfgptr->cfgmode);
       cfgptr->init = dlsym(lib_handle,fname);
 
       if (cfgptr->init == NULL ) {
          printf("[CONFIG] %s %d no function %s for config mode %s\n",
-               __FILE__, __LINE__,fname, cfgmode);
+               __FILE__, __LINE__,fname, cfgptr->cfgmode);
       } else {
-         st=cfgptr->init(cfgP,numP); 
+         st=cfgptr->init(cfgptr->cfgP,cfgptr->num_cfgP); 
          printf("[CONFIG] function %s returned %i\n",
                fname, st);	 
       }
 
-      sprintf (fname,"config_%s_get",cfgmode);
+      sprintf (fname,"config_%s_get",cfgptr->cfgmode);
       cfgptr->get = dlsym(lib_handle,fname);
       if (cfgptr->get == NULL ) { 
          printf("[CONFIG] %s %d no function %s for config mode %s\n",
-               __FILE__, __LINE__,fname, cfgmode);
+               __FILE__, __LINE__,fname, cfgptr->cfgmode);
 	 st = -1;
       }
       
-      sprintf (fname,"config_%s_getlist",cfgmode);
+      sprintf (fname,"config_%s_getlist",cfgptr->cfgmode);
       cfgptr->getlist = dlsym(lib_handle,fname);
       if (cfgptr->getlist == NULL ) { 
          printf("[CONFIG] %s %d no function %s for config mode %s\n",
-               __FILE__, __LINE__,fname, cfgmode);
+               __FILE__, __LINE__,fname, cfgptr->cfgmode);
 	 st = -1;
       }
 
-      sprintf (fname,"config_%s_end",cfgmode);
+      sprintf (fname,"config_%s_end",cfgptr->cfgmode);
       cfgptr->end = dlsym(lib_handle,fname);
       if (cfgptr->getlist == NULL ) { 
          printf("[CONFIG] %s %d no function %s for config mode %s\n",
-               __FILE__, __LINE__,fname, cfgmode);
+               __FILE__, __LINE__,fname, cfgptr->cfgmode);
       }      
    } 
    
@@ -105,23 +105,23 @@ char *cfgparam=NULL;
 char *modeparams=NULL;
 char *cfgmode=NULL;
 char *strtokctx=NULL;
-char *cfgP[CONFIG_MAX_OOPT_PARAMS];
-
-int i; 
-int p;  
-
+char *atoken;
+uint32_t tmpflags=0;
+int i;
  
-  for(i=0; i<CONFIG_MAX_OOPT_PARAMS ; i++) {
-      cfgP[i]=NULL;
-  }
-    
 /* first parse the command line to look for the -O option */
   opterr=0;
-  while ((i = getopt(argc, argv, "O:")) != -1) {
-       if ( i == 'O' ) {
-          cfgparam = optarg; 
-       }      
+  for (i = 0;i<argc;i++) {
+       if (strlen(argv[i]) < 2) continue;
+       if ( argv[i][1] == 'O' && i < (argc -1)) {
+          cfgparam = argv[i+1]; 
+       } 
+        if ( argv[i][1] == 'h' ) {
+          tmpflags = CONFIG_HELP; 
+       }            
    }
+   optind=1;
+
 /* look for the OAI_CONFIGMODULE environement variable */
   if ( cfgparam == NULL ) {
      cfgparam = getenv("OAI_CONFIGMODULE");
@@ -135,71 +135,87 @@ int p;
    i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams);
    if (i< 0) {
        fprintf(stderr,"[CONFIG] %s, %d, sscanf error parsing config source  %s: %s\n", __FILE__, __LINE__,cfgparam, strerror(errno));
-       return NULL;
+       cfgmode=strdup("libconfig");
+       modeparams = strdup("oaisoftmodem.conf");
    }
    else if ( i == 1 ) {
+  /* -O argument doesn't contain ":" separator, assume -O <conf file> option, default cfgmode to libconfig
+     with one parameter, the path to the configuration file */
        modeparams=cfgmode;
        cfgmode=strdup("libconfig");
    }
 
    cfgptr = malloc(sizeof(configmodule_interface_t));
-
-   p=0;
-   cfgP[p]=strtok_r(modeparams,":",&strtokctx);     
-   while ( p< CONFIG_MAX_OOPT_PARAMS && cfgP[p] != NULL) {
+   memset(cfgptr,0,sizeof(configmodule_interface_t));
+
+   cfgptr->rtflags = cfgptr->rtflags | tmpflags;
+   cfgptr->argc   = argc;
+   cfgptr->argv   = argv; 
+   cfgptr->cfgmode=strdup(cfgmode);
+
+   cfgptr->num_cfgP=0;
+   atoken=strtok_r(modeparams,":",&strtokctx);     
+   while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) {
+       /* look for debug level in the config parameters, it is commom to all config mode 
+          and will be removed frome the parameter array passed to the shared module */
        char *aptr;
-       aptr=strcasestr(cfgP[p],"dbgl");
+       aptr=strcasestr(atoken,"dbgl");
        if (aptr != NULL) {
-           cfgptr->rtflags = strtol(aptr+4,NULL,0);
-           Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].paramflags = Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].paramflags | PARAMFLAG_DONOTREAD;
-           for (int j=p; j<(CONFIG_MAX_OOPT_PARAMS-1); j++) cfgP[j] = cfgP[j+1];
-           p--;
+           cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0);
+
+       } else {
+           cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken);
+           cfgptr->num_cfgP++;
        }
-       p++;
-       cfgP[p] = strtok_r(NULL,":",&strtokctx);
+       atoken = strtok_r(NULL,":",&strtokctx);
    }
 
    
    printf("[CONFIG] get parameters from %s ",cfgmode);
-   for (i=0;i<p; i++) {
-        printf("%s ",cfgP[i]); 
+   for (i=0;i<cfgptr->num_cfgP; i++) {
+        printf("%s ",cfgptr->cfgP[i]); 
    }
    printf("\n");
 
  
-   i=load_config_sharedlib(cfgmode, cfgP,p,cfgptr);
+   i=load_config_sharedlib(cfgptr);
    if (i< 0) {
       fprintf(stderr,"[CONFIG] %s %d config module %s couldn't be loaded\n", __FILE__, __LINE__,cfgmode);
-      return NULL;
+      cfgptr->rtflags = cfgptr->rtflags | CONFIG_HELP | CONFIG_ABORT;
    } else {
       printf("[CONFIG] config module %s loaded\n",cfgmode);
+      Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags);
+      config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME ); 
    }
 
-   Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags);
-   config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME );   
+  
 
    if (modeparams != NULL) free(modeparams);
    if (cfgmode != NULL) free(cfgmode);
-   optind=1;
-   cfgptr->argc = argc;
-   cfgptr->argv  = argv;    
+   if (CONFIG_ISFLAGSET(CONFIG_ABORT)) config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params));
    return cfgptr;
 }
 
 void end_configmodule()
 { 
   if (cfgptr != NULL) {
-      printf ("[CONFIG] free %u pointers\n",cfgptr->numptrs);  
+      if (cfgptr->end != NULL) {
+         printf ("[CONFIG] calling config module end function...\n"); 
+         cfgptr->end();
+      }
+      if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode);
+      printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP);  
+      for (int i=0; i<cfgptr->num_cfgP; i++) {
+          if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]);
+          }
+      printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs);  
       for(int i=0; i<cfgptr->numptrs ; i++) {
           if (cfgptr->ptrs[i] != NULL) {
              free(cfgptr->ptrs[i]);
           }
           cfgptr->ptrs[i]=NULL;
       }
-      if (cfgptr->end != NULL) {
-      printf ("[CONFIG] calling config module end function...\n"); 
-      cfgptr->end();
-      }
+
   free(cfgptr);
   cfgptr=NULL;
   }
diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h
index 530470173fbdcca788eccdc3d051806477e858ee..71c642f68054180bf521dfcd8a7e0f12bc39e57b 100644
--- a/common/config/config_load_configmodule.h
+++ b/common/config/config_load_configmodule.h
@@ -38,12 +38,15 @@
 #include <stdlib.h>
 #include "common/config/config_paramdesc.h"
 #define CONFIG_MAX_OOPT_PARAMS    10     // maximum number of parameters in the -O option (-O <cfgmode>:P1:P2...
-#define CONFIG_MAX_ALLOCATEDPTRS  1024   // maximum number of parameters that can be dynamicaly alloted in the config module
+#define CONFIG_MAX_ALLOCATEDPTRS  1024   // maximum number of parameters that can be dynamicaly allocated in the config module
 
 /* rtflags bit position definitions */
 #define CONFIG_PRINTPARAMS    1        // print parameters values while processing
 #define CONFIG_DEBUGPTR       2        // print memory allocation/free debug messages
 #define CONFIG_DEBUGCMDLINE   4        // print command line processing messages
+#define CONFIG_HELP           8        // print help message
+#define CONFIG_ABORT          16       // config failed,abort execution 
+
 
 typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP);
 typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix);
@@ -51,31 +54,38 @@ typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int num
 typedef void(*configmodule_endfunc_t)(void);
 typedef struct configmodule_interface
 {
-  int   argc;
-  char  **argv;
+  int      argc;
+  char     **argv;
+  char     *cfgmode;
+  int      num_cfgP;
+  char     *cfgP[CONFIG_MAX_OOPT_PARAMS];
   configmodule_initfunc_t         init;
   configmodule_getfunc_t          get;
   configmodule_getlistfunc_t      getlist;
   configmodule_endfunc_t          end;
-  uint32_t                        numptrs;
-  uint32_t                        rtflags;
-  char  *ptrs[CONFIG_MAX_ALLOCATEDPTRS];  
+  uint32_t numptrs;
+  uint32_t rtflags;
+  char     *ptrs[CONFIG_MAX_ALLOCATEDPTRS];  
 } configmodule_interface_t;
 
 #ifdef CONFIG_LOADCONFIG_MAIN
 configmodule_interface_t *cfgptr=NULL;
 
-static char config_helpstr [] =" \
-      config debugflags: mask, 1->print parameters, 2->print memory allocations debug messages \
-                               4->print command line processing debug messages \
-          -O <config mode><:dbg> \
-          debugflags can also be defined in the config_libconfig section of the config file \
-";
+static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbg[debugflags]> \n \
+          debugflags can also be defined in the config_libconfig section of the config file\n \
+          debugflags: mask,    1->print parameters, 2->print memory allocations debug messages\n \
+                               4->print command line processing debug messages\n ";
+			       
 #define CONFIG_SECTIONNAME "config"
-
 #define CONFIGPARAM_DEBUGFLAGS_IDX        0
+
+
 static paramdef_t Config_Params[] = {
-{"debugflags",         "",   config_helpstr,   0,   uptr:NULL,   defintval:0,        TYPE_UINT,  0}, 
+/*-----------------------------------------------------------------------------------------------------------------------*/
+/*                                            config parameters for config module                                        */
+/*   optname              helpstr           paramflags     XXXptr       defXXXval            type       numelt           */
+/*-----------------------------------------------------------------------------------------------------------------------*/
+{"debugflags",            config_helpstr,   0,             uptr:NULL,   defintval:0,        TYPE_MASK,  0}, 
 };
 
 #else
diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h
index 978178eac4bb95a47f9c11714ffef3d9a57b0383..a7de5e3098ffabc47226eb8c04ab0381b3593af8 100644
--- a/common/config/config_paramdesc.h
+++ b/common/config/config_paramdesc.h
@@ -38,55 +38,67 @@
 
 
 #define MAX_OPTNAME_SIZE 64
-#define MAX_SHORTOPT_SIZE 8
 
 
-/* parameter flags definitions */
-/*   Flags to be used by calling modules in their parameters definitions: */
-#define PARAMFLAG_DISABLECMDLINE          (1 << 0)         // parameter can bet set from comand line
 
-/*   Flags used by config modules: */
-/* flags to be used by caller modules when defining parameters */
-#define PARAMFLAG_MANDATORY               (1 << 1)               // parameter must be explicitely set, default value ignored
+/* parameter flags definitions */
+/*   Flags to be used by calling modules in their parameters definitions to modify  config module behavior*/
+#define PARAMFLAG_MANDATORY               (1 << 0)         // parameter must be explicitely set, default value ignored
+#define PARAMFLAG_DISABLECMDLINE          (1 << 1)         // parameter cannot bet set from comand line
+#define PARAMFLAG_DONOTREAD               (1 << 2)         // parameter must be ignored in get function
+#define PARAMFLAG_NOFREE                  (1 << 3)         // don't free parameter in end function
+#define PARAMFLAG_BOOL                    (1 << 4)         // integer param can be 0 or 1
 
-/* flags used by config modules, at runtime to manage memory allocations */
-#define PARAMFLAG_MALLOCINCONFIG         (1 << 15)        // parameter allocated in config module
-#define PARAMFLAG_NOFREE                 (1 << 14)        // don't free parameter in end function
 
-/* flags to be used by caller modules to modify get behavior */
-#define PARAMFLAG_DONOTREAD              (1 << 20)        // parameter must be ignored in get function
+/*   Flags used by config modules to return info to calling modules and/or to  for internal usage*/
+#define PARAMFLAG_MALLOCINCONFIG          (1 << 15)        // parameter allocated in config module
+#define PARAMFLAG_PARAMSET                (1 << 16)        // parameter has been explicitely set in get functions
+#define PARAMFLAG_PARAMSETDEF             (1 << 17)        // parameter has been set to default value in get functions
 
 typedef struct paramdef
 {
-   char optname[MAX_OPTNAME_SIZE];
-   char shortopt[MAX_SHORTOPT_SIZE];
-   char *helpstr;
-   unsigned int paramflags;
-   union {
+   char optname[MAX_OPTNAME_SIZE];        /* parameter name, can be used as long command line option */
+   char *helpstr;                         /* help string */
+   unsigned int paramflags;               /* value is a "ored" combination of above PARAMFLAG_XXXX values */
+   union {                                /* pointer to the parameter value, completed by the config module */
      char **strptr;
      char **strlistptr;
-     uint32_t *uptr;
-     int32_t *iptr;
-     uint64_t *u64ptr;
-     int64_t *i64ptr;
+     uint8_t   *u8ptr;
+     char      *i8ptr;     
+     uint16_t  *u16ptr;
+     int16_t   *i16ptr;
+     uint32_t  *uptr;
+     int32_t   *iptr;
+     uint64_t  *u64ptr;
+     int64_t   *i64ptr;
+     double    *dblptr;
      } ;
-   union {
+   union {                                /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */
      char *defstrval;
      char **defstrlistval;
      uint32_t defuintval;
      int defintval;
      uint64_t defint64val;
      int *defintarrayval;
+     double defdblval;
      } ;   
-   char type;
-   int numelt;
+   char type;                              /* parameter value type, as listed below as TYPE_XXXX macro */
+   int numelt;                             /* number of elements in a list or array parameters or max size of string value */ 
 } paramdef_t;
 
+#define TYPE_INT        TYPE_INT32
+#define TYPE_UINT       TYPE_UINT32
 #define TYPE_STRING     1
-#define TYPE_INT        2
-#define TYPE_UINT       3
-#define TYPE_INT64      4
-#define TYPE_UINT64     5
+#define TYPE_INT8       2
+#define TYPE_UINT8      3
+#define TYPE_INT16      4
+#define TYPE_UINT16     5
+#define TYPE_INT32      6
+#define TYPE_UINT32     7
+#define TYPE_INT64      8
+#define TYPE_UINT64     9
+#define TYPE_MASK       10
+#define TYPE_DOUBLE     16
 #define TYPE_IPV4ADDR   20
 
 
@@ -94,7 +106,7 @@ typedef struct paramdef
 #define TYPE_INTARRAY   51
 #define TYPE_UINTARRAY  52
 #define TYPE_LIST       55
-#define NO_UINTDEFAULT ((int)(-1))
+
 #define ANY_IPV4ADDR_STRING "0.0.0.0"
 
 typedef struct paramlist_def {
diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c
index 3b0a0a2a56d9e8c667425b57cfafcd4e0db78dc9..339889ea2f209ef720fd2034495c45777b056410 100644
--- a/common/config/config_userapi.c
+++ b/common/config/config_userapi.c
@@ -47,7 +47,7 @@ configmodule_interface_t *config_get_if(void)
     return cfgptr;
 }
 
-char * check_valptr(paramdef_t *cfgoptions, char **ptr, int length) 
+char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) 
 {
 
      printf_ptrs("-- %s 0x%08lx %i\n",cfgoptions->optname,(uintptr_t)(*ptr),length);
@@ -60,18 +60,62 @@ char * check_valptr(paramdef_t *cfgoptions, char **ptr, int length)
                  config_get_if()->numptrs++;
              }
         } else {
-             fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__);
+             fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__);
              exit(-1);
         }       
      }
      return *ptr;
 }
 
+void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val)
+{
+int tmpval=val;
+  if ( ((cfgoptions->paramflags &PARAMFLAG_BOOL) != 0) && tmpval >1) {
+      tmpval =1;
+  }
+  switch (cfgoptions->type) {
+       	case TYPE_UINT8:
+	     *(cfgoptions->u8ptr) = (uint8_t)tmpval;
+	     printf_params("[CONFIG] %s: %u\n", fullname, (uint8_t)tmpval);
+	break;
+       	case TYPE_INT8:
+	     *(cfgoptions->i8ptr) = (int8_t)tmpval;
+	     printf_params("[CONFIG] %s: %i\n", fullname, (int8_t)tmpval);
+	break;		
+       	case TYPE_UINT16:
+	     *(cfgoptions->u16ptr) = (uint16_t)tmpval;
+	     printf_params("[CONFIG] %s: %hu\n", fullname, (uint16_t)tmpval);     
+	break;
+       	case TYPE_INT16:
+	     *(cfgoptions->i16ptr) = (int16_t)tmpval;
+	     printf_params("[CONFIG] %s: %hi\n", fullname, (int16_t)tmpval);
+	break;	
+       	case TYPE_UINT32:
+	     *(cfgoptions->uptr) = (uint32_t)tmpval;
+	     printf_params("[CONFIG] %s: %u\n", fullname, (uint32_t)tmpval);
+	break;
+       	case TYPE_MASK:
+	     *(cfgoptions->uptr) = *(cfgoptions->uptr) | (uint32_t)tmpval;
+	     printf_params("[CONFIG] %s: 0x%08x\n", fullname, (uint32_t)tmpval);
+	break;
+       	case TYPE_INT32:
+	     *(cfgoptions->iptr) = (int32_t)tmpval;
+	     printf_params("[CONFIG] %s: %i\n", fullname, (int32_t)tmpval);
+	break;	
+	default:
+	     fprintf (stderr,"[CONFIG] %s %i type %i non integer parameter %s not assigned\n",__FILE__, __LINE__,cfgoptions->type,fullname);
+	break;
+  }
+}
+
 void config_printhelp(paramdef_t *params,int numparams)
 {
    for (int i=0 ; i<numparams ; i++) {
        if ( params[i].helpstr != NULL) {
-           printf("%s", params[i].helpstr);
+           printf("%s%s: %s",
+	           (strlen(params[i].optname) <= 1) ? "-" : "--", 
+	           params[i].optname,
+	           params[i].helpstr);
        }
    }
 }
@@ -79,13 +123,28 @@ void config_printhelp(paramdef_t *params,int numparams)
 int config_get(paramdef_t *params,int numparams, char *prefix)
 {
 int ret= -1;
+
+printf("numparams:%d prefix:%s\n", numparams, prefix);
+if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
+    fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n");
+    return ret;
+}
 configmodule_interface_t *cfgif = config_get_if();
-if (cfgif != NULL) {
-    ret = config_get_if()->get(params, numparams,prefix);
-    if (ret >= 0) {
-       config_process_cmdline(params,numparams,prefix);
-   }
+  if (cfgif != NULL) {
+      ret = config_get_if()->get(params, numparams,prefix);
+      if (ret >= 0) {
+         config_process_cmdline(params,numparams,prefix);
+     }
+  return ret;
+  }
 return ret;
 }
-return ret;
+
+int config_isparamset(paramdef_t *params,int paramidx)
+{
+  if ((params[paramidx].paramflags & PARAMFLAG_PARAMSET) != 0) {
+      return 1;
+  } else {
+      return 0;
+  }
 }
diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h
index 06e531f56c347592a87496bbcccdbafcd671216e..6acaacf7166b3e3dcac77c46bff4bef5b7d4d807 100644
--- a/common/config/config_userapi.h
+++ b/common/config/config_userapi.h
@@ -38,14 +38,21 @@
 extern "C"
 {
 #endif
+#define CONFIG_GETSOURCE    ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgmode       )
+#define CONFIG_GETNUMP      ( (config_get_if()==NULL) ? 0    : config_get_if()->num_cfgP      )
+#define CONFIG_GETP(P)      ( (config_get_if()==NULL) ? NULL : config_get_if()->cfgP[P]       )
+#define CONFIG_ISFLAGSET(P) ( (config_get_if()==NULL) ? 0    : !!(config_get_if()->rtflags & P))
 
 extern configmodule_interface_t *config_get_if(void);
-extern char * check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ;
+extern char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ;
 extern void config_printhelp(paramdef_t *,int numparams);
 extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix);
 extern int config_get(paramdef_t *params,int numparams, char *prefix);
+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/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c
index 797666bf0683163ec80b8de783dbc1172fd4e5ce..35a70dfcc79d49fd560a5f8952f4441812c24bf9 100644
--- a/common/config/libconfig/config_libconfig.c
+++ b/common/config/libconfig/config_libconfig.c
@@ -11,6 +11,10 @@
 #include "../config_userapi.h"
 #include "errno.h"
 
+#if ( LIBCONFIG_VER_MAJOR == 1 && LIBCONFIG_VER_MINOR < 5)
+#define config_setting_lookup config_lookup_from
+#endif
+
 void config_libconfig_end(void );
 
 int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath)
@@ -58,16 +62,18 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
 
 
   config_setting_t *setting;
-  const char *str;
+  char *str;
   int i,u;
   long long int llu;
+  double dbl; 
   int rst;
   int status=0;
   int notfound;
+  int defval;
   int fatalerror=0;
   char *cfgpath; /* listname.[listindex].paramname */
-  int defvals=0;
- 
+  int numdefvals=0;
+  
   i = (prefix ==NULL) ? 0 : strlen(prefix); 
   cfgpath = malloc( i+ MAX_OPTNAME_SIZE +1);
   if (cfgpath == NULL) {
@@ -87,20 +93,26 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
          continue;
      }
      notfound=0;
+     defval=0;
      switch(cfgoptions[i].type)
        {
        	case TYPE_STRING:
            
-           if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, &str)) {
-              check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
-              check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
+           if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
+              if ( cfgoptions[i].numelt > 0  && str != NULL && strlen(str) >= cfgoptions[i].numelt ) {
+                  fprintf(stderr,"[LIBCONFIG] %s:  %s exceeds maximum length of %i bytes, value truncated\n",
+                           cfgpath,str,cfgoptions[i].numelt); 
+                  str[strlen(str)-1] = 0;
+              }
+              config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
+              config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1);
               sprintf( *(cfgoptions[i].strptr) , "%s", str);
               printf_params("[LIBCONFIG] %s: %s\n", cfgpath,*(cfgoptions[i].strptr) );
            } else {
 	      if( cfgoptions[i].defstrval != NULL) {
-                 defvals++;
-                 check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
-                 check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1);
+                 defval=1;
+                 config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *));
+                 config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(cfgoptions[i].defstrval)+1);
                  sprintf(*(cfgoptions[i].strptr), "%s",cfgoptions[i].defstrval);
                  printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, *(cfgoptions[i].strptr));
               } else {
@@ -114,8 +126,8 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
               read_strlist(&cfgoptions[i],setting,cfgpath);
            } else {
               if( cfgoptions[i].defstrlistval != NULL) {
-                cfgoptions[i].strlistptr=cfgoptions[i].defstrlistval;
-                defvals++;
+                  cfgoptions[i].strlistptr=cfgoptions[i].defstrlistval;
+                  defval=1;
 		for(int j=0; j<cfgoptions[i].numelt; j++)
                      printf_params("[LIBCONFIG] %s%i set to default value %s\n", cfgpath,j, cfgoptions[i].strlistptr[j]);
               } else {
@@ -123,23 +135,21 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
               }
 	   }
        break;
-	
-       	case TYPE_UINT:
-       	case TYPE_INT:
-           check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].iptr)),sizeof(int));
+       	case TYPE_UINT8:
+       	case TYPE_INT8:	
+       	case TYPE_UINT16:
+       	case TYPE_INT16:
+       	case TYPE_UINT32:
+       	case TYPE_INT32:
+       	case TYPE_MASK:	
+           config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].iptr)),sizeof(int32_t));
            if ( config_lookup_int(&(libconfig_privdata.cfg),cfgpath, &u)) {
-              if(cfgoptions[i].type==TYPE_UINT) {
-                 *(cfgoptions[i].uptr) = (unsigned int)u;
-                 printf_params("[LIBCONFIG] %s: %u\n", cfgpath,*(cfgoptions[i].uptr) );
-              } else {
-                 *(cfgoptions[i].iptr) = u;
-                 printf_params("[LIBCONFIG] %s: %i\n", cfgpath,*(cfgoptions[i].iptr) ); 
-              }
+	      config_assign_int(&(cfgoptions[i]),cfgpath,u);
            } else {
-	      if( cfgoptions[i].defuintval != NO_UINTDEFAULT) {
-                 *(cfgoptions[i].uptr)=cfgoptions[i].defuintval;
-                 defvals++;
-                 printf_params("[LIBCONFIG] %s set to default value %i\n", cfgpath, (int32_t)(*(cfgoptions[i].uptr)));
+	      if( ((cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) == 0)) {
+                 config_assign_int(&(cfgoptions[i]),cfgpath,cfgoptions[i].defintval);
+                 defval=1;
+                 printf_params("[LIBCONFIG] %s set to default value\n", cfgpath);
               } else {
 	         notfound=1;
               }
@@ -147,7 +157,7 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
         break;
        	case TYPE_UINT64:
        	case TYPE_INT64:
-           check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].i64ptr),sizeof(long long));
+           config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].i64ptr),sizeof(long long));
            if ( config_lookup_int64(&(libconfig_privdata.cfg),cfgpath, &llu)) {
               if(cfgoptions[i].type==TYPE_UINT64) {
                  *(cfgoptions[i].u64ptr) = (uint64_t)llu;
@@ -157,9 +167,9 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
                  printf_params("[LIBCONFIG] %s: %lli\n", cfgpath,(long long unsigned)(*(cfgoptions[i].i64ptr)) ); 
               }
            } else {
-	      if( cfgoptions[i].defuintval != NO_UINTDEFAULT) {
+	      if( ((cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) == 0)) {
                  *(cfgoptions[i].u64ptr)=cfgoptions[i].defuintval;
-                 defvals++;
+                 defval=1;
                  printf_params("[LIBCONFIG] %s set to default value %llu\n", cfgpath, (long long unsigned)(*(cfgoptions[i].u64ptr)));
               } else {
 	         notfound=1;
@@ -173,9 +183,9 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
               read_intarray(&cfgoptions[i],setting,cfgpath);
            } else {
               if( cfgoptions[i].defintarrayval != NULL) {
-                check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].iptr), sizeof(int32_t));
+                config_check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].iptr), sizeof(int32_t));
                 cfgoptions[i].iptr=cfgoptions[i].defintarrayval;
-                defvals++;
+                defval=1;
                 for (int j=0; j<cfgoptions[i].numelt ; j++) {
                     printf_params("[LIBCONFIG] %s[%i] set to default value %i\n", cfgpath,j,(int)cfgoptions[i].iptr[j]);
                 }
@@ -184,11 +194,26 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
               }
 	   }    
         break;
+       	case TYPE_DOUBLE:
+           config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].dblptr),sizeof(double));
+           if ( config_lookup_float(&(libconfig_privdata.cfg),cfgpath, &dbl)) {
+                 *(cfgoptions[i].dblptr) = dbl;
+                 printf_params("[LIBCONFIG] %s: %lf\n", cfgpath,*(cfgoptions[i].dblptr) );
+           } else {
+	      if( ((cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) == 0)) {
+                 *(cfgoptions[i].u64ptr)=cfgoptions[i].defdblval;
+                 defval=1;
+                 printf_params("[LIBCONFIG] %s set to default value %lf\n", cfgpath, *(cfgoptions[i].dblptr));
+              } else {
+	         notfound=1;
+              }
+	   }	      
+        break;  
        	case TYPE_IPV4ADDR:
-           check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].uptr), sizeof(int));
-           if ( !config_lookup_string(&(libconfig_privdata.cfg),cfgpath, &str)) {
+           config_check_valptr(&(cfgoptions[i]),(char **)&(cfgoptions[i].uptr), sizeof(int));
+           if ( !config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) {
 	      str=cfgoptions[i].defstrval;
-              defvals++;
+              defval=1;
 	      printf_params("[LIBCONFIG] %s set to default value %s\n", cfgpath, str);
 	   }
 	   if (str != NULL) {
@@ -231,12 +256,18 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix )
            printf("\n");
         }
     } else {
+      if (defval == 1) {
+          numdefvals++;
+	  cfgoptions[i].paramflags = cfgoptions[i].paramflags |  PARAMFLAG_PARAMSETDEF;
+      } else {
+          cfgoptions[i].paramflags = cfgoptions[i].paramflags |  PARAMFLAG_PARAMSET;
+      }
       status++;
     }
   } /* for loop on options */
   printf("[LIBCONFIG] %s: %i/%i parameters successfully set, (%i to default value)\n",
          ((prefix == NULL)?"(root)":prefix), 
-         status,numoptions,defvals );
+         status,numoptions,numdefvals );
   if (fatalerror == 1) {
       fprintf(stderr,"[LIBCONFIG] fatal errors found when processing  %s \n", libconfig_privdata.configfile );
       config_libconfig_end();
@@ -310,13 +341,13 @@ int config_libconfig_init(char *cfgP[], int numP)
   config_init(&(libconfig_privdata.cfg));
   libconfig_privdata.configfile = strdup((char *)cfgP[0]);
   config_get_if()->numptrs=0;
- 
   memset(config_get_if()->ptrs,0,sizeof(void *) * CONFIG_MAX_ALLOCATEDPTRS);
 
   /* Read the file. If there is an error, report it and exit. */
   if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) {
-    fprintf(stderr,"[LIBCONFIG] %s:%d - %s\n", config_error_file(&(libconfig_privdata.cfg)),
-            config_error_line(&(libconfig_privdata.cfg)), config_error_text(&(libconfig_privdata.cfg)));
+    fprintf(stderr,"[LIBCONFIG] %s %d file %s - %d - %s\n",__FILE__, __LINE__,
+                   libconfig_privdata.configfile, config_error_line(&(libconfig_privdata.cfg)),
+                   config_error_text(&(libconfig_privdata.cfg)));
     config_destroy(&(libconfig_privdata.cfg));
     printf( "\n");
     return -1;
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..0eef56505a1e8484f24134d8779f0cfe8c96d19a 100644
--- a/common/utils/T/T_messages.txt
+++ b/common/utils/T/T_messages.txt
@@ -16,63 +16,67 @@ ID = ENB_PHY_DL_TICK
 ID = ENB_PHY_DLSCH_UE_DCI
     DESC = eNodeB downlink UE specific DCI as sent by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format : int,harq_pid : int,mcs : int,TBS
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,dci_format : int,harq_pid : int,mcs : int,TBS
 ID = ENB_PHY_DLSCH_UE_ACK
     DESC = eNodeB downlink UE ACK as seen by the PHY layer in process_HARQ_feedback
     GROUP = ALL:PHY:GRAPHIC:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = ENB_PHY_DLSCH_UE_NACK
     DESC = eNodeB downlink UE NACK as seen by the PHY layer in process_HARQ_feedback
     GROUP = ALL:PHY:GRAPHIC:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = ENB_PHY_ULSCH_UE_DCI
     DESC = eNodeB uplink UE specific DCI as sent by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS : int,L : int,firstCCE
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS : int,L : int,firstCCE
 ID = ENB_PHY_ULSCH_UE_NO_DCI_RETRANSMISSION
     DESC = eNodeB uplink UE retransmission due to PHICH NACK (see generate_phich_top)
     GROUP = ALL:PHY:GRAPHIC:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = ENB_PHY_ULSCH_UE_ACK
     DESC = eNodeB uplink UE ACK as seen by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = ENB_PHY_ULSCH_UE_NACK
     DESC = eNodeB uplink UE NACK as seen by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 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
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,antenna : buffer,chest_t
+    FORMAT = int,eNB_ID : int,rnti : int,frame : int,subframe : int,antenna : buffer,chest_t
 ID = ENB_PHY_PUSCH_IQ
     DESC = eNodeB PUSCH received IQ data
     GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pusch_comp
+    FORMAT = int,eNB_ID : int,rnti : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pusch_comp
 ID = ENB_PHY_PUCCH_1AB_IQ
     DESC = eNodeB PUCCH received IQ data
     GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,I : int,Q
+    FORMAT = int,eNB_ID : int,rnti : int,frame : int,subframe : int,I : int,Q
 ID = ENB_PHY_PUCCH_1_ENERGY
     DESC = eNodeB PUCCH 1 energy and threshold
     GROUP = ALL:PHY:GRAPHIC:HEAVY:ENB
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,energy : int,threshold
+    FORMAT = int,eNB_ID : int,rnti : int,frame : int,subframe : int,energy : int,threshold
 ID = ENB_PHY_PHICH
     DESC = eNodeB PHICH
     GROUP = ALL:PHY:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,NGROUP : int,NSF : int,ngroup : int,nseq : int,ACK : int,first_rb : int,n_DMRS
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid : int,NGROUP : int,NSF : int,ngroup : int,nseq : int,ACK : int,first_rb : int,n_DMRS
 ID = ENB_PHY_MSG3_ALLOCATION
     DESC = eNodeB Msg3 allocation/reallocation
     GROUP = ALL:PHY:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,first_transmission : int,Msg3_frame : int,Msg3_subframe
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,first_transmission : int,Msg3_frame : int,Msg3_subframe
 ID = ENB_PHY_INITIATE_RA_PROCEDURE
     DESC = eNodeB initiates a random access procedure after detecting enough energy for one of the preambles
     GROUP = ALL:PHY:ENB
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,preamble : int,energy : int,delay
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,preamble : int,energy : int,delay
 
 #MAC logs
 ID = ENB_MAC_UE_DL_SDU
@@ -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
@@ -826,27 +834,27 @@ ID = UE_PHY_DL_TICK
 ID = UE_PHY_DLSCH_UE_DCI
     DESC = UE downlink UE specific DCI as sent by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:UE
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,dci_format : int,harq_pid : int,mcs : int,TBS
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,dci_format : int,harq_pid : int,mcs : int,TBS
 ID = UE_PHY_DLSCH_UE_ACK
     DESC = UE downlink UE ACK as seen by the PHY layer in process_HARQ_feedback
     GROUP = ALL:PHY:GRAPHIC:UE
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = UE_PHY_DLSCH_UE_NACK
     DESC = UE downlink UE NACK as seen by the PHY layer in process_HARQ_feedback
     GROUP = ALL:PHY:GRAPHIC:UE
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = UE_PHY_ULSCH_UE_DCI
     DESC = UE uplink UE specific DCI as sent by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:UE
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid : int,mcs : int,round : int,first_rb : int,nb_rb : int,TBS
 ID = UE_PHY_ULSCH_UE_ACK
     DESC = UE uplink UE ACK as seen by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:UE
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = UE_PHY_ULSCH_UE_NACK
     DESC = UE uplink UE NACK as seen by the PHY layer
     GROUP = ALL:PHY:GRAPHIC:UE
-    FORMAT = int,eNB_ID : int,frame : int,subframe : int,UE_id : int,rnti : int,harq_pid
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,harq_pid
 ID = UE_PHY_INPUT_SIGNAL
     DESC = UE received signal in the time domain for a duration of 1ms
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
@@ -854,7 +862,7 @@ ID = UE_PHY_INPUT_SIGNAL
 ID = UE_PHY_DL_CHANNEL_ESTIMATE
     DESC = UE channel estimation in the time domain
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,antenna : buffer,chest_t
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,antenna : buffer,chest_t
 ID = UE_PHY_PDCCH_IQ
     DESC = UE PDCCH received IQ data
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
@@ -862,27 +870,27 @@ ID = UE_PHY_PDCCH_IQ
 ID = UE_PHY_PDCCH_ENERGY
     DESC = UE PDSCH 1 energy and threshold
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,pdcch_ch_level00 : int,pdcch_ch_level01 : int,pdcch_ch_level10: int,pdcch_ch_level11
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,pdcch_ch_level00 : int,pdcch_ch_level01 : int,pdcch_ch_level10: int,pdcch_ch_level11
 ID = UE_PHY_PDSCH_IQ
     DESC = UE PDSCH received IQ data
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pusch_comp
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,nb_rb : int,N_RB_UL : int,symbols_per_tti : buffer,pusch_comp
 ID = UE_PHY_PDSCH_ENERGY
     DESC = UE PDSCH 1 energy and threshold
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,pdsch_ch_level00 : int,pdsch_ch_level01 : int,pdsch_ch_level10: int,pdsch_ch_level11
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,pdsch_ch_level00 : int,pdsch_ch_level01 : int,pdsch_ch_level10: int,pdsch_ch_level11
 ID = UE_PHY_PUSCH_TX_POWER
     DESC = UE PUSCH  tx power
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
-    FORMAT = int,eNB_ID : int,UE_id : int,frame : int,subframe : int,p0_pusch : int,ampl: int,g_pusch: int,pl: int,nb_rb
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,p0_pusch : int,ampl: int,g_pusch: int,pl: int,nb_rb
 ID = UE_PHY_PUCCH_TX_POWER
     DESC = UE PDSCH 1 energy and threshold
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
-    FORMAT = int,eNB_ID : int,UE_id : int,frame : int,subframe : int,p0_pucch : int,ampl: int,g_pucch: int,pl
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,p0_pucch : int,ampl: int,g_pucch: int,pl
 ID = UE_PHY_MEAS
     DESC = UE PHY measurements
     GROUP = ALL:PHY:GRAPHIC:HEAVY:UE
-    FORMAT = int,eNB_ID : int,UE_ID : int,frame : int,subframe : int,rsrp : int,rssi : int,snr: int,rx_power: int,noise_power: int,w_cqi: int,freq_offset
+    FORMAT = int,eNB_ID : int,frame : int,subframe : int,rsrp : int,rssi : int,snr: int,rx_power: int,noise_power: int,w_cqi: int,freq_offset
 
 #for debug/test - not used
 ID = first
@@ -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/enb.c b/common/utils/T/tracer/enb.c
index 27d8630fd8d53f8f84f3235fee5cebe36a2c3dc2..74bea1e675b8defd7ce88f1d90ba74a3cbe02ac0 100644
--- a/common/utils/T/tracer/enb.c
+++ b/common/utils/T/tracer/enb.c
@@ -17,6 +17,40 @@
 #include "openair_logo.h"
 #include "config.h"
 
+/****************************************************************************/
+/* conversion from rnti to "ue_id" (which does not really exists)           */
+/* the idea is to assign an ue_id to an rnti as soon as we get an event     */
+/* for the rnti                                                             */
+/****************************************************************************/
+
+int ue_id[65536];
+int next_ue_id;
+
+void reset_ue_ids(void)
+{
+  int i;
+  printf("resetting known UEs\n");
+  for (i = 0; i < 65536; i++) ue_id[i] = -1;
+  next_ue_id = 0;
+}
+
+int ue_id_from_rnti(void *_priv, int rnti)
+{
+rnti = 0; /* HACK, to be removed */
+  if (rnti < 0 || rnti > 65535) { printf("bad rnti %d\n", rnti); exit(1); }
+  /* rnti not seen yet? give it a new ue_id */
+  if (ue_id[rnti] == -1) {
+    ue_id[rnti] = next_ue_id;
+    next_ue_id++;
+  }
+  return ue_id[rnti];
+}
+
+/****************************************************************************/
+/* end of rnti->ue_id conversion                                            */
+/****************************************************************************/
+
+
 typedef struct {
   view *phyview;
   view *macview;
@@ -25,6 +59,7 @@ typedef struct {
   view *rrcview;
   view *legacy;
   widget *current_ue_label;
+  widget *current_ue_button;
   widget *prev_ue_button;
   widget *next_ue_button;
   widget *pusch_iq_ue_xy_plot;
@@ -116,11 +151,15 @@ static void *gui_thread(void *_g)
 static filter *ticktime_filter(void *database, char *event, int i, int ue)
 {
   /* filter is "harq_pid == i && UE_id == 0 && eNB_id == 0" */
+  /* we get the UE_id from the rnti */
   return
     filter_and(
       filter_eq(filter_evarg(database, event, "harq_pid"), filter_int(i)),
       filter_and(
-        filter_eq(filter_evarg(database, event, "UE_id"), filter_int(ue)),
+        filter_eq(
+          filter_evfun(database, ue_id_from_rnti, NULL,
+            filter_evarg(database, event, "rnti")),
+          filter_int(ue)),
         filter_eq(filter_evarg(database, event, "eNB_ID"), filter_int(0))));
 }
 
@@ -148,23 +187,28 @@ static void set_current_ue(gui *g, enb_data *e, int ue)
 
   logger_set_filter(e->e->pusch_iq_ue_logger,
       filter_eq(
-        filter_evarg(e->database, "ENB_PHY_PUSCH_IQ", "UE_ID"),
+        filter_evfun(e->database, ue_id_from_rnti, NULL,
+          filter_evarg(e->database, "ENB_PHY_PUSCH_IQ", "rnti")),
         filter_int(ue)));
   logger_set_filter(e->e->ul_estimate_ue_logger,
       filter_eq(
-        filter_evarg(e->database, "ENB_PHY_UL_CHANNEL_ESTIMATE", "UE_ID"),
+        filter_evfun(e->database, ue_id_from_rnti, NULL,
+          filter_evarg(e->database, "ENB_PHY_UL_CHANNEL_ESTIMATE", "rnti")),
         filter_int(ue)));
   logger_set_filter(e->e->pucch1_energy_ue_threshold_logger,
       filter_eq(
-        filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
+        filter_evfun(e->database, ue_id_from_rnti, NULL,
+          filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "rnti")),
         filter_int(ue)));
   logger_set_filter(e->e->pucch1_energy_ue_energy_logger,
       filter_eq(
-        filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "UE_ID"),
+        filter_evfun(e->database, ue_id_from_rnti, NULL,
+          filter_evarg(e->database, "ENB_PHY_PUCCH_1_ENERGY", "rnti")),
         filter_int(ue)));
   logger_set_filter(e->e->pucch_iq_ue_logger,
       filter_eq(
-        filter_evarg(e->database, "ENB_PHY_PUCCH_1AB_IQ", "UE_ID"),
+        filter_evfun(e->database, ue_id_from_rnti, NULL,
+          filter_evarg(e->database, "ENB_PHY_PUCCH_1AB_IQ", "rnti")),
         filter_int(ue)));
   for (i = 0; i < 8; i++) {
     logger_set_filter(e->e->dl_dci_logger[i],
@@ -185,11 +229,13 @@ static void set_current_ue(gui *g, enb_data *e, int ue)
   }
   logger_set_filter(e->e->dl_mcs_logger,
       filter_eq(
-        filter_evarg(e->database, "ENB_PHY_DLSCH_UE_DCI", "UE_id"),
+        filter_evfun(e->database, ue_id_from_rnti, NULL,
+          filter_evarg(e->database, "ENB_PHY_DLSCH_UE_DCI", "rnti")),
         filter_int(ue)));
   logger_set_filter(e->e->ul_mcs_logger,
       filter_eq(
-        filter_evarg(e->database, "ENB_PHY_ULSCH_UE_DCI", "UE_id"),
+        filter_evfun(e->database, ue_id_from_rnti, NULL,
+          filter_evarg(e->database, "ENB_PHY_ULSCH_UE_DCI", "rnti")),
         filter_int(ue)));
 }
 
@@ -205,6 +251,7 @@ static void click(void *private, gui *g,
   if (button != 1) return;
   if (w == e->prev_ue_button) { ue--; if (ue < 0) ue = 0; }
   if (w == e->next_ue_button) ue++;
+  if (w == e->current_ue_button) reset_ue_ids();
 
   if (pthread_mutex_lock(&ed->lock)) abort();
   if (ue != ed->ue) {
@@ -248,10 +295,12 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
   widget_add_child(g, col, logo, -1);
   w = new_container(g, HORIZONTAL);
   widget_add_child(g, col, w, -1);
+  /* TODO: use button widget, not label widget */
   w2 = new_label(g, "");
   widget_add_child(g, w, w2, -1);
+  label_set_clickable(g, w2, 1);
+  e->current_ue_button = w2;
   e->current_ue_label = w2;
-  /* TODO: use button widget, not label widget */
   w2 = new_label(g, "  [prev UE]  ");
   widget_add_child(g, w, w2, -1);
   label_set_clickable(g, w2, 1);
@@ -590,6 +639,7 @@ static void enb_main_gui(enb_gui *e, gui *g, event_handler *h, void *database,
   e->legacy = new_view_textlist(10000, 10, g, text);
 
   set_current_ue(g, ed, 0);
+  register_notifier(g, "click", e->current_ue_button, click, ed);
   register_notifier(g, "click", e->prev_ue_button, click, ed);
   register_notifier(g, "click", e->next_ue_button, click, ed);
 }
@@ -628,6 +678,8 @@ int main(int n, char **v)
   enb_gui eg;
   enb_data enb_data;
 
+  reset_ue_ids();
+
   /* write on a socket fails if the other end is closed and we get SIGPIPE */
   if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort();
 
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/common/utils/T/tracer/filter/filter.c b/common/utils/T/tracer/filter/filter.c
index d26dc2500058a091e9ce1ba49a0739f437db5b86..ddc9e3af3ea6a651ff159c6f206184145fc76ee4 100644
--- a/common/utils/T/tracer/filter/filter.c
+++ b/common/utils/T/tracer/filter/filter.c
@@ -10,6 +10,8 @@ struct filter {
     struct { struct filter *a, *b; } op2;
     int v;
     struct { int event_type; int arg_index; } evarg;
+    struct { int (*fun)(void *priv, int v); void *priv;
+             struct filter *x; } evfun;
   } v;
 
   int (*eval)(struct filter *this, event e);
@@ -52,6 +54,11 @@ int eval_evarg(struct filter *f, event e)
   return e.e[f->v.evarg.arg_index].i;
 }
 
+int eval_evfun(struct filter *f, event e)
+{
+  return f->v.evfun.fun(f->v.evfun.priv, f->v.evfun.x->eval(f->v.evfun.x, e));
+}
+
 /****************************************************************************/
 /*                     free memory functions                                */
 /****************************************************************************/
@@ -63,6 +70,12 @@ void free_op2(struct filter *f)
   free(f);
 }
 
+void free_evfun(struct filter *f)
+{
+  free_filter(f->v.evfun.x);
+  free(f);
+}
+
 void free_noop(struct filter *f)
 {
   free(f);
@@ -135,6 +148,19 @@ filter *filter_evarg(void *database, char *event_name, char *varname)
   return ret;
 }
 
+filter *filter_evfun(void *database, int (*fun)(void *priv, int v),
+    void *priv, filter *x)
+{
+  struct filter *ret = calloc(1, sizeof(struct filter));
+  if (ret == NULL) abort();
+  ret->eval = eval_evfun;
+  ret->free = free_evfun;
+  ret->v.evfun.fun  = fun;
+  ret->v.evfun.priv = priv;
+  ret->v.evfun.x    = x;
+  return ret;
+}
+
 void free_filter(filter *_f)
 {
   struct filter *f;
diff --git a/common/utils/T/tracer/filter/filter.h b/common/utils/T/tracer/filter/filter.h
index d45e0bdd86e8537a23dead4960c54c12e0d0b543..0e48fb6ca3f30680161224304ca2cc258bfaad40 100644
--- a/common/utils/T/tracer/filter/filter.h
+++ b/common/utils/T/tracer/filter/filter.h
@@ -9,6 +9,8 @@ filter *filter_and(filter *a, filter *b);
 filter *filter_eq(filter *a, filter *b);
 filter *filter_int(int v);
 filter *filter_evarg(void *database, char *event_name, char *varname);
+filter *filter_evfun(void *database, int (*fun)(void *priv, int v),
+    void *priv, filter *x);
 
 int filter_eval(filter *f, event e);
 
diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c
new file mode 100644
index 0000000000000000000000000000000000000000..27e7ba8b0992e83327017190f08a4ac62a51d00d
--- /dev/null
+++ b/common/utils/load_module_shlib.c
@@ -0,0 +1,52 @@
+
+/* FT NOKBLF:
+ *  this source is to be linked with the program using the telnet server, it looks for
+ *  the telnet server dynamic library, possibly loads it and calls the telnet server
+ *  init functions
+*/
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#include "openair1/PHY/defs.h"
+#define LOAD_MODULE_SHLIB_MAIN
+#include "load_module_shlib.h"
+int load_module_shlib(char *modname)
+{
+   void *lib_handle;
+   initfunc_t fpi;
+   char *tmpstr;
+   int ret=0;
+ 
+   tmpstr = malloc(strlen(modname)+16);
+   if (tmpstr == NULL) {
+      fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno));
+      return -1; 
+   }
+   sprintf(tmpstr,"lib%s.so",modname);
+   lib_handle = dlopen(tmpstr, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
+   if (!lib_handle) {
+      printf("[LOADER] library %s is not loaded: %s\n", tmpstr,dlerror());
+      ret = -1;
+   } else {
+      sprintf(tmpstr,"init_%s",modname);
+      fpi = dlsym(lib_handle,tmpstr);
+
+      if (fpi != NULL )
+         {
+	 fpi();
+	 }
+      else
+         {
+         fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),tmpstr);
+         ret =  -1;
+         }
+    } 
+	  	 
+   if (tmpstr != NULL) free(tmpstr);
+   if (lib_handle != NULL) dlclose(lib_handle); 
+   return ret;	       
+}
diff --git a/common/utils/load_module_shlib.h b/common/utils/load_module_shlib.h
new file mode 100644
index 0000000000000000000000000000000000000000..2db1d17ec0c48e44b04c4f4608ed7f3209f0262a
--- /dev/null
+++ b/common/utils/load_module_shlib.h
@@ -0,0 +1,11 @@
+#ifndef LOAD_SHLIB_H
+#define LOAD_SHLIB_H
+
+
+typedef int(*initfunc_t)(void);
+#ifdef LOAD_MODULE_SHLIB_MAIN
+#else
+extern int load_module_shlib(char *modname);
+#endif
+
+#endif
diff --git a/common/utils/telnetsrv/CMakeLists.txt b/common/utils/telnetsrv/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..51284ad2e835377e9eb6f8d682578594bd2bec16
--- /dev/null
+++ b/common/utils/telnetsrv/CMakeLists.txt
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
+IF(DEFINED ENV{OPENAIR_DIR})
+  message("...using oai source files in $ENV{OPENAIR_DIR}")
+ELSE()
+  message("OPENAIR_DIR is not defined.  You must run \"source oaienv\" from the oai root dir")
+  # exit early 
+  return()
+ENDIF()
+
+
+
+set(OPENAIR_DIR $ENV{OPENAIR_DIR})
+set(APPROOT ${OPENAIR_DIR}/common/utils/telnetsrv )
+set(OPENAIR_BUILD_DIR $ENV{OPENAIR_DIR}/cmake_targets)
+set(OPENAIR1_DIR $ENV{OPENAIR1_DIR})
+set(OPENAIR2_DIR $ENV{OPENAIR2_DIR})
+set(OPENAIR3_DIR $ENV{OPENAIR3_DIR})
+set(OPENAIR_PHY_DIR $ENV{OPENAIR1_DIR}/PHY)
+set(OPENAIR_TARGET_DIR $ENV{OPENAIR_DIR}/targets)
+set(OPENAIR_COMMONUTILS_DIR $ENV{OPENAIR_DIR}/common/utils)
+set(OPENAIR2_COMMON_DIR $ENV{OPENAIR_DIR}/openair2/COMMON)
+set(OPENAIR_ASN1INC  ${OPENAIR_BUILD_DIR}/lte_build_oai/build/CMakeFiles/Rel14)
+set(OPENAIR_NFAPIINC $ENV{NFAPI_DIR} )
+
+set(CMAKE_INSTALL_PREFIX $ENV{OPENAIR_TARGETS})
+
+add_definitions (-DRel14  -DCMAKER -DENABLE_FXP -DENABLE_ITTI -DENABLE_NAS_UE_LOGGING -DENABLE_SECURITY  -DENABLE_USE_CPU_EXECUTION_TIME  -DENABLE_USE_MME -DENABLE_VCD -DENB_AGENT -DENB_MODE -DETHERNET=1  -DEXMIMO_IOT -DJUMBO_FRAME  -DLINK_ENB_PDCP_TO_GTPV1U -DLOG_NO_THREAD -DMAC_CONTEXT -DMAX_NUM_CCs=1  -DNAS_BUILT_IN_UE -DNAS_UE  -DNB_ANTENNAS_RX=2 -DNB_ANTENNAS_TX=2 -DNB_ANTENNAS_TXRX=2 -DNEW_FFT -DNO_RRM -DNone=1 -DOAI_NW_DRIVER_USE_NETLINK  -DOPENAIR1 -DOPENAIR2  -DOPENAIR_LTE -DPC_DSP -DPC_TARGET -DPHYSIM  -DPHY_CONTEXT -DPUCCH -DRel10=1  -DS1AP_VERSION=R10   -DTRACE_RLC_MUTEX -DUSER_MODE -DX2AP_VERSION=R11 -DXFORMS -mavx2 -msse4.1 -mssse3)
+add_compile_options( -fPIC -march=native -Ofast)
+
+include_directories( ./ ${OPENAIR_COMMON_DIR} ${OPENAIR_DIR} ${OPENAIR1_DIR} ${OPENAIR2_DIR} ${OPENAIR2_COMMON_DIR} ${OPENAIR2_DIR}/UTIL/LOG 
+                    ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC}
+		    ${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0  ${OPENAIR_COMMONUTILS_DIR}/msc ${OPENAIR_COMMONUTILS_DIR}/itti ${OPENAIR_COMMONUTILS_DIR}/hashtable ${OPENAIR_COMMONUTILS_DIR} ${OPENAIR_ASN1INC}
+		    ${OPENAIR2_DIR}/LAYER2/RLC  ${OPENAIR2_DIR}/UTIL/LISTS   ${OPENAIR2_DIR}/UTIL/MEM  ${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0 
+		    ${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0 ${OPENAIR2_DIR}/RRC/LITE ${OPENAIR_TARGET_DIR}/COMMON  ${OPENAIR_TARGET_DIR}/ARCH/COMMON
+		    ${OPENAIR3_DIR}/NAS/COMMON/API/NETWORK ${OPENAIR3_DIR}/NAS/COMMON/EMM/MSG/ ${OPENAIR3_DIR}/NAS/COMMON/IES/ ${OPENAIR3_DIR}/NAS/COMMON/UTIL 
+		    ${OPENAIR3_DIR}/NAS/COMMON/ESM/MSG/  ${OPENAIR3_DIR}/GTPV1-U  ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/shared ${OPENAIR3_DIR}/GTPV1-U/nw-gtpv1u/include
+		    ${OPENAIR3_DIR}/UTILS ${OPENAIR_NFAPIINC})
+
+set(TELNETSRV_SOURCE
+    ${APPROOT}/telnetsrv.c
+    ${APPROOT}/telnetsrv_phycmd.c
+    ${APPROOT}/telnetsrv_proccmd.c
+    )
+
+#set(TELNETSRV_ETHDEVCMD_SOURCE
+#    ${APPROOT}/telnetsrv/telnetsrv_ethdevcmd.c
+#    )
+
+
+
+add_library(telnetsrv MODULE ${TELNETSRV_SOURCE} )
+#add_library(telnetsrv_ethdevcmd MODULE ${TELNETSRV_ETHDEVCMD_SOURCE} )
+
+
+install(TARGETS telnetsrv DESTINATION bin)
+
+if (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
+     install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/lte_build_oai/build)
+endif (EXISTS "${OPENAIR_BUILD_DIR}/lte_build_oai/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/lte_build_oai/build")
diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c
new file mode 100644
index 0000000000000000000000000000000000000000..6d6b84f5684f209f20b2b4cf2504f16dc7e140b1
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv.c
@@ -0,0 +1,696 @@
+/*
+ * 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
+ */
+
+/*! \file common/utils/telnetsrv.c
+ * \brief: implementation of a telnet server
+ * \author Francois TABURET
+ * \date 2017
+ * \version 0.1
+ * \company NOKIA BellLabs France
+ * \email: francois.taburet@nokia-bell-labs.com
+ * \note
+ * \warning
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <pthread.h>
+#include <telnetsrv.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "common/config/config_userapi.h"
+
+
+#include "telnetsrv_phycmd.h"
+#include "telnetsrv_proccmd.h"	
+static char* telnet_defstatmod[] = {"softmodem","phy"}; 
+static telnetsrv_params_t telnetparams;
+#define TELNETSRV_LISTENADDR 0
+#define TELNETSRV_LISTENPORT 1
+#define TELNETSRV_PRIORITY   2
+#define TELNETSRV_DEBUG      3
+#define TELNETSRV_STATICMOD  7
+#define TELNETSRV_SHRMOD     8
+paramdef_t telnetoptions[] = {
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            configuration parameters for telnet utility                                                                             */
+/*   optname                     helpstr                paramflags           XXXptr                               defXXXval               type                 numelt */
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+	{"listenaddr",    "<listen ip address>",         0,                 uptr:&telnetparams.listenaddr,        defstrval:"0.0.0.0",            TYPE_IPV4ADDR,  0 },
+	{"listenport",    "<local port>",                0,                 uptr:&(telnetparams.listenport),      defuintval:9090,                TYPE_UINT,      0 },
+        {"priority",      "<scheduling policy (0-99)",   0,                 uptr:&telnetparams.priority,          defuintval:0,                   TYPE_INT,       0 }, 
+	{"debug",         "<debug level>",               0,                 uptr:NULL,                            defuintval:0,                   TYPE_UINT,      0 },
+	{"loopcount",     "<loop command iterations>",   0,                 uptr:&(telnetparams.loopcount),       defuintval:10,                  TYPE_UINT,      0 },
+	{"loopdelay",     "<loop command delay (ms)>",   0,                 uptr:&(telnetparams.loopdelay),       defuintval:5000,                TYPE_UINT,      0 },
+	{"phypbsize",     "<phy dump buff size (bytes)>",0,                 uptr:&(telnetparams.phyprntbuff_size),defuintval:65000,               TYPE_UINT,      0 },
+        {"staticmod",     "<static modules selection>",  0,                 NULL,                                 defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,1},
+        {"shrmod",        "<static modules selection>",  0,                 NULL,                                 NULL,TYPE_STRINGLIST,0 },
+};
+
+int get_phybsize() {return telnetparams.phyprntbuff_size; };
+int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd );
+int setoutput(char *buff, int debug, telnet_printfunc_t prnt);
+int setparam(char *buff, int debug, telnet_printfunc_t prnt);
+
+telnetshell_vardef_t telnet_vardef[] = {
+{"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg},
+{"prio",TELNET_VARTYPE_INT32,&telnetparams.priority},
+{"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount},
+{"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay},
+{"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size},
+{"",0,NULL}
+};
+
+telnetshell_cmddef_t  telnet_cmdarray[] = {
+   {"redirlog","[here,file,off]",setoutput},
+   {"param","[prio]",setparam},
+   {"","",NULL},
+};
+
+
+void client_printf(const char *message, ...)
+{
+    va_list va_args;
+    
+    va_start(va_args, message);
+    if (telnetparams.new_socket > 0)
+       {
+       vsnprintf(telnetparams.msgbuff,sizeof(telnetparams.msgbuff)-1,message, va_args);
+       send(telnetparams.new_socket,telnetparams.msgbuff , strlen(telnetparams.msgbuff), MSG_NOSIGNAL);
+       }
+    else
+       {
+       vprintf(message, va_args);
+       }
+    va_end(va_args);
+    return ;
+}
+
+#define NICE_MAX 19
+#define NICE_MIN -20
+void set_sched(pthread_t tid, int pid, int priority)
+{
+int rt; 
+struct sched_param schedp;
+int policy;
+char strpolicy[10];
+
+
+//sched_get_priority_max(SCHED_FIFO)
+if (priority < NICE_MIN)
+   {
+   policy=SCHED_FIFO;
+   sprintf(strpolicy,"%s","fifo");
+   schedp.sched_priority= NICE_MIN - priority ;   
+   }
+else if (priority > NICE_MAX)
+   {
+   policy=SCHED_IDLE;
+   sprintf(strpolicy,"%s","idle");
+   schedp.sched_priority=0;   
+   } 
+else 
+   {
+   policy=SCHED_OTHER;
+   sprintf(strpolicy,"%s","other");
+   schedp.sched_priority=0;   
+   } 
+if( tid != 0)
+  {  
+  rt = pthread_setschedparam(tid, policy, &schedp);
+  }
+else if(pid > 0)
+  {
+  rt = sched_setscheduler( pid, policy,&schedp);
+  }
+if (rt != 0)
+    {
+    client_printf("Error %i: %s modifying sched param to %s:%i, \n",
+                  errno,strerror(errno),strpolicy,schedp.sched_priority); 
+    }
+else
+    {
+    client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority);
+    }
+
+
+
+if ( policy == SCHED_OTHER)
+   {
+   if ( tid > 0 && tid != pthread_self())
+     {
+     client_printf("setting nice value using a thread id not implemented....\n");    
+     }
+   else if (pid > 0)
+     {
+     errno=0;
+     rt = setpriority(PRIO_PROCESS,pid,priority);
+     if (rt != 0)
+        {
+        client_printf("Error %i: %s calling setpriority, \n",errno,strerror(errno)); 
+        }
+     else
+        {
+        client_printf("nice value set to %i\n",priority);
+        }
+     }
+   }
+}
+
+void set_affinity(pthread_t tid, int pid, int coreid)
+{
+cpu_set_t cpuset;
+int rt;
+
+  CPU_ZERO(&cpuset);
+  CPU_SET(coreid, &cpuset);
+  if (tid > 0)
+     {
+     rt = pthread_setaffinity_np((pthread_t)tid, sizeof(cpu_set_t), &cpuset);
+     }
+  else if (pid > 0)
+     {
+     rt = sched_setaffinity((pid_t)pid, sizeof(cpu_set_t), &cpuset);
+     }
+  if (rt != 0)
+      {
+      client_printf("Error %i: %s calling , xxx_setaffinity...\n",errno,strerror(errno)); 
+      }
+  else
+      {
+      client_printf("thread %i affinity set to %i\n",(pid==0)?(int)tid:pid,coreid);
+      }  
+}
+/*------------------------------------------------------------------------------------*/
+/*
+function implementing telnet server specific commands, parameters of the
+telnet_cmdarray table
+*/
+
+void redirstd(char *newfname,telnet_printfunc_t prnt )
+{
+FILE *fd;
+   fd=freopen(newfname, "w", stdout);
+   if (fd == NULL)
+      {
+      prnt("ERROR: stdout redir to %s error %s",strerror(errno));
+      }
+   fd=freopen(newfname, "w", stderr);
+   if (fd == NULL)
+      {
+      prnt("ERROR: stderr redir to %s error %s",strerror(errno));
+      }
+}
+int setoutput(char *buff, int debug, telnet_printfunc_t prnt)
+{
+
+char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
+char *logfname;
+char stdout_str[64];
+
+
+#define LOGFILE "logfile.log"
+memset(cmds,0,sizeof(cmds));
+sscanf(buff,"%9s %32s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4]  );
+if (strncasecmp(cmds[0],"here",4) == 0)
+   {
+   fflush(stdout);
+   sprintf(stdout_str,"/proc/%i/fd/%i",getpid(),telnetparams.new_socket);
+   dup2(telnetparams.new_socket,fileno(stdout));
+//   freopen(stdout_str, "w", stdout);
+//   freopen(stdout_str, "w", stderr);
+   dup2(telnetparams.new_socket,fileno(stderr));
+   prnt("Log output redirected to this terminal (%s)\n",stdout_str);
+   }
+if (strncasecmp(cmds[0],"file",4) == 0)
+   {
+   if (cmds[1][0] == 0)
+      logfname=LOGFILE;
+   else
+      logfname=cmds[1];   
+   fflush(stdout);
+   redirstd(logfname,prnt);
+
+   }   
+if (strncasecmp(cmds[0],"off",3) == 0)
+   {
+   fflush(stdout);
+   redirstd("/dev/tty",prnt); 
+   } 
+
+return CMDSTATUS_FOUND;   
+} /* setoutput */
+
+int setparam(char *buff, int debug, telnet_printfunc_t prnt)
+{
+char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
+
+
+memset(cmds,0,sizeof(cmds));
+sscanf(buff,"%9s %9s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4]  );
+if (strncasecmp(cmds[0],"prio",4) == 0)
+   {
+   pthread_attr_t attr;
+   int prio;
+   prio=(int)strtol(cmds[1],NULL,0);
+   if (errno == ERANGE)
+       return CMDSTATUS_VARNOTFOUND;
+   telnetparams.priority = prio;
+   set_sched(pthread_self(),0,prio);
+   return CMDSTATUS_FOUND; 
+   }
+if (strncasecmp(cmds[0],"aff",3) == 0)
+   {
+   int aff;
+   aff=(int)strtol(cmds[1],NULL,0);
+   if (errno == ERANGE)
+       return CMDSTATUS_VARNOTFOUND;
+   set_affinity(pthread_self(),0,aff);
+   return CMDSTATUS_FOUND; 
+   }
+
+return CMDSTATUS_NOTFOUND;   
+} /* setparam */
+/*-------------------------------------------------------------------------------------------------------*/
+/*
+generic commands available for all modules loaded by the server
+*/
+
+int setgetvar(int moduleindex,char getorset,char *params)
+{
+int n,i;
+char varname[TELNET_CMD_MAXSIZE];
+char varval[TELNET_CMD_MAXSIZE];
+
+   memset(varname,0,sizeof(varname));
+   memset(varval,0,sizeof(varval));
+   n = sscanf(params,"%s %s",varname,varval);
+   for ( i=0 ; telnetparams.CmdParsers[moduleindex].var[i].varvalptr != NULL ; i++)
+      {
+      if ( strncasecmp(telnetparams.CmdParsers[moduleindex].var[i].varname,varname,strlen(telnetparams.CmdParsers[moduleindex].var[i].varname)) == 0)
+         {
+	 if (n > 0 && (getorset == 'g' || getorset == 'G'))
+	    {
+	    client_printf("%s, %s = ", telnetparams.CmdParsers[moduleindex].module,
+	               telnetparams.CmdParsers[moduleindex].var[i].varname );
+	    switch(telnetparams.CmdParsers[moduleindex].var[i].vartype)
+	        {
+		case TELNET_VARTYPE_INT32:
+	             client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+		break;
+		case TELNET_VARTYPE_INT16:
+	             client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+		break;	
+		case TELNET_VARTYPE_DOUBLE:
+	             client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+		break;
+		case TELNET_VARTYPE_PTR:
+	             client_printf("0x%08x\n",*((unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)));						
+                break;
+		default:
+		     client_printf("unknown type\n");
+		break;
+		}
+	    }
+	 if (n > 1 && (getorset == 's' || getorset == 'S'))
+	    {
+	    client_printf("%s, %s set to \n", telnetparams.CmdParsers[moduleindex].module,
+	           telnetparams.CmdParsers[moduleindex].var[i].varname);
+		   
+	    switch(telnetparams.CmdParsers[moduleindex].var[i].vartype)
+	        {
+		case TELNET_VARTYPE_INT32:
+		     *(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (int)strtol(varval,NULL,0);
+	             client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+		break;
+		case TELNET_VARTYPE_INT16:
+		     *(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0);
+	             client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+		break;	
+		case TELNET_VARTYPE_DOUBLE:
+		     *(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL);
+	             client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
+		break;				
+		default:
+		     client_printf("unknown type\n");
+		break;
+		}		   
+	    }		   
+	 }
+      } 
+return CMDSTATUS_VARNOTFOUND;
+}
+/*----------------------------------------------------------------------------------------------------*/
+char *get_time(char *buff,int bufflen)
+{
+
+struct tm  tmstruct;
+time_t now = time (0);
+strftime (buff, bufflen, "%Y-%m-%d %H:%M:%S.000", localtime_r(&now,&tmstruct));
+return buff;
+}
+
+int process_command(char *buf)
+{
+int i,j,k;
+char modulename[TELNET_CMD_MAXSIZE];
+char cmd[TELNET_CMD_MAXSIZE];
+char cmdb[TELNET_MAX_MSGLENGTH];
+char *bufbck;
+int rt;
+
+memset(modulename,0,sizeof(modulename));
+memset(cmd,0,sizeof(cmd));
+memset(cmdb,0,sizeof(cmdb));
+if (strncasecmp(buf,"ex",2) == 0)
+   return CMDSTATUS_EXIT;
+
+if (strncasecmp(buf,"help",4) == 0)
+   {
+   for (i=0; telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++)
+    {
+     client_printf("   module %i = %s:\n",i,telnetparams.CmdParsers[i].module);
+     for(j=0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL ; j++)
+        {
+	client_printf("      %s [get set] %s <value>\n",
+	       telnetparams.CmdParsers[i].module, telnetparams.CmdParsers[i].var[j].varname);
+	} 
+     for(j=0; telnetparams.CmdParsers[i].cmd[j].cmdfunc != NULL ; j++)
+        {
+	client_printf("      %s %s %s\n",
+	       telnetparams.CmdParsers[i].module,telnetparams.CmdParsers[i].cmd[j].cmdname,
+	       telnetparams.CmdParsers[i].cmd[j].helpstr);
+	} 	
+    }
+   return CMDSTATUS_FOUND;
+   }
+
+memset(modulename,0,sizeof(modulename));
+memset(cmd,0,sizeof(cmd));
+memset(cmdb,0,sizeof(cmdb));  
+bufbck=strdup(buf); 
+rt=CMDSTATUS_NOTFOUND;   
+j = sscanf(buf,"%9s %9s %[^\t\n]",modulename,cmd,cmdb);
+if (telnetparams.telnetdbg > 0)
+    printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);   
+for (i=0; j>=2 && telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++)
+    {
+    if ( (strncasecmp(telnetparams.CmdParsers[i].module,modulename,strlen(telnetparams.CmdParsers[i].module)) == 0))
+       {
+        if (strncasecmp(cmd,"getall",7) == 0 )
+	    { 
+            for(j=0; telnetparams.CmdParsers[i].var[j].varvalptr != NULL ; j++)
+               {
+	       setgetvar(i,'g',telnetparams.CmdParsers[i].var[j].varname);
+	       }
+	    rt= CMDSTATUS_FOUND;              
+	    }       
+        else if (strncasecmp(cmd,"get",3) == 0 || strncasecmp(cmd,"set",3) == 0)
+	    {
+            rt= setgetvar(i,cmd[0],cmdb);	    
+	    }	    
+        else
+	    {
+	    for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++)
+	        {
+	        if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0)
+                   {
+	           telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
+                   rt= CMDSTATUS_FOUND;
+	           }
+		} /* for k */
+	    }/* else */
+	}/* strncmp: module name test */
+     else if (strncasecmp(modulename,"loop",4) == 0 )
+	{
+	int lc;
+        int f = fcntl(telnetparams.new_socket,F_GETFL);
+	fcntl (telnetparams.new_socket, F_SETFL, O_NONBLOCK | f);
+	for(lc=0; lc<telnetparams.loopcount; lc++)
+	   {
+	   char dummybuff[20];
+	   char tbuff[64];
+       int rs;
+	   client_printf(CSI "1J" CSI "1;10H         " STDFMT "%s %i/%i\n",
+	                 get_time(tbuff,sizeof(tbuff)),lc,telnetparams.loopcount );  
+       process_command(bufbck+strlen("loop")+1);
+       usleep(telnetparams.loopdelay * 1000);
+	   rs = read(telnetparams.new_socket,dummybuff,sizeof(dummybuff)); 
+	   if ( rs > 0 )
+	       {
+	       break;
+	       }
+	   }
+	fcntl (telnetparams.new_socket, F_SETFL, f);
+	rt= CMDSTATUS_FOUND;	    
+	} /* loop */
+    } /* for i */
+free(bufbck);
+return rt;
+}
+
+void run_telnetsrv(void) 
+{
+int sock;
+struct sockaddr_in name;
+char buf[TELNET_MAX_MSGLENGTH];
+struct sockaddr cli_addr;
+unsigned int cli_len = sizeof(cli_addr);
+int readc , filled;
+
+int status;
+int optval = 1;
+
+pthread_setname_np(pthread_self(), "telnet");
+set_sched(pthread_self(),0,telnetparams.priority);
+sock = socket(AF_INET, SOCK_STREAM, 0);
+if (sock < 0) 
+    fprintf(stderr,"[TELNETSRV] Error %s on socket call\n",strerror(errno));
+
+setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
+name.sin_family = AF_INET;
+if (telnetparams.listenaddr == 0)
+    name.sin_addr.s_addr = INADDR_ANY;
+else
+    name.sin_addr.s_addr = telnetparams.listenaddr;
+name.sin_port = htons((unsigned short)(telnetparams.listenport));
+
+if(bind(sock, (void*) &name, sizeof(name))) 
+     fprintf(stderr,"[TELNETSRV] Error %s on bind call\n",strerror(errno));
+if(listen(sock, 1) == -1)
+     fprintf(stderr,"[TELNETSRV] Error %s on listen call\n",strerror(errno));
+
+
+
+printf("\nInitializing telnet server...\n");
+while( (telnetparams.new_socket = accept(sock, &cli_addr, &cli_len)) )
+     {
+     printf("[TELNETSRV] Telnet client connected....\n");
+
+
+    if(telnetparams.new_socket < 0)
+       fprintf(stderr,"[TELNETSRV] Error %s on accept call\n",strerror(errno));
+
+    while(telnetparams.new_socket>0)
+         {
+	 filled = 0;
+	 memset(buf,0,sizeof(buf));
+         while(filled < ( TELNET_MAX_MSGLENGTH-1))
+	     {
+             readc = recv(telnetparams.new_socket, buf+filled, TELNET_MAX_MSGLENGTH-filled-1, 0);
+             if(!readc)
+	        break;
+             filled += readc;
+             if(buf[filled-1] == '\n')
+	        {
+		buf[filled-1] = 0;
+		
+	        break;
+		}
+             }
+         if(!readc)
+	   {
+           printf ("[TELNETSRV] Telnet Client disconnected.\n");
+           break;
+           }
+         if (telnetparams.telnetdbg > 0)
+	    printf("[TELNETSRV] Command received: readc %i filled %i %s\n", readc, filled ,buf);
+	 if (strlen(buf) >= 2 )
+	    {
+            status=process_command(buf);
+	    }
+	 else
+	    status=CMDSTATUS_NOCMD;
+	    
+         if (status != CMDSTATUS_EXIT)
+	    {
+	    if (status == CMDSTATUS_NOTFOUND)
+	       {
+	       char msg[TELNET_MAX_MSGLENGTH + 50];
+	       sprintf(msg,"Error: \n      %s\n is not a softmodem command\n",buf);
+	       send(telnetparams.new_socket, msg, strlen(msg), MSG_NOSIGNAL);
+	       }
+            send(telnetparams.new_socket, TELNET_PROMPT, sizeof(TELNET_PROMPT), MSG_NOSIGNAL);
+	    }
+	 else
+	    {
+	    printf ("[TELNETSRV] Closing telnet connection...\n");
+	    break;
+	    }
+    }
+
+    close(telnetparams.new_socket);
+    printf ("[TELNETSRV] Telnet server waitting for connection...\n");
+    }
+close(sock);
+return;
+}
+
+/*------------------------------------------------------------------------------------------------*/
+/* set_telnetmodule loads the commands delivered with the telnet server
+ *
+ *
+ * 
+*/
+void exec_moduleinit(char *modname)
+{
+void (*fptr)();
+char initfunc[TELNET_CMD_MAXSIZE+9];
+
+       if (strlen(modname) > TELNET_CMD_MAXSIZE)
+	  {
+          fprintf(stderr,"[TELNETSRV] module %s not loaded, name exceeds the %i size limit\n",
+			 modname, TELNET_CMD_MAXSIZE);
+	  return; 
+          }
+       sprintf(initfunc,"add_%s_cmds",modname);
+       fptr = dlsym(RTLD_DEFAULT,initfunc);
+       if ( fptr != NULL)
+          {
+          fptr();
+          }
+       else
+          {
+          fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,modname);
+          }
+}
+
+int add_embeddedmodules()
+{
+
+
+
+
+    for(int i=0; i<telnetoptions[TELNETSRV_STATICMOD].numelt;i++)
+       {
+       exec_moduleinit(telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]);
+       }
+}
+
+int add_sharedmodules()
+{
+char initfunc[TELNET_CMD_MAXSIZE+9];
+void (*fptr)();
+
+
+    for(int i=0; i<telnetoptions[TELNETSRV_SHRMOD].numelt;i++)
+       {
+       sprintf(initfunc,"add_%s_cmds",telnetoptions[TELNETSRV_SHRMOD].strlistptr[i]);
+       fptr = dlsym(RTLD_DEFAULT,initfunc);
+       if ( fptr != NULL)
+          {
+          fptr();
+          }
+       else
+          {
+          fprintf(stderr,"[TELNETSRV] couldn't find %s for module %s \n",initfunc,telnetoptions[TELNETSRV_STATICMOD].strlistptr[i]);
+          }
+       }
+}
+
+int init_telnetsrv(char *cfgfile)
+ {
+  void *lib_handle;
+  char** moduleslist; 
+
+   memset(&telnetparams,0,sizeof(telnetparams));
+
+   config_get( telnetoptions,sizeof(telnetoptions)/sizeof(paramdef_t),NULL); 
+
+ 
+   if(pthread_create(&telnetparams.telnet_pthread,NULL, (void *(*)(void *))run_telnetsrv, NULL) != 0)
+     {
+     fprintf(stderr,"[TELNETSRV] Error %s on pthread_create call\n",strerror(errno));
+     return -1;
+     }
+  add_telnetcmd("telnet", telnet_vardef, telnet_cmdarray);
+  add_embeddedmodules();
+  return 0;
+ }
+ 
+/*---------------------------------------------------------------------------------------------*/
+/* add_telnetcmd is used to add a set of commands to the telnet server. A module calls this
+ * function at init time. the telnet server is delivered with a set of commands which
+ * will be loaded or not depending on the telnet section of the config file
+*/
+int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd)
+ {
+ int i;
+ if( modulename == NULL || var == NULL || cmd == NULL)
+     {
+     fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n");
+     return -1;
+     }
+ for (i=0; i<TELNET_MAXCMD ; i++)
+     {
+     if (telnetparams.CmdParsers[i].var == NULL)
+        {
+        strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
+        telnetparams.CmdParsers[i].cmd = cmd;
+        telnetparams.CmdParsers[i].var = var;
+        printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
+               i,telnetparams.CmdParsers[i].module);
+        break;
+        }
+     }
+  return 0;
+ }
+
+
+
+
+
diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h
new file mode 100644
index 0000000000000000000000000000000000000000..f54557e751d90611c25bca4d00fc56bf62a3d1e1
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv.h
@@ -0,0 +1,108 @@
+#ifndef TELNETSRV_H
+#define TELNETSRV_H
+
+#define TELNETSRV_MODNAME  "telnetsrv"
+
+#define TELNET_PORT               9090
+#define TELNET_MAX_MSGLENGTH      2048
+#define TELNET_PROMPT             "softmodem> "
+#define TELNET_MAXCMD             20
+#define TELNET_CMD_MAXSIZE        10
+#define TELNET_HELPSTR_SIZE       80
+
+/* status return by the command parser after it analysed user input */
+#define CMDSTATUS_NOCMD       0
+#define CMDSTATUS_EXIT        1
+#define CMDSTATUS_FOUND       2
+#define CMDSTATUS_VARNOTFOUND 3
+#define CMDSTATUS_NOTFOUND    4
+
+/*----------------------------------------------------------------------------*/
+/* structure to be used when adding a module to the telnet server */
+/* This is the second parameter of the add_telnetcmd function, which can be used   */
+/* to add a set of new command to the telnet server shell */
+typedef void(*telnet_printfunc_t)(const char* format, ...);
+typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt);
+
+typedef struct cmddef {
+    char cmdname[TELNET_CMD_MAXSIZE];
+    char helpstr[TELNET_HELPSTR_SIZE];
+    cmdfunc_t cmdfunc; 
+} telnetshell_cmddef_t;
+
+/*----------------------------------------------------------------------------*/
+/*structure to be used when adding a module to the telnet server */
+/* This is the first parameter of the add_telnetcmd function, which can be used   */
+/* to add a set of new variables which can be got/set from the telnet server shell */
+#define TELNET_VARTYPE_INT32  1
+#define TELNET_VARTYPE_INT16  2
+#define TELNET_VARTYPE_INT64  3
+#define TELNET_VARTYPE_STRING 4
+#define TELNET_VARTYPE_DOUBLE 5
+#define TELNET_VARTYPE_PTR    6
+typedef struct variabledef {
+    char varname[TELNET_CMD_MAXSIZE];
+    char vartype;
+    void *varvalptr;
+} telnetshell_vardef_t;
+
+
+
+/*----------------------------------------------------------------------------*/
+/* internal structure definitions                                             */
+/* cmdparser_t is used to store all modules which have been added to the telnet server.  */
+/* Each time the add_telnetcmd function is used, the internal array cmdparser_t[] of the */
+/* telnet server is populated with the new commands and variables                   */
+typedef struct cmdparser {
+    char module[TELNET_CMD_MAXSIZE];   // module name = first token of the telnet shell command
+    telnetshell_cmddef_t   *cmd;       // array of functions added to the shell
+    telnetshell_vardef_t   *var;       // array of variables added to the shell
+} cmdparser_t;
+
+/* telnetsrv_params_t is an internal structure storing all the current parameters and */
+/* global variables used by the telnet server                                        */
+typedef struct {
+     pthread_t telnet_pthread;       // thread id of the telnet server
+     int telnetdbg;                  // debug level of the server
+     int priority;                   // server running priority
+     int new_socket;                 // socket of the client connection
+     int logfilefd;                  // file id of the log file when log output is redirected to a file
+     int  saved_stdout;              // file id of the previous stdout, used to be able to restore original stdout 
+     cmdparser_t CmdParsers[TELNET_MAXCMD];   // array of registered modules.
+     char msgbuff[TELNET_MAX_MSGLENGTH];      // internal buffer of the client_printf function which is used to print to the client terminal */
+     unsigned int   listenport;           // ip port the telnet server is listening on
+     unsigned int   listenaddr;           // ip address the telnet server is listening on
+     unsigned int   loopcount;            // loop command param: number of loop iteration
+     unsigned int   loopdelay;            // loop command param: delay in ms between 2 iterations
+     unsigned int   phyprntbuff_size;     // for phy module,  dump_eNB_stats function buffer size
+} telnetsrv_params_t;
+
+
+
+typedef int(*addcmdfunc_t)(char*, telnetshell_vardef_t*, telnetshell_cmddef_t*);
+
+typedef void(*settelnetmodule_t)(char *name, void *ptr); 
+
+/*-------------------------------------------------------------------------------------------*/
+/* 
+VT escape sequence definition, for smarter display....
+*/
+
+#define ESC      "\x1b"
+#define CSI      "\x1b["
+#define BOLD     "\x1b[1m"
+#define RED      "\x1b[31m"
+#define GREEN    "\x1b[32m"
+#define BLUE     "\x1b[34m"
+#define MAGENTA  "\x1b[35m"
+#define CYAN     "\x1b[36m"
+#define STDFMT   "\x1b[0m"
+
+/*---------------------------------------------------------------------------------------------*/
+#ifdef TELNETSERVERCODE
+int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
+void set_sched(pthread_t tid, int pid,int priority);
+void set_affinity(pthread_t tid, int pid, int coreid);
+extern int get_phybsize(); 
+#endif
+#endif
diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.c b/common/utils/telnetsrv/telnetsrv_phycmd.c
new file mode 100644
index 0000000000000000000000000000000000000000..1e267f689014c0f96cf826157de16ad534f2517f
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv_phycmd.c
@@ -0,0 +1,111 @@
+#define _GNU_SOURCE 
+#include <string.h>
+#include <pthread.h>
+
+
+#define TELNETSERVERCODE
+#include "telnetsrv.h"
+#define TELNETSRV_PHYCMD_MAIN
+#include "telnetsrv_phycmd.h"
+char *prnbuff;
+extern int dump_eNB_stats(PHY_VARS_eNB *eNB, char* buffer, int length);
+
+void init_phytelnet()
+{
+prnbuff=malloc(get_phybsize() );
+if (prnbuff == NULL)
+   {
+   fprintf(stderr,"Error %s on malloc in init_phytelnet()\n",strerror(errno));
+   }
+}
+
+void display_uestatshead( telnet_printfunc_t prnt)
+{
+prnt("cc  ue  rnti Dmcs Umcs tao  tau   Dbr  Dtb   \n");
+}
+
+void dump_uestats(int debug, telnet_printfunc_t prnt, uint8_t prntflag)
+{
+
+int p;
+
+        p=dump_eNB_l2_stats( prnbuff, 0);
+	if(prntflag>=1)
+	   prnt("%s\n",prnbuff);
+	if(debug>=1)
+	   prnt("%i bytes printed\n",p);	   
+
+
+}
+
+void display_uestats(int debug, telnet_printfunc_t prnt, int ue)
+{
+   for (int cc=0; cc<1 ; cc++)
+       {
+ 
+ 
+       }
+}
+
+void display_phycounters(char *buf, int debug, telnet_printfunc_t prnt)
+{    
+   prnt("  DLSCH kb      DLSCH kb/s\n");
+
+   dump_uestats(debug, prnt,0);
+
+}
+
+int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt)
+{
+   
+   
+
+   if (debug > 0)
+       prnt("phy interface module received %s\n",buf);
+   if (strcasestr(buf,"phycnt") != NULL)
+       {
+       display_phycounters(buf, debug, prnt);
+       }
+   if (strcasestr(buf,"uestat") != NULL)
+      {
+      char *cptr=strcasestr(buf+sizeof("uestat"),"UE");
+      display_uestatshead(prnt);
+      if (cptr != NULL)
+         {
+	 int ueidx = strtol( cptr+sizeof("UE"), NULL, 10);
+	 if (ueidx < NUMBER_OF_UE_MAX && ueidx >= 0)
+	    {
+	    display_uestats(debug, prnt,ueidx);
+	    }
+	 } /* if cptr != NULL */
+      else
+         {
+	 for (int ue=0; ue<NUMBER_OF_UE_MAX ; ue++)
+	     {
+	     display_uestats(debug, prnt,ue);
+	     }
+	 } /* else cptr != NULL */
+      } /* uestat */
+   if (strcasestr(buf,"uedump") != NULL)
+       {
+       dump_uestats(debug, prnt,1);
+       }      
+   return 0;
+}
+
+
+
+telnetshell_cmddef_t phy_cmdarray[] = {
+   {"disp","[phycnt,uedump,uestat UE<x>]", dump_phyvars},
+
+   {"","",NULL},
+};
+
+
+/*-------------------------------------------------------------------------------------*/
+void add_phy_cmds()
+{
+
+   init_phytelnet();
+   add_telnetcmd("phy", phy_vardef, phy_cmdarray);
+}
diff --git a/common/utils/telnetsrv/telnetsrv_phycmd.h b/common/utils/telnetsrv/telnetsrv_phycmd.h
new file mode 100644
index 0000000000000000000000000000000000000000..7289810c8a9047d062132539bea8912ed358f771
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv_phycmd.h
@@ -0,0 +1,35 @@
+
+
+#ifdef TELNETSRV_PHYCMD_MAIN
+
+#include "UTIL/LOG/log.h"
+
+
+#include "openair1/PHY/extern.h"
+
+
+#define TELNETVAR_PHYCC0    0
+#define TELNETVAR_PHYCC1    1
+
+telnetshell_vardef_t phy_vardef[] = {
+{"phycc1",TELNET_VARTYPE_PTR,NULL},
+{"phycc2",TELNET_VARTYPE_PTR,NULL},
+//{"iqmax",TELNET_VARTYPE_INT16,NULL},
+//{"iqmin",TELNET_VARTYPE_INT16,NULL},
+//{"loglvl",TELNET_VARTYPE_INT32,NULL},
+//{"sndslp",TELNET_VARTYPE_INT32,NULL},
+//{"rxrescale",TELNET_VARTYPE_INT32,NULL},
+//{"txshift",TELNET_VARTYPE_INT32,NULL},
+//{"rachemin",TELNET_VARTYPE_INT32,NULL},
+//{"rachdmax",TELNET_VARTYPE_INT32,NULL},
+{"",0,NULL}
+};
+
+#else
+
+extern void add_phy_cmds();
+
+#endif
+
+/*-------------------------------------------------------------------------------------*/
+
diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.c b/common/utils/telnetsrv/telnetsrv_proccmd.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd409ab27cdad2eb93a669c99dc4310775b68c6b
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv_proccmd.c
@@ -0,0 +1,231 @@
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <pthread.h>
+#include <string.h>
+#include <stdarg.h>
+#include <dirent.h>
+
+#define READCFG_DYNLOAD
+
+#define TELNETSERVERCODE
+#include "telnetsrv.h"
+#define TELNETSRV_PROCCMD_MAIN
+#include "log.h"
+#include "log_extern.h"
+#include "telnetsrv_proccmd.h"
+
+void decode_procstat(char *record, int debug, telnet_printfunc_t prnt)
+{
+char prntline[160];
+char *procfile_fiels;
+char *strtokptr;
+char *lptr;
+int fieldcnt;
+char toksep[2];
+
+  fieldcnt=0;	  
+  procfile_fiels =strtok_r(record," ",&strtokptr);
+  lptr= prntline;
+/*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */
+ 
+  while( 	procfile_fiels != NULL && fieldcnt < 42)
+    {
+    if (strlen(procfile_fiels) == 0)
+       continue;
+    fieldcnt++;
+    sprintf(toksep," ");
+    switch(fieldcnt)
+       {
+       case 1: /* id */
+           lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
+           sprintf(toksep,")");
+       break;  
+       case 2: /* name */
+	   lptr+=sprintf(lptr,"%20.20s ",procfile_fiels+1);
+       break;              
+       case 3:   //thread state
+           lptr+=sprintf(lptr,"  %c   ",procfile_fiels[0]);
+       break;
+       case 14:   //time in user mode
+       case 15:   //time in kernel mode
+           lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
+       break;
+       case 18:   //priority
+       case 19:   //nice	       
+           lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
+       break;
+       case 23:   //vsize	       
+           lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
+       break;
+       case 39:   //processor	       
+           lptr+=sprintf(lptr," %2.2s  ",procfile_fiels);
+       break;
+       case 41:   //policy	       
+           lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
+       break;
+       default:
+       break;	       	       	       	       	       
+       }/* switch on fieldcnr */  
+    procfile_fiels =strtok_r(NULL,toksep,&strtokptr); 
+    } /* while on proc_fields != NULL */
+  prnt("%s\n",prntline); 
+} /*decode_procstat */
+
+void read_statfile(char *fname,int debug, telnet_printfunc_t prnt)
+{
+FILE *procfile;
+char arecord[1024];
+
+    procfile=fopen(fname,"r");
+    if (procfile == NULL)
+       {
+       prnt("Error: Couldn't open %s %i %s\n",fname,errno,strerror(errno));
+       return;
+       }    
+    if ( fgets(arecord,sizeof(arecord),procfile) == NULL)
+       {
+       prnt("Error: Nothing read from %s %i %s\n",fname,errno,strerror(errno));
+       fclose(procfile);
+       return;
+       }    
+    fclose(procfile);
+    decode_procstat(arecord, debug, prnt);
+}
+
+void print_threads(char *buf, int debug, telnet_printfunc_t prnt)
+{
+char aname[256];
+
+DIR *proc_dir;
+struct dirent *entry;
+
+int rt;
+
+    prnt("  id          name            state   USRmod    KRNmod  prio nice   vsize   proc pol \n\n");
+    snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid());
+    read_statfile(aname,debug,prnt);
+    prnt("\n");
+    snprintf(aname, sizeof(aname), "/proc/%d/task", getpid());
+    proc_dir = opendir(aname);
+    if (proc_dir == NULL)
+       {
+       prnt("Error: Couldn't open %s %i %s\n",aname,errno,strerror(errno));
+       return;
+       }
+    
+    while ((entry = readdir(proc_dir)) != NULL)
+        {
+        if(entry->d_name[0] == '.')
+            continue;
+	snprintf(aname, sizeof(aname), "/proc/%d/task/%s/stat", getpid(),entry->d_name);    
+        read_statfile(aname,debug,prnt);      
+        } /* while entry != NULL */
+	closedir(proc_dir);
+} /* print_threads */
+
+
+int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
+{
+extern log_t *g_log;   
+   
+   if (debug > 0)
+       prnt(" proccmd_show received %s\n",buf);
+   if (strcasestr(buf,"thread") != NULL)
+       {
+       print_threads(buf,debug,prnt);
+       }
+   if (strcasestr(buf,"loglvl") != NULL) {
+       for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++){
+            prnt("\t%s:\t%s\t%s\n",g_log->log_component[i].name, map_int_to_str(log_verbosity_names,g_log->log_component[i].flag),
+	        map_int_to_str(log_level_names,g_log->log_component[i].level));
+       }
+   }
+   return 0;
+} 
+
+int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt)
+{
+int bv1,bv2;   
+int res;
+char sv1[64]; 
+char tname[32];  
+   bv1=0;
+   bv2=0;
+   sv1[0]=0;
+   if (debug > 0)
+       prnt("proccmd_thread received %s\n",buf);
+   res=sscanf(buf,"%i %9s %i",&bv1,sv1,&bv2);
+   if (debug > 0)
+       prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2);   
+   if(res != 3)
+     {
+     prnt("softmodem thread needs 3 params, %i received\n",res);
+     return 0;
+     }
+
+  
+   if (strcasestr(sv1,"prio") != NULL)
+       {
+       set_sched(0,bv1, bv2);
+       }
+   else if (strcasestr(sv1,"aff") != NULL)
+       {
+       set_affinity(0,bv1, bv2);
+       }
+   else
+       {
+       prnt("%s is not a valid thread command\n",sv1);
+       }
+   return 0;
+} 
+int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt)
+{
+extern void exit_fun(const char* s);   
+   
+   if (debug > 0)
+       prnt("process module received %s\n",buf);
+
+   exit_fun("telnet server received exit command\n");
+   return 0;
+}
+ 
+int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt)
+{
+int idx1=0;
+int idx2=NUM_LOG_LEVEL-1;
+int s = sscanf(buf,"%*s %i-%i",&idx1,&idx2);   
+   
+   if (debug > 0)
+       prnt("process module received %s\n",buf);
+
+   if (strcasestr(buf,"enable") != NULL)
+       {
+       set_glog_onlinelog(1);
+       }
+   if (strcasestr(buf,"disable") != NULL)
+       {
+       set_glog_onlinelog(0);
+       }
+    if (strcasestr(buf,"show") != NULL)
+       {
+       proccmd_show("loglvl",debug,prnt);
+       }      
+   return 0;
+} 
+/*-------------------------------------------------------------------------------------*/
+
+void add_softmodem_cmds()
+{
+   add_telnetcmd("softmodem",proc_vardef,proc_cmdarray);
+}
diff --git a/common/utils/telnetsrv/telnetsrv_proccmd.h b/common/utils/telnetsrv/telnetsrv_proccmd.h
new file mode 100644
index 0000000000000000000000000000000000000000..60eaa2e40620fb7145128c9ffe3ae8b202ae180f
--- /dev/null
+++ b/common/utils/telnetsrv/telnetsrv_proccmd.h
@@ -0,0 +1,57 @@
+/*
+ * 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
+ */
+
+/*! \file common/utils/telnetsrv_proccmd.h
+ * \brief: Include file defining telnet commands related to this linux process
+ * \author Francois TABURET
+ * \date 2017
+ * \version 0.1
+ * \company NOKIA BellLabs France
+ * \email: francois.taburet@nokia-bell-labs.com
+ * \note
+ * \warning
+ */
+#include <dlfcn.h>
+#include "telnetsrv.h"
+
+
+#ifdef TELNETSRV_PROCCMD_MAIN
+
+
+extern int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt);
+extern int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt);
+extern int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt);
+extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt);
+telnetshell_vardef_t proc_vardef[] = {
+{"",0,NULL}
+};
+
+telnetshell_cmddef_t proc_cmdarray[] = {
+   {"show","loglvl|thread", proccmd_show},
+   {"log","[enable,disable]", proccmd_log},
+   {"thread","<id> aff|prio <aff|prio>", proccmd_thread},
+   {"exit","", proccmd_exit},
+   {"","",NULL},
+};
+#else
+extern void add_proccmd_cmds();
+#endif  /* TELNETSRV_PROCCMD_MAIN */
+
diff --git a/nfapi/nfapi_pnf.c b/nfapi/nfapi_pnf.c
index 5b2f93184092c830a20be680a245d064c35e6c78..ce0ceed8ea872dfa8fd4b66183a8b34e6cf0ac5f 100644
--- a/nfapi/nfapi_pnf.c
+++ b/nfapi/nfapi_pnf.c
@@ -947,6 +947,7 @@ void nfapi_procedures(PHY_VARS_eNB *eNB, int sfn, int sf)
 
   common_signal_procedures(eNB, sfn, sf);
 
+  LOG_E(PHY,"SFN/SF:%d/%d pdcch_vars[num_dci:%d num_pdcch_symbols:%d dci_alloc:dci_length:%d]\n", sfn, sf, pdcch_vars->num_dci, pdcch_vars->num_pdcch_symbols, pdcch_vars->dci_alloc[0].dci_length);
   if (pdcch_vars->num_dci > 0)
   {
     LOG_D(PHY,"SFN/SF:%d/%d pdcch_vars[num_dci:%d num_pdcch_symbols:%d dci_alloc:dci_length:%d]\n", sfn, sf, pdcch_vars->num_dci, pdcch_vars->num_pdcch_symbols, pdcch_vars->dci_alloc[0].dci_length);
@@ -1011,9 +1012,9 @@ void nfapi_procedures(PHY_VARS_eNB *eNB, int sfn, int sf)
 
 int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request_t* req)
 {
-#if 0
-if (NFAPI_SFNSF2SF(req->sfn_sf)==5)
-    printf("[PNF] dl config request sfn_sf:%d pdcch:%u dci:%u pdu:%d pdsch_rnti:%d pcfich:%u RC.ru:%p RC.eNB:%p sync_var:%d\n", 
+#if 1
+//if (1)//NFAPI_SFNSF2SF(req->sfn_sf)==5)
+    LOG_E(PHY,"[PNF] dl config request sfn_sf:%d pdcch:%u dci:%u pdu:%d pdsch_rnti:%d pcfich:%u RC.ru:%p RC.eNB:%p sync_var:%d\n", 
         NFAPI_SFNSF2DEC(req->sfn_sf), 
         req->dl_config_request_body.number_pdcch_ofdm_symbols, 
         req->dl_config_request_body.number_dci,
@@ -1162,6 +1163,8 @@ int  pnf_phy_tx_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_tx_request_t* req)
   uint16_t sfn = NFAPI_SFNSF2SFN(req->sfn_sf);
   uint16_t sf = NFAPI_SFNSF2SF(req->sfn_sf);
 
+  LOG_D(PHY,"%s() SFN/SF:%d/%d PDUs:%d\n", __FUNCTION__, sfn, sf, req->tx_request_body.number_of_pdus);
+
   if (req->tx_request_body.tl.tag==NFAPI_TX_REQUEST_BODY_TAG)
   {
     for (int i=0; i<req->tx_request_body.number_of_pdus; i++)
@@ -1793,6 +1796,8 @@ void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr,
 
 void oai_subframe_ind(uint16_t frame, uint16_t subframe)
 {
+  LOG_D(PHY,"%s(frame:%d, subframe:%d)\n", __FUNCTION__, frame, subframe);
+
   //TODO FIXME - HACK - DJP - using a global to bodge it in 
 
   if (p7_config_g != NULL && sync_var==0)
diff --git a/nfapi/nfapi_vnf.c b/nfapi/nfapi_vnf.c
index bda9d0286e3db47a542503a36671ca0c622c8595..cbe9ce27f41b03f591a95bcf661f4df637125d22 100644
--- a/nfapi/nfapi_vnf.c
+++ b/nfapi/nfapi_vnf.c
@@ -311,16 +311,19 @@ void oai_create_enb(void)
     memset((void*)RC.eNB[bodge_counter][bodge_counter],0,sizeof(PHY_VARS_eNB));
 
     eNB = RC.eNB[bodge_counter][bodge_counter];
+  }
 
-    eNB->Mod_id  = bodge_counter;
-    eNB->CC_id   = bodge_counter;
-    eNB->if_inst = IF_Module_init(bodge_counter);
-    eNB->abstraction_flag   = 0;
-    eNB->single_thread_flag = 0;//single_thread_flag;
-    eNB->td                   = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
-    eNB->te                   = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding;
+  eNB->Mod_id  = bodge_counter;
+  eNB->CC_id   = bodge_counter;
+  eNB->abstraction_flag   = 0;
+  eNB->single_thread_flag = 0;//single_thread_flag;
+  eNB->td                   = ulsch_decoding_data;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data;
+  eNB->te                   = dlsch_encoding;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding;
 
-    RC.nb_CC[bodge_counter] = 1;
+  RC.nb_CC[bodge_counter] = 1;
+
+  if (eNB->if_inst==0) {
+    eNB->if_inst = IF_Module_init(bodge_counter);
   }
 
   //init_eNB_proc(bodge_counter);
@@ -328,7 +331,7 @@ void oai_create_enb(void)
   // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY
   // that will result in eNB->configured being set to TRUE.
   // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values
-  if (RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0)
+  if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0)
   {
     printf("RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n");
     install_schedule_handlers(RC.eNB[0][0]->if_inst);
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 61577018c168b7c7fb166ff4aa153c9163a05b23..cea18b08e3ca4ef010fa69bf7234cee10ba15c08 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -127,6 +127,7 @@ void phy_config_request(PHY_Config_t *phy_config) {
 
   fp->phich_config_common.phich_resource = phich_resource_table[cfg->phich_config.phich_resource.value];
   fp->phich_config_common.phich_duration = cfg->phich_config.phich_duration.value;
+  // Note: "from_earfcn" has to be in a common library with MACRLC
   fp->dl_CarrierFreq                     = from_earfcn(eutra_band,dl_CarrierFreq);
   fp->ul_CarrierFreq                     = fp->dl_CarrierFreq - (get_uldl_offset(eutra_band)*100000);
 
@@ -1037,10 +1038,13 @@ void phy_config_harq_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
   phy_vars_ue->ulsch[eNB_id]->Mlimit = max_harq_tx;
 }
 
+extern uint16_t beta_cqi[16];
+
 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;
@@ -1092,7 +1096,7 @@ void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
 
       LOG_D(PHY,"pusch_config_dedicated.betaOffset_ACK_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index);
       LOG_D(PHY,"pusch_config_dedicated.betaOffset_RI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index);
-      LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index);
+      LOG_D(PHY,"pusch_config_dedicated.betaOffset_CQI_Index %d => %d)\n",phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index,beta_cqi[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index]);
       LOG_D(PHY,"\n");
 
 
@@ -1231,9 +1235,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;
@@ -1358,18 +1366,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);
@@ -1405,6 +1415,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*) );
@@ -1431,145 +1442,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 );
+	}
       }
     }
     
@@ -1596,17 +1629,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) );
 
@@ -1731,6 +1766,9 @@ int phy_init_RU(RU_t *ru) {
       }
 #endif
     }
+    
+    AssertFatal(RC.nb_L1_inst <= NUMBER_OF_eNB_MAX,"eNB instances %d > %d\n",
+		RC.nb_L1_inst,NUMBER_OF_eNB_MAX);
 
     LOG_E(PHY,"[INIT] %s() RC.nb_L1_inst:%d \n", __FUNCTION__, RC.nb_L1_inst);
 
@@ -1745,24 +1783,22 @@ int phy_init_RU(RU_t *ru) {
 	    // antenna ports 0-3 are mapped on antennas 0-3
 	    // antenna port 4 is mapped on antenna 0
 	    // antenna ports 5-14 are mapped on all antennas 
-	    if (((i<4) && (i==j)) || ((i==4) && (j==0))) {
+	    if (((p<4) && (p==j)) || ((p==4) && (j==0))) {
 	      for (re=0; re<fp->ofdm_symbol_size; re++) 
               {
 		ru->beam_weights[i][p][j][re] = 0x00007fff; 
 
-                LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
+                //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
               }
 	    }
-	    else if (i>4) {
+	    else if (p>4) {
 	      for (re=0; re<fp->ofdm_symbol_size; re++) 
               {
 		ru->beam_weights[i][p][j][re] = 0x00007fff/ru->nb_tx; 
-                LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
+                //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d][%d][%d] = %d\n", i,p,j,re,ru->beam_weights[i][p][j][re]);
               }
 	    }  
-	    LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n",
-		  i,j,ru->beam_weights[i][p][j],
-		  fp->ofdm_symbol_size*sizeof(int32_t)); 
+	    //LOG_D(PHY,"[INIT] lte_common_vars->beam_weights[%d][%d] = %p (%lu bytes)\n", i,j,ru->beam_weights[i][p][j], fp->ofdm_symbol_size*sizeof(int32_t)); 
 	  }
 	}
       }
@@ -1787,7 +1823,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB,
 #ifdef Rel14
   LTE_eNB_PRACH* const prach_vars_br = &eNB->prach_vars_br;
 #endif
-  int i,  UE_id; 
+  int i, UE_id; 
 
   LOG_I(PHY,"[eNB %d] %s() About to wait for eNB to be configured", eNB->Mod_id, __FUNCTION__);
 
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 5d10cbf6802b5ff5d4c2b240a4493e596557341a..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);
 }
 
@@ -239,7 +268,7 @@ int lte_est_timing_advance_pusch(PHY_VARS_eNB* eNB,uint8_t UE_id)
     max_pos_fil2 = ((max_pos_fil2 * coef) + (max_pos * ncoef)) >> 15;
 
   //#ifdef DEBUG_PHY
-  LOG_I(PHY,"frame %d: max_pos = %d, max_pos_fil = %d, sync_pos=%d\n",eNB->proc.frame_rx,max_pos,max_pos_fil2,sync_pos);
+  LOG_D(PHY,"frame %d: max_pos = %d, max_pos_fil = %d, sync_pos=%d\n",eNB->proc.frame_rx,max_pos,max_pos_fil2,sync_pos);
   //#endif //DEBUG_PHY
 
   return(max_pos_fil2-sync_pos);
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..8edb66ab4c66fc20722261e0f6748c0769566472 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,19 +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));
-#endif
+  T(T_UE_PHY_DL_CHANNEL_ESTIMATE, T_INT(eNB_id),
+    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));
 
   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_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index 17ddd9b5545f9f12707805e4b2d4b4f0f2eb99d8..65423aa9b6600b8b68f7f5c40db5b18a9a930e38 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -302,7 +302,7 @@ int32_t temp_in_ifft_0[2048*2] __attribute__((aligned(32)));
 
 #if T_TRACER
       if (aa == 0)
-        T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(0), T_INT(UE_id),
+        T(T_ENB_PHY_UL_CHANNEL_ESTIMATE, T_INT(0), T_INT(eNB->ulsch[UE_id]->rnti),
           T_INT(proc->frame_rx), T_INT(subframe),
           T_INT(0), T_BUFFER(ul_ch_estimates_time[0], 512  * 4));
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c
index f561680491b4b23362c9fcd4529b4ec3e40212fb..5e29c0060145944ec633fd544988f6e418e749d8 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,92 @@ 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
+  T(T_UE_PHY_PDCCH_ENERGY, T_INT(eNB_id),  T_INT(frame%1024), T_INT(subframe),
+                           T_INT(avgP[0]), T_INT(avgP[1]),    T_INT(avgP[2]),  T_INT(avgP[3]));
+
+  // 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 +1854,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 +1876,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 +1892,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 +2176,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 +2198,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;
@@ -2109,7 +2251,7 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
     break;
   }
 
-  
+
   generate_pcfich(num_pdcch_symbols,
                   amp,
                   frame_parms,
@@ -2128,6 +2270,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) {
@@ -2135,11 +2278,13 @@ uint8_t generate_dci_top(uint8_t num_pdcch_symbols,
 
       if (dci_alloc[i].L == (uint8_t)L) {
 
-#ifdef DEBUG_DCI_ENCODING
-        LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x)\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L,
-              *(unsigned int*)dci_alloc[i].dci_pdu);
-        dump_dci(frame_parms,&dci_alloc[i]);
-#endif
+	//#ifdef DEBUG_DCI_ENCODING
+	if (dci_alloc[i].rnti!=0xFFFF)
+	  LOG_I(PHY,"Generating DCI %d/%d (nCCE %d) of length %d, aggregation %d (%x), rnti %x\n",i,num_dci,dci_alloc[i].firstCCE,dci_alloc[i].dci_length,dci_alloc[i].L,
+		*(unsigned int*)dci_alloc[i].dci_pdu,
+		dci_alloc[i].rnti);
+        //dump_dci(frame_parms,&dci_alloc[i]);
+	//#endif
 
         if (dci_alloc[i].firstCCE>=0) {
           e_ptr = generate_dci0(dci_alloc[i].dci_pdu,
@@ -2372,6 +2517,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,
@@ -2436,7 +2582,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)
 {
@@ -2575,7 +2721,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;
         }
@@ -2600,6 +2747,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,
@@ -2725,20 +2873,22 @@ 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);
+
+      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
@@ -2754,29 +2904,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
         }
 
@@ -2793,7 +2943,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;
@@ -2815,7 +2965,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);
 
 
@@ -2839,19 +2989,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,
@@ -2861,7 +3192,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;
@@ -3080,6 +3411,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) ,
@@ -3108,6 +3440,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),
@@ -3140,6 +3473,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),
@@ -3168,6 +3502,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),
@@ -3202,6 +3537,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),
@@ -3225,12 +3561,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),
@@ -3254,16 +3594,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),
@@ -3287,12 +3629,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),
@@ -3316,9 +3663,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
@@ -3326,6 +3673,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),
@@ -3344,6 +3692,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))
@@ -3357,6 +3706,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),
@@ -3375,7 +3725,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))
@@ -3389,6 +3739,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),
@@ -3407,6 +3758,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)))
@@ -3421,6 +3773,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),
@@ -3439,6 +3792,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)))
@@ -3458,6 +3812,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),
@@ -3493,6 +3848,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),
@@ -3527,6 +3883,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),
@@ -3562,6 +3919,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),
@@ -3596,6 +3954,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),
@@ -3628,6 +3987,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),
@@ -3660,6 +4020,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),
@@ -3693,6 +4054,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),
@@ -3723,6 +4085,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),
@@ -3756,6 +4119,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),
@@ -3788,6 +4152,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),
@@ -3822,6 +4187,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 ace04441f3541a63d86cbb510f8e0e719328f53d..3ef73aa4ab647462e907f3271d13fe637faffab5 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -821,7 +821,6 @@ void check_dlsch(char *file, int line)
   }
 
   memcpy(oldbuf, buf, sizeof(buf));
- 
 }
 
 int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
@@ -880,7 +879,7 @@ uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti)
 }
 */
 
-int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) {
+void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) {
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
 
@@ -904,8 +903,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
   dci_alloc->harq_pid = rel8->harq_process;
   dci_alloc->ra_flag  = 0;
 
-
-  LOG_D(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n",
+  LOG_I(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n",
 	rel8->dci_format,rel8->cce_idx,rel8->aggregation_level,rel8->rnti,rel8->harq_process);
   if ((rel8->rnti_type == 2 ) && (rel8->rnti != SI_RNTI) && (rel8->rnti != P_RNTI)) dci_alloc->ra_flag = 1;
 
@@ -914,20 +912,34 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
   AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
   dlsch0 = eNB->dlsch[UE_id][0];
   dlsch1 = eNB->dlsch[UE_id][1];
-  
+
+    
   beamforming_mode                          = eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id];
   dlsch0_harq                               = dlsch0->harq_processes[rel8->harq_process];
   dlsch0_harq->codeword                     = 0;
   dlsch1_harq                               = dlsch1->harq_processes[rel8->harq_process];
   dlsch1_harq->codeword                     = 1;
-  dlsch0->subframe_tx[subframe]             = 1;  
-  dlsch0->harq_mask                         |= (1<<rel8->harq_process);
+  dlsch0->subframe_tx[subframe]             = 1;
+  if ((dlsch0->harq_mask & (1<<rel8->harq_process)) > 0 ) {
+    if (rel8->new_data_indicator_1 != dlsch0_harq->ndi)
+      dlsch0_harq->round=0;
+  }
+  else  { // process is inactive, so activate and set round to 0
+    dlsch0->harq_mask                         |= (1<<rel8->harq_process);
+    dlsch0_harq->round=0;
+  }
+  dlsch0_harq->ndi = rel8->new_data_indicator_1;
+
+  LOG_I(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) \n",rel8->harq_process,dlsch0->harq_mask,dlsch0_harq->round,
+	dlsch0_harq->ndi,rel8->new_data_indicator_1);
+
   switch (rel8->dci_format) {
 
   case NFAPI_DL_DCI_FORMAT_1A:
     dci_alloc->format     = format1A;
-    dlsch0->active       = 1;
-    dlsch0->harq_mask                         |= (1<<rel8->harq_process);
+    dlsch0->active        = 1;
+    if (rel8->rnti == SI_RNTI)
+      dlsch0_harq->round    = 0;
 
     switch (fp->N_RB_DL) {
     case 6:
@@ -1092,7 +1104,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
 
     dci_alloc->format           = format1;
     dlsch0->active              = 1;
-    dlsch0->harq_mask           |= (1<<rel8->harq_process);
 
     LOG_D(PHY,"Frame %d, Subframe %d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",proc->frame_tx,subframe,rel8->harq_process);
 
@@ -1193,10 +1204,8 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
       break;
     }
 
-    if (rel8->harq_process>=8) {
-      LOG_E(PHY,"ERROR: Format 1: harq_pid=%d >= 8\n", rel8->harq_process);
-      return(-1);
-    }
+    AssertFatal(rel8->harq_process<8,"Format 1: harq_pid=%d >= 8\n", rel8->harq_process);
+
 
     dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
     dlsch0_harq->codeword=0;
@@ -1216,9 +1225,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
     NPRB      = dlsch0_harq->nb_rb;
 
 
-    if (NPRB==0)
-      return(-1);
-
+    AssertFatal(NPRB>0,"NPRB == 0\n");
 
     dlsch0_harq->rvidx       = rel8->redundancy_version_1;
 
@@ -1239,6 +1246,7 @@ int 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;
@@ -1388,14 +1396,13 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
       break;
 
     }
-    if (rel8->harq_process>=8) {
-      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process);
-      return(-1);
-    }
+
+    AssertFatal(rel8->harq_process<8,"Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process);
 
 
     // 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];
@@ -1423,8 +1430,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
 								 fp->N_RB_DL);
     dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
 
-    if (dlsch0_harq->nb_rb == 0)
-      return(-1);
+    AssertFatal(dlsch0_harq->nb_rb > 0,"nb_rb=0\n");
 
     dlsch0_harq->mcs       = rel8->mcs_1;
     dlsch1_harq->mcs       = rel8->mcs_2;
@@ -1708,10 +1714,7 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
 
     }
 
-    if (rel8->harq_process>=8) {
-      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process);
-      return(-1);
-    }
+    AssertFatal(rel8->harq_process>=8, "Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process);
 
 
     // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
@@ -1834,10 +1837,6 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
     }
 
 
-    /*if (dlsch0_harq->nb_rb == 0)
-      return(-1);*/
-
-
     // assume both TBs are active
     if (dlsch0_harq != NULL)
       dlsch0_harq->Nl        = 1;
@@ -2002,29 +2001,23 @@ int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_
 
 #endif
     
-    // compute DL power control parameters
+#if T_TRACER
+  if (dlsch0->active)
+    T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(proc->frame_tx), T_INT(proc->subframe_tx),
+      T_INT(rel8->rnti), T_INT(rel8->dci_format), T_INT(rel8->harq_process),
+      T_INT(rel8->mcs_1), T_INT(dlsch0_harq->TBS));
+#endif
 
-    if (dlsch0 != NULL){
-      computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch0,dlsch0_harq->dl_power_off, fp->nb_antenna_ports_eNB);
-      computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(fp->pdsch_config_common),fp->nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off);
-    }
-    if (dlsch1 != NULL){
-      computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch1,dlsch1_harq->dl_power_off, fp->nb_antenna_ports_eNB);
-      computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(fp->pdsch_config_common),fp->nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off);
-    }
-    
-    LOG_D(PHY, "%s() dci_length:%d\n", __FUNCTION__, dci_alloc->dci_length);
-    
 }
 
-int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) {
+void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) {
 
   LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
 
   uint8_t *dci_pdu = &dci_alloc->dci_pdu[0];
   nfapi_dl_config_mpdcch_pdu_rel13_t *rel13 = &pdu->mpdcch_pdu_rel13;
-  int harq_pid;
-  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
+
+  LTE_eNB_DLSCH_t *dlsch0=NULL;
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL;
   int UE_id;
   int subframe = proc->subframe_tx;
@@ -2258,8 +2251,8 @@ int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dc
 }
 
 void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
-	      nfapi_hi_dci0_dci_pdu *pdu) {
-
+               nfapi_hi_dci0_dci_pdu *pdu)
+{
   uint8_t UE_id;
 
   AssertFatal((UE_id=find_ulsch(pdu->dci_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
@@ -2272,21 +2265,34 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
   uint32_t cshift  = pdu->dci_pdu_rel8.cyclic_shift_2_for_drms;
   uint32_t TPC     = pdu->dci_pdu_rel8.tpc;
   uint32_t mcs     = pdu->dci_pdu_rel8.mcs_1;
+  uint32_t hopping = pdu->dci_pdu_rel8.frequency_hopping_enabled_flag;
   uint32_t rballoc = computeRIV(frame_parms->N_RB_DL,
 				pdu->dci_pdu_rel8.resource_block_start,
 				pdu->dci_pdu_rel8.number_of_resource_block);
 
   uint32_t ndi     = pdu->dci_pdu_rel8.new_data_indication_1;
 
+#ifdef T_TRACER
+  T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx),
+    T_INT(pdu->dci_pdu_rel8.rnti), T_INT(((proc->frame_tx*10+proc->subframe_tx+4) % 8) /* TODO: correct harq pid */),
+    T_INT(mcs), T_INT(-1 /* TODO: remove round? */),
+    T_INT(pdu->dci_pdu_rel8.resource_block_start),
+    T_INT(pdu->dci_pdu_rel8.number_of_resource_block),
+    T_INT(-1 /* TODO: get TBS */),
+    T_INT(pdu->dci_pdu_rel8.aggregation_level),
+    T_INT(pdu->dci_pdu_rel8.cce_index));
+#endif
+
   void *dci_pdu = (void*)dci_alloc->dci_pdu;
 
-  LOG_I(PHY,"Filling DCI0 with cqi %d\n",cqi_req);
+  LOG_I(PHY,"Filling DCI0 with cqi %d, mcs %d, hopping %d, rballoc %x (%d,%d) ndi %d TPC %d cshift %d\n",cqi_req,
+	mcs,hopping,rballoc,pdu->dci_pdu_rel8.resource_block_start,pdu->dci_pdu_rel8.number_of_resource_block,
+	ndi,TPC,cshift);
 
   dci_alloc->format   = format0;
   dci_alloc->firstCCE = pdu->dci_pdu_rel8.cce_index;
   dci_alloc->L        = pdu->dci_pdu_rel8.aggregation_level;
   dci_alloc->rnti     = pdu->dci_pdu_rel8.rnti;
-  //  dci_alloc->harq_pid = pdu->dci_pdu_rel8.harq_process;
   dci_alloc->ra_flag  = 0;
 
   switch (frame_parms->N_RB_DL) {
@@ -2299,9 +2305,9 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
       ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
       ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
       ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
-      //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
       ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
-      dci_alloc->dci_length                         = sizeof_DCI0_1_5MHz_TDD_1_6_t; 
+      dci_alloc->dci_length                       = sizeof_DCI0_1_5MHz_TDD_1_6_t; 
     } else {
       ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
       ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift      = cshift;
@@ -2309,9 +2315,9 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
       ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs         = mcs;
       ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi         = ndi;
       ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
-      //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping;
+      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping     = hopping;
       ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type        = 0;
-      dci_alloc->dci_length                         = sizeof_DCI0_1_5MHz_FDD_t; 
+      dci_alloc->dci_length                       = sizeof_DCI0_1_5MHz_FDD_t; 
     }
     
     break;
@@ -2325,7 +2331,7 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
       ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
       ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
       ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
-      //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
       ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
       dci_alloc->dci_length                     = sizeof_DCI0_5MHz_TDD_1_6_t; 
     } else {
@@ -2335,7 +2341,7 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
       ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs         = mcs;
       ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi         = ndi;
       ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
-      //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping;
+      ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping     = hopping;
       ((DCI0_5MHz_FDD_t *)dci_pdu)->type        = 0;
       dci_alloc->dci_length                     = sizeof_DCI0_5MHz_FDD_t; 
     }
@@ -2351,7 +2357,7 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
       ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
       ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
       ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
-      //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping;
+      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
       ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
       dci_alloc->dci_length                      = sizeof_DCI0_10MHz_TDD_1_6_t; 
     } else {
@@ -2361,8 +2367,8 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
       ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs         = mcs;
       ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi         = ndi;
       ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
-      //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping;
-      ((DCI0_10MHz_FDD_t *)dci_pdu)->type = 0;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping     = hopping;
+      ((DCI0_10MHz_FDD_t *)dci_pdu)->type        = 0;
       dci_alloc->dci_length                      = sizeof_DCI0_10MHz_FDD_t; 
     }
     
@@ -2376,2056 +2382,131 @@ void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
       ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
       ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
       ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
-      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
-      //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping;
-      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
-      dci_alloc->dci_length                      = sizeof_DCI0_20MHz_TDD_1_6_t; 
-    } else {
-      ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
-      ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift      = cshift;
-      ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC         = TPC;
-      ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs         = mcs;
-      ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi         = ndi;
-      ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
-      //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping;
-      ((DCI0_20MHz_FDD_t *)dci_pdu)->type        = 0;
-      dci_alloc->dci_length                      = sizeof_DCI0_20MHz_FDD_t; 
-    }
-    
-      //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc);
-      break;
-      
-  default:
-    LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
-    DevParam (frame_parms->N_RB_DL, 0, 0);
-    break;
-  }
-}
-
-void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) {
-
-  uint8_t harq_pid;
-
-  uint8_t UE_id;
-
-  AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
-	      "No existing UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti);
-
-  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
-  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
-
-  int use_srs = 0;
-
-  harq_pid = ulsch_pdu->ulsch_pdu_rel8.harq_process_number;
-
-
-  ulsch->harq_processes[harq_pid]->frame                                 = frame;
-  ulsch->harq_processes[harq_pid]->subframe                              = subframe;
-
-  ulsch->harq_processes[harq_pid]->first_rb                              = ulsch_pdu->ulsch_pdu_rel8.resource_block_start;
-  ulsch->harq_processes[harq_pid]->nb_rb                                 = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
-
-  AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
-
-  ulsch->harq_processes[harq_pid]->dci_alloc                             = 1;
-  ulsch->harq_processes[harq_pid]->rar_alloc                             = 0;
-  ulsch->harq_processes[harq_pid]->n_DMRS                                = ulsch_pdu->ulsch_pdu_rel8.cyclic_shift_2_for_drms;
-  
-  ulsch->harq_processes[harq_pid]->Nsymb_pusch                           = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
-  ulsch->harq_processes[harq_pid]->srs_active                            = use_srs;
-  
-  //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
-  if(ulsch->harq_processes[harq_pid]->n_DMRS == 0)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
-  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 1)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
-  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 2)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
-  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 3)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
-  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 4)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
-  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 5)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
-  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 6)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
-  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7)
-    ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;
-  
-   
-  LOG_D(PHY,"[eNB %d][PUSCH %d] Programming PUSCH with n_DMRS2 %d (cshift %d) for Frame %d, Subframe %d\n",
-	eNB->Mod_id,harq_pid,ulsch->harq_processes[harq_pid]->n_DMRS2,ulsch->harq_processes[harq_pid]->n_DMRS,
-	frame,subframe);
-  
-  
-  ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version;
-  ulsch->harq_processes[harq_pid]->Qm    = ulsch_pdu->ulsch_pdu_rel8.modulation_type;
-
-
-  if ((ulsch->harq_processes[harq_pid]->status == SCH_IDLE) ||
-      (ulsch->harq_processes[harq_pid]->ndi    != ulsch_pdu->ulsch_pdu_rel8.new_data_indication)){
-    ulsch->harq_processes[harq_pid]->status        = ACTIVE;
-    
-    ulsch->harq_processes[harq_pid]->TBS           = ulsch_pdu->ulsch_pdu_rel8.size<<3;
-    
-    ulsch->harq_processes[harq_pid]->Msc_initial   = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
-    ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch;
-    ulsch->harq_processes[harq_pid]->round         = 0;
-    ulsch->harq_processes[harq_pid]->ndi           = ulsch_pdu->ulsch_pdu_rel8.new_data_indication;
-    ulsch->harq_processes[harq_pid]->Or1           = 0;
-    ulsch->harq_processes[harq_pid]->Or2           = 0;
-    ulsch->harq_processes[harq_pid]->O_ACK         = 0;
-  } 
-  else  ulsch->harq_processes[harq_pid]->round++;
-
-  ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
-  LOG_I(PHY,"Filling ULSCH %x for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
-	ulsch->rnti,
-	frame,
-	subframe,
-	harq_pid,
-	ulsch->harq_processes[harq_pid]->first_rb,
-	ulsch->harq_processes[harq_pid]->nb_rb,
-	ulsch->harq_processes[harq_pid]->rvidx,
-	ulsch->harq_processes[harq_pid]->Qm,
-	ulsch->harq_processes[harq_pid]->TBS,
-	ulsch->harq_processes[harq_pid]->round);  
-  
-  
-}
-
-int generate_eNB_dlsch_params_from_dci(int frame,
-                                       uint8_t subframe,
-                                       void *dci_pdu,
-                                       uint16_t rnti,
-                                       DCI_format_t dci_format,
-                                       LTE_eNB_DLSCH_t **dlsch,
-                                       LTE_DL_FRAME_PARMS *fp,
-                                       PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
-                                       uint16_t si_rnti,
-                                       uint16_t ra_rnti,
-                                       uint16_t p_rnti,
-                                       uint16_t DL_pmi_single,
-                                       uint8_t beamforming_mode)
-{
-
-  uint8_t harq_pid = UINT8_MAX;
-  uint32_t rballoc = UINT32_MAX;
-  uint32_t RIV_max = 0;
-  uint8_t NPRB,tbswap,tpmi=0;
-  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
-  uint8_t frame_type=fp->frame_type;
-  uint8_t vrb_type=0;
-  uint8_t mcs=0,mcs1=0,mcs2=0;
-  uint8_t I_mcs = 0;
-  uint8_t rv=0,rv1=0,rv2=0;
-  uint8_t rah=0;
-  uint8_t TPC=0;
-  uint8_t TB0_active=0,TB1_active=0;
-  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
-
-  //   printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);
-
-  switch (dci_format) {
-
-  case format0:
-    return(-1);
-    break;
-
-  case format1A:  // This is DLSCH allocation for control traffic
-
-
-
-    dlsch[0]->subframe_tx[subframe] = 1;
-
-
-    switch (fp->N_RB_DL) {
-    case 6:
-      if (frame_type == TDD) {
-        vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
-
-        //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
-      } else {
-        vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
-
-        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
-      }
-
-      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-      dlsch0_harq->codeword=0;
-
-      AssertFatal(vrb_type==LOCALIZED,"Distributed RB allocation not done yet\n");
-      dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT6[rballoc];
-      dlsch0_harq->vrb_type       = vrb_type;
-      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT6[rballoc];//NPRB;
-      RIV_max = RIV_max6;
-
-
-      break;
-
-    case 25:
-      if (frame_type == TDD) {
-        vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
-
-        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
-      } else {
-        vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid;
-
-        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
-      }
-
-      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
-
-      AssertFatal(vrb_type==LOCALIZED,"Distributed RB allocation not done yet\n");
-      dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT25[rballoc];
-      dlsch0_harq->vrb_type       = vrb_type;
-      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT25[rballoc];//NPRB;
-      RIV_max                     = RIV_max25;
-      break;
-
-    case 50:
-      if (frame_type == TDD) {
-        vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
-
-        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
-      } else {
-        vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid;
-        //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
-      }
-
-      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-      AssertFatal(vrb_type==LOCALIZED,"Distributed RB allocation not done yet\n");
-      dlsch0_harq->rb_alloc[0]     = localRIV2alloc_LUT50_0[rballoc];
-      dlsch0_harq->rb_alloc[1]     = localRIV2alloc_LUT50_1[rballoc];
-      dlsch0_harq->vrb_type        = vrb_type;
-      dlsch0_harq->nb_rb           = RIV2nb_rb_LUT50[rballoc];//NPRB;
-      RIV_max = RIV_max50;
-      break;
-
-    case 100:
-      if (frame_type == TDD) {
-        vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
-        //      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
-      } else {
-        vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type;
-        mcs      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs;
-        rballoc  = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv;
-        TPC      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC;
-        harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid;
-        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
-      }
-
-      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-
-      dlsch0_harq->vrb_type         = vrb_type;
-      AssertFatal(vrb_type==LOCALIZED,"Distributed RB allocation not done yet\n");
-      dlsch0_harq->rb_alloc[0]      = localRIV2alloc_LUT100_0[rballoc];
-      dlsch0_harq->rb_alloc[1]      = localRIV2alloc_LUT100_1[rballoc];
-      dlsch0_harq->rb_alloc[2]      = localRIV2alloc_LUT100_2[rballoc];
-      dlsch0_harq->rb_alloc[3]      = localRIV2alloc_LUT100_3[rballoc];
-      dlsch0_harq->nb_rb            = RIV2nb_rb_LUT100[rballoc];//NPRB;
-      RIV_max                       = RIV_max100;
-      break;
-
-    default:
-      LOG_E(PHY,"Invalid N_RB_D %dL\n", fp->N_RB_DL);
-      DevParam (fp->N_RB_DL, 0, 0);
-      break;
-    }
-
-    // harq_pid field is reserved
-    if ((rnti==si_rnti) || (rnti==ra_rnti) || (rnti==p_rnti)) { //
-      harq_pid=0;
-
-    } else {
-      if (harq_pid>=8) {
-        LOG_E(PHY,"ERROR: Format 1A: harq_pid=%d >= 8\n", harq_pid);
-        return(-1);
-      }
-
-      if (rballoc>RIV_max) {
-        LOG_E(PHY,"ERROR: Format 1A: rb_alloc (%x) > RIV_max (%x)\n",rballoc,RIV_max);
-        return(-1);
-      }
-
-      NPRB      = dlsch0_harq->nb_rb;
-      I_mcs     = get_I_TBS(mcs);
-    }
-
-    if (NPRB==0)
-      return(-1);
-
-    //printf("NPRB %d, nb_rb %d, ndi %d\n",NPRB,dlsch0_harq->nb_rb,ndi);
-    dlsch0_harq->rvidx     = rv;
-
-    dlsch0_harq->Nl          = 1;
-    //dlsch0_harq->layer_index = 0;
-
-    dlsch0_harq->mimo_mode   = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI;
-    /*
-    if ((rnti!=si_rnti)&&(rnti!=ra_rnti)&&(rnti!=p_rnti)) {  //handle toggling for C-RNTI
-    if (dlsch0_harq->first_tx == 1) {
-    LOG_D(PHY,"First TX for TC-RNTI %x, clearing first_tx flag\n",rnti);
-    dlsch0_harq->first_tx=0;
-    dlsch0_harq->Ndi = 1;
-    }
-    else {
-    if (ndi == dlsch0_harq->DCINdi)
-    dlsch0_harq->Ndi         = 0;
-    else
-    dlsch0_harq->Ndi         = 1;
-    }
-
-    dlsch0_harq->DCINdi=ndi;
-    }
-    else {
-    dlsch0_harq->Ndi         = 1;
-    }
-    */
-    dlsch0_harq->dl_power_off = 1;
-
-
-
-    dlsch0_harq->mcs           = mcs;
-    dlsch0_harq->TBS           = TBStable[I_mcs][NPRB-1];
-
-    dlsch[0]->harq_ids[subframe] = harq_pid;
-
-    dlsch[0]->active = 1;
-    dlsch0 = dlsch[0];
-
-    dlsch[0]->rnti = rnti;
-
-    dlsch[0]->harq_ids[subframe] = harq_pid;
-
-    if (dlsch0_harq->round == 0)
-      dlsch0_harq->status = ACTIVE;
-
-    break;
-
-  case format1:
-
-    switch (fp->N_RB_DL) {
-
-    case 6:
-      if (frame_type == TDD) {
-        mcs       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs;
-        rballoc   = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah;
-        rv        = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv;
-        harq_pid  = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs;
-        rah      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah;
-        rballoc  = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv;
-        harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 25:
-
-      if (frame_type == TDD) {
-        mcs       = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs;
-        rballoc   = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah;
-        rv        = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv;
-        harq_pid  = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid;
-        LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_TDD_t *)dci_pdu)->ndi,harq_pid);
-      } else {
-        mcs      = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs;
-        rah      = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah;
-        rballoc  = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv;
-        harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid;
-        LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_FDD_t *)dci_pdu)->ndi,harq_pid);
-
-      }
-
-      break;
-
-    case 50:
-      if (frame_type == TDD) {
-        mcs       = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs;
-        rballoc   = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah;
-        rv        = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv;
-        harq_pid  = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs      = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs;
-        rah      = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah;
-        rballoc  = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv;
-        harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 100:
-      if (frame_type == TDD) {
-        mcs       = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs;
-        rballoc   = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah;
-        rv        = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv;
-        harq_pid  = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs      = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs;
-        rah      = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah;
-        rballoc  = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc;
-        rv       = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv;
-        harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    }
-
-    if (harq_pid>=8) {
-      LOG_E(PHY,"ERROR: Format 1: harq_pid=%d >= 8\n", harq_pid);
-      return(-1);
-    }
-
-    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
-    dlsch0_harq->codeword=0;
-
-    // printf("DCI: Setting subframe_tx for subframe %d\n",subframe);
-    dlsch[0]->subframe_tx[subframe] = 1;
-
-    conv_rballoc(rah,
-                 rballoc,fp->N_RB_DL,
-                 dlsch0_harq->rb_alloc);
-
-    dlsch0_harq->nb_rb = conv_nprb(rah,
-                                   rballoc,
-                                   fp->N_RB_DL);
-
-    NPRB      = dlsch0_harq->nb_rb;
-
-
-    if (NPRB==0)
-      return(-1);
-
-
-    dlsch0_harq->rvidx       = rv;
-
-    dlsch0_harq->Nl          = 1;
-    //    dlsch[0]->layer_index = 0;
-    if (beamforming_mode == 0)
-      dlsch0_harq->mimo_mode = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI;
-    else if (beamforming_mode == 7)
-      dlsch0_harq->mimo_mode = TM7;
-    else
-      LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
-
-    dlsch0_harq->dl_power_off = 1;
-    /*
-      if (dlsch[0]->harq_processes[harq_pid]->first_tx == 1) {
-      LOG_D(PHY,"First TX for C-RNTI %x, clearing first_tx flag, shouldn't happen!\n",rnti);
-      dlsch[0]->harq_processes[harq_pid]->first_tx=0;
-      dlsch[0]->harq_processes[harq_pid]->Ndi = 1;
-      }
-      else {
-      LOG_D(PHY,"Checking for Toggled Ndi for C-RNTI %x, old value %d, DCINdi %d\n",rnti,dlsch[0]->harq_processes[harq_pid]->DCINdi,ndi);
-      if (ndi == dlsch[0]->harq_processes[harq_pid]->DCINdi)
-      dlsch[0]->harq_processes[harq_pid]->Ndi         = 0;
-      else
-      dlsch[0]->harq_processes[harq_pid]->Ndi         = 1;
-      }
-      dlsch[0]->harq_processes[harq_pid]->DCINdi=ndi;
-    */
-
-    dlsch[0]->active = 1;
-
-
-
-    if (dlsch0_harq->round == 0) {
-      dlsch0_harq->status = ACTIVE;
-      //            printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
-      // MCS and TBS don't change across HARQ rounds
-      dlsch0_harq->mcs         = mcs;
-      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];
-
-    }
-
-    dlsch[0]->harq_ids[subframe] = harq_pid;
-
-
-
-    dlsch0 = dlsch[0];
-
-    dlsch[0]->rnti = rnti;
-
-
-    break;
-
-  case format2: // DL Scheduling assignment for MIMO including closed loop spatial multiplexing
-
-    switch (fp->N_RB_DL) {
-
-    case 6:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-
-    case 25:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-
-    case 50:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-
-    case 100:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-    }
-
-
-    if (harq_pid>=8) {
-      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
-      return(-1);
-    }
-
-
-    // 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
-    TB0_active = 1;
-    TB1_active = 1;
-
-    if ((rv1 == 1) && (mcs1 == 0)) {
-      TB0_active=0;
-    }
-    if ((rv2 == 1) && (mcs2 == 0)) {
-      TB1_active=0;
-    }
-#ifdef DEBUG_HARQ
-    printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rv1, rv2, mcs1, mcs2);
-#endif
-    if (TB0_active && TB1_active && tbswap==0) {
-      dlsch0=dlsch[0];
-      dlsch1=dlsch[1];
-      dlsch0->active = 1;
-      dlsch1->active = 1;
-      dlsch0_harq = dlsch0->harq_processes[harq_pid];
-      dlsch1_harq = dlsch1->harq_processes[harq_pid];
-      dlsch0_harq->mcs = mcs1;
-      dlsch1_harq->mcs = mcs2;
-      dlsch0_harq->rvidx = rv1;
-      dlsch1_harq->rvidx = rv2;
-      dlsch0_harq->status = ACTIVE;
-      dlsch1_harq->status = ACTIVE;
-      dlsch0_harq->codeword=0;
-      dlsch1_harq->codeword=1;
-#ifdef DEBUG_HARQ
-      printf("\n ENB: BOTH ACTIVE\n");
-#endif
-    }
-    else if (TB0_active && TB1_active && tbswap==1) {
-      dlsch0=dlsch[0];
-      dlsch1=dlsch[1];
-      dlsch0->active = 1;
-      dlsch1->active = 1;
-      dlsch0_harq = dlsch0->harq_processes[harq_pid];
-      dlsch1_harq = dlsch1->harq_processes[harq_pid];
-      dlsch0_harq->mcs = mcs1;
-      dlsch1_harq->mcs = mcs2;
-      dlsch0_harq->rvidx = rv1;
-      dlsch1_harq->rvidx = rv2;
-      dlsch0_harq->status = ACTIVE;
-      dlsch1_harq->status = ACTIVE;
-      dlsch0_harq->codeword=1;
-      dlsch1_harq->codeword=0;
-    }
-    else if (TB0_active && (TB1_active==0)) {
-      dlsch0=dlsch[0];
-      dlsch0->active = 1;
-      dlsch0_harq = dlsch0->harq_processes[harq_pid];
-      dlsch0_harq->mcs = mcs1;
-      dlsch0_harq->rvidx = rv1;
-      dlsch0_harq->status = ACTIVE;
-      dlsch0_harq->codeword = 0;
-      dlsch1=NULL;
-      dlsch1_harq = NULL;
-#ifdef DEBUG_HARQ
-      printf("\n ENB: TB1 is deactivated, retransmit TB0 transmit in TM6\n");
-#endif
-    }
-    else if ((TB0_active==0) && TB1_active) {
-      dlsch1=dlsch[1];
-      dlsch1->active = 1;
-      dlsch1_harq = dlsch1->harq_processes[harq_pid];
-      dlsch1_harq->mcs = mcs2;
-      dlsch1_harq->rvidx = rv2;
-      dlsch1_harq->status = ACTIVE;
-      dlsch1_harq->codeword = 0;
-      dlsch0=NULL;
-      dlsch0_harq = NULL;
-#ifdef DEBUG_HARQ
-      printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
-#endif
-    }
-
-    if (dlsch0 != NULL){
-      dlsch0->subframe_tx[subframe] = 1;
-
-      dlsch0->harq_ids[subframe] = harq_pid;
-    }
-
-    if (dlsch1_harq != NULL){
-      dlsch1->harq_ids[subframe] = harq_pid;
-    }
-
-
-    if (dlsch0 != NULL ){
-      conv_rballoc(rah,
-                   rballoc,
-                   fp->N_RB_DL,
-                   dlsch0_harq->rb_alloc);
-
-      dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, fp->N_RB_DL);
-
-      if (dlsch1 != NULL){
-        dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
-        dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
-      }
-    } else if ((dlsch0 == NULL ) && (dlsch1 != NULL )){
-        conv_rballoc(rah,
-                     rballoc,
-                     fp->N_RB_DL,
-                     dlsch1_harq->rb_alloc);
-
-        dlsch1_harq->nb_rb = conv_nprb(rah, rballoc, fp->N_RB_DL);
-    }
-
-
-    /*if (dlsch0_harq->nb_rb == 0)
-      return(-1);*/
-
-
-    // assume both TBs are active
-    if (dlsch0_harq != NULL)
-      dlsch0_harq->Nl        = 1;
-    if (dlsch1_harq != NULL)
-      dlsch1_harq->Nl        = 1;
-
-
-    // check if either TB is disabled (see 36-213 V11.3 Section )
-
-    if (fp->nb_antenna_ports_eNB == 2) {
-      if ((dlsch0 != NULL) && (dlsch1 != NULL)) {  //two CW active
-
-        dlsch0_harq->dl_power_off = 1;
-        dlsch1_harq->dl_power_off = 1;
-        dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-        dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
-        switch (tpmi) {
-        case 0:
-          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
-          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
-          dlsch0_harq->pmi_alloc   = pmi_extend(fp,0,1);
-          dlsch1_harq->pmi_alloc   = pmi_extend(fp,0,1);
-          break;
-        case 1:
-          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
-          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
-          dlsch0_harq->pmi_alloc   = pmi_extend(fp,1,1);
-          dlsch0_harq->pmi_alloc   = pmi_extend(fp,1,1);
-
-          break;
-        case 2: // PUSCH precoding
-          dlsch0_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
-          dlsch0_harq->pmi_alloc   = DL_pmi_single;
-          dlsch1_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
-          dlsch1_harq->pmi_alloc   = DL_pmi_single;
-          break;
-        default:
-          break;
-        }
-      } else if ((dlsch0 != NULL) && (dlsch1 == NULL))  { // only CW 0 active
-        dlsch0_harq->dl_power_off = 1;
-        dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-        switch (tpmi) {
-        case 0 :
-          dlsch0_harq->mimo_mode   = ALAMOUTI;
-          break;
-        case 1:
-          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
-          dlsch0_harq->pmi_alloc   = pmi_extend(fp,0,0);
-          break;
-        case 2:
-          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
-          dlsch0_harq->pmi_alloc   = pmi_extend(fp,1,0);
-          break;
-        case 3:
-          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
-          dlsch0_harq->pmi_alloc   = pmi_extend(fp,2,0);
-          break;
-        case 4:
-          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
-          dlsch0_harq->pmi_alloc   = pmi_extend(fp,3,0);
-          break;
-        case 5:
-          dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
-          dlsch0_harq->pmi_alloc   = DL_pmi_single;
-          break;
-        case 6:
-          dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
-          dlsch0_harq->pmi_alloc   = DL_pmi_single;
-          break;
-        }
-      } else if ((dlsch0 == NULL) && (dlsch1 != NULL))  {
-          dlsch1_harq->dl_power_off = 1;
-          dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
-          switch (tpmi) {
-          case 0 :
-            dlsch1_harq->mimo_mode   = ALAMOUTI;
-            break;
-          case 1:
-            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING11;
-            dlsch1_harq->pmi_alloc   = pmi_extend(fp,0,0);
-            break;
-          case 2:
-            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1m1;
-            dlsch1_harq->pmi_alloc   = pmi_extend(fp,1,0);
-            break;
-          case 3:
-            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1j;
-            dlsch1_harq->pmi_alloc   = pmi_extend(fp,2,0);
-            break;
-          case 4:
-            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1mj;
-            dlsch1_harq->pmi_alloc   = pmi_extend(fp,3,0);
-            break;
-          case 5:
-            dlsch1_harq->mimo_mode   = PUSCH_PRECODING0;
-            dlsch1_harq->pmi_alloc   = DL_pmi_single;
-            break;
-          case 6:
-            dlsch1_harq->mimo_mode   = PUSCH_PRECODING1;
-            dlsch1_harq->pmi_alloc   = DL_pmi_single;
-            break;
-          }
-        }
-
-    } else if (fp->nb_antenna_ports_eNB == 4) {
-      // fill in later
-    }
-
-    // reset HARQ process if this is the first transmission
-   /* if (dlsch0_harq->round == 0)
-      dlsch0_harq->status = ACTIVE;
-
-    if (dlsch1_harq->round == 0)
-      dlsch1_harq->status = ACTIVE;*/
-    if (dlsch0_harq != NULL)
-      dlsch0->rnti = rnti;
-    if (dlsch1 != NULL)
-      dlsch1->rnti = rnti;
-
-    break;
-
-  case format2A:
-
-    switch (fp->N_RB_DL) {
-
-    case 6:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-        } else {
-          mcs1      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rv1       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-
-    case 25:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-        } else {
-          mcs1      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-
-    case 50:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-        } else {
-          mcs1      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-
-    case 100:
-      if (fp->nb_antenna_ports_eNB == 2) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
-        } else {
-          mcs1      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
-        }
-      } else if (fp->nb_antenna_ports_eNB == 4) {
-        if (frame_type == TDD) {
-          mcs1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
-          tpmi      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
-        } else {
-          mcs1      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
-          mcs2      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
-          rballoc   = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
-          rah       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah;
-          rv1       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1;
-          rv2       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2;
-          harq_pid  = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
-          tbswap    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
-          tpmi    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
-        }
-      } else {
-        LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,fp->nb_antenna_ports_eNB);
-      }
-
-      break;
-    }
-
-
-    if (harq_pid>=8) {
-      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
-      return(-1);
-    }
-
-
-    // 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 (tbswap == 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->subframe_tx[subframe] = 1;
-
-    dlsch0->harq_ids[subframe] = harq_pid;
-    dlsch1->harq_ids[subframe] = harq_pid;
-    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
-
-
-    conv_rballoc(rah,
-                 rballoc,
-                 fp->N_RB_DL,
-                 dlsch0_harq->rb_alloc);
-
-    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
-    dlsch0_harq->nb_rb                               = conv_nprb(rah,
-								 rballoc,
-								 fp->N_RB_DL);
-    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
-
-    if (dlsch0_harq->nb_rb == 0)
-      return(-1);
-
-    dlsch0_harq->mcs       = mcs1;
-    dlsch1_harq->mcs       = mcs2;
-    dlsch0_harq->rvidx     = rv1;
-    dlsch1_harq->rvidx     = rv2;
-
-    // assume both TBs are active
-    dlsch0_harq->Nl        = 1;
-    dlsch1_harq->Nl        = 1;
-    dlsch0->active = 1;
-    dlsch1->active = 1;
-
-
-    // check if either TB is disabled (see 36-213 V11.3 Section )
-    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
-      dlsch0->active = 0;
-    }
-
-    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
-      dlsch1->active = 0;
-    }
-
-   // dlsch0_harq->dl_power_off = 0;
-   // dlsch1_harq->dl_power_off = 0;
-
-
-    if (fp->nb_antenna_ports_eNB == 2) {
-      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-      dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
-
-      if ((dlsch0->active==1) && (dlsch1->active==1)) {
-
-        dlsch0_harq->mimo_mode = LARGE_CDD;
-        dlsch1_harq->mimo_mode = LARGE_CDD;
-        dlsch0_harq->dl_power_off = 1;
-        dlsch1_harq->dl_power_off = 1;
-      } else {
-        dlsch0_harq->mimo_mode   = ALAMOUTI;
-        dlsch1_harq->mimo_mode   = ALAMOUTI;
-      }
-    } else if (fp->nb_antenna_ports_eNB == 4) { // 4 antenna case
-      if ((dlsch0->active==1) && (dlsch1->active==1)) {
-        switch (tpmi) {
-        case 0: // one layer per transport block
-          dlsch0_harq->mimo_mode   = LARGE_CDD;
-          dlsch1_harq->mimo_mode   = LARGE_CDD;
-          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-          dlsch0_harq->dl_power_off = 1;
-          dlsch1_harq->dl_power_off = 1;
-          break;
-
-        case 1: // one-layers on TB 0, two on TB 1
-          dlsch0_harq->mimo_mode   = LARGE_CDD;
-          dlsch1_harq->mimo_mode   = LARGE_CDD;
-          dlsch1_harq->Nl          = 2;
-          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
-          dlsch0_harq->dl_power_off = 1;
-          dlsch1_harq->dl_power_off = 1;
-          break;
-
-        case 2: // two-layers on TB 0, two on TB 1
-          dlsch0_harq->mimo_mode   = LARGE_CDD;
-          dlsch1_harq->mimo_mode   = LARGE_CDD;
-          dlsch0_harq->Nl          = 2;
-          dlsch0_harq->dl_power_off = 1;
-          dlsch1_harq->dl_power_off = 1;
-
-          if (fp->N_RB_DL <= 56) {
-            dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
-            dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
-          } else {
-            LOG_E(PHY,"Add implementation of Table 7.1.7.2.2-1 for two-layer TBS conversion with N_RB_DL > 56\n");
-          }
-
-          break;
-
-        case 3: //
-          LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
-          break;
-        }
-      } else if (dlsch0->active == 1) {
-        switch (tpmi) {
-        case 0: // one layer per transport block
-          dlsch0_harq->mimo_mode   = ALAMOUTI;
-          dlsch1_harq->mimo_mode   = ALAMOUTI;
-          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-          break;
-
-        case 1: // two-layers on TB 0
-          dlsch0_harq->mimo_mode   = LARGE_CDD;
-          dlsch0_harq->Nl          = 2;
-          dlsch0_harq->dl_power_off = 1;
-          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
-          break;
-
-        case 2: // two-layers on TB 0, two on TB 1
-        case 3: //
-          LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
-          break;
-        }
-      } else if (dlsch1->active == 1) {
-        switch (tpmi) {
-        case 0: // one layer per transport block
-          dlsch0_harq->mimo_mode   = ALAMOUTI;
-          dlsch1_harq->mimo_mode   = ALAMOUTI;
-          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
-          break;
-
-        case 1: // two-layers on TB 0
-          dlsch1_harq->mimo_mode   = LARGE_CDD;
-          dlsch1_harq->Nl          = 2;
-          dlsch1_harq->dl_power_off = 1;
-          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
-          break;
-
-        case 2: // two-layers on TB 0, two on TB 1
-        case 3: //
-          LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
-          break;
-        }
-      }
-    } else {
-      LOG_E(PHY,"Illegal number of antennas for eNB %d\n",fp->nb_antenna_ports_eNB);
-    }
-
-    // reset HARQ process if this is the first transmission
-    if ((dlsch0->active==1) && (dlsch0_harq->round == 0))
-      dlsch0_harq->status = ACTIVE;
-
-    if ((dlsch1->active==1) && (dlsch1_harq->round == 0))
-      dlsch1_harq->status = ACTIVE;
-
-    dlsch0->rnti = rnti;
-    dlsch1->rnti = rnti;
-
-
-    //    printf("eNB: Format 2A TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS);
-
-    break;
-
-  case format2B:
-
-    switch (fp->N_RB_DL) {
-
-    case 6:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rv1       = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rv1       = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 25:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2B_5MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_5MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_5MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2B_5MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_5MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_5MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 50:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2B_10MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_10MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_10MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2B_10MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_10MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_10MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 100:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2B_20MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_20MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_20MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2B_20MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2B_20MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2B_20MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-    }
-
-
-    if (harq_pid>=8) {
-      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
-      return(-1);
-    }
-
-
-
-    dlsch0 = dlsch[0];
-    dlsch1 = dlsch[1];
-
-
-    dlsch0->subframe_tx[subframe] = 1;
-
-    dlsch0->harq_ids[subframe] = harq_pid;
-    dlsch1->harq_ids[subframe] = harq_pid;
-    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
-
-
-    dlsch0_harq = dlsch0->harq_processes[harq_pid];
-    dlsch1_harq = dlsch1->harq_processes[harq_pid];
-
-    // Needs to be checked
-    dlsch0_harq->codeword=0;
-    dlsch1_harq->codeword=1;
-
-    conv_rballoc(rah,
-                 rballoc,
-                 fp->N_RB_DL,
-                 dlsch0_harq->rb_alloc);
-
-    dlsch1_harq->rb_alloc[0]     = dlsch0_harq->rb_alloc[0];
-
-    dlsch0_harq->nb_rb           = conv_nprb(rah,
-					     rballoc,
-					     fp->N_RB_DL);
-    dlsch1_harq->nb_rb           = dlsch0_harq->nb_rb;
-
-    dlsch0_harq->mcs       = mcs1;
-    dlsch1_harq->mcs       = mcs2;
-    dlsch0_harq->rvidx     = rv1;
-    dlsch1_harq->rvidx     = rv2;
-
-    // check if either TB is disabled (see 36-213 V8.6 p. 26)
-
-
-    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0))
-      dlsch0_harq->status = DISABLED;
-
-    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0))
-      dlsch1_harq->status = DISABLED;
-
-    dlsch0_harq->Nl        = 1;
-
-
-    if (dlsch0_harq->round == 0) {
-      dlsch0_harq->status = ACTIVE;
-      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
-    }
-
-    dlsch0_harq->mcs         = mcs1;
-
-    if (dlsch0_harq->nb_rb > 0) {
-      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-    } else {
-      dlsch0_harq->TBS = 0;
-    }
-
-    dlsch0->active = 1;
-
-    dlsch0->rnti = rnti;
-    dlsch1->rnti = rnti;
-
-    dlsch0_harq->dl_power_off = 1;
-    dlsch1_harq->dl_power_off = 1;
-
-    break;
-
-  case format2C:
-
-    switch (fp->N_RB_DL) {
-
-    case 6:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rv1       = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rv1       = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 25:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2C_5MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_5MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_5MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2C_5MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_5MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_5MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 50:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2C_10MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_10MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_10MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2C_10MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_10MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_10MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 100:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2C_20MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_20MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_20MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2C_20MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2C_20MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2C_20MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-    }
-
-
-    if (harq_pid>=8) {
-      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
-      return(-1);
-    }
-
-
-
-    dlsch0 = dlsch[0];
-    dlsch1 = dlsch[1];
-
-    dlsch0->subframe_tx[subframe] = 1;
-
-    dlsch0->harq_ids[subframe] = harq_pid;
-    dlsch1->harq_ids[subframe] = harq_pid;
-    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
-
-    dlsch0_harq = dlsch0->harq_processes[harq_pid];
-    dlsch1_harq = dlsch1->harq_processes[harq_pid];
-
-    // Needs to be checked
-    dlsch0_harq->codeword=0;
-    dlsch1_harq->codeword=1;
-
-    conv_rballoc(rah,
-                 rballoc,
-                 fp->N_RB_DL,
-                 dlsch0_harq->rb_alloc);
-    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
-
-    dlsch0_harq->nb_rb                               = conv_nprb(rah,
-								 rballoc,
-								 fp->N_RB_DL);
-    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
-
-    if (dlsch0_harq->nb_rb == 0)
-      return(-1);
-
-    dlsch0_harq->mcs       = mcs1;
-    dlsch1_harq->mcs       = mcs2;
-    dlsch0_harq->rvidx     = rv1;
-    dlsch1_harq->rvidx     = rv2;
-
-    // check if either TB is disabled (see 36-213 V8.6 p. 26)
-
-
-    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
-      dlsch0->active = 0;
-    }
-
-    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
-      dlsch1->active = 0;
-    }
-
-
-
-    if ((dlsch0_harq->round == 0) && (dlsch0->active == 1) ) {
-      dlsch0_harq->status      = ACTIVE;
-      dlsch0_harq->mcs         = mcs1;
-    }
-
-    if ((dlsch1_harq->round == 0) && (dlsch1->active == 1) ) {
-      dlsch1_harq->status      = ACTIVE;
-      dlsch1_harq->mcs         = mcs2;
-    }
-
-    // check TPMI information to compute TBS
-    if (fp->nb_antenna_ports_eNB == 2) {
-      if (dlsch1->active == 1) { // both TBs are active
-        dlsch0_harq->TBS           = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-        dlsch1_harq->TBS           = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
-      } else {
-        dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-      }
-    } else if (fp->nb_antenna_ports_eNB == 4) {
-
-    }
-
-    dlsch0->rnti = rnti;
-    dlsch1->rnti = rnti;
-
-    dlsch0_harq->dl_power_off = 1;
-    dlsch1_harq->dl_power_off = 1;
-
-    break;
-
-  case format2D:
-
-    switch (fp->N_RB_DL) {
-
-    case 6:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rv1       = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rv1       = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 25:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2D_5MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_5MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_5MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2D_5MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_5MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_5MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 50:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2D_10MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_10MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_10MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2D_10MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_10MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_10MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-
-    case 100:
-      if (frame_type == TDD) {
-        mcs1      = ((DCI2D_20MHz_TDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_20MHz_TDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_20MHz_TDD_t *)dci_pdu)->harq_pid;
-      } else {
-        mcs1      = ((DCI2D_20MHz_FDD_t *)dci_pdu)->mcs1;
-        mcs2      = ((DCI2D_20MHz_FDD_t *)dci_pdu)->mcs2;
-        rballoc   = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rballoc;
-        rah       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rah;
-        rv1       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rv1;
-        rv2       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rv2;
-        harq_pid  = ((DCI2D_20MHz_FDD_t *)dci_pdu)->harq_pid;
-      }
-
-      break;
-    }
-
-
-    if (harq_pid>=8) {
-      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
-      return(-1);
-    }
-
-
-
-    dlsch0 = dlsch[0];
-    dlsch1 = dlsch[1];
-
-    dlsch0->subframe_tx[subframe] = 1;
-
-    dlsch0->harq_ids[subframe] = harq_pid;
-    dlsch1->harq_ids[subframe] = harq_pid;
-    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
-
-
-    dlsch0_harq = dlsch0->harq_processes[harq_pid];
-    dlsch1_harq = dlsch1->harq_processes[harq_pid];
-
-    // Needs to be checked
-    dlsch0_harq->codeword=0;
-    dlsch1_harq->codeword=1;
-
-    conv_rballoc(rah,
-                 rballoc,
-                 fp->N_RB_DL,
-                 dlsch0_harq->rb_alloc);
-    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
-
-    dlsch0_harq->nb_rb                               = conv_nprb(rah,
-								 rballoc,
-								 fp->N_RB_DL);
-    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;
-
-    dlsch0_harq->mcs       = mcs1;
-    dlsch1_harq->mcs       = mcs2;
-    dlsch0_harq->rvidx     = rv1;
-    dlsch1_harq->rvidx     = rv2;
-
-    // check if either TB is disabled (see 36-213 V8.6 p. 26)
-
-
-    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0))
-      dlsch0_harq->status = DISABLED;
-
-    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0))
-      dlsch1_harq->status = DISABLED;
-
-    dlsch0_harq->Nl        = 1;
-
-
-    if (dlsch0_harq->round == 0) {
-      dlsch0_harq->status = ACTIVE;
-      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
-    }
-
-    dlsch0_harq->mcs         = mcs1;
-
-    if (dlsch0_harq->nb_rb > 0) {
-      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
-    } else {
-      dlsch0_harq->TBS = 0;
-    }
-
-    dlsch0->active = 1;
-
-    dlsch0->rnti = rnti;
-    dlsch1->rnti = rnti;
-
-    dlsch0_harq->dl_power_off = 1;
-    dlsch1_harq->dl_power_off = 1;
-
-    break;
-
-
-  case format1E_2A_M10PRB:
-
-    harq_pid  = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid;
-
-    if (harq_pid>=8) {
-      LOG_E(PHY,"ERROR: Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid);
-      return(-1);
-    }
-
-    /*
-      tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap;
-      if (tbswap == 0) {
-      dlsch0 = dlsch[0];
-      dlsch1 = dlsch[1];
-      }
-      else{
-      dlsch0 = dlsch[1];
-      dlsch1 = dlsch[0];
-      }
-    */
-    dlsch0 = dlsch[0];
-    dlsch0->subframe_tx[subframe] = 1;
-
-
-    dlsch0->harq_ids[subframe] = harq_pid;
-    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
-    dlsch0_harq = dlsch0->harq_processes[harq_pid];
-       // Needs to be checked
-    dlsch0_harq->codeword=0;
-
-    conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
-                 ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,fp->N_RB_DL,
-                 dlsch0_harq->rb_alloc);
-
-    //dlsch1->rb_alloc[0]                         = dlsch0->rb_alloc[0];
-
-    dlsch0_harq->nb_rb                               = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
-        ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,
-        fp->N_RB_DL);
-    //dlsch1->nb_rb                               = dlsch0->nb_rb;
-
-    dlsch0_harq->mcs       = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
-    //dlsch1_harq->mcs       = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2;
-    dlsch0_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv;
-    //dlsch1_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2;
-
-    // check if either TB is disabled (see 36-213 V8.6 p. 26) --> only for format 2 and 2A
-
-    //if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0))
-    //  dlsch0_harq->status = DISABLED;
-
-    //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0))
-    // dlsch1_harq->status = DISABLED;
-
-    dlsch0_harq->Nl        = 1;
-
-    //dlsch0->layer_index                         = tbswap;
-    //dlsch1->layer_index                         = 1-tbswap;
-
-    // Fix this
-    tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi;
-
-    switch (tpmi) {
-    case 0 :
-      dlsch0_harq->mimo_mode   = ALAMOUTI;
-      break;
-
-    case 1:
-      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
-      dlsch0_harq->pmi_alloc   = pmi_extend(fp,0, 0);
-
-      break;
-
-    case 2:
-      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
-      dlsch0_harq->pmi_alloc   = pmi_extend(fp,1, 0);
-
-      break;
-
-    case 3:
-      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
-      dlsch0_harq->pmi_alloc   = pmi_extend(fp,2, 0);
-
-      break;
-
-    case 4:
-      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
-      dlsch0_harq->pmi_alloc   = pmi_extend(fp,3, 0);
-      break;
-
-    case 5:
-      dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
-      dlsch0_harq->pmi_alloc   = DL_pmi_single;
-      break;
-
-    case 6:
-      dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
-      return(-1);
-      break;
-    }
-
-    //    printf("Set pmi %x (tpmi %d)\n",dlsch0->pmi_alloc,tpmi);
-
-
-    if (fp->nb_antenna_ports_eNB == 1)
-      dlsch0_harq->mimo_mode   = SISO;
-
-    //    dlsch0_harq->Ndi         = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
-    if (dlsch0_harq->round == 0) {
-      dlsch0_harq->status = ACTIVE;
-      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
-    }
-
-    dlsch0_harq->mcs         = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
-
-    if (dlsch0_harq->nb_rb > 0) {
-      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
+      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
+      dci_alloc->dci_length                      = sizeof_DCI0_20MHz_TDD_1_6_t; 
     } else {
-      dlsch0_harq->TBS = 0;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift      = cshift;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC         = TPC;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs         = mcs;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi         = ndi;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping     = hopping;
+      ((DCI0_20MHz_FDD_t *)dci_pdu)->type        = 0;
+      dci_alloc->dci_length                      = sizeof_DCI0_20MHz_FDD_t; 
     }
+    
+      //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc);
+      break;
+      
+  default:
+    LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
+    DevParam (frame_parms->N_RB_DL, 0, 0);
+    break;
+  }
+}
 
-    dlsch0->active = 1;
-
-    dlsch0->rnti = rnti;
-    //dlsch1->rnti = rnti;
+void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) {
 
-    //    dlsch0->dl_power_off = 1;
-    dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off;
-    //dlsch1->dl_power_off = 1;
+  uint8_t harq_pid;
 
-    break;
+  uint8_t UE_id;
 
-  default:
-    LOG_E(PHY,"Unknown DCI format\n");
-    return(-1);
-    break;
-  }
+  AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
+	      "No existing UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti);
 
+  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
+  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
 
-  if (dlsch0_harq) {
-    dlsch0_harq->frame   = frame;
-    dlsch0_harq->subframe = subframe;
-  }
-  if (dlsch1_harq) {
-    dlsch1_harq->frame   = frame;
-    dlsch1_harq->subframe = subframe;
-  }
+  int use_srs = 0;
 
-#ifdef DEBUG_DCI
+  harq_pid = ulsch_pdu->ulsch_pdu_rel8.harq_process_number;
 
-  if (dlsch0) {
-    printf("dlsch0 eNB: dlsch0   %p\n",dlsch0);
-    printf("dlsch0 eNB: rnti     %x\n",dlsch0->rnti);
-    printf("dlsch0 eNB: NBRB     %d\n",dlsch0_harq->nb_rb);
-    printf("dlsch0 eNB: rballoc  %x\n",dlsch0_harq->rb_alloc[0]);
-    printf("dlsch0 eNB: harq_pid %d\n",harq_pid);
-    printf("dlsch0 eNB: round    %d\n",dlsch0_harq->round);
-    printf("dlsch0 eNB: rvidx    %d\n",dlsch0_harq->rvidx);
-    printf("dlsch0 eNB: TBS      %d (NPRB %d)\n",dlsch0_harq->TBS,NPRB);
-    printf("dlsch0 eNB: mcs      %d\n",dlsch0_harq->mcs);
-    printf("dlsch0 eNB: tpmi %d\n",tpmi);
-    printf("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode);
-  }
 
-    if (dlsch1) {
-    printf("dlsch1 eNB: dlsch1   %p\n",dlsch1);
-    printf("dlsch1 eNB: rnti     %x\n",dlsch1->rnti);
-    printf("dlsch1 eNB: NBRB     %d\n",dlsch1_harq->nb_rb);
-    printf("dlsch1 eNB: rballoc  %x\n",dlsch1_harq->rb_alloc[0]);
-    printf("dlsch1 eNB: harq_pid %d\n",harq_pid);
-    printf("dlsch1 eNB: round    %d\n",dlsch1_harq->round);
-    printf("dlsch1 eNB: rvidx    %d\n",dlsch1_harq->rvidx);
-    printf("dlsch1 eNB: TBS      %d (NPRB %d)\n",dlsch1_harq->TBS,NPRB);
-    printf("dlsch1 eNB: mcs      %d\n",dlsch1_harq->mcs);
-    printf("dlsch1 eNB: tpmi %d\n",tpmi);
-    printf("dlsch1 eNB: mimo_mode %d\n",dlsch1_harq->mimo_mode);
-  }
+  ulsch->harq_processes[harq_pid]->frame                                 = frame;
+  ulsch->harq_processes[harq_pid]->subframe                              = subframe;
 
-#endif
+  ulsch->harq_processes[harq_pid]->first_rb                              = ulsch_pdu->ulsch_pdu_rel8.resource_block_start;
+  ulsch->harq_processes[harq_pid]->nb_rb                                 = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
 
-  // compute DL power control parameters
+  AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
 
-  if (dlsch0 != NULL){
-  computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, fp->nb_antenna_ports_eNB);
-  computeRhoB_eNB(pdsch_config_dedicated,&(fp->pdsch_config_common),fp->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
-  }
-  if (dlsch1 != NULL){
-      computeRhoA_eNB(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, fp->nb_antenna_ports_eNB);
-  computeRhoB_eNB(pdsch_config_dedicated,&(fp->pdsch_config_common),fp->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off);
-  }
+  ulsch->harq_processes[harq_pid]->dci_alloc                             = 1;
+  ulsch->harq_processes[harq_pid]->rar_alloc                             = 0;
+  ulsch->harq_processes[harq_pid]->n_DMRS                                = ulsch_pdu->ulsch_pdu_rel8.cyclic_shift_2_for_drms;
+  
+  ulsch->harq_processes[harq_pid]->Nsymb_pusch                           = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
+  ulsch->harq_processes[harq_pid]->srs_active                            = use_srs;
+  
+  //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
+  if(ulsch->harq_processes[harq_pid]->n_DMRS == 0)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 1)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 2)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 3)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 4)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 5)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 6)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
+  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7)
+    ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;
+  
+   
+  LOG_D(PHY,"[eNB %d][PUSCH %d] Programming PUSCH with n_DMRS2 %d (cshift %d) for Frame %d, Subframe %d\n",
+	eNB->Mod_id,harq_pid,ulsch->harq_processes[harq_pid]->n_DMRS2,ulsch->harq_processes[harq_pid]->n_DMRS,
+	frame,subframe);
+  
+  
+  ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version;
+  ulsch->harq_processes[harq_pid]->Qm    = ulsch_pdu->ulsch_pdu_rel8.modulation_type;
+  // Set O_ACK to 0 by default, will be set of DLSCH is scheduled and needs to be 
+  ulsch->harq_processes[harq_pid]->O_ACK         = 0;
 
+  if ((ulsch->harq_processes[harq_pid]->status == SCH_IDLE) ||
+      (ulsch->harq_processes[harq_pid]->ndi    != ulsch_pdu->ulsch_pdu_rel8.new_data_indication)){
+    ulsch->harq_processes[harq_pid]->status        = ACTIVE;
+    
+    ulsch->harq_processes[harq_pid]->TBS           = ulsch_pdu->ulsch_pdu_rel8.size<<3;
+    
+    ulsch->harq_processes[harq_pid]->Msc_initial   = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
+    ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch;
+    ulsch->harq_processes[harq_pid]->round         = 0;
+    ulsch->harq_processes[harq_pid]->ndi           = ulsch_pdu->ulsch_pdu_rel8.new_data_indication;
+    // note here, the CQI bits need to be kept constant as in initial transmission
+    // set to 0 in initial transmission, and don't touch them during retransmissions
+    // will be set if MAC has activated ULSCH_CQI_RI_PDU or ULSCH_CQI_HARQ_RI_PDU
+    ulsch->harq_processes[harq_pid]->Or1           = 0;
+    ulsch->harq_processes[harq_pid]->Or2           = 0;
+  } 
+  else  ulsch->harq_processes[harq_pid]->round++;
 
-  return(0);
+  ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
+  LOG_I(PHY,"Filling ULSCH %x for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
+	ulsch->rnti,
+	frame,
+	subframe,
+	harq_pid,
+	ulsch->harq_processes[harq_pid]->first_rb,
+	ulsch->harq_processes[harq_pid]->nb_rb,
+	ulsch->harq_processes[harq_pid]->rvidx,
+	ulsch->harq_processes[harq_pid]->Qm,
+	ulsch->harq_processes[harq_pid]->TBS,
+	ulsch->harq_processes[harq_pid]->round);  
+  
+  
 }
 
 
+
 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
@@ -6387,6 +4468,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)
     {
@@ -6527,7 +4609,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) {
@@ -6638,22 +4720,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");
@@ -6731,10 +4806,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,
@@ -6755,8 +4890,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)
     {
@@ -6796,13 +4933,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;
@@ -6814,7 +4954,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
@@ -6826,27 +4965,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;
         }
     }
 
@@ -6957,7 +5107,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];
@@ -6971,11 +5120,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,
@@ -7078,6 +5236,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)
@@ -7106,6 +5272,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;
@@ -7137,20 +5306,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,
@@ -7251,6 +5417,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,
@@ -7272,14 +5440,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;
@@ -7327,6 +5492,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;
@@ -7340,9 +5515,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){
@@ -7397,10 +5572,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))
@@ -7415,11 +5593,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);
@@ -7427,18 +5608,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]
@@ -7461,27 +5642,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]
@@ -7502,18 +5689,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,
@@ -7521,6 +5715,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,
@@ -7531,12 +5727,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;
 
@@ -7600,7 +5796,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
@@ -7610,6 +5809,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,
@@ -7660,6 +5861,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,
@@ -7701,7 +5904,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
@@ -7711,6 +5918,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,
@@ -7732,20 +5941,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,
@@ -7760,18 +5968,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;
 
@@ -7819,6 +6029,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,
@@ -7957,11 +6169,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
 
@@ -7971,6 +6187,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;
@@ -7998,36 +6215,34 @@ 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
 
-  #if T_TRACER
+#if T_TRACER
     if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti))
     {
-    T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe), T_INT(0),
-            T_INT(dlsch[0]->rnti), T_INT(dci_format),
-            T_INT(harq_pid),
-            T_INT(dlsch0_harq->mcs),
-            T_INT(dlsch0_harq->TBS));
+      T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe),
+        T_INT(dlsch[0]->rnti), T_INT(dci_format),
+        T_INT(harq_pid),
+        T_INT(dlsch0_harq->mcs),
+        T_INT(dlsch0_harq->TBS));
     }
-  #endif
+#endif
 
 
     // compute DL power control parameters
@@ -8805,7 +7020,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];
@@ -8860,7 +7075,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type;
       } else {
         cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req;
@@ -8869,7 +7084,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type;
       }
 
@@ -8888,7 +7103,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type;
       } else {
         cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req;
@@ -8897,7 +7112,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_5MHz_FDD_t *)dci_pdu)->type;
       }
 
@@ -8916,7 +7131,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type;
       } else {
         cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req;
@@ -8925,7 +7140,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_10MHz_FDD_t *)dci_pdu)->type;
       }
 
@@ -8944,7 +7159,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type;
       } else {
         cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req;
@@ -8953,7 +7168,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ndi     = ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi;
         mcs     = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_20MHz_FDD_t *)dci_pdu)->type;
       }
 
@@ -9612,7 +7827,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;
@@ -9627,7 +7842,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;
     }
@@ -9644,6 +7859,9 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
         ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,
         ulsch->bundling,
         ulsch->harq_processes[harq_pid]->O_ACK);*/
+    LOG_D(PHY,"Setting beta_offset_cqi_times8 to %d, index %d\n",
+	  beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index],
+	  ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index);
 
     ulsch->beta_offset_cqi_times8                = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18;
     ulsch->beta_offset_ri_times8                 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10;
@@ -9688,35 +7906,35 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu,
     if (ue->ulsch_Msg3_active[eNB_id] == 1)
       ue->ulsch_Msg3_active[eNB_id] = 0;
 
-    LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d\n",
+    LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d, cqi_req %d => O %d\n",
         ue->Mod_id,harq_pid,
         proc->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,
-        ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id]);
+	  ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id],cqi_req,ulsch->O);
 
   // 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
@@ -9782,7 +8000,7 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
         TPC     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
         mcs     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type;
       } else {
         cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req;
@@ -9790,7 +8008,7 @@ int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
         TPC     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC;
         mcs     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs;
         rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc;
-        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping;
+        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping;
         //  type    = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type;
       }
       
@@ -10368,7 +8586,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 7a76514fe38f26c5625d98394c3b53596deb1b84..b52ea105a6391c952b968064167c7c7ccec70be3 100644
--- a/openair1/PHY/LTE_TRANSPORT/defs.h
+++ b/openair1/PHY/LTE_TRANSPORT/defs.h
@@ -146,6 +146,8 @@ typedef struct {
   uint32_t cqi_alloc2;
   /// Current Number of RBs
   uint16_t nb_rb;
+  /// Current NDI
+  uint8_t ndi;
   /// downlink power offset field
   uint8_t dl_power_off;
   /// start symbold of pdsch
@@ -319,8 +321,8 @@ typedef struct {
   uint8_t srs_active;
   /// Pointers to 8 HARQ processes for the ULSCH
   LTE_UL_UE_HARQ_t *harq_processes[8];
-  /// Pointer to CQI data
-  uint8_t o[MAX_CQI_BYTES];
+  /// Pointer to CQI data (+1 for 8 bits crc)
+  uint8_t o[1+MAX_CQI_BYTES];
   /// Length of CQI data (bits)
   uint8_t O;
   /// Format of CQI data
@@ -566,6 +568,8 @@ typedef struct {
   uint16_t    n_pucch_3[2];
   /// TDD Bundling/multiplexing flag
   uint8_t     tdd_bundling;
+  /// Received Energy
+  uint32_t stat;
 #ifdef Rel14
   /// non BL/CE, CEmodeA, CEmodeB
   UE_type_t ue_type;
@@ -858,7 +862,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..dfd2b2af5f32648c9704a489b2669fc3b74fcdca 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,24 +510,49 @@ 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)
     {
-      T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id),  T_INT(0), T_INT(frame%1024), T_INT(subframe),
-                               T_INT(avg[0]), T_INT(avg[1]),    T_INT(avg[2]),             T_INT(avg[3]));
+      T(T_UE_PHY_PDSCH_ENERGY, T_INT(eNB_id), T_INT(frame%1024), T_INT(subframe),
+                               T_INT(avg[0]), T_INT(avg[1]),     T_INT(avg[2]),   T_INT(avg[3]));
     }
 #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,
+                       (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,
-                       pdsch_vars[eNB_id]->llr[0],
+                       (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);
@@ -1088,16 +1232,13 @@ int rx_pdsch(PHY_VARS_UE *ue,
   }
 #endif
 
-#if T_TRACER
-  T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(ue->Mod_id), T_INT(frame%1024),
+  T(T_UE_PHY_PDSCH_IQ, T_INT(eNB_id), T_INT(frame%1024),
     T_INT(subframe), T_INT(nb_rb),
     T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_tti),
     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);
 
+  return 0;
 }
 
 //==============================================================================================
@@ -3377,7 +3518,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 +3529,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 +3545,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 +3571,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 +4748,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 +6038,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 +6091,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/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
index 606a9b70980b7ebc046ca0ee3287324903908c03..6024f859c9d3d7838624141ecc36f803566f7259 100644
--- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c
@@ -354,7 +354,7 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint
     }
 
     LOG_D(PHY,"PRACH_IF4p5: CC_id %d : frame %d, subframe %d => %d dB\n",ru->idx,*frame,*subframe,
-	  dB_fixed(signal_energy(&prach_rxsigF[0][0],839)));
+	  dB_fixed(signal_energy((int*)&prach_rxsigF[0][0],839)));
     for (idx=0;idx<ru->num_eNB;idx++) ru->wakeup_prach_eNB(ru->eNB_list[idx],ru,*frame,*subframe);
 
   } else if (*packet_type == IF4p5_PULTICK) {
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..dd04a7d119ae9c9bc4cab88159ed4d46b969ec6e 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++;
@@ -1442,7 +1452,7 @@ void rx_phich(PHY_VARS_UE *ue,
       }
     }
 #if T_TRACER
-    T(T_UE_PHY_ULSCH_UE_NACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ue->Mod_id), T_INT(ulsch->rnti),
+    T(T_UE_PHY_ULSCH_UE_NACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ulsch->rnti),
       T_INT(harq_pid));
 #endif
 
@@ -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);
@@ -1481,7 +1491,7 @@ void rx_phich(PHY_VARS_UE *ue,
     ue->ulsch_Msg3_active[eNB_id] = 0;
 
 #if T_TRACER
-    T(T_UE_PHY_ULSCH_UE_ACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ue->Mod_id), T_INT(ulsch->rnti),
+    T(T_UE_PHY_ULSCH_UE_ACK, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(subframe), T_INT(ulsch->rnti),
       T_INT(harq_pid));
 #endif
 
@@ -1542,7 +1552,7 @@ void generate_phich_top(PHY_VARS_eNB *eNB,
 	  phich->first_rb);
     
     T(T_ENB_PHY_PHICH, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(subframe),
-      T_INT(i), T_INT(0), T_INT(harq_pid),
+      T_INT(-1 /* TODO: rnti */), T_INT(harq_pid),
       T_INT(Ngroup_PHICH), T_INT(NSF_PHICH),
       T_INT(ngroup_PHICH), T_INT(nseq_PHICH),
       T_INT(phich->hi),
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/power_control.c b/openair1/PHY/LTE_TRANSPORT/power_control.c
index 743c16b2f0928b6ff19742443f8aa4766c6f39b4..9421efe52d7857f59c07503110a950a8667ef259 100644
--- a/openair1/PHY/LTE_TRANSPORT/power_control.c
+++ b/openair1/PHY/LTE_TRANSPORT/power_control.c
@@ -52,7 +52,7 @@ double computeRhoA_eNB(PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
     rho_a_dB-=10*log10(2);
 
   if(n_antenna_port==4) // see TS 36.213 Section 5.2
-    rho_a_dB=+10*log10(2);
+    rho_a_dB+=10*log10(2);
 
   sqrt_rho_a_lin= pow(10,(0.05*rho_a_dB));
 
diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c
index dfa5fb315a6c66bae84dbcc4e089806ebd4b6b53..aa9070f6e52f45161df5088931fc1c37c439db42 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach.c
@@ -491,13 +491,10 @@ int is_prach_subframe0(LTE_DL_FRAME_PARMS *frame_parms,uint8_t prach_ConfigIndex
     //implement Table 5.7.1-2 from 36.211 (Rel-10, p.41)
     if ((((frame&1) == 1) && (subframe < 9)) ||
         (((frame&1) == 0) && (subframe == 9)))  // This is an odd frame, ignore even-only PRACH frames
-
-      /*
       if (((prach_ConfigIndex&0xf)<3) || // 0,1,2,16,17,18,32,33,34,48,49,50
           ((prach_ConfigIndex&0x1f)==18) || // 18,50
           ((prach_ConfigIndex&0xf)==15))   // 15,47
         return(0);
-      */
 
     switch (prach_ConfigIndex&0x1f) {
     case 0:
@@ -1096,9 +1093,9 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1
 
 void rx_prach0(PHY_VARS_eNB *eNB,
 	       RU_t *ru,
-	       int16_t *max_preamble,
-	       int16_t *max_preamble_energy,
-	       int16_t *max_preamble_delay,
+	       uint16_t *max_preamble,
+	       uint16_t *max_preamble_energy,
+	       uint16_t *max_preamble_delay,
 	       uint16_t Nf, 
 	       uint8_t tdd_mapindex
 #ifdef Rel14
@@ -1134,8 +1131,6 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   uint16_t d_start=0;
   uint16_t numshift=0;
   uint16_t *prach_root_sequence_map;
-  uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
-  uint16_t N_ZC = (prach_fmt <4)?839:139;
   uint8_t not_found;
   int k;
   uint16_t u;
@@ -1149,8 +1144,8 @@ void rx_prach0(PHY_VARS_eNB *eNB,
   int16_t levdB;
   int fft_size,log2_ifft_size;
   int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32)));
-  int32_t *prach_ifft;
-  int32_t **prach_ifftp;
+  int32_t *prach_ifft=(int32_t*)NULL;
+  int32_t **prach_ifftp=(int32_t **)NULL;
 #ifdef Rel14
   int prach_ifft_cnt=0;
 #endif
@@ -1201,6 +1196,8 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     }
 
   int16_t *prach[nb_rx];
+  uint8_t prach_fmt = get_prach_fmt(prach_ConfigIndex,frame_type);
+  uint16_t N_ZC = (prach_fmt <4)?839:139;
   
   if (eNB) {
 #ifdef Rel14
@@ -1209,7 +1206,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
       frame               = eNB->proc.frame_prach_br;
       subframe            = eNB->proc.subframe_prach_br;
       prachF              = eNB->prach_vars_br.prachF;
-      rxsigF              = eNB->prach_vars_br.rxsigF;
+      rxsigF              = eNB->prach_vars_br.rxsigF[ce_level];
 #ifdef PRACH_DEBUG
       if ((frame&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach (br_flag %d, ce_level %d) for frame %d subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d, rootSequenceIndex %d, repetition number %d,numRepetitionsPrePreambleAttempt %d\n",
 				   br_flag,ce_level,frame,subframe,
@@ -1226,7 +1223,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
         frame             = eNB->proc.frame_prach;
         subframe          = eNB->proc.subframe_prach;
         prachF            = eNB->prach_vars.prachF;
-        rxsigF            = eNB->prach_vars.rxsigF;
+        rxsigF            = eNB->prach_vars.rxsigF[0];
 #ifdef PRACH_DEBUG
         //if ((frame&1023) < 20) LOG_I(PHY,"PRACH (eNB) : running rx_prach for subframe %d, prach_FreqOffset %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset,prach_ConfigIndex,rootSequenceIndex);
 #endif
@@ -1485,7 +1482,7 @@ void rx_prach0(PHY_VARS_eNB *eNB,
     return;
   } else if (eNB!=NULL) {
 
-    en = dB_fixed(signal_energy(&rxsigF[0][0],840));
+    en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
 #ifdef PRACH_DEBUG
     if ((en > 60)&&(br_flag==1)) LOG_I(PHY,"PRACH (br_flag %d,ce_level %d, n_ra_prb %d, k %d): Frame %d, Subframe %d => %d dB\n",br_flag,ce_level,n_ra_prb,k,eNB->proc.frame_rx,eNB->proc.subframe_rx,en);
 #endif
@@ -1698,9 +1695,9 @@ void rx_prach0(PHY_VARS_eNB *eNB,
 	    *max_preamble_energy  = levdB;
 	    *max_preamble_delay   = ((i*fft_size)>>log2_ifft_size)*update_TA/update_TA2;
 	    *max_preamble         = preamble_index;
-	    //#ifdef PRACH_DEBUG
-	    if ((en>60) && (br_flag==1)) LOG_I(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",frame,subframe,*max_preamble_energy,*max_preamble_delay,*max_preamble,br_flag,ce_level,levdB,lev);
-	    //#endif
+#ifdef PRACH_DEBUG
+	    if ((en>60) && (br_flag==1)) LOG_D(PHY,"frame %d, subframe %d : max_preamble_energy %d, max_preamble_delay %d, max_preamble %d (br_flag %d,ce_level %d, levdB %d, lev %d)\n",frame,subframe,*max_preamble_energy,*max_preamble_delay,*max_preamble,br_flag,ce_level,levdB,lev);
+#endif
 	  }
 	}
 
diff --git a/openair1/PHY/LTE_TRANSPORT/proto.h b/openair1/PHY/LTE_TRANSPORT/proto.h
index f69a22419c900ce26a87b04cbfb7cefd36f9978c..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,
@@ -1656,12 +1715,12 @@ int generate_ue_dlsch_params_from_dci(int frame,
                                       uint8_t beamforming_mode,
                                       uint16_t tc_rnti);
 
-int fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
+void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,
 			eNB_rxtx_proc_t *proc,
 			DCI_ALLOC_t *dci_alloc,
 			nfapi_dl_config_dci_dl_pdu *pdu);
 
-int fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu);
+void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu);
 
 void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
 	      nfapi_hi_dci0_dci_pdu *pdu);
@@ -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,28 +1760,28 @@ 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,
                                        uint8_t use_srs);
 
 
-void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id);
+void dump_ulsch(PHY_VARS_eNB *phy_vars_eNB,int frame, int subframe, uint8_t UE_id);
 
 int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci);
 
@@ -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 7c82829e84fdbc09af132941d9bee3bc2bce7af7..afa15aba0f17d61e3472e258e458c3dad6d5a2bd 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -506,7 +506,11 @@ void generate_pucch1x(int32_t **txdataF,
             }
 
             break;
-
+	  case pucch_format1b_csA2:
+	  case pucch_format1b_csA3:
+	  case pucch_format1b_csA4:
+	    AssertFatal(1==0,"PUCCH format 1b_csX not supported yet\n");
+	    break;
           case pucch_format2:
           case pucch_format2a:
           case pucch_format2b:
@@ -1171,10 +1175,10 @@ uint16_t pucchfmt3_subCarrierDeMapping( PHY_VARS_eNB *eNB,
                 if (carrier_offset==frame_parms->ofdm_symbol_size)
                     carrier_offset = 0;
                 
-                #ifdef DEBUG_PUCCH_RX
+		/*                #ifdef DEBUG_PUCCH_RX
                     LOG_D(PHY,"[eNB] PUCCH subframe %d (%d,%d,%d,%d) : (%d,%d)\n",subframe,l,k,carrier_offset,m,
                     SubCarrierDeMapData[aa][l][k][0],SubCarrierDeMapData[aa][l][k][1]);
-                #endif
+		    #endif*/
             }
         }
     }
@@ -1786,12 +1790,9 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
   LTE_eNB_COMMON *common_vars                        = &eNB->common_vars;
   LTE_DL_FRAME_PARMS *frame_parms                    = &eNB->frame_parms;
   //  PUCCH_CONFIG_DEDICATED *pucch_config_dedicated = &eNB->pucch_config_dedicated[UE_id];
-  int8_t sigma2_dB                                   = eNB->measurements.n0_subband_power_tot_dB[0]-10;
-  uint32_t *Po_PUCCH                                 = &(eNB->UE_stats[UE_id].Po_PUCCH);
-  int32_t *Po_PUCCH_dBm                              = &(eNB->UE_stats[UE_id].Po_PUCCH_dBm);
-  uint32_t *Po_PUCCH1_below                          = &(eNB->UE_stats[UE_id].Po_PUCCH1_below);
-  uint32_t *Po_PUCCH1_above                          = &(eNB->UE_stats[UE_id].Po_PUCCH1_above);
-  int32_t *Po_PUCCH_update                           = &(eNB->UE_stats[UE_id].Po_PUCCH_update);
+
+  int8_t sigma2_dB                                   = 20;//eNB->measurements.n0_subband_power_tot_dB[0]-10;
+
   uint32_t u,v,n,aa;
   uint32_t z[12*14];
   int16_t *zptr;
@@ -1806,9 +1807,13 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
   int16_t tmp_re,tmp_im,W_re=0,W_im=0;
   int16_t *rxptr;
   uint32_t symbol_offset;
-  int16_t stat_ref_re,stat_ref_im,*cfo,chest_re,chest_im;
+  int16_t stat_ref_re,stat_ref_im,*cfo;
+  int16_t chest0_re[NB_ANTENNAS_RX][12],chest0_im[NB_ANTENNAS_RX][12];
+  int16_t chest1_re[NB_ANTENNAS_RX][12],chest1_im[NB_ANTENNAS_RX][12];
+  int32_t chest_mag;
   int32_t stat_re=0,stat_im=0;
   uint32_t stat,stat_max=0;
+  uint8_t log2_maxh;
 
   uint8_t deltaPUCCH_Shift          = frame_parms->pucch_config_common.deltaPUCCH_Shift;
   uint8_t NRB2                      = frame_parms->pucch_config_common.nRB_CQI;
@@ -2056,12 +2061,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)],
@@ -2135,8 +2140,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
@@ -2145,11 +2151,12 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
     LOG_I(PHY,"[eNB] PUCCH fmt1:  stat_max : %d, sigma2_dB %d (%d, %d), phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,eNB->measurements.n0_subband_power_tot_dBm[6],pucch1_thres,phase_max);
 #endif
 
+    
     eNB->pucch1_stats[UE_id][(subframe<<10)+eNB->pucch1_stats_cnt[UE_id][subframe]] = stat_max;
     eNB->pucch1_stats_thres[UE_id][(subframe<<10)+eNB->pucch1_stats_cnt[UE_id][subframe]] = sigma2_dB+pucch1_thres;
     eNB->pucch1_stats_cnt[UE_id][subframe] = (eNB->pucch1_stats_cnt[UE_id][subframe]+1)&1023;
 
-    T(T_ENB_PHY_PUCCH_1_ENERGY, T_INT(eNB->Mod_id), T_INT(UE_id), T_INT(frame), T_INT(subframe),
+    T(T_ENB_PHY_PUCCH_1_ENERGY, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UE_id].rnti), T_INT(frame), T_INT(subframe),
       T_INT(stat_max), T_INT(sigma2_dB+pucch1_thres));
 
     /*
@@ -2165,15 +2172,10 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
     // This is a moving average of the PUCCH1 statistics conditioned on being above or below the threshold
     if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  {
       *payload = 1;
-      *Po_PUCCH1_above = ((*Po_PUCCH1_above<<9) + (stat_max<<9)+1024)>>10;
-      //LOG_I(PHY,"[eNB] PUCCH fmt1:  stat_max : %d, sigma2_dB %d (%d, %d), phase_max : %d\n",dB_fixed(stat_max),sigma2_dB,eNB->PHY_measurements_eNB[0].n0_power_tot_dBm,pucch1_thres,phase_max);
     }
     else {
       *payload = 0;
-      *Po_PUCCH1_below = ((*Po_PUCCH1_below<<9) + (stat_max<<9)+1024)>>10;
     }
-    //printf("[eNB] PUCCH fmt1:  stat_max : %d, sigma2_dB %d (I0 %d dBm, thres %d), Po_PUCCH1_below/above : %d / %d\n",dB_fixed(stat_max),sigma2_dB,eNB->measurements[0].n0_subband_power_tot_dBm[6],pucch1_thres,dB_fixed(*Po_PUCCH1_below),dB_fixed(*Po_PUCCH1_above));
-    *Po_PUCCH_update = 1;
     if (UE_id==0) {
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SR_ENERGY,dB_fixed(stat_max));
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SR_THRES,sigma2_dB+pucch1_thres);
@@ -2184,11 +2186,15 @@ 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++) {
         for (re=0; re<12; re++) {
+
+	  // compute received energy first slot, seperately for data and reference
+	  // by coherent combining across symbols but not resource elements
+	  // Note: assumption is that channel is stationary over symbols in slot after CFO
           stat_re=0;
           stat_im=0;
           stat_ref_re=0;
@@ -2214,9 +2220,15 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
                   stat_re,stat_im);
 #endif
           }
+	  // this is total energy received, summed over data and reference
+	  stat += ((((stat_re*stat_re)) + ((stat_im*stat_im)) +
+		    ((stat_ref_re*stat_ref_re)) + ((stat_ref_im*stat_ref_im)))/nsymb);
 
-
-
+	  // now second slot
+	  stat_re=0;
+	  stat_im=0;
+          stat_ref_re=0;
+          stat_ref_im=0;
 
           for (l2=0,l=(nsymb>>1); l<(nsymb-1); l++,l2++) {
             if ((l2<2) || ((l2>(nsymb>>1) - 3)) ) {  // data symbols
@@ -2264,116 +2276,123 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 
     stat_re=0;
     stat_im=0;
-    //    printf("PUCCH1A : Po_PUCCH before %d dB (%d)\n",dB_fixed(*Po_PUCCH),*Po_PUCCH);
-    *Po_PUCCH = ((*Po_PUCCH>>1) + ((stat_max)>>1));
-    *Po_PUCCH_dBm = dB_fixed(*Po_PUCCH/frame_parms->N_RB_UL) - eNB->rx_total_gain_dB;
-    *Po_PUCCH_update = 1;
-    /*
-    printf("PUCCH1A : stat_max %d (%d,%d,%d) => Po_PUCCH %d\n",
-	   dB_fixed(stat_max),
-	   pucch1_thres+sigma2_dB,
-	   pucch1_thres,
-	   sigma2_dB,
-	   dB_fixed(*Po_PUCCH));
-    */
+
     // Do detection now
     if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  {//
 
-
-      *Po_PUCCH = ((*Po_PUCCH*1023) + stat_max)>>10;
-
       chL = (nsymb>>1)-4;
+      chest_mag=0;
+      cfo =  (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase_max] : &cfo_pucch_ep[12*phase_max];
 
       for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+	// channel estimates first
         for (re=0; re<12; re++) {
-          chest_re=0;
-          chest_im=0;
-          cfo =  (frame_parms->Ncp==0) ? &cfo_pucch_np[14*phase_max] : &cfo_pucch_ep[12*phase_max];
 
           // channel estimate for first slot
+          chest0_re[aa][re]=0;
+          chest0_im[aa][re]=0;
+	  for (l=2; l<(nsymb>>1)-2; l++) {
+	    off=(re<<1) + (24*l);
+	    chest0_re[aa][re] += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/chL;
+	    chest0_im[aa][re] += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/chL;
+	  }	    
+	  
+
+          // channel estimate for second slot
+	  chest1_re[aa][re]=0;
+	  chest1_im[aa][re]=0;
           for (l=2; l<(nsymb>>1)-2; l++) {
-            off=(re<<1) + (24*l);
-            chest_re += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/chL;
-	    chest_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/chL;
+            off=(re<<1) + (24*l) + (nsymb>>1)*24;
+            chest1_re[aa][re] += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/chL;
+	    chest1_im[aa][re] += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/chL;
           }
+	  chest_mag = max(chest_mag,(chest0_re[aa][re]*chest0_re[aa][re]) + (chest0_im[aa][re]*chest0_im[aa][re]));
+	  chest_mag = max(chest_mag,(chest1_re[aa][re]*chest1_re[aa][re]) + (chest1_im[aa][re]*chest1_im[aa][re]));
 
+	}
+      }
+      log2_maxh = log2_approx(chest_mag)/2;
 #ifdef DEBUG_PUCCH_RX
-          printf("[eNB] PUCCH subframe %d l %d re %d chest1 => (%d,%d)\n",subframe,l,re,
-                chest_re,chest_im);
+      printf("PUCCH 1A: log2_maxh %d\n",log2_maxh);
 #endif
+	// now do channel matched filter
+      for (aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
+	for (re=0; re<12; re++) {
 
+#ifdef DEBUG_PUCCH_RX
+          printf("[eNB] PUCCH subframe %d chest0[%d][%d] => (%d,%d)\n",subframe,aa,re,
+                chest0_re[aa][re],chest0_im[aa][re]);
+#endif
+	  // first slot, left of RS    
           for (l=0; l<2; l++) {
             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*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh));
+            stat_im += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh));
             off+=2;
 #ifdef DEBUG_PUCCH_RX
-            printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,re,
-                  rxcomp[aa][off],rxcomp[aa][1+off],
-                  cfo[l<<1],cfo[1+(l<<1)],
-                  stat_re,stat_im);
+            printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
+		   rxcomp[aa][off],rxcomp[aa][1+off],
+		   cfo[l<<1],cfo[1+(l<<1)],
+		   tmp_re,tmp_im,
+		   stat_re,stat_im);
 #endif
-          }
-
+	  }
+	  // first slot, right of RS
           for (l=(nsymb>>1)-2; l<(nsymb>>1); l++) {
             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*chest0_re[aa][re])>>log2_maxh) + ((tmp_im*chest0_im[aa][re])>>log2_maxh));
+            stat_im += (((tmp_re*chest0_im[aa][re])>>log2_maxh) - ((tmp_im*chest0_re[aa][re])>>log2_maxh));
             off+=2;
 #ifdef DEBUG_PUCCH_RX
-            printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,re,
-                  rxcomp[aa][off],rxcomp[aa][1+off],
-                  cfo[l<<1],cfo[1+(l<<1)],
-                  stat_re,stat_im);
+            printf("[eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
+		   rxcomp[aa][off],rxcomp[aa][1+off],
+		   cfo[l<<1],cfo[1+(l<<1)],
+		   tmp_re,tmp_im,
+		   stat_re,stat_im);
 #endif
-          }
-
-          chest_re=0;
-          chest_im=0;
-
-          // channel estimate for second slot
-          for (l=2; l<(nsymb>>1)-2; l++) {
-            off=(re<<1) + (24*l) + (nsymb>>1)*24;
-            chest_re += (((rxcomp[aa][off]*(int32_t)cfo[l<<1])>>15)     - ((rxcomp[aa][1+off]*(int32_t)cfo[1+(l<<1)])>>15))/chL;
-	    chest_im += (((rxcomp[aa][off]*(int32_t)cfo[1+(l<<1)])>>15) + ((rxcomp[aa][1+off]*(int32_t)cfo[(l<<1)])>>15))/chL;
-          }
+	  }
+	  
+      
 
 #ifdef DEBUG_PUCCH_RX
-          printf("[eNB] PUCCH subframe %d l %d re %d chest2 => (%d,%d)\n",subframe,l,re,
-                chest_re,chest_im);
+          printf("[eNB] PUCCH subframe %d chest1[%d][%d] => (%d,%d)\n",subframe,aa,re,
+                chest0_re[aa][re],chest0_im[aa][re]);
 #endif
-
+	  // second slot, left of RS    	  
           for (l=0; l<2; l++) {
-            off=(re<<1) + (24*l) + (nsymb>>1)*24;
-            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;
+	    off=(re<<1) + (24*l) + (nsymb>>1)*24;
+	    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*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh));
+            stat_im += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh));
             off+=2;
 #ifdef DEBUG_PUCCH_RX
-            printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,re,
-                  rxcomp[aa][off],rxcomp[aa][1+off],
-                  cfo[l<<1],cfo[1+(l<<1)],
-                  stat_re,stat_im);
+            printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
+		   rxcomp[aa][off],rxcomp[aa][1+off],
+		   cfo[l<<1],cfo[1+(l<<1)],
+		   tmp_re,tmp_im,
+		   stat_re,stat_im);
 #endif
           }
 
+	  // second slot, right of RS    	  
           for (l=(nsymb>>1)-2; l<(nsymb>>1)-1; l++) {
             off=(re<<1) + (24*l) + (nsymb>>1)*24;
             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*chest1_re[aa][re])>>log2_maxh) + ((tmp_im*chest1_im[aa][re])>>log2_maxh));
+            stat_im += (((tmp_re*chest1_im[aa][re])>>log2_maxh) - ((tmp_im*chest1_re[aa][re])>>log2_maxh));
             off+=2;
 #ifdef DEBUG_PUCCH_RX
-            printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d)\n",subframe,l,re,
-                  rxcomp[aa][off],rxcomp[aa][1+off],
-                  cfo[l<<1],cfo[1+(l<<1)],
-                  stat_re,stat_im);
+            printf("[PHY][eNB] PUCCH subframe %d (%d,%d) => (%d,%d) x (%d,%d) : (%d,%d) => (%d,%d)\n",subframe,l,re,
+		   rxcomp[aa][off],rxcomp[aa][1+off],
+		   cfo[l<<1],cfo[1+(l<<1)],
+		   tmp_re,tmp_im,
+		   stat_re,stat_im);
 #endif
           }
 
@@ -2384,31 +2403,31 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
         } //re
       } // aa
 
-#ifdef DEBUG_PUCCH_RX
+
       LOG_I(PHY,"PUCCH 1a/b: subframe %d : stat %d,%d (pos %d)\n",subframe,stat_re,stat_im,
 	    (subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe]));
-#endif
-
-	eNB->pucch1ab_stats[UE_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_re);
-	eNB->pucch1ab_stats[UE_id][(subframe<<11) + 1+2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_im);
-	eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023;
+      LOG_I(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);      
+      
+      eNB->pucch1ab_stats[UE_id][(subframe<<11) + 2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_re);
+      eNB->pucch1ab_stats[UE_id][(subframe<<11) + 1+2*(eNB->pucch1ab_stats_cnt[UE_id][subframe])] = (stat_im);
+      eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023;
 
       /* frame not available here - set to -1 for the moment */
-      T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(eNB->Mod_id), T_INT(UE_id), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im));
+      T(T_ENB_PHY_PUCCH_1AB_IQ, T_INT(eNB->Mod_id), T_INT(eNB->uci_vars[UE_id].rnti), T_INT(-1), T_INT(subframe), T_INT(stat_re), T_INT(stat_im));
 
-	  
       *payload = (stat_re<0) ? 1 : 2; // 1 == ACK, 2 == NAK
 
       if (fmt==pucch_format1b)
-        *(1+payload) = (stat_im<0) ? 1 : 0;
+        *(1+payload) = (stat_im<0) ? 1 : 2;
     } else { // insufficient energy on PUCCH so NAK
+      LOG_D(PHY,"PUCCH 1a/b: subframe %d : sigma2_dB %d, stat_max %d, pucch1_thres %d\n",subframe,sigma2_dB,dB_fixed(stat_max),pucch1_thres);
       *payload = 4;  // DTX
       ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[0] = (int16_t)(stat_re);
       ((int16_t*)&eNB->pucch1ab_stats[UE_id][(subframe<<10) + (eNB->pucch1ab_stats_cnt[UE_id][subframe])])[1] = (int16_t)(stat_im);
       eNB->pucch1ab_stats_cnt[UE_id][subframe] = (eNB->pucch1ab_stats_cnt[UE_id][subframe]+1)&1023;
 
       if (fmt==pucch_format1b)
-        *(1+payload) = 6;
+        *(1+payload) = 4;
     }
   } else {
     LOG_E(PHY,"[eNB] PUCCH fmt2/2a/2b not supported\n");
@@ -2494,45 +2513,3 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
   return((int32_t)stat_max);
 
 }
-
-
-int32_t rx_pucch_emul(PHY_VARS_eNB *eNB,
-		      eNB_rxtx_proc_t *proc,
-                      uint8_t UE_index,
-                      PUCCH_FMT_t fmt,
-                      uint8_t n1_pucch_sel,
-                      uint8_t *payload)
-
-{
-  uint8_t UE_id;
-  uint16_t rnti;
-  int subframe = proc->subframe_rx;
-  uint8_t CC_id = eNB->CC_id;
-
-  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)
-      break;
-  }
-
-  if (UE_id==NB_UE_INST) {
-    LOG_W(PHY,"rx_pucch_emul: Didn't find UE with rnti %x\n",rnti);
-    return(-1);
-  }
-
-  if (fmt == pucch_format1) {
-    payload[0] = PHY_vars_UE_g[UE_id][CC_id]->sr[subframe];
-  } else if (fmt == pucch_format1a) {
-    payload[0] = PHY_vars_UE_g[UE_id][CC_id]->pucch_payload[0];
-  } else if (fmt == pucch_format1b) {
-    payload[0] = PHY_vars_UE_g[UE_id][CC_id]->pucch_payload[0];
-    payload[1] = PHY_vars_UE_g[UE_id][CC_id]->pucch_payload[1];
-  } else
-    LOG_E(PHY,"[eNB] Frame %d: Can't handle formats 2/2a/2b\n",proc->frame_rx);
-
-  if (PHY_vars_UE_g[UE_id][CC_id]->pucch_sel[subframe] == n1_pucch_sel)
-    return(99);
-  else
-    return(0);
-}
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 7d850c7566da1190e84fe99a2379de3aba81069c..206eb61fc21be18cbfc47e0dd5dd07b33de5b2c3 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -226,7 +226,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
   LTE_UL_eNB_HARQ_t *ulsch_harq = ulsch->harq_processes[harq_pid];
   int Q_m = ulsch_harq->Qm;
   int G = ulsch_harq->G;
-  uint32_t E;
+  uint32_t E=0;
   uint32_t Gp,GpmodC,Nl=1;
   uint32_t C = ulsch_harq->C;
 
@@ -273,8 +273,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) {
     else if (Kr_bytes <= 768)
       iind = 123 + ((Kr_bytes-256)>>3);
     else {
-      LOG_E(PHY,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
-      return(-1);
+      AssertFatal(1==0,"ulsch_decoding: Illegal codeword size %d!!!\n",Kr_bytes);
     }
 
     // This is stolen from rate-matching algorithm to get the value of E
@@ -865,7 +864,6 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   unsigned int Qprime_ACK,Qprime_RI,len_ACK=0,len_RI=0;
   //  uint8_t q_ACK[MAX_ACK_PAYLOAD],q_RI[MAX_RI_PAYLOAD];
   int metric,metric_new;
-  uint8_t o_flip[8];
   uint32_t x1, x2, s=0;
   int16_t ys,c;
   uint32_t wACK_idx;
@@ -873,7 +871,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   int16_t y[6*14*1200] __attribute__((aligned(32)));
   uint8_t ytag[14*1200];
   //  uint8_t ytag2[6*14*1200],*ytag2_ptr;
-  int16_t cseq[6*14*1200];
+  int16_t cseq[6*14*1200] __attribute__((aligned(32)));
   int off;
 
   int subframe = proc->subframe_rx;
@@ -954,7 +952,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   }
 
   AssertFatal(sumKr>0,
-	      "[eNB %d] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
+	      "[eNB] ulsch_decoding.c: FATAL sumKr is 0! (Nid_cell %d, rnti %x, x2 %x): harq_pid %d round %d, RV %d, O_RI %d, O_ACK %d, G %d, subframe %d\n",
 	      frame_parms->Nid_cell,ulsch->rnti,x2,
 	      harq_pid,
 	      ulsch_harq->round,
@@ -1562,29 +1560,12 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
                                 &ulsch_harq->o_d[96],
                                 &ulsch_harq->o_w[0]);
 
-    memset(o_flip,0,1+((8+ulsch_harq->Or1)/8));
-    phy_viterbi_lte_sse2(ulsch_harq->o_d+96,o_flip,8+ulsch_harq->Or1);
+    memset(ulsch_harq->o,0,(7+8+ulsch_harq->Or1) / 8);
+    phy_viterbi_lte_sse2(ulsch_harq->o_d+96,ulsch_harq->o,8+ulsch_harq->Or1);
 
-    if (extract_cqi_crc(o_flip,ulsch_harq->Or1) == (crc8(o_flip,ulsch_harq->Or1)>>24))
+    if (extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1) == (crc8(ulsch_harq->o,ulsch_harq->Or1)>>24))
       ulsch_harq->cqi_crc_status = 1;
 
-    if (ulsch->harq_processes[harq_pid]->Or1<=32) {
-      ulsch_harq->o[3] = o_flip[0] ;
-      ulsch_harq->o[2] = o_flip[1] ;
-      ulsch_harq->o[1] = o_flip[2] ;
-      ulsch_harq->o[0] = o_flip[3] ;
-    } else {
-      ulsch_harq->o[7] = o_flip[0] ;
-      ulsch_harq->o[6] = o_flip[1] ;
-      ulsch_harq->o[5] = o_flip[2] ;
-      ulsch_harq->o[4] = o_flip[3] ;
-      ulsch_harq->o[3] = o_flip[4] ;
-      ulsch_harq->o[2] = o_flip[5] ;
-      ulsch_harq->o[1] = o_flip[6] ;
-      ulsch_harq->o[0] = o_flip[7] ;
-
-    }
-
 #ifdef DEBUG_ULSCH_DECODING
     printf("ulsch_decoding: Or1=%d\n",ulsch_harq->Or1);
 
@@ -1592,9 +1573,9 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
       printf("ulsch_decoding: O[%d] %d\n",i,ulsch_harq->o[i]);
 
     if (ulsch_harq->cqi_crc_status == 1)
-      printf("RX CQI CRC OK (%x)\n",extract_cqi_crc(o_flip,ulsch_harq->Or1));
+      printf("RX CQI CRC OK (%x)\n",extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1));
     else
-      printf("RX CQI CRC NOT OK (%x)\n",extract_cqi_crc(o_flip,ulsch_harq->Or1));
+      printf("RX CQI CRC NOT OK (%x)\n",extract_cqi_crc(ulsch_harq->o,ulsch_harq->Or1));
 
 #endif
   }
@@ -1997,7 +1978,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/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
index 1c947949a71b555f9e6dc2db28a634b6186bb563..0a7d7b1a21f76ce8d3ad8622edb1ec2c68fe93f9 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
@@ -1266,7 +1266,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB,
 
   llrp = (int16_t*)&pusch_vars->llr[0];
 
-  T(T_ENB_PHY_PUSCH_IQ, T_INT(0), T_INT(UE_id), T_INT(proc->frame_rx),
+  T(T_ENB_PHY_PUSCH_IQ, T_INT(0), T_INT(ulsch[UE_id]->rnti), T_INT(proc->frame_rx),
     T_INT(subframe), T_INT(ulsch[UE_id]->harq_processes[harq_pid]->nb_rb),
     T_INT(frame_parms->N_RB_UL), T_INT(frame_parms->symbols_per_tti),
     T_BUFFER(pusch_vars->rxdataF_comp[0],
@@ -1329,23 +1329,21 @@ void rx_ulsch_emul(PHY_VARS_eNB *eNB,
 }
 
 
- void dump_ulsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id)
-{
+ void dump_ulsch(PHY_VARS_eNB *eNB,int frame,int subframe,uint8_t UE_id) {
   
   uint32_t nsymb = (eNB->frame_parms.Ncp == 0) ? 14 : 12;
   uint8_t harq_pid;
-  int subframe = proc->subframe_rx;
 
-  harq_pid = subframe2harq_pid(&eNB->frame_parms,proc->frame_rx,subframe);
+  harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
 
-  printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,
+  printf("Dumping ULSCH in subframe %d with harq_pid %d, for NB_rb %d, TBS %d, Qm %d, N_symb %d\n", 
+	 subframe,harq_pid,eNB->ulsch[UE_id]->harq_processes[harq_pid]->nb_rb,
          eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS,eNB->ulsch[UE_id]->harq_processes[harq_pid]->Qm,
          eNB->ulsch[UE_id]->harq_processes[harq_pid]->Nsymb_pusch);
   //#ifndef OAI_EMU
   write_output("/tmp/ulsch_d.m","ulsch_dseq",&eNB->ulsch[UE_id]->harq_processes[harq_pid]->d[0][96],
                eNB->ulsch[UE_id]->harq_processes[harq_pid]->Kplus*3,1,0);
   if (eNB->common_vars.rxdata) write_output("/tmp/rxsig0.m","rxs0", &eNB->common_vars.rxdata[0][0],eNB->frame_parms.samples_per_tti*10,1,1);
-
   
   if (eNB->frame_parms.nb_antennas_rx>1)
     if (eNB->common_vars.rxdata) write_output("/tmp/rxsig1.m","rxs1", &eNB->common_vars.rxdata[1][0],eNB->frame_parms.samples_per_tti*10,1,1);
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/MODULATION/slot_fep_ul.c b/openair1/PHY/MODULATION/slot_fep_ul.c
index cf586dec1a9ddf7792e134912610c07bdabe3756..bbf29508745a9ec68c5644f85322735ac4337a85 100644
--- a/openair1/PHY/MODULATION/slot_fep_ul.c
+++ b/openair1/PHY/MODULATION/slot_fep_ul.c
@@ -35,7 +35,6 @@ int slot_fep_ul(RU_t *ru,
   unsigned char aa;
   RU_COMMON *common=&ru->common;
   LTE_DL_FRAME_PARMS *fp = &ru->frame_parms;
-  RU_proc_t *proc = &ru->proc;
   unsigned char symbol = l+((7-fp->Ncp)*(Ns&1)); ///symbol within sub-frame
   unsigned int nb_prefix_samples = (no_prefix ? 0 : fp->nb_prefix_samples);
   unsigned int nb_prefix_samples0 = (no_prefix ? 0 : fp->nb_prefix_samples0);
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 9c2fc6a16776e606c063a5f3a18871124af1f9aa..6987551a00574722780e8c08a856130cad417742 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 {
@@ -613,7 +645,8 @@ typedef enum {
   REMOTE_IF5      =1,
   REMOTE_MBP_IF5  =2,
   REMOTE_IF4p5    =3,
-  MAX_RU_IF_TYPES =4
+  REMOTE_IF1pp    =4,
+  MAX_RU_IF_TYPES =5
 } RU_if_south_t;
 
 typedef struct RU_t_s{
@@ -698,11 +731,11 @@ typedef struct RU_t_s{
   /// function pointer to TX front-end processing routine (PRECODING)
   void                 (*feptx_prec)(struct RU_t_s *ru);
   /// function pointer to wakeup routine in lte-enb.
-  int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB,int frame_rx,int subframe_rx);
+  int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru);
   /// function pointer to wakeup routine in lte-enb.
-  int (*wakeup_prach_eNB)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
+  void (*wakeup_prach_eNB)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
   /// function pointer to wakeup routine in lte-enb.
-  int (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
+  void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
   /// function pointer to eNB entry routine
   void (*eNB_top)(struct PHY_VARS_eNB_s *eNB, int frame_rx, int subframe_rx, char *string);
   /// Timing statistics
@@ -710,7 +743,7 @@ typedef struct RU_t_s{
   /// RX and TX buffers for precoder output
   RU_COMMON            common;
   /// beamforming weight vectors per eNB
-  int32_t **beam_weights[NUMBER_OF_eNB_MAX][15];
+  int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15];
 
   /// received frequency-domain signal for PRACH (IF4p5 RRU) 
   int16_t              **prach_rxsigF;
@@ -1157,16 +1190,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 +1293,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 +1360,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 +1376,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 +1395,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 +1414,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/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index 57288e258496e2bde32e49195cb16ddabf16bee9..2c89b49859eb74e9ea6e91e3e52e9a2a348dd1fa 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -82,7 +82,6 @@ void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
 void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,  
 				 nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) {
   
-  nfapi_hi_dci0_hi_pdu *pdu      = &hi_dci0_config_pdu->hi_pdu;
   LTE_eNB_PHICH *phich           = &eNB->phich_vars[proc->subframe_tx&1];
 
   // copy dci configuration in to eNB structure
@@ -90,7 +89,7 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
 	hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value,
 	hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start,
 	hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms,
-        pdu);
+        hi_dci0_config_pdu);
 
   phich->config[phich->num_hi].hi       = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.hi_value;
   phich->config[phich->num_hi].first_rb = hi_dci0_config_pdu->hi_pdu.hi_pdu_rel8.resource_block_start;
@@ -162,16 +161,33 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
   dlsch1_harq     = dlsch1->harq_processes[harq_pid];
   AssertFatal(dlsch0_harq!=NULL,"dlsch_harq is null\n");
 
+  // compute DL power control parameters
+  eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa;
+
+  if (dlsch0->active){
+    computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
+    computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off);
+  }
+  if (dlsch1->active){
+    computeRhoA_eNB(&eNB->pdsch_config_dedicated[UE_id], dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
+    computeRhoB_eNB(&eNB->pdsch_config_dedicated[UE_id],&(eNB->frame_parms.pdsch_config_common),eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off);
+  }
+
   
   dlsch0_harq->pdsch_start = eNB->pdcch_vars[proc->subframe_tx & 1].num_pdcch_symbols;
 
   if (dlsch0_harq->round==0) {  //get pointer to SDU if this a new SDU
-    LOG_D(PHY,"NFAPI: frame %d, subframe %d: programming dlsch, rnti %x, UE_id %d, harq_pid %d\n",
-	  proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid);
+    if (rel8->rnti != 0xFFFF) LOG_I(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n",
+				    proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid);
     if (codeword_index == 0) dlsch0_harq->pdu                    = sdu;
     else                     dlsch1_harq->pdu                    = sdu;
   }
-
+  else {
+    if (rel8->rnti != 0xFFFF) LOG_I(PHY,"NFAPI: frame %d, subframe %d: programming dlsch for round %d, rnti %x, UE_id %d, harq_pid %d\n",
+				    proc->frame_tx,proc->subframe_tx,dlsch0_harq->round,
+				    rel8->rnti,UE_id,harq_pid);
+  }
+  
 #ifdef Rel14
   dlsch0->sib1_br_flag=0;
 
@@ -300,7 +316,7 @@ void handle_uci_harq_information(PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci,nfapi_ul_co
   if (eNB->frame_parms.frame_type == FDD) {
     uci->num_pucch_resources = harq_information->harq_information_rel9_fdd.number_of_pucch_resources; 
 
-    LOG_D(PHY,"Programming UCI HARQ mode %d : size %d in (%d,%d)\n",
+    LOG_I(PHY,"Programming UCI HARQ mode %d : size %d in (%d,%d)\n",
 	  harq_information->harq_information_rel9_fdd.ack_nack_mode,
 	  harq_information->harq_information_rel9_fdd.harq_size,
 	  uci->frame,uci->subframe);
@@ -405,7 +421,7 @@ void handle_uci_sr_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu_t
   uci->srs_active          = srs_active;
   uci->active              = 1;
 
-  LOG_D(PHY,"Programming UCI SR rnti %x, pucch1_0 %d for (%d,%d)\n",
+  LOG_I(PHY,"Programming UCI SR rnti %x, pucch1_0 %d for (%d,%d)\n",
 	uci->rnti,uci->n_pucch_1_0_sr[0],frame,subframe);
   
 
@@ -424,7 +440,7 @@ void handle_uci_sr_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_
   uci->type                = HARQ_SR;
   uci->num_antenna_ports   = 1;
   uci->num_pucch_resources = 1;
-  uci->n_pucch_1_0_sr[0]    = ul_config_pdu->uci_sr_harq_pdu.sr_information.sr_information_rel8.pucch_index;
+  uci->n_pucch_1_0_sr[0]   = ul_config_pdu->uci_sr_harq_pdu.sr_information.sr_information_rel8.pucch_index;
   uci->srs_active          = srs_active;
   uci->active              = 1;
 
@@ -436,6 +452,7 @@ void handle_uci_harq_pdu(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_request_pdu
 
   LTE_eNB_UCI *uci = &eNB->uci_vars[UE_id];
 
+  LOG_I(PHY,"Frame %d, Subframe %d: Programming UCI_HARQ process (type %d)\n",frame,subframe,HARQ);
   uci->frame             = frame;
   uci->subframe          = subframe;
   uci->rnti              = ul_config_pdu->uci_harq_pdu.ue_information.ue_information_rel8.rnti;
@@ -653,10 +670,12 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
     case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE:
       LOG_D(PHY,"%s() NFAPI_DL_CONFIG_DLSCH_PDU_TYPE TX:%d/%d RX:%d/%d transport_blocks:%d pdu_index:%d data:%p\n", __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->frame_rx, proc->subframe_rx, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index, TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data);
 
+      /*
       AssertFatal(dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index<TX_req->tx_request_body.number_of_pdus,
 		  "dlsch_pdu_rel8.pdu_index>=TX_req->number_of_pdus (%d>%d)\n",
 		  dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,
 		  TX_req->tx_request_body.number_of_pdus);
+      */
       AssertFatal((dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks<3) &&
 		  (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks>0),
 		  "dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = %d not in [1,2]\n",
diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h
index 62e427563043c540065069841cd4d909a228c7d9..cae9d271c3e51a656aaf8ab1f4f21c58b4dc1e1c 100644
--- a/openair1/SCHED/fapi_l1.h
+++ b/openair1/SCHED/fapi_l1.h
@@ -39,7 +39,7 @@
 void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask);
 void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling);
 void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti);
-void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe);
+void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat);
 void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe);
 void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag);
 void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
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 25be138e5bbeeb6ef2d0ab81d2348c0f2d3f15b7..bb0c8e785a3c8b14473871f3e74613d00434198f 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -50,6 +50,7 @@
 #   include "intertask_interface.h"
 #endif
 
+extern uint8_t nfapi_pnf;
 int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind);
 
 
@@ -58,13 +59,15 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn,rel
 
 
 #if defined(Rel10) || defined(Rel14)
-  MCH_PDU *mch_pduP;
+  MCH_PDU *mch_pduP=NULL;
   MCH_PDU  mch_pdu;
   //  uint8_t sync_area=255;
 #endif
 
   int subframe = proc->subframe_tx;
 
+  AssertFatal(1==0,"pmch not tested for the moment, exiting\n");
+
   // This is DL-Cell spec pilots in Control region
   generate_pilots_slot(eNB,
 		       eNB->common_vars.txdataF,
@@ -377,6 +380,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
   stop_meas(&eNB->dlsch_modulation_stats);
 
   dlsch->active = 0;
+  dlsch_harq->round++;
 }
 
 
@@ -407,8 +411,6 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+offset,1);
   if (do_meas==1) start_meas(&eNB->phy_proc_tx);
 
-  T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
-
   // clear the transmit data array for the current subframe
   for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) {      
     memset(&eNB->common_vars.txdataF[aa][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)],
@@ -469,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;
@@ -515,24 +518,33 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 	// get harq_pid
 	harq_pid = dlsch0->harq_ids[subframe];
 	AssertFatal(harq_pid>=0,"harq_pid is negative\n");
-	// generate pdsch
-	pdsch_procedures(eNB,
-			 proc,
-			 harq_pid,
-			 dlsch0,
-			 dlsch1,
-			 &eNB->UE_stats[(uint32_t)UE_id],
-			 0);
+
+        if (harq_pid>=8)
+        {
+          LOG_E(PHY,"harq_pid:%d corrupt must be 0-7\n", harq_pid);
+        }
+        else
+        {
+          // generate pdsch
+          pdsch_procedures(eNB,
+              proc,
+              harq_pid,
+              dlsch0,
+              dlsch1,
+              &eNB->UE_stats[(uint32_t)UE_id],
+              0);
+        }
 
 
       }
 
+
       else if ((dlsch0)&&
-	       (dlsch0->rnti>0)&&
-	       (dlsch0->active == 0)) {
+          (dlsch0->rnti>0)&&
+          (dlsch0->active == 0)) {
 
-	// clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
-	dlsch0->subframe_tx[subframe]=0;
+        // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
+        dlsch0->subframe_tx[subframe]=0;
       }
     }
 
@@ -547,15 +559,17 @@ 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;
+  LTE_eNB_PRACH *prach_vars=NULL;
+
 #ifdef Rel14
   if (br_flag==1) {
     subframe = eNB->proc.subframe_prach_br;
@@ -679,7 +693,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
 	      max_preamble_energy[0]%10,
 	      max_preamble_delay[0]);
 	
-	    T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), 0,
+	    T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
 	      T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0]));
 	    
 	    
@@ -697,20 +711,24 @@ void prach_procedures(PHY_VARS_eNB *eNB,
 	    eNB->preamble_list[0].preamble_rel13.rach_resource_type   = 0;
 	    eNB->preamble_list[0].instance_length                     = 0; //don't know exactly what this is
 	    
-            nfapi_rach_indication_t rach_ind;
-            rach_ind.header.message_id = NFAPI_RACH_INDICATION;
-            rach_ind.sfn_sf = frame<<4 | subframe;
-            rach_ind.rach_indication_body = eNB->UL_INFO.rach_ind;
+            // If NFAPI PNF then we need to send the message to the VNF
+            if (nfapi_pnf == 1)
+            {
+              nfapi_rach_indication_t rach_ind;
+              rach_ind.header.message_id = NFAPI_RACH_INDICATION;
+              rach_ind.sfn_sf = frame<<4 | subframe;
+              rach_ind.rach_indication_body = eNB->UL_INFO.rach_ind;
 
-	    LOG_I(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n");
-	    LOG_I(PHY,"Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
-		  eNB->preamble_list[0].preamble_rel8.timing_advance,
-		  eNB->preamble_list[0].preamble_rel8.preamble,
-		  eNB->preamble_list[0].preamble_rel8.rnti,
-		  eNB->preamble_list[0].preamble_rel13.rach_resource_type);	    
+              LOG_I(PHY,"\n\n\n\nDJP - this needs to be sent to VNF **********************************************\n\n\n\n");
+              LOG_I(PHY,"Filling NFAPI indication for RACH : TA %d, Preamble %d, rnti %x, rach_resource_type %d\n",
+                  eNB->preamble_list[0].preamble_rel8.timing_advance,
+                  eNB->preamble_list[0].preamble_rel8.preamble,
+                  eNB->preamble_list[0].preamble_rel8.rnti,
+                  eNB->preamble_list[0].preamble_rel13.rach_resource_type);	    
 
 
-            oai_nfapi_rach_ind(&rach_ind);
+              oai_nfapi_rach_ind(&rach_ind);
+            }
 
 	    pthread_mutex_unlock(&eNB->UL_INFO_mutex);
       
@@ -766,8 +784,8 @@ void srs_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
   }
 }
 
-void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe) {
-
+void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat) {
+  
   pthread_mutex_lock(&eNB->UL_INFO_mutex);
   nfapi_sr_indication_pdu_t *pdu =   &eNB->UL_INFO.sr_ind.sr_pdu_list[eNB->UL_INFO.sr_ind.number_of_srs];
 
@@ -775,6 +793,14 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe)
   //  pdu->rx_ue_information.handle                       = handle;
   pdu->rx_ue_information.rnti                         = rnti;
 
+  int SNRtimes10 = dB_fixed_times10(stat) - 200;//(10*eNB->measurements.n0_power_dB[0]);
+
+
+  if      (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
+  else if (SNRtimes10 >  635) pdu->ul_cqi_information.ul_cqi=255;
+  else                        pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5;
+  pdu->ul_cqi_information.channel = 0;
+
   eNB->UL_INFO.sr_ind.number_of_srs++;
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 }
@@ -784,11 +810,6 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
   uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0};
   int32_t metric[4]={0,0,0,0},metric_SR=0,max_metric;
-  ANFBmode_t bundling_flag;
-#ifdef DEBUG_PHY_PROC
-  uint8_t pucch_sel = 0;
-  PUCCH_FMT_t format;
-#endif
   const int subframe = proc->subframe_rx;
   const int frame = proc->frame_rx;
   int i;
@@ -803,6 +824,9 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	(uci->frame == frame) &&
 	(uci->subframe == subframe)) {
 
+      LOG_I(PHY,"Frame %d, subframe %d: Running uci procedures (type %d) for %d \n",frame,subframe,uci->type,i);
+      uci->active=0;
+
       // Null out PUCCH PRBs for noise measurement
       switch(fp->N_RB_UL) {
       case 6:
@@ -854,7 +878,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	      uci->n_pucch_1_0_sr[0]);
 	if (uci->type == SR) {
 	  if (SR_payload == 1) {
-	    fill_sr_indication(eNB,uci->rnti,frame,subframe);
+	    fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
 	    return;
 	  }
 	  else {
@@ -863,7 +887,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	}
       case HARQ:
 	if (fp->frame_type == FDD) {
-	  LOG_D(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n",
+	  LOG_I(PHY,"Frame %d Subframe %d Demodulating PUCCH (UCI %d) for ACK/NAK (uci->pucch_fmt %d,uci->type %d.uci->frame %d, uci->subframe %d): n1_pucch0 %d SR_payload %d\n",
 		frame,subframe,i,
 		uci->pucch_fmt,uci->type,
 		uci->frame,uci->subframe,uci->n_pucch_1[0][0],
@@ -883,7 +907,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	  
 	  /* cancel SR detection if reception on n1_pucch0 is better than on SR PUCCH resource index, otherwise send it up to MAC */
 	  if (uci->type==HARQ_SR && metric[0] > metric_SR) SR_payload = 0;
-	  else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe);
+	  else if (SR_payload == 1) fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
  
 	  if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
 	    /* when transmitting ACK/NACK on SR PUCCH resource index, SR payload is always 1 */
@@ -901,19 +925,19 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 			       PUCCH1a_THRES);
 	  }
 	  
-#ifdef DEBUG_PHY_PROC
-	  LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
+
+	  LOG_I(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d pucch1a (FDD) payload %d (metric %d)\n",
 		eNB->Mod_id,
 		uci->rnti,
 		frame,subframe,
-		pucch_b0b1[0][0],metric0);
-#endif
+		pucch_b0b1[0][0],metric[0]);
+
 	  
 	  fill_uci_harq_indication(eNB,uci,frame,subframe,pucch_b0b1[0],0,0xffff);
 
 	}
 	else { // frame_type == TDD
-	  
+
 
 	  // if SR was detected, use the n1_pucch from SR
 	  if (SR_payload==1) {
@@ -981,7 +1005,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	    }
 	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,2,0xffff); // special_bundling mode
 	  } 
-	  else if ((bundling_flag == 0) && (res==2)){ // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2
+	  else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==2)){ // multiplexing + no SR, implement Table 10.1.3-5 (Rel14) for multiplexing with M=2
 	    if (pucch_b0b1[0][0] == 4 ||
 		pucch_b0b1[1][0] == 4) { // there isn't a likely transmission
 	      harq_ack[0] = 4; // DTX
@@ -1021,8 +1045,8 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	      }
 	    }
 	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
-	  } //else if ((bundling_flag == 0) && (res==2))
-	  else if ((bundling_flag == 0) && (res==3)){ // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3
+	  } //else if ((uci->tdd_bundling == 0) && (res==2))
+	  else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==3)){ // multiplexing + no SR, implement Table 10.1.3-6 (Rel14) for multiplexing with M=3
 	    
 	    if (harq_ack[0] == 4 ||
 		harq_ack[1] == 4 ||
@@ -1102,8 +1126,8 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	      }
 	    }
 	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
-	  } //else if ((bundling_flag == 0) && (res==3)) 
-	  else if ((bundling_flag == 0) && (res==4)){ // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4
+	  } //else if ((uci->tdd_bundling == 0) && (res==3)) 
+	  else if ((uci->tdd_bundling == 0) && (uci->num_pucch_resources==4)){ // multiplexing + no SR, implement Table 10.1.3-7 (Rel14) for multiplexing with M=4
 	    if (pucch_b0b1[0][0] == 4 ||
 		pucch_b0b1[1][0] == 4 ||
 		pucch_b0b1[2][0] == 4 ||
@@ -1238,7 +1262,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	      }
 	    }
 	    fill_uci_harq_indication(eNB,uci,frame,subframe,harq_ack,1,tdd_multiplexing_mask); // multiplexing mode
-	  } // else if ((bundling_flag == 0) && (res==4))
+	  } // else if ((uci->tdd_bundling == 0) && (res==4))
 	  else { // bundling
 	    harq_ack[0] = pucch_b0b1[0][0];
 	    harq_ack[1] = pucch_b0b1[0][1];
@@ -1246,10 +1270,10 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	  }
 	  
 #ifdef DEBUG_PHY_PROC
-	  LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, sel %d, (%d,%d)\n",eNB->Mod_id,
+	  LOG_D(PHY,"[eNB %d][PDSCH %x] Frame %d subframe %d ACK/NAK metric 0 %d, metric 1 %d, (%d,%d)\n",eNB->Mod_id,
 		eNB->dlsch[UE_id][0]->rnti,
 		frame,subframe,
-		metric0,metric1,pucch_sel,pucch_b0b1[0],pucch_b0b1[1]);
+		metric0,metric1,pucch_b0b1[0],pucch_b0b1[1]);
 #endif
 	}
 	break;
@@ -1278,14 +1302,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
 
   uint32_t ret=0,i;
-#ifdef DEBUG_PHY_PROC
-#ifdef DEBUG_ULSCH
-  uint32_t j;
-#endif
-#endif
-
   uint32_t harq_pid;
-  uint8_t nPRS;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
   LTE_eNB_ULSCH_t *ulsch;
   LTE_UL_eNB_HARQ_t *ulsch_harq;
@@ -1301,11 +1318,25 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
 
     ulsch = eNB->ulsch[i];
-    if (ulsch)
-    {
-      ulsch_harq = ulsch->harq_processes[harq_pid];
-      if (ulsch->rnti>0) LOG_D(PHY,"Frame %d, subframe %d: PUSCH procedures, harq_pid %d, UE %d/%x\n",
-          frame,subframe,harq_pid,i,ulsch->rnti);
+    ulsch_harq = ulsch->harq_processes[harq_pid];
+    if (ulsch->rnti>0) LOG_D(PHY,"Frame %d, subframe %d: PUSCH procedures, harq_pid %d, UE %d/%x\n",
+			     frame,subframe,harq_pid,i,ulsch->rnti);
+    
+    if ((ulsch) &&
+        (ulsch->rnti>0) &&
+        (ulsch_harq->status == ACTIVE) &&
+	(ulsch_harq->frame == frame) &&
+	(ulsch_harq->subframe == subframe)) {
+      
+      
+      // UE is has ULSCH scheduling
+ 
+      for (int rb=0;
+           rb<=ulsch_harq->nb_rb;
+	   rb++) {
+	int rb2 = rb+ulsch_harq->first_rb;
+	eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
+      }
 
       if ((ulsch) &&
           (ulsch->rnti>0) &&
@@ -1328,14 +1359,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
             i);
 
 
-        nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
-
-        ulsch->cyclicShift = (ulsch_harq->n_DMRS2 + 
-            fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +
-            nPRS)%12;
-
-        LOG_D(PHY,
-            "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, nprs %d), O_ACK %d \n",
+      LOG_D(PHY,
+            "[eNB %d][PUSCH %d] Frame %d Subframe %d Demodulating PUSCH: dci_alloc %d, rar_alloc %d, round %d, first_rb %d, nb_rb %d, Qm %d, TBS %d, rv %d, cyclic_shift %d (n_DMRS2 %d, cyclicShift_common %d, ), O_ACK %d, beta_cqi %d \n",
             eNB->Mod_id,harq_pid,frame,subframe,
             ulsch_harq->dci_alloc,
             ulsch_harq->rar_alloc,
@@ -1348,8 +1373,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
             ulsch->cyclicShift,
             ulsch_harq->n_DMRS2,
             fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift,
-            nPRS,
-            ulsch_harq->O_ACK);
+            ulsch_harq->O_ACK,
+	    ulsch->beta_offset_cqi_times8);
 
         start_meas(&eNB->ulsch_demodulation_stats);
 
@@ -1396,24 +1421,29 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
 #endif
 
 
-          fill_ulsch_cqi_indication(eNB,frame,subframe,
-              ulsch_harq,
-              ulsch->rnti);
-        }
-
-        if (ret == (1+MAX_TURBO_ITERATIONS)) {
-          T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti),
-              T_INT(harq_pid));
-
-          fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC
-
-          LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
-              eNB->Mod_id,harq_pid,
-              frame,subframe, i,
-              ulsch_harq->round-1,
-              ulsch->Mlimit,
-              ulsch_harq->o_ACK[0],
-              ulsch_harq->o_ACK[1]);
+	fill_ulsch_cqi_indication(eNB,frame,subframe,
+				  ulsch_harq,
+				  ulsch->rnti);
+      }
+      
+      if (ret == (1+MAX_TURBO_ITERATIONS)) {
+        T(T_ENB_PHY_ULSCH_UE_NACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti),
+          T_INT(harq_pid));
+
+	fill_crc_indication(eNB,i,frame,subframe,1); // indicate NAK to MAC
+	fill_rx_indication(eNB,i,frame,subframe);  // indicate SDU to MAC
+
+	LOG_D(PHY,"[eNB %d][PUSCH %d] frame %d subframe %d UE %d Error receiving ULSCH, round %d/%d (ACK %d,%d)\n",
+	      eNB->Mod_id,harq_pid,
+	      frame,subframe, i,
+	      ulsch_harq->round-1,
+	      ulsch->Mlimit,
+	      ulsch_harq->o_ACK[0],
+	      ulsch_harq->o_ACK[1]);
+	/*
+	if (dB_fixed_times10(eNB->pusch_vars[i]->ulsch_power[0]) > 300) {
+	  dump_ulsch(eNB,frame,subframe,i); exit(-1);
+	  }*/
 
 #if defined(MESSAGE_CHART_GENERATOR_PHY)
           MSC_LOG_RX_DISCARDED_MESSAGE(
@@ -1426,15 +1456,11 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) {
               );
 #endif
 
-        }  // ulsch in error
-        else {
-
-
-          fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
-          fill_rx_indication(eNB,i,frame,subframe);    // indicate SDU to MAC
-          T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(ulsch->rnti),
-              T_INT(harq_pid));
-          ulsch_harq->status = SCH_IDLE;
+	fill_crc_indication(eNB,i,frame,subframe,0); // indicate ACK to MAC
+	fill_rx_indication(eNB,i,frame,subframe);  // indicate SDU to MAC
+        T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(ulsch->rnti),
+          T_INT(harq_pid));
+	ulsch_harq->status = SCH_IDLE;
 
 #if defined(MESSAGE_CHART_GENERATOR_PHY)
           MSC_LOG_RX_MESSAGE(
@@ -1543,6 +1569,10 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
   // estimate timing advance for MAC
   sync_pos                               = lte_est_timing_advance_pusch(eNB,UE_id);
   timing_advance_update                  = sync_pos - eNB->frame_parms.nb_prefix_samples/4; //to check
+
+
+  //  if (timing_advance_update > 10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
+  //  if (timing_advance_update < -10) { dump_ulsch(eNB,frame,subframe,UE_id); exit(-1);}
   switch (eNB->frame_parms.N_RB_DL) {
   case 6:
     pdu->rx_indication_rel8.timing_advance = timing_advance_update;  
@@ -1571,10 +1601,16 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe) {
   // estimate UL_CQI for MAC (from antenna port 0 only)
   int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 200;//(10*eNB->measurements.n0_power_dB[0]);
 
+
   if      (SNRtimes10 < -640) pdu->rx_indication_rel8.ul_cqi=0;
   else if (SNRtimes10 >  635) pdu->rx_indication_rel8.ul_cqi=255;
   else                        pdu->rx_indication_rel8.ul_cqi=(640+SNRtimes10)/5;
 
+
+  LOG_D(PHY,"[PUSCH %d] Filling RX_indication with SNR %d (%d), timing_advance %d (update %d)\n",
+	harq_pid,SNRtimes10,pdu->rx_indication_rel8.ul_cqi,pdu->rx_indication_rel8.timing_advance,
+	timing_advance_update);
+
   eNB->UL_INFO.rx_ind.number_of_pdus++;
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
 
@@ -1677,13 +1713,13 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe
   else               pdu->cqi_indication_rel9.data_offset = 1; // fill in after all cqi_indications have been generated when non-zero
 
   // by default set O to rank 1 value
-  pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + (ulsch_harq->Or1&7) > 0 ? 1 : 0; 
+  pdu->cqi_indication_rel9.length = (ulsch_harq->Or1>>3) + ((ulsch_harq->Or1&7) > 0 ? 1 : 0);
   pdu->cqi_indication_rel9.ri[0]  = 0;
 
   // if we have RI bits, set them and if rank2 overwrite O
   if (ulsch_harq->O_RI>0) {
     pdu->cqi_indication_rel9.ri[0] = ulsch_harq->o_RI[0];
-    if (ulsch_harq->o_RI[0] == 2)   pdu->cqi_indication_rel9.length = (ulsch_harq->Or2>>3) + (ulsch_harq->Or2&7) > 0 ? 1 : 0; 
+    if (ulsch_harq->o_RI[0] == 2)   pdu->cqi_indication_rel9.length = (ulsch_harq->Or2>>3) + ((ulsch_harq->Or2&7) > 0 ? 1 : 0);
     pdu->cqi_indication_rel9.timing_advance = 0;
   }
   
@@ -1695,8 +1731,8 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe
 
 }
 
-void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling) {
-
+void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,uint16_t rnti, int frame,int subframe,int bundling)
+{
   int UE_id = find_dlsch(rnti,eNB,SEARCH_EXIST);
   AssertFatal(UE_id>=0,"UE_id doesn't exist\n");
 
@@ -1710,7 +1746,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
   pdu->rx_ue_information.rnti                         = rnti;
 
   if (eNB->frame_parms.frame_type == FDD) {
-    pdu->harq_indication_fdd_rel13.mode = 0;  
+    pdu->harq_indication_fdd_rel13.mode = 0;
     pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
 
     for (i=0;i<ulsch_harq->O_ACK;i++) {
@@ -1719,14 +1755,23 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
       pdu->harq_indication_fdd_rel13.harq_tb_n[i] = 2-ulsch_harq->o_ACK[i];
       // release DLSCH if needed
       if (ulsch_harq->o_ACK[i] == 1) release_harq(eNB,UE_id,i,frame,subframe,0xffff);
-   
+
+#if T_TRACER
+      /* TODO: get correct harq pid */
+      if (ulsch_harq->o_ACK[i] != 1)
+        T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe),
+          T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10]));
+      else
+        T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe),
+          T_INT(rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10]));
+#endif
     }
   }
   else { // TDD
     M=ul_ACK_subframe2_M(&eNB->frame_parms,
 			 subframe);
 
-    pdu->harq_indication_fdd_rel13.mode = 1-bundling;  
+    pdu->harq_indication_fdd_rel13.mode = 1-bundling;
     pdu->harq_indication_fdd_rel13.number_of_ack_nack = ulsch_harq->O_ACK;
 
     for (i=0;i<ulsch_harq->O_ACK;i++) {
@@ -1744,12 +1789,18 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
       }
     }	
   }
+
   eNB->UL_INFO.harq_ind.number_of_harqs++;
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
-
 }
 
-void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int subframe,uint8_t *harq_ack,uint8_t tdd_mapping_mode,uint16_t tdd_multiplexing_mask) {
+void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
+			      LTE_eNB_UCI *uci,
+			      int frame,
+			      int subframe,
+			      uint8_t *harq_ack,
+			      uint8_t tdd_mapping_mode,
+			      uint16_t tdd_multiplexing_mask) {
 
   int UE_id=find_dlsch(uci->rnti,eNB,SEARCH_EXIST);
 
@@ -1761,6 +1812,14 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int s
   //  pdu->rx_ue_information.handle                       = handle;
   pdu->rx_ue_information.rnti                         = uci->rnti;
 
+  // estimate UL_CQI for MAC (from antenna port 0 only)
+  int SNRtimes10 = dB_fixed_times10(uci->stat) - 200;//(10*eNB->measurements.n0_power_dB[0]);
+
+
+  if      (SNRtimes10 < -640) pdu->ul_cqi_information.ul_cqi=0;
+  else if (SNRtimes10 >  635) pdu->ul_cqi_information.ul_cqi=255;
+  else                        pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5;
+  pdu->ul_cqi_information.channel = 0;
 
   if (eNB->frame_parms.frame_type == FDD) {
     if (uci->pucch_fmt == pucch_format1a) {
@@ -1771,6 +1830,15 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,LTE_eNB_UCI *uci,int frame,int s
       pdu->harq_indication_fdd_rel13.harq_tb_n[0] = harq_ack[0];
       // release DLSCH if needed
       if (harq_ack[0] == 1) release_harq(eNB,UE_id,0,frame,subframe,0xffff);
+
+#if T_TRACER
+      if (harq_ack[0] != 1)
+        T(T_ENB_PHY_DLSCH_UE_NACK, T_INT(0), T_INT(frame), T_INT(subframe),
+          T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10]));
+      else
+        T(T_ENB_PHY_DLSCH_UE_ACK, T_INT(0), T_INT(frame), T_INT(subframe),
+          T_INT(uci->rnti), T_INT(eNB->dlsch[UE_id][0]->harq_ids[(subframe+6)%10]));
+#endif
     }
     else if (uci->pucch_fmt == pucch_format1b) {
       pdu->harq_indication_fdd_rel13.mode = 0;  
@@ -1913,12 +1981,11 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,const
 
   T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));
 
+  /* TODO: use correct rxdata */
   T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0),
-    T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti],
+    T_BUFFER(&eNB->RU_list[0]->common.rxdata[0][subframe*eNB->frame_parms.samples_per_tti],
              eNB->frame_parms.samples_per_tti * 4));
 
-
-
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX_UESPEC, 1 );
 
   LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_uespec_RX(%d)\n",eNB->Mod_id,frame, subframe);
diff --git a/openair1/SCHED/phy_procedures_lte_ue.c b/openair1/SCHED/phy_procedures_lte_ue.c
index ea5b1150ab6123058a41a745035c47755b8aa60a..2e398b4aa4651d335a341ca8aaa399bb9a8e1fc1 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;
 
 void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id);
@@ -88,29 +90,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)
@@ -123,23 +125,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);
   /*
@@ -222,19 +224,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);
   /*
@@ -260,7 +262,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
@@ -324,6 +326,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;
     }
   }
 
@@ -371,7 +374,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
@@ -454,9 +457,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;
@@ -470,7 +473,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)
       {
@@ -508,7 +511,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)
@@ -518,7 +521,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;
@@ -577,19 +580,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
@@ -623,7 +626,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))
   {
@@ -631,10 +635,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;
@@ -648,7 +656,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");
           }*/
       }
   }
@@ -682,7 +690,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,
@@ -705,10 +713,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 {
@@ -717,10 +725,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);
     }
 
@@ -771,7 +779,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];
@@ -813,18 +821,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,
@@ -899,31 +907,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,
@@ -932,30 +941,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",
@@ -966,28 +975,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,
@@ -998,37 +1017,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;
@@ -1075,9 +1096,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)
@@ -1176,10 +1241,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-
@@ -1206,14 +1272,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;
@@ -1235,37 +1301,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);
@@ -1273,17 +1339,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;
@@ -1292,11 +1358,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
@@ -1309,10 +1375,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);
 
@@ -1339,6 +1407,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,
@@ -1348,9 +1417,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
@@ -1359,7 +1428,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)) {
@@ -1367,7 +1435,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",
@@ -1388,9 +1456,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,
@@ -1415,32 +1485,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;
 
@@ -1472,37 +1541,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;
@@ -1547,9 +1617,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);
@@ -1559,40 +1629,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
@@ -1607,53 +1676,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(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(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,
@@ -1670,8 +1741,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,
@@ -1681,9 +1753,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,
@@ -1694,8 +1774,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) {
@@ -1710,6 +1791,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);
@@ -1729,49 +1813,68 @@ 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
-#if T_TRACER
-    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(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_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,
@@ -1787,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);
@@ -1845,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);
   }
 }
 
@@ -1858,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)
 
@@ -1912,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);
@@ -1952,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;
@@ -1975,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
@@ -1998,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)))) {
@@ -2008,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
@@ -2020,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;
@@ -2033,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,
@@ -2070,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,
@@ -2083,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,14 +2223,16 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
       tx_amp = AMP;
 #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(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_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[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,
@@ -2131,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" : "??")),
@@ -2144,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" : "??")),
@@ -2157,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(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(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,19 +2318,18 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin
       tx_amp = AMP;
 #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(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_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[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,
@@ -2230,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:
@@ -2255,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;
@@ -2264,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],
@@ -2296,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
+
 	
   	
 
@@ -2311,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)) {
@@ -2322,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,
@@ -2352,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
@@ -2381,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;
@@ -2395,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(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
 
@@ -2451,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,
@@ -2460,12 +2590,13 @@ 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)
 {
 
@@ -2491,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,
@@ -2499,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;
     }
@@ -2540,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];
@@ -2554,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,
@@ -2600,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);
 
@@ -2621,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");
@@ -2634,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);
 }
@@ -2650,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);
   
@@ -2682,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,
@@ -2815,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);
@@ -2837,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,
@@ -2845,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,
@@ -2876,14 +3067,13 @@ 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,
                                  pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,proc->subframe_rx),
                                  pdcch_alloc2ul_subframe(frame_parms,proc->subframe_rx));
 
-    T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), T_INT(ue->Mod_id),
+    T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx),
       T_INT(dci_alloc_rx[i].rnti), T_INT(harq_pid),
       T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs),
       T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round),
@@ -2892,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
 
@@ -2913,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);
 }
@@ -2966,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,
@@ -2981,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++) {
 	
@@ -3054,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
@@ -3079,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
@@ -3143,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))
       {
@@ -3159,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!!!
@@ -3174,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,
@@ -3193,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) {
 
@@ -3206,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,
@@ -3226,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,
@@ -3287,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;
@@ -3339,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:
@@ -3353,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,
@@ -3483,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,
@@ -3553,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,
@@ -3619,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;
-
   
+  
+}
 
-  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN);
+/*!
+ * \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);
 
 #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;
@@ -3666,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
@@ -3689,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
@@ -3698,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) {
     //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -3715,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) {
@@ -3750,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);
   }
 
@@ -3782,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);
@@ -3802,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);
@@ -3817,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
@@ -3856,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,"");
   }
@@ -3929,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];
@@ -4021,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)) {
@@ -4032,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)
@@ -4088,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,
@@ -4194,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/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index ca480adb28c8bf15d00b67f737aba3d4dcba5af2..e4ca10a03b8a8581f4e4385e6d9b122779687a68 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -75,7 +75,7 @@ void feptx_ofdm(RU_t *ru) {
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM , 1 );
 
-  //  slot_offset_F = (subframe<<1)*slot_sizeF;
+  slot_offset_F = 0;
 
   slot_offset = subframe*fp->samples_per_tti;
 
@@ -186,7 +186,7 @@ void feptx_ofdm(RU_t *ru) {
        }
      }
      LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, subframe %d: txp (time %p) %d dB, txp (freq) %d dB\n",
-	   ru->proc.frame_tx,subframe,txdata,dB_fixed(signal_energy(txdata,fp->samples_per_tti)),
+	   ru->proc.frame_tx,subframe,txdata,dB_fixed(signal_energy((int32_t*)txdata,fp->samples_per_tti)),
 	   dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF)));
     }
   }
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_app.c b/openair2/ENB_APP/enb_app.c
index 33f0e526be135e000d82190a6e1eaeca718660fa..81542aa35609835fc878c5ca66b2659e83073052 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -106,7 +106,7 @@ static void configure_rrc(uint32_t enb_id)
   msg_p = itti_alloc_new_message (TASK_ENB_APP, RRC_CONFIGURATION_REQ);
 
   if (RC.rrc[enb_id]) {
-    RCconfig_RRC(msg_p,enb_id,RC.rrc[enb_id]);
+    RCconfig_RRC(msg_p,enb_id, RC.rrc[enb_id]);
     
   /*
   RRC_CONFIGURATION_REQ (msg_p).cell_identity =   enb_properties->properties[enb_id]->eNB_id;
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index ba431024b377c9d5fb8213ca87c3f63399d7247e..cc060bed8311a83b44be39098a794658eb6dd79a 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -28,7 +28,6 @@
 */
 
 #include <string.h>
-#include <libconfig.h>
 #include <inttypes.h>
 
 #include "log.h"
@@ -56,297 +55,12 @@
 #include "nfapi_vnf.h"
 #include "nfapi_pnf.h"
 
-/* those macros are here to help diagnose problems in configuration files
- * if the lookup fails, a warning is printed
- * (yes we can use the function name for the macro itself, the C preprocessor
- * won't die in an infinite loop)
- */
-#define config_setting_lookup_int(setting, name, value)			\
-  (config_setting_lookup_int(setting, name, value) ||			\
-   (printf("WARNING: setting '%s' not found in configuration file\n", name), 0))
-#define config_setting_lookup_int64(setting, name, value)		\
-  (config_setting_lookup_int64(setting, name, value) ||			\
-   (printf("WARNING: setting '%s' not found in configuration file\n", name), 0))
-#define config_setting_lookup_float(setting, name, value)		\
-  (config_setting_lookup_float(setting, name, value) ||			\
-   (printf("WARNING: setting '%s' not found in configuration file\n", name), 0))
-#define config_setting_lookup_bool(setting, name, value)		\
-  (config_setting_lookup_bool(setting, name, value) ||			\
-   (printf("WARNING: setting '%s' not found in configuration file\n", name), 0))
-#define config_setting_lookup_string(setting, name, value)		\
-  (config_setting_lookup_string(setting, name, value) ||		\
-   (printf("WARNING: setting '%s' not found in configuration file\n", name), 0))
-
-#define ENB_CONFIG_STRING_ACTIVE_ENBS                   "Active_eNBs"
-
-#define ENB_CONFIG_STRING_ENB_LIST                      "eNBs"
-#define ENB_CONFIG_STRING_ENB_ID                        "eNB_ID"
-#define ENB_CONFIG_STRING_CELL_TYPE                     "cell_type"
-#define ENB_CONFIG_STRING_ENB_NAME                      "eNB_name"
-
-#define ENB_CONFIG_STRING_TRACKING_AREA_CODE            "tracking_area_code"
-#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE           "mobile_country_code"
-#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE           "mobile_network_code"
-
-#define ENB_CONFIG_STRING_LOCAL_S_IF_NAME               "local_s_if_name"
-#define ENB_CONFIG_STRING_LOCAL_S_ADDRESS               "local_s_address"
-#define ENB_CONFIG_STRING_REMOTE_S_ADDRESS              "remote_s_address"
-#define ENB_CONFIG_STRING_LOCAL_S_PORTC                 "local_s_portc"
-#define ENB_CONFIG_STRING_REMOTE_S_PORTC                "remote_s_portc"
-#define ENB_CONFIG_STRING_LOCAL_S_PORTD                 "local_s_portd"
-#define ENB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
-#define ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE        "tr_s_preference"
-
-
-#define ENB_CONFIG_STRING_COMPONENT_CARRIERS                            "component_carriers"
-
-#define ENB_CONFIG_STRING_CC_NODE_FUNCTION                              "node_function"
-#define ENB_CONFIG_STRING_CC_NODE_TIMING                                "node_timing"   
-#define ENB_CONFIG_STRING_CC_NODE_SYNCH_REF                             "node_synch_ref"   
-
-#define ENB_CONFIG_STRING_FRAME_TYPE                                    "frame_type"
-#define ENB_CONFIG_STRING_TDD_CONFIG                                    "tdd_config"
-#define ENB_CONFIG_STRING_TDD_CONFIG_S                                  "tdd_config_s"
-#define ENB_CONFIG_STRING_PREFIX_TYPE                                   "prefix_type"
-#define ENB_CONFIG_STRING_PBCH_REPETITION                               "pbch_repetition"
-#define ENB_CONFIG_STRING_EUTRA_BAND                                    "eutra_band"
-#define ENB_CONFIG_STRING_DOWNLINK_FREQUENCY                            "downlink_frequency"
-#define ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET                       "uplink_frequency_offset"
-
-#define ENB_CONFIG_STRING_NID_CELL                                      "Nid_cell"
-#define ENB_CONFIG_STRING_N_RB_DL                                       "N_RB_DL"
-#define ENB_CONFIG_STRING_CELL_MBSFN                                  "Nid_cell_mbsfn"
-#define ENB_CONFIG_STRING_NB_ANT_PORTS                              "nb_antenna_ports"
-#define ENB_CONFIG_STRING_NB_ANT_TX                                 "nb_antennas_tx"
-#define ENB_CONFIG_STRING_NB_ANT_RX                                 "nb_antennas_rx"
-#define ENB_CONFIG_STRING_TX_GAIN                                       "tx_gain"
-#define ENB_CONFIG_STRING_RX_GAIN                                       "rx_gain"
-#define ENB_CONFIG_STRING_PRACH_ROOT                                  "prach_root"
-#define ENB_CONFIG_STRING_PRACH_CONFIG_INDEX                          "prach_config_index"
-#define ENB_CONFIG_STRING_PRACH_HIGH_SPEED                          "prach_high_speed"
-#define ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION                  "prach_zero_correlation"
-#define ENB_CONFIG_STRING_PRACH_FREQ_OFFSET                         "prach_freq_offset"
-#define ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT                         "pucch_delta_shift"
-#define ENB_CONFIG_STRING_PUCCH_NRB_CQI                                 "pucch_nRB_CQI"
-#define ENB_CONFIG_STRING_PUCCH_NCS_AN                                  "pucch_nCS_AN"
-#if !defined(Rel10) && !defined(Rel14)
-#define ENB_CONFIG_STRING_PUCCH_N1_AN                                 "pucch_n1_AN"
-#endif
-#define ENB_CONFIG_STRING_PDSCH_RS_EPRE                                 "pdsch_referenceSignalPower"
-#define ENB_CONFIG_STRING_PDSCH_PB                                  "pdsch_p_b"
-#define ENB_CONFIG_STRING_PUSCH_N_SB                                  "pusch_n_SB"
-#define ENB_CONFIG_STRING_PUSCH_HOPPINGMODE                             "pusch_hoppingMode"
-#define ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET                           "pusch_hoppingOffset"
-#define ENB_CONFIG_STRING_PUSCH_ENABLE64QAM                         "pusch_enable64QAM"
-#define ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN                  "pusch_groupHoppingEnabled"
-#define ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT                  "pusch_groupAssignment"
-#define ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN                 "pusch_sequenceHoppingEnabled"
-#define ENB_CONFIG_STRING_PUSCH_NDMRS1                                  "pusch_nDMRS1"
-#define ENB_CONFIG_STRING_PHICH_DURATION                          "phich_duration"
-#define ENB_CONFIG_STRING_PHICH_RESOURCE                          "phich_resource"
-#define ENB_CONFIG_STRING_SRS_ENABLE                                  "srs_enable"
-#define ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG                          "srs_BandwidthConfig"
-#define ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG                         "srs_SubframeConfig"
-#define ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG                          "srs_ackNackST"
-#define ENB_CONFIG_STRING_SRS_MAXUPPTS                                  "srs_MaxUpPts"
-#define ENB_CONFIG_STRING_PUSCH_PO_NOMINAL                          "pusch_p0_Nominal"
-#define ENB_CONFIG_STRING_PUSCH_ALPHA                                 "pusch_alpha"
-#define ENB_CONFIG_STRING_PUCCH_PO_NOMINAL                          "pucch_p0_Nominal"
-#define ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE                         "msg3_delta_Preamble"
-#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1                          "pucch_deltaF_Format1"
-#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b                         "pucch_deltaF_Format1b"
-#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2                          "pucch_deltaF_Format2"
-#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A                         "pucch_deltaF_Format2a"
-#define ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B                         "pucch_deltaF_Format2b"
-#define ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES                         "rach_numberOfRA_Preambles"
-#define ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG                  "rach_preamblesGroupAConfig"
-#define ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA                 "rach_sizeOfRA_PreamblesGroupA"
-#define ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA                        "rach_messageSizeGroupA"
-#define ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB                 "rach_messagePowerOffsetGroupB"
-#define ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP                         "rach_powerRampingStep"
-#define ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER "rach_preambleInitialReceivedTargetPower"
-#define ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX                         "rach_preambleTransMax"
-#define ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE                 "rach_raResponseWindowSize"
-#define ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER         "rach_macContentionResolutionTimer"
-#define ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX                          "rach_maxHARQ_Msg3Tx"
-#define ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE                     "pcch_default_PagingCycle"
-#define ENB_CONFIG_STRING_PCCH_NB                                       "pcch_nB"
-#define ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF                  "bcch_modificationPeriodCoeff"
-#define ENB_CONFIG_STRING_UETIMERS_T300                                 "ue_TimersAndConstants_t300"
-#define ENB_CONFIG_STRING_UETIMERS_T301                                 "ue_TimersAndConstants_t301"
-#define ENB_CONFIG_STRING_UETIMERS_T310                                 "ue_TimersAndConstants_t310"
-#define ENB_CONFIG_STRING_UETIMERS_T311                                 "ue_TimersAndConstants_t311"
-#define ENB_CONFIG_STRING_UETIMERS_N310                                 "ue_TimersAndConstants_n310"
-#define ENB_CONFIG_STRING_UETIMERS_N311                                 "ue_TimersAndConstants_n311"
-#define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE                          "ue_TransmissionMode"
-
-#define ENB_CONFIG_STRING_SRB1                                          "srb1_parameters"
-#define ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT                    "timer_poll_retransmit"
-#define ENB_CONFIG_STRING_SRB1_TIMER_REORDERING                         "timer_reordering"
-#define ENB_CONFIG_STRING_SRB1_TIMER_STATUS_PROHIBIT                    "timer_status_prohibit"
-#define ENB_CONFIG_STRING_SRB1_POLL_PDU                                 "poll_pdu"
-#define ENB_CONFIG_STRING_SRB1_POLL_BYTE                                "poll_byte"
-#define ENB_CONFIG_STRING_SRB1_MAX_RETX_THRESHOLD                       "max_retx_threshold"
-#define ENB_CONFIG_STRING_MME_IP_ADDRESS                "mme_ip_address"
-#define ENB_CONFIG_STRING_MME_IPV4_ADDRESS              "ipv4"
-#define ENB_CONFIG_STRING_MME_IPV6_ADDRESS              "ipv6"
-#define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE         "active"
-#define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE     "preference"
-
-#define ENB_CONFIG_STRING_SCTP_CONFIG                    "SCTP"
-#define ENB_CONFIG_STRING_SCTP_INSTREAMS                 "SCTP_INSTREAMS"
-#define ENB_CONFIG_STRING_SCTP_OUTSTREAMS                "SCTP_OUTSTREAMS"
-
-#define ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG     "NETWORK_INTERFACES"
-#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME"
-#define ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME   "ENB_IPV4_ADDRESS_FOR_S1_MME"
-#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U    "ENB_INTERFACE_NAME_FOR_S1U"
-#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U         "ENB_IPV4_ADDRESS_FOR_S1U"
-#define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U              "ENB_PORT_FOR_S1U"
-
-#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG     "NETWORK_CONTROLLER"
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME      "FLEXRAN_AGENT_INTERFACE_NAME"
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS        "FLEXRAN_AGENT_IPV4_ADDRESS"
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT                "FLEXRAN_AGENT_PORT"
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE               "FLEXRAN_AGENT_CACHE"
-
-
-
-
-#define ENB_CONFIG_STRING_ASN1_VERBOSITY                   "Asn1_verbosity"
-#define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE              "none"
-#define ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING          "annoying"
-#define ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO              "info"
-
-// OTG config per ENB-UE DL
-#define ENB_CONF_STRING_OTG_CONFIG                         "otg_config"
-#define ENB_CONF_STRING_OTG_UE_ID                          "ue_id"
-#define ENB_CONF_STRING_OTG_APP_TYPE                       "app_type"
-#define ENB_CONF_STRING_OTG_BG_TRAFFIC                     "bg_traffic"
-
-// per eNB configuration
-#define ENB_CONFIG_STRING_LOG_CONFIG                       "log_config"
-#define ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL                 "global_log_level"
-#define ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY             "global_log_verbosity"
-#define ENB_CONFIG_STRING_HW_LOG_LEVEL                     "hw_log_level"
-#define ENB_CONFIG_STRING_HW_LOG_VERBOSITY                 "hw_log_verbosity"
-#define ENB_CONFIG_STRING_PHY_LOG_LEVEL                    "phy_log_level"
-#define ENB_CONFIG_STRING_PHY_LOG_VERBOSITY                "phy_log_verbosity"
-#define ENB_CONFIG_STRING_MAC_LOG_LEVEL                    "mac_log_level"
-#define ENB_CONFIG_STRING_MAC_LOG_VERBOSITY                "mac_log_verbosity"
-#define ENB_CONFIG_STRING_RLC_LOG_LEVEL                    "rlc_log_level"
-#define ENB_CONFIG_STRING_RLC_LOG_VERBOSITY                "rlc_log_verbosity"
-#define ENB_CONFIG_STRING_PDCP_LOG_LEVEL                   "pdcp_log_level"
-#define ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY               "pdcp_log_verbosity"
-#define ENB_CONFIG_STRING_RRC_LOG_LEVEL                    "rrc_log_level"
-#define ENB_CONFIG_STRING_RRC_LOG_VERBOSITY                "rrc_log_verbosity"
-#define ENB_CONFIG_STRING_GTPU_LOG_LEVEL                   "gtpu_log_level"
-#define ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY               "gtpu_log_verbosity"
-#define ENB_CONFIG_STRING_UDP_LOG_LEVEL                    "udp_log_level"
-#define ENB_CONFIG_STRING_UDP_LOG_VERBOSITY                "udp_log_verbosity"
-#define ENB_CONFIG_STRING_OSA_LOG_LEVEL                    "osa_log_level"
-#define ENB_CONFIG_STRING_OSA_LOG_VERBOSITY                "osa_log_verbosity"
-
-#define CONFIG_STRING_MACRLC_LIST                          "MACRLCs"
-#define CONFIG_STRING_MACRLC_CONFIG                        "macrlc_config"
-#define CONFIG_STRING_MACRLC_CC                            "num_cc"
-#define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME               "local_n_if_name"
-#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS               "local_n_address"
-#define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS              "remote_n_address"
-#define CONFIG_STRING_MACRLC_LOCAL_N_PORTC                 "local_n_portc"
-#define CONFIG_STRING_MACRLC_REMOTE_N_PORTC                "remote_n_portc"
-#define CONFIG_STRING_MACRLC_LOCAL_N_PORTD                 "local_n_portd"
-#define CONFIG_STRING_MACRLC_REMOTE_N_PORTD                "remote_n_portd"
-#define CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME               "local_s_if_name"
-#define CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS               "local_s_address"
-#define CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS              "remote_s_address"
-#define CONFIG_STRING_MACRLC_LOCAL_S_PORTC                 "local_s_portc"
-#define CONFIG_STRING_MACRLC_REMOTE_S_PORTC                "remote_s_portc"
-#define CONFIG_STRING_MACRLC_LOCAL_S_PORTD                 "local_s_portd"
-#define CONFIG_STRING_MACRLC_REMOTE_S_PORTD                "remote_s_portd"
-#define CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE        "tr_s_preference"
-#define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE        "tr_n_preference"
-
-#define CONFIG_STRING_L1_LIST                              "L1s"
-#define CONFIG_STRING_L1_CONFIG                            "l1_config"
-#define CONFIG_STRING_L1_CC                                "num_cc"
-#define CONFIG_STRING_L1_LOCAL_N_IF_NAME                   "local_n_if_name"
-#define CONFIG_STRING_L1_LOCAL_N_ADDRESS                   "local_n_address"
-#define CONFIG_STRING_L1_REMOTE_N_ADDRESS                  "remote_n_address"
-#define CONFIG_STRING_L1_LOCAL_N_PORTC                     "local_n_portc"
-#define CONFIG_STRING_L1_REMOTE_N_PORTC                    "remote_n_portc"
-#define CONFIG_STRING_L1_LOCAL_N_PORTD                     "local_n_portd"
-#define CONFIG_STRING_L1_REMOTE_N_PORTD                    "remote_n_portd"
-#define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE            "tr_n_preference"
-
-#define CONFIG_STRING_ACTIVE_RUS                  "Active_RUs"
-#define CONFIG_STRING_RU_LIST                     "RUs"
-#define CONFIG_STRING_RU_CONFIG                   "ru_config"
-#define CONFIG_STRING_RU_LOCAL_IF_NAME            "local_if_name"
-#define CONFIG_STRING_RU_LOCAL_ADDRESS            "local_address"
-#define CONFIG_STRING_RU_REMOTE_ADDRESS           "remote_address"
-#define CONFIG_STRING_RU_LOCAL_PORTC              "local_portc"
-#define CONFIG_STRING_RU_REMOTE_PORTC             "remote_portc"
-#define CONFIG_STRING_RU_LOCAL_PORTD              "local_portd"
-#define CONFIG_STRING_RU_REMOTE_PORTD             "remote_portd"
-#define CONFIG_STRING_RU_LOCAL_RF                 "local_rf"
-#define CONFIG_STRING_RU_TRANSPORT_PREFERENCE     "tr_preference"
-#define CONFIG_STRING_RU_BAND_LIST                "bands"
-#define CONFIG_STRING_RU_ENB_LIST                 "eNB_instances"
-#define CONFIG_STRING_RU_NB_TX                    "nb_tx"
-#define CONFIG_STRING_RU_NB_RX                    "nb_rx"
-#define CONFIG_STRING_RU_ATT_TX                   "att_tx"
-#define CONFIG_STRING_RU_ATT_RX                   "att_rx"
-#define CONFIG_STRING_RU_MAX_RS_EPRE              "max_pdschReferenceSignalPower"
-#define CONFIG_STRING_RU_MAX_RXGAIN               "max_rxgain"
-#define CONFIG_STRING_RU_IF_COMPRESSION           "if_compression"
-
-#define KHz (1000UL)
-#define MHz (1000 * KHz)
-
-typedef struct eutra_band_s {
-  int16_t             band;
-  uint32_t            ul_min;
-  uint32_t            ul_max;
-  uint32_t            dl_min;
-  uint32_t            dl_max;
-  lte_frame_type_t    frame_type;
-} eutra_band_t;
-
-static const eutra_band_t eutra_bands[] = {
-  { 1, 1920    * MHz, 1980    * MHz, 2110    * MHz, 2170    * MHz, FDD},
-  { 2, 1850    * MHz, 1910    * MHz, 1930    * MHz, 1990    * MHz, FDD},
-  { 3, 1710    * MHz, 1785    * MHz, 1805    * MHz, 1880    * MHz, FDD},
-  { 4, 1710    * MHz, 1755    * MHz, 2110    * MHz, 2155    * MHz, FDD},
-  { 5,  824    * MHz,  849    * MHz,  869    * MHz,  894    * MHz, FDD},
-  { 6,  830    * MHz,  840    * MHz,  875    * MHz,  885    * MHz, FDD},
-  { 7, 2500    * MHz, 2570    * MHz, 2620    * MHz, 2690    * MHz, FDD},
-  { 8,  880    * MHz,  915    * MHz,  925    * MHz,  960    * MHz, FDD},
-  { 9, 1749900 * KHz, 1784900 * KHz, 1844900 * KHz, 1879900 * KHz, FDD},
-  {10, 1710    * MHz, 1770    * MHz, 2110    * MHz, 2170    * MHz, FDD},
-  {11, 1427900 * KHz, 1452900 * KHz, 1475900 * KHz, 1500900 * KHz, FDD},
-  {12,  698    * MHz,  716    * MHz,  728    * MHz,  746    * MHz, FDD},
-  {13,  777    * MHz,  787    * MHz,  746    * MHz,  756    * MHz, FDD},
-  {14,  788    * MHz,  798    * MHz,  758    * MHz,  768    * MHz, FDD},
-
-  {17,  704    * MHz,  716    * MHz,  734    * MHz,  746    * MHz, FDD},
-  {20,  832    * MHz,  862    * MHz,  791    * MHz,  821    * MHz, FDD},
-  {33, 1900    * MHz, 1920    * MHz, 1900    * MHz, 1920    * MHz, TDD},
-  {33, 1900    * MHz, 1920    * MHz, 1900    * MHz, 1920    * MHz, TDD},
-  {34, 2010    * MHz, 2025    * MHz, 2010    * MHz, 2025    * MHz, TDD},
-  {35, 1850    * MHz, 1910    * MHz, 1850    * MHz, 1910    * MHz, TDD},
-  {36, 1930    * MHz, 1990    * MHz, 1930    * MHz, 1990    * MHz, TDD},
-  {37, 1910    * MHz, 1930    * MHz, 1910    * MHz, 1930    * MHz, TDD},
-  {38, 2570    * MHz, 2620    * MHz, 2570    * MHz, 2630    * MHz, TDD},
-  {39, 1880    * MHz, 1920    * MHz, 1880    * MHz, 1920    * MHz, TDD},
-  {40, 2300    * MHz, 2400    * MHz, 2300    * MHz, 2400    * MHz, TDD},
-  {41, 2496    * MHz, 2690    * MHz, 2496    * MHz, 2690    * MHz, TDD},
-  {42, 3400    * MHz, 3600    * MHz, 3400    * MHz, 3600    * MHz, TDD},
-  {43, 3600    * MHz, 3800    * MHz, 3600    * MHz, 3800    * MHz, TDD},
-  {44, 703    * MHz, 803    * MHz, 703    * MHz, 803    * MHz, TDD},
-};
+#include "enb_paramdef.h"
+#include "common/config/config_userapi.h"
 
 
+int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc);
+int RCconfig_S1(MessageDef *msg_p, uint32_t i);
 
 
 static int enb_check_band_frequencies(char* lib_config_file_name_pP,
@@ -386,304 +100,132 @@ static int enb_check_band_frequencies(char* lib_config_file_name_pP,
     }
   }
 
+
   return errors;
 }
 
-#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
-extern int asn_debug;
-extern int asn1_xer_print;
-#endif
-
-#ifdef LIBCONFIG_LONG
-#define libconfig_int long
-#else
-#define libconfig_int int
-#endif
-
-typedef enum {
-  RU     = 0,
-  L1     = 1,
-  L2     = 2,
-  L3     = 3,
-  S1     = 4,
-  lastel = 5
-} RC_config_functions_t;
-
-extern int mac_top_init_eNB(void );
-
+extern void mac_top_init_eNB(void );
 extern uint8_t  nfapi_pnf;
 
 
-void load_config_file(config_t *cfg) {
-
-  config_init(cfg);
-  
-  if (RC.config_file_name != NULL) {
-    // Read the file. If there is an error, report it and exit. 
-    if (! config_read_file(cfg, RC.config_file_name)) {
-      config_destroy(cfg);
-      AssertFatal (0, "Failed to parse eNB configuration file %s!\n", RC.config_file_name);
-    }
-  } else {
-    config_destroy(cfg);
-    AssertFatal (0, "No eNB configuration file provided!\n");
-  }
-
-}
 
+/* --------------------------------------------------------*/
+/* from here function to use configuration module          */
 void RCconfig_RU(void) {
-
-  config_t          cfg;
-  config_setting_t *setting                       = NULL;
-  config_setting_t *setting_ru                    = NULL;
-  config_setting_t *setting_band                  = NULL;
-  config_setting_t *setting_band_elem             = NULL;
-  config_setting_t *setting_eNB_list              = NULL;
-  config_setting_t *setting_eNB_list_elem         = NULL;
-  char*             if_name                       = NULL;
-  char*             ipv4                          = NULL;
-  char*             ipv4_remote                   = NULL;
-  char              *local_rf                     = NULL;
-  char*             tr_preference                 = NULL;
-
-  libconfig_int     local_portc                   = 0;
-  libconfig_int     remote_portc                  = 0;
-  libconfig_int     local_portd                   = 0;
-  libconfig_int     remote_portd                  = 0;
-
-  libconfig_int     nb_tx                         = 0;
-  libconfig_int     nb_rx                         = 0;
-  libconfig_int     att_tx                        = 0;
-  libconfig_int     att_rx                        = 0;
-  libconfig_int     max_pdschReferenceSignalPower = 0;
-  libconfig_int     max_rxgain                    = 0;
+  
   int               j                             = 0;
   int               i                             = 0;
   int               num_bands                     = 0;
-  libconfig_int     band[256];
-  int               num_eNB4RU                    = 0;
-  libconfig_int     eNB_list[256];
-  int               fronthaul_flag                = CONFIG_TRUE;
-  /// TRUE for eNB or RRU, FALSE for RAU
-  int		    local_rf_flag		  = CONFIG_TRUE;
 
-  load_config_file(&cfg);
-
-  // Output a list of all RUs. 
-  setting = config_lookup(&cfg, CONFIG_STRING_RU_LIST);
   
-  if (setting != NULL) {
+  paramdef_t RUParams[] = RUPARAMS_DESC;
+  paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
 
 
-    RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*));
-   
-    RC.ru_mask=(1<<NB_RU) - 1;
+  config_getlist( &RUParamList,RUParams,sizeof(RUParams)/sizeof(paramdef_t), NULL);  
 
+  
+  if ( RUParamList.numelt > 0) {
 
-    for (j = 0; j < RC.nb_RU; j++) {
-      
-      setting_ru = config_setting_get_elem(setting, j);
-      printf("rru %d/%d\n",j,RC.nb_RU);
-
-
-      if (  !(
-	      config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_IF_NAME,(const char **)&if_name)
-	      )
-	    ) {
-	fronthaul_flag = CONFIG_FALSE;
-      }
-
-      if (  !(
-              config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_RF,(const char **)&local_rf)
-              )
-            ) {
-        local_rf_flag = CONFIG_FALSE;
-      }			  
-      
-      if (local_rf_flag == CONFIG_TRUE) { // eNB or RRU
-	
+    RC.ru = (RU_t**)malloc(RC.nb_RU*sizeof(RU_t*));
+   
 
-	if (  !(
-                config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_MAX_RS_EPRE, &max_pdschReferenceSignalPower) &&
-                config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_MAX_RXGAIN, &max_rxgain)
-               )
-              ) {
-          AssertFatal (0,
-                       "Failed to parse configuration file %s, RU %d config !\n",
-                       RC.config_file_name, j);
-          continue;
-        }
 
 
-	AssertFatal((setting_band = config_setting_get_member(setting_ru, CONFIG_STRING_RU_BAND_LIST))!=NULL,"No allowable LTE bands\n");
-	
-	if (setting_band != NULL) num_bands    = config_setting_length(setting_band);
-	else num_bands=0;
-	
-	for (i=0;i<num_bands;i++) {
-	  setting_band_elem = config_setting_get_elem(setting_band,i);
-	  band[i] = config_setting_get_int(setting_band_elem);
-	  printf("RU %d: band %d\n",j,band[i]);
-	}
-      } // fronthaul_flag == CONFIG_FALSE
-      
-      if (fronthaul_flag == CONFIG_TRUE) { // fronthaul_flag == CONFIG_TRUE
-	if (  !(
-		config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_LOCAL_ADDRESS,        (const char **)&ipv4)
-	 	&& config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_REMOTE_ADDRESS,       (const char **)&ipv4_remote)
-		&& config_setting_lookup_int   (setting_ru, CONFIG_STRING_RU_LOCAL_PORTC,          &local_portc)
-		&& config_setting_lookup_int   (setting_ru, CONFIG_STRING_RU_REMOTE_PORTC,         &remote_portc)
-		&& config_setting_lookup_int   (setting_ru, CONFIG_STRING_RU_LOCAL_PORTD,          &local_portd)
-		&& config_setting_lookup_int   (setting_ru, CONFIG_STRING_RU_REMOTE_PORTD,         &remote_portd)
-		&& config_setting_lookup_string(setting_ru, CONFIG_STRING_RU_TRANSPORT_PREFERENCE, (const char **)&tr_preference)
-		)
-	      ) {
-	  AssertFatal (0,
-		       "Failed to parse configuration file %s, RU %d config !\n",
-		       RC.config_file_name, j);
-	  continue;
-	}
-
-      }
+    RC.ru_mask=(1<<NB_RU) - 1;
+    printf("Set RU mask to %lx\n",RC.ru_mask);
 
-      if (nfapi_pnf == 1 || nfapi_pnf == 2)
-      {
-        printf("DJP - COMMENTED OUT nb_L1_inst %s:%d\n\n\n\n", __FILE__, __LINE__);
-      }
-      else
-      {
-        printf("Before eNB_list\n");
-        printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
-        if (RC.nb_L1_inst>0) {
-          AssertFatal((setting_eNB_list = config_setting_get_member(setting_ru, CONFIG_STRING_RU_ENB_LIST))!=NULL,"No RU<->eNB mappings\n");
-
-          if (setting_eNB_list != NULL) num_eNB4RU    = config_setting_length(setting_eNB_list);
-          else num_eNB4RU=0;
-          AssertFatal(num_eNB4RU>0,"Number of eNBs is zero\n");
-
-          printf("num_eNB4RU:%u\n", num_eNB4RU);
-          for (i=0;i<num_eNB4RU;i++) {
-            setting_eNB_list_elem = config_setting_get_elem(setting_eNB_list,i);
-            eNB_list[i] = config_setting_get_int(setting_eNB_list_elem);
-            printf("RU %d: eNB %d\n",j,eNB_list[i]);
-          }
-        }
-      }
+    for (j = 0; j < RC.nb_RU; j++) {
 
-      config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_ATT_TX, &att_tx);
-      config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_ATT_RX, &att_rx);
-
-      if ( !(
-            config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_TX,  &nb_tx)
-            && config_setting_lookup_int(setting_ru, CONFIG_STRING_RU_NB_RX,  &nb_rx)
-            )) {
-	AssertFatal (0,
-	  "Failed to parse configuration file %s, RU %d config !\n",
-	  RC.config_file_name, j);
-	continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
-      }
-      
       RC.ru[j]                                    = (RU_t*)malloc(sizeof(RU_t));
       memset((void*)RC.ru[j],0,sizeof(RU_t));
-      
       RC.ru[j]->idx                                 = j;
-      
+
       RC.ru[j]->if_timing                           = synch_to_ext_device;
-      RC.ru[j]->num_eNB                             = num_eNB4RU;
+      RC.ru[j]->num_eNB                             = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt;
+      for (i=0;i<RC.ru[j]->num_eNB;i++) RC.ru[j]->eNB_list[i] = RC.eNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0];     
 
-      printf("RC.ru[%d]->num_eNB:%u\n", j, RC.ru[j]->num_eNB);
 
-      //for (i=0;i<num_eNB4RU;i++) RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0];
-      for (i=0;i<num_eNB4RU;i++)
-      {
-        printf("Copying RC.ru[%d]->eNB_list[%d] = RC.eNB[eNB_list[%d][0]\n", j, i, i);
-        RC.ru[j]->eNB_list[i] = RC.eNB[eNB_list[i]][0];
-      }
-      
-      if (strcmp(local_rf, "yes") == 0) {
-	if (fronthaul_flag == CONFIG_FALSE) {
+      if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) {
+	if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) {
 	  RC.ru[j]->if_south                        = LOCAL_RF;
 	  RC.ru[j]->function                        = eNodeB_3GPP;
 	  printf("Setting function for RU %d to eNodeB_3GPP\n",j);
         }
         else { 
-	  RC.ru[j]->eth_params.local_if_name            = strdup(if_name);
-	  RC.ru[j]->eth_params.my_addr                  = strdup(ipv4);
-	  RC.ru[j]->eth_params.remote_addr              = strdup(ipv4_remote);
-	  RC.ru[j]->eth_params.my_portc                 = local_portc;
-	  RC.ru[j]->eth_params.remote_portc             = remote_portc;
-	  RC.ru[j]->eth_params.my_portd                 = local_portd;
-	  RC.ru[j]->eth_params.remote_portd             = remote_portd;
-
-	  if (strcmp(tr_preference, "udp") == 0) {
+          RC.ru[j]->eth_params.local_if_name            = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));    
+          RC.ru[j]->eth_params.my_addr                  = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); 
+          RC.ru[j]->eth_params.remote_addr              = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
+          RC.ru[j]->eth_params.my_portc                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
+          RC.ru[j]->eth_params.remote_portc             = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
+          RC.ru[j]->eth_params.my_portd                 = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
+          RC.ru[j]->eth_params.remote_portd             = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
+
+	  if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
 	    RC.ru[j]->if_south                        = LOCAL_RF;
 	    RC.ru[j]->function                        = NGFI_RRU_IF5;
 	    RC.ru[j]->eth_params.transp_preference    = ETH_UDP_MODE;
 	    printf("Setting function for RU %d to NGFI_RRU_IF5 (udp)\n",j);
-	  } else if (strcmp(tr_preference, "raw") == 0) {
+	  } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
 	    RC.ru[j]->if_south                        = LOCAL_RF;
 	    RC.ru[j]->function                        = NGFI_RRU_IF5;
 	    RC.ru[j]->eth_params.transp_preference    = ETH_RAW_MODE;
 	    printf("Setting function for RU %d to NGFI_RRU_IF5 (raw)\n",j);
-	  } else if (strcmp(tr_preference, "udp_if4p5") == 0) {
+	  } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
 	    RC.ru[j]->if_south                        = LOCAL_RF;
 	    RC.ru[j]->function                        = NGFI_RRU_IF4p5;
 	    RC.ru[j]->eth_params.transp_preference    = ETH_UDP_IF4p5_MODE;
 	    printf("Setting function for RU %d to NGFI_RRU_IF4p5 (udp)\n",j);
-	  } else if (strcmp(tr_preference, "raw_if4p5") == 0) {
+	  } else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
 	    RC.ru[j]->if_south                        = LOCAL_RF;
 	    RC.ru[j]->function                        = NGFI_RRU_IF4p5;
 	    RC.ru[j]->eth_params.transp_preference    = ETH_RAW_IF4p5_MODE;
 	    printf("Setting function for RU %d to NGFI_RRU_IF4p5 (raw)\n",j);
 	  }
 	}
-
-	RC.ru[j]->max_pdschReferenceSignalPower     = max_pdschReferenceSignalPower;
-	RC.ru[j]->max_rxgain                        = max_rxgain;
-	RC.ru[j]->num_bands                         = num_bands;
-	RC.ru[j]->att_tx                         = att_tx; 
-	RC.ru[j]->att_rx                         = att_rx; 
-	for (i=0;i<num_bands;i++) RC.ru[j]->band[i] = band[i]; 
-      }
+	RC.ru[j]->max_pdschReferenceSignalPower     = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);;
+	RC.ru[j]->max_rxgain                        = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr);
+	RC.ru[j]->num_bands                         = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt;
+	for (i=0;i<num_bands;i++) RC.ru[j]->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; 
+      } //strcmp(local_rf, "yes") == 0
       else {
-	printf("RU %d: Transport %s\n",j,tr_preference);
-
-	RC.ru[j]->eth_params.local_if_name            = strdup(if_name);
-	RC.ru[j]->eth_params.my_addr                  = strdup(ipv4);
-	RC.ru[j]->eth_params.remote_addr              = strdup(ipv4_remote);
-	RC.ru[j]->eth_params.my_portc                 = local_portc;
-	RC.ru[j]->eth_params.remote_portc             = remote_portc;
-	RC.ru[j]->eth_params.my_portd                 = local_portd;
-	RC.ru[j]->eth_params.remote_portd             = remote_portd;
-
-	if (strcmp(tr_preference, "udp") == 0) {
+	printf("RU %d: Transport %s\n",j,*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr));
+
+        RC.ru[j]->eth_params.local_if_name	      = strdup(*(RUParamList.paramarray[j][RU_LOCAL_IF_NAME_IDX].strptr));    
+        RC.ru[j]->eth_params.my_addr		      = strdup(*(RUParamList.paramarray[j][RU_LOCAL_ADDRESS_IDX].strptr)); 
+        RC.ru[j]->eth_params.remote_addr	      = strdup(*(RUParamList.paramarray[j][RU_REMOTE_ADDRESS_IDX].strptr));
+        RC.ru[j]->eth_params.my_portc		      = *(RUParamList.paramarray[j][RU_LOCAL_PORTC_IDX].uptr);
+        RC.ru[j]->eth_params.remote_portc	      = *(RUParamList.paramarray[j][RU_REMOTE_PORTC_IDX].uptr);
+        RC.ru[j]->eth_params.my_portd		      = *(RUParamList.paramarray[j][RU_LOCAL_PORTD_IDX].uptr);
+        RC.ru[j]->eth_params.remote_portd	      = *(RUParamList.paramarray[j][RU_REMOTE_PORTD_IDX].uptr);
+	if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp") == 0) {
 	  RC.ru[j]->if_south                     = REMOTE_IF5;
 	  RC.ru[j]->function                     = NGFI_RAU_IF5;
 	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_MODE;
-	} else if (strcmp(tr_preference, "raw") == 0) {
+	} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw") == 0) {
 	  RC.ru[j]->if_south                     = REMOTE_IF5;
 	  RC.ru[j]->function                     = NGFI_RAU_IF5;
 	  RC.ru[j]->eth_params.transp_preference = ETH_RAW_MODE;
-	} else if (strcmp(tr_preference, "udp_if4p5") == 0) {
+	} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "udp_if4p5") == 0) {
 	  RC.ru[j]->if_south                     = REMOTE_IF4p5;
 	  RC.ru[j]->function                     = NGFI_RAU_IF4p5;
 	  RC.ru[j]->eth_params.transp_preference = ETH_UDP_IF4p5_MODE;
-	} else if (strcmp(tr_preference, "raw_if4p5") == 0) {
+	} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if4p5") == 0) {
 	  RC.ru[j]->if_south                     = REMOTE_IF4p5;
 	  RC.ru[j]->function                     = NGFI_RAU_IF4p5;
 	  RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF4p5_MODE;
-	} else if (strcmp(tr_preference, "raw_if5_mobipass") == 0) {
+	} else if (strcmp(*(RUParamList.paramarray[j][RU_TRANSPORT_PREFERENCE_IDX].strptr), "raw_if5_mobipass") == 0) {
 	  RC.ru[j]->if_south                     = REMOTE_IF5;
 	  RC.ru[j]->function                     = NGFI_RAU_IF5;
 	  RC.ru[j]->if_timing                    = synch_to_other;
 	  RC.ru[j]->eth_params.transp_preference = ETH_RAW_IF5_MOBIPASS;
 	}
-	RC.ru[j]->att_tx                         = att_tx; 
-	RC.ru[j]->att_rx                         = att_rx; 
-      }
+	RC.ru[j]->att_tx                         = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); 
+	RC.ru[j]->att_rx                         = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); 
+      }  /* strcmp(local_rf, "yes") != 0 */
 
-      RC.ru[j]->nb_tx                             = nb_tx;
-      RC.ru[j]->nb_rx                             = nb_rx;
+      RC.ru[j]->nb_tx                             = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr);
+      RC.ru[j]->nb_rx                             = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr);
       
     }// j=0..num_rus
   } else {
@@ -695,108 +237,54 @@ void RCconfig_RU(void) {
 }
 
 void RCconfig_L1(void) {
-
   int               i,j;
+  paramdef_t L1_Params[] = L1PARAMS_DESC;
+  paramlist_def_t L1_ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
 
-  config_t          cfg;
-  config_setting_t *setting                         = NULL;
-  config_setting_t *setting_l1                      = NULL;
-
-  char*             if_name_n                       = NULL;
-  char*             ipv4_n                          = NULL;
-  char*             ipv4_n_remote                   = NULL;
-
-  char*             tr_n_preference                 = NULL;
-  libconfig_int     local_n_portc                   = 0;
-  libconfig_int     remote_n_portc                  = 0;
-  libconfig_int     local_n_portd                   = 0;
-  libconfig_int     remote_n_portd                  = 0;
-
-  printf("%s()\n", __FUNCTION__);
-
-  load_config_file(&cfg);
-
-  printf("%s() RC.eNB:%p - NEED? malloc it\n", __FUNCTION__, RC.eNB);
 
   if (RC.eNB == NULL) {
-    RC.eNB                               = (PHY_VARS_eNB ***)malloc((1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***));
-    LOG_I(PHY,"RC.eNB:%p\n",RC.eNB);
+    RC.eNB                       = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**));
+    LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
     memset(RC.eNB,0,(1+NUMBER_OF_eNB_MAX)*sizeof(PHY_VARS_eNB***));
     RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int));
-    LOG_I(PHY,"%s() RC.eNB:%p RC.nb_L1_CC:%p\n", __FUNCTION__, RC.eNB, RC.nb_L1_CC);
   }
 
-  setting = config_lookup(&cfg, CONFIG_STRING_L1_LIST);
-
-  printf("%s() CONFIG_STRING_L1_LIST setting:%p\n", __FUNCTION__, setting);
+  config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL);    
+  if (L1_ParamList.numelt > 0) {
 
-  for (j = 0; j < RC.nb_L1_inst; j++) {
+    for (j = 0; j < RC.nb_L1_inst; j++) {
+      RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr);
 
-    if (RC.eNB[j] == NULL) {
-      RC.eNB[j]                       = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**));
-      LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
-      memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***));
-    }
-
-    if (setting != NULL) {
-
-      setting_l1 = config_setting_get_elem(setting, j);
-      if (!config_setting_lookup_int   (setting_l1,CONFIG_STRING_L1_CC,&RC.nb_L1_CC[j]))
-        AssertFatal (0,
-            "Failed to parse configuration file %s, L1 %d config !\n",
-            RC.config_file_name, j);	
-    }
-
-    for (i=0;i<RC.nb_L1_CC[j];i++) {
-      if (RC.eNB[j][i] == NULL) {
-        RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB));
-        memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB));
-        LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]);
-        RC.eNB[j][i]->Mod_id  = j;
-        RC.eNB[j][i]->CC_id   = i;
+      if (RC.eNB[j] == NULL) {
+	RC.eNB[j]                       = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**));
+	LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
+	memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***));
       }
-    }
-
-    printf("l1 %d/%d (nb CC %d)\n",j,RC.nb_inst,RC.nb_L1_CC[j]);
 
-    if (setting_l1)
-    {
-      if (!(config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE, (const char **)&tr_n_preference))) {
-        AssertFatal (0,
-            "Failed to parse configuration file %s, L1 %d config !\n",
-            RC.config_file_name, j);
+      for (i=0;i<RC.nb_L1_CC[j];i++) {
+        if (RC.eNB[j][i] == NULL) {
+          RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB));
+          memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB));
+          LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]);
+          RC.eNB[j][i]->Mod_id  = j;
+          RC.eNB[j][i]->CC_id   = i;
+        }
       }
-      printf("RU %d: Transport %s\n",j,tr_n_preference);
 
-      if (strcmp(tr_n_preference, "local_mac") == 0) {
+      if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_mac") == 0) {
 
       }
-      else if (strcmp(tr_n_preference, "nfapi") == 0) {
-        if (  !(
-              config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_IF_NAME,        (const char **)&if_name_n)
-              && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_LOCAL_N_ADDRESS,        (const char **)&ipv4_n)
-              && config_setting_lookup_string(setting_l1, CONFIG_STRING_L1_REMOTE_N_ADDRESS,       (const char **)&ipv4_n_remote)
-              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTC,          &local_n_portc)
-              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTC,         &remote_n_portc)
-              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_LOCAL_N_PORTD,          &local_n_portd)
-              && config_setting_lookup_int   (setting_l1, CONFIG_STRING_L1_REMOTE_N_PORTD,         &remote_n_portd)
-              )
-           ) {
-          AssertFatal (0,
-              "Failed to parse configuration file %s, L1 %d config !\n",
-              RC.config_file_name, j);
-          continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
-        }
-        RC.eNB[j][0]->eth_params_n.local_if_name            = strdup(if_name_n);
-        RC.eNB[j][0]->eth_params_n.my_addr                  = strdup(ipv4_n);
-        RC.eNB[j][0]->eth_params_n.remote_addr              = strdup(ipv4_n_remote);
-        RC.eNB[j][0]->eth_params_n.my_portc                 = local_n_portc;
-        RC.eNB[j][0]->eth_params_n.remote_portc             = remote_n_portc;
-        RC.eNB[j][0]->eth_params_n.my_portd                 = local_n_portd;
-        RC.eNB[j][0]->eth_params_n.remote_portd             = remote_n_portd;
-        RC.eNB[j][0]->eth_params_n.transp_preference        = ETH_UDP_MODE;
-
-        configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n.remote_portd);
+      else if (strcmp(*(L1_ParamList.paramarray[j][L1_TRANSPORT_N_PREFERENCE_IDX].strptr), "nfapi") == 0) {
+        RC.eNB[j][0]->eth_params_n.local_if_name            = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_IF_NAME_IDX].strptr));
+	RC.eNB[j][0]->eth_params_n.my_addr                  = strdup(*(L1_ParamList.paramarray[j][L1_LOCAL_N_ADDRESS_IDX].strptr));
+	RC.eNB[j][0]->eth_params_n.remote_addr              = strdup(*(L1_ParamList.paramarray[j][L1_REMOTE_N_ADDRESS_IDX].strptr));
+	RC.eNB[j][0]->eth_params_n.my_portc                 = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTC_IDX].iptr);
+	RC.eNB[j][0]->eth_params_n.remote_portc             = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTC_IDX].iptr);
+	RC.eNB[j][0]->eth_params_n.my_portd                 = *(L1_ParamList.paramarray[j][L1_LOCAL_N_PORTD_IDX].iptr);
+	RC.eNB[j][0]->eth_params_n.remote_portd             = *(L1_ParamList.paramarray[j][L1_REMOTE_N_PORTD_IDX].iptr);
+	RC.eNB[j][0]->eth_params_n.transp_preference        = ETH_UDP_MODE;
+
+        nfapi_pnf = 1;
 
         RC.nb_macrlc_inst = 1;  // This is used by mac_top_init_eNB()
 
@@ -811,333 +299,286 @@ void RCconfig_L1(void) {
         LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_macrlc_inst:%d because used by mac_top_init_eNB()\n", __FUNCTION__, RC.nb_macrlc_inst);
 
         mac_top_init_eNB();
+
+
+        configure_nfapi_pnf(RC.eNB[j][0]->eth_params_n.remote_addr, RC.eNB[j][0]->eth_params_n.remote_portc, RC.eNB[j][0]->eth_params_n.my_addr, RC.eNB[j][0]->eth_params_n.my_portd, RC.eNB[j][0]->eth_params_n     .remote_portd);
+
       }
       else { // other midhaul
       }	
-    } // setting
-  }// j=0..num_inst
-  printf("Initializing northbound interface for L1\n");
-  l1_north_init_eNB();
+    }// j=0..num_inst
+    printf("Initializing northbound interface for L1\n");
+    l1_north_init_eNB();
+  } else {
+#if 0
+    // DJP need to create some structures for VNF
+    AssertFatal (0,
+        "No " CONFIG_STRING_L1_LIST " configuration found");    
+#else
+    j = 0;
 
-}
+    RC.nb_L1_CC = malloc((1+RC.nb_L1_inst)*sizeof(int)); // DJP - 1 lot then???
 
-void RCconfig_macrlc(void) {
+    RC.nb_L1_CC[j]=1; // DJP - hmmm
 
-  int               j;
+    if (RC.eNB[j] == NULL) {
+      RC.eNB[j]                       = (PHY_VARS_eNB **)malloc((1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB**));
+      LOG_I(PHY,"RC.eNB[%d] = %p\n",j,RC.eNB[j]);
+      memset(RC.eNB[j],0,(1+MAX_NUM_CCs)*sizeof(PHY_VARS_eNB***));
+    }
 
-  config_t          cfg;
-  config_setting_t *setting                         = NULL;
-  config_setting_t *setting_macrlc                  = NULL;
-  char*             if_name_s                       = NULL;
-  char*             ipv4_s                          = NULL;
-  char*             ipv4_s_remote                   = NULL;
- 
-  char*             tr_s_preference                 = NULL;
-  libconfig_int     local_s_portc                   = 0;
-  libconfig_int     remote_s_portc                  = 0;
-  libconfig_int     local_s_portd                   = 0;
-  libconfig_int     remote_s_portd                  = 0;
-  char*             if_name_n                       = NULL;
-  char*             ipv4_n                          = NULL;
-  char*             ipv4_n_remote                   = NULL;
- 
-  char*             tr_n_preference                 = NULL;
-  libconfig_int     local_n_portc                   = 0;
-  libconfig_int     remote_n_portc                  = 0;
-  libconfig_int     local_n_portd                   = 0;
-  libconfig_int     remote_n_portd                  = 0;
+    for (i=0;i<RC.nb_L1_CC[j];i++) {
+      if (RC.eNB[j][i] == NULL) {
+        RC.eNB[j][i] = (PHY_VARS_eNB *)malloc(sizeof(PHY_VARS_eNB));
+        memset((void*)RC.eNB[j][i],0,sizeof(PHY_VARS_eNB));
+        LOG_I(PHY,"RC.eNB[%d][%d] = %p\n",j,i,RC.eNB[j][i]);
+        RC.eNB[j][i]->Mod_id  = j;
+        RC.eNB[j][i]->CC_id   = i;
+      }
+    }
+#endif
+
+  }
+}
+
+void RCconfig_macrlc() {
+  int               j;
 
-  printf("%s() Enter\n" , __FUNCTION__);
 
-  load_config_file(&cfg);
+  paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC;
+  paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
 
-  setting = config_lookup(&cfg, CONFIG_STRING_MACRLC_LIST);
+  config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL);    
   
-  if (setting != NULL) {
-    
-    if ((RC.nb_macrlc_inst=config_setting_length(setting))>0) mac_top_init_eNB();
-    else AssertFatal(1==0,"improper macrlc setting\n");
-    
+  if ( MacRLC_ParamList.numelt > 0) {
+
+    RC.nb_macrlc_inst=MacRLC_ParamList.numelt; 
+    mac_top_init_eNB();   
     for (j=0;j<RC.nb_macrlc_inst;j++) {
-      setting_macrlc = config_setting_get_elem(setting, j);
-      
-      printf("macrlc %d/%d \n",j,RC.nb_macrlc_inst);
-      
-      if (!(config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE, (const char **)&tr_n_preference))) {
-	AssertFatal (0,
-		     "Failed to parse configuration file %s, L1 %d config !\n",
-		     RC.config_file_name, j);
-      }
 
-      printf("MACRLC %d: Northbound Transport %s\n",j,tr_n_preference);
-      
-      if (strcmp(tr_n_preference, "local_RRC") == 0) {
+      if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "local_RRC") == 0) {
 	// check number of instances is same as RRC/PDCP
 	
-      }
-      else if (strcmp(tr_n_preference, "cudu") == 0) {
-	if (  !(
-		config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME,        (const char **)&if_name_n)
-		&& config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS,        (const char **)&ipv4_n)
-		&& config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS,       (const char **)&ipv4_n_remote)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_N_PORTC,          &local_n_portc)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_REMOTE_N_PORTC,         &remote_n_portc)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_N_PORTD,          &local_n_portd)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_REMOTE_N_PORTD,         &remote_n_portd)
-		)
-	      ) {
-	  AssertFatal (0,
-		       "Failed to parse configuration file %s, L1 %d config !\n",
-		       RC.config_file_name, j);
-	  continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
-	}
-	RC.mac[j]->eth_params_n.local_if_name            = strdup(if_name_n);
-	RC.mac[j]->eth_params_n.my_addr                  = strdup(ipv4_n);
-	RC.mac[j]->eth_params_n.remote_addr              = strdup(ipv4_n_remote);
-	RC.mac[j]->eth_params_n.my_portc                 = local_n_portc;
-	RC.mac[j]->eth_params_n.remote_portc             = remote_n_portc;
-	RC.mac[j]->eth_params_n.my_portd                 = local_n_portd;
-	RC.mac[j]->eth_params_n.remote_portd             = remote_n_portd;
+      } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) {
+	RC.mac[j]->eth_params_n.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr));
+	RC.mac[j]->eth_params_n.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr));
+	RC.mac[j]->eth_params_n.remote_addr              = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr));
+	RC.mac[j]->eth_params_n.my_portc                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr);
+	RC.mac[j]->eth_params_n.remote_portc             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr);
+	RC.mac[j]->eth_params_n.my_portd                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTD_IDX].iptr);
+	RC.mac[j]->eth_params_n.remote_portd             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTD_IDX].iptr);;
 	RC.mac[j]->eth_params_n.transp_preference        = ETH_UDP_MODE;
-      }
-      
-      else { // other midhaul
-	AssertFatal(1==0,"MACRLC %d: unknown northbound midhaul\n",j);
+      } else { // other midhaul
+	AssertFatal(1==0,"MACRLC %d: %s unknown northbound midhaul\n",j, *(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr));
       }	
 
-      if (!(config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE, (const char **)&tr_s_preference))) {
-	AssertFatal (0,
-		     "Failed to parse configuration file %s, L1 %d config !\n",
-		     RC.config_file_name, j);
-	continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
-      }
-
-      printf("MACRLC %d: Southbound Transport %s\n",j,tr_s_preference);
-      
-      if (strcmp(tr_s_preference, "local_L1") == 0) {
+      if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_L1") == 0) {
 
 	
-      }
-      else if (strcmp(tr_s_preference, "nfapi") == 0) {
-	if (  !( 
-		config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME,        (const char **)&if_name_s)
-		&& config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS,        (const char **)&ipv4_s)
-		&& config_setting_lookup_string(setting_macrlc, CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS,       (const char **)&ipv4_s_remote)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_S_PORTC,          &local_s_portc)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_REMOTE_S_PORTC,         &remote_s_portc)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_LOCAL_S_PORTD,          &local_s_portd)
-		&& config_setting_lookup_int   (setting_macrlc, CONFIG_STRING_MACRLC_REMOTE_S_PORTD,         &remote_s_portd)
-		 )){
-	  AssertFatal (0,
-		       "Failed to parse configuration file %s, L1 %d config !\n",
-		       RC.config_file_name, j);
-	  continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
-	}
-
-	RC.mac[j]->eth_params_s.local_if_name            = strdup(if_name_s);
-	RC.mac[j]->eth_params_s.my_addr                  = strdup(ipv4_s);
-	RC.mac[j]->eth_params_s.remote_addr              = strdup(ipv4_s_remote);
-	RC.mac[j]->eth_params_s.my_portc                 = local_s_portc;
-	RC.mac[j]->eth_params_s.remote_portc             = remote_s_portc;
-	RC.mac[j]->eth_params_s.my_portd                 = local_s_portd;
-	RC.mac[j]->eth_params_s.remote_portd             = remote_s_portd;
+      } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr), "nfapi") == 0) {
+	RC.mac[j]->eth_params_s.local_if_name            = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_IF_NAME_IDX].strptr));
+	RC.mac[j]->eth_params_s.my_addr                  = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_ADDRESS_IDX].strptr));
+	RC.mac[j]->eth_params_s.remote_addr              = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_ADDRESS_IDX].strptr));
+	RC.mac[j]->eth_params_s.my_portc                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTC_IDX].iptr);
+	RC.mac[j]->eth_params_s.remote_portc             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTC_IDX].iptr);
+	RC.mac[j]->eth_params_s.my_portd                 = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_S_PORTD_IDX].iptr);
+	RC.mac[j]->eth_params_s.remote_portd             = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr);
 	RC.mac[j]->eth_params_s.transp_preference        = ETH_UDP_MODE;
 
+        nfapi_pnf = 2;
+
         printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
         configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc);
         printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc);
-      }
       
-      else { // other midhaul
-	AssertFatal(1==0,"MACRLC %d: unknown southbound midhaul\n",j);
+      } else { // other midhaul
+	AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
       }	
     }// j=0..num_inst
-  }
-  else
-  {
-    printf("No MAC/RLC instances\n");
+  } else {// MacRLC_ParamList.numelt > 0
+	  AssertFatal (0,
+		       "No " CONFIG_STRING_MACRLC_LIST " configuration found");     
   }
 }
 	       
 int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
-  config_t          cfg;
-  config_setting_t *setting                       = NULL;
-  config_setting_t *setting_component_carriers    = NULL;
-  config_setting_t *component_carrier             = NULL;
-  config_setting_t *setting_srb1                  = NULL;
-  config_setting_t *setting_enb                   = NULL;
+
   int               num_enbs                      = 0;
+ 
   int               num_component_carriers        = 0;
-  int               j                             = 0;
-  libconfig_int     enb_id                        = 0;
+  int               j,k                           = 0;
+  int32_t     enb_id                        = 0;
   int               nb_cc                         = 0;
 
-  char*             if_name_s                       = NULL;
-  char*             ipv4_s                          = NULL;
-  char*             ipv4_s_remote                   = NULL;
- 
-  char*             tr_s_preference                 = NULL;
-  libconfig_int     local_s_portc                   = 0;
-  libconfig_int     remote_s_portc                  = 0;
-  libconfig_int     local_s_portd                   = 0;
-  libconfig_int     remote_s_portd                  = 0;
-
-  const char*       cell_type                     = NULL;
-  const char*       tac                           = 0;
-  const char*       enb_name                      = NULL;
-  const char*       mcc                           = 0;
-  const char*       mnc                           = 0;
-  const char*       frame_type                    = NULL;
-  libconfig_int     tdd_config                    = 0;
-  libconfig_int     tdd_config_s                  = 0;
-  const char*       prefix_type                   = NULL;
-  const char*       pbch_repetition               = NULL;
-  libconfig_int     eutra_band                    = 0;
+
+  char*       frame_type                    = NULL;
+  int32_t     tdd_config                    = 0;
+  int32_t     tdd_config_s                  = 0;
+
+  char*       prefix_type                   = NULL;
+  char*       pbch_repetition               = NULL;
+  
+  int32_t     eutra_band                    = 0;
   long long int     downlink_frequency            = 0;
-  libconfig_int     uplink_frequency_offset       = 0;
-  libconfig_int     Nid_cell                      = 0;
-  libconfig_int     Nid_cell_mbsfn                = 0;
-  libconfig_int     N_RB_DL                       = 0;
-  libconfig_int     nb_antenna_ports              = 0;
-  libconfig_int     prach_root                    = 0;
-  libconfig_int     prach_config_index            = 0;
-  const char*            prach_high_speed         = NULL;
-  libconfig_int     prach_zero_correlation        = 0;
-  libconfig_int     prach_freq_offset             = 0;
-  libconfig_int     pucch_delta_shift             = 0;
-  libconfig_int     pucch_nRB_CQI                 = 0;
-  libconfig_int     pucch_nCS_AN                  = 0;
-#if !defined(Rel10) && !defined(Rel14)
-  libconfig_int     pucch_n1_AN                   = 0;
-#endif
-  libconfig_int     pdsch_referenceSignalPower    = 0;
-  libconfig_int     pdsch_p_b                     = 0;
-  libconfig_int     pusch_n_SB                    = 0;
-  const char *      pusch_hoppingMode             = NULL;
-  libconfig_int     pusch_hoppingOffset           = 0;
-  const char*          pusch_enable64QAM          = NULL;
-  const char*          pusch_groupHoppingEnabled  = NULL;
-  libconfig_int     pusch_groupAssignment         = 0;
-  const char*          pusch_sequenceHoppingEnabled = NULL;
-  libconfig_int     pusch_nDMRS1                  = 0;
-  const char*       phich_duration                = NULL;
-  const char*       phich_resource                = NULL;
-  const char*       srs_enable                    = NULL;
-  libconfig_int     srs_BandwidthConfig           = 0;
-  libconfig_int     srs_SubframeConfig            = 0;
-  const char*       srs_ackNackST                 = NULL;
-  const char*       srs_MaxUpPts                  = NULL;
-  libconfig_int     pusch_p0_Nominal              = 0;
-  const char*       pusch_alpha                   = NULL;
-  libconfig_int     pucch_p0_Nominal              = 0;
-  libconfig_int     msg3_delta_Preamble           = 0;
-  //libconfig_int     ul_CyclicPrefixLength         = 0;
-  const char*       pucch_deltaF_Format1          = NULL;
+  int32_t     uplink_frequency_offset       = 0;
+  int32_t     Nid_cell                      = 0;
+  int32_t     Nid_cell_mbsfn                = 0;
+  int32_t     N_RB_DL                       = 0;
+  int32_t     nb_antenna_ports              = 0;
+
+  int32_t     prach_root                    = 0;
+  int32_t     prach_config_index            = 0;
+  char*            prach_high_speed         = NULL;
+  int32_t     prach_zero_correlation        = 0;
+  int32_t     prach_freq_offset             = 0;
+  int32_t     pucch_delta_shift             = 0;
+  int32_t     pucch_nRB_CQI                 = 0;
+  int32_t     pucch_nCS_AN                  = 0;
+//#if !defined(Rel10) && !defined(Rel14)
+  int32_t     pucch_n1_AN                   = 0;
+//#endif
+  int32_t     pdsch_referenceSignalPower    = 0;
+  int32_t     pdsch_p_b                     = 0;
+  int32_t     pusch_n_SB                    = 0;
+  char *      pusch_hoppingMode             = NULL;
+  int32_t     pusch_hoppingOffset           = 0;
+  char*          pusch_enable64QAM          = NULL;
+  char*          pusch_groupHoppingEnabled  = NULL;
+  int32_t     pusch_groupAssignment         = 0;
+  char*          pusch_sequenceHoppingEnabled = NULL;
+  int32_t     pusch_nDMRS1                  = 0;
+  char*       phich_duration                = NULL;
+  char*       phich_resource                = NULL;
+  char*       srs_enable                    = NULL;
+  int32_t     srs_BandwidthConfig           = 0;
+  int32_t     srs_SubframeConfig            = 0;
+  char*       srs_ackNackST                 = NULL;
+  char*       srs_MaxUpPts                  = NULL;
+  int32_t     pusch_p0_Nominal              = 0;
+  char*       pusch_alpha                   = NULL;
+  int32_t     pucch_p0_Nominal              = 0;
+  int32_t     msg3_delta_Preamble           = 0;
+  //int32_t     ul_CyclicPrefixLength         = 0;
+  char*       pucch_deltaF_Format1          = NULL;
   //const char*       pucch_deltaF_Format1a         = NULL;
-  const char*       pucch_deltaF_Format1b         = NULL;
-  const char*       pucch_deltaF_Format2          = NULL;
-  const char*       pucch_deltaF_Format2a         = NULL;
-  const char*       pucch_deltaF_Format2b         = NULL;
-  libconfig_int     rach_numberOfRA_Preambles     = 0;
-  const char*       rach_preamblesGroupAConfig    = NULL;
-  libconfig_int     rach_sizeOfRA_PreamblesGroupA = 0;
-  libconfig_int     rach_messageSizeGroupA        = 0;
-  const char*       rach_messagePowerOffsetGroupB = NULL;
-  libconfig_int     rach_powerRampingStep         = 0;
-  libconfig_int     rach_preambleInitialReceivedTargetPower    = 0;
-  libconfig_int     rach_preambleTransMax         = 0;
-  libconfig_int     rach_raResponseWindowSize     = 0;
-  libconfig_int     rach_macContentionResolutionTimer = 0;
-  libconfig_int     rach_maxHARQ_Msg3Tx           = 0;
-  libconfig_int     pcch_defaultPagingCycle       = 0;
-  const char*       pcch_nB                       = NULL;
-  libconfig_int     bcch_modificationPeriodCoeff  = 0;
-  libconfig_int     ue_TimersAndConstants_t300    = 0;
-  libconfig_int     ue_TimersAndConstants_t301    = 0;
-  libconfig_int     ue_TimersAndConstants_t310    = 0;
-  libconfig_int     ue_TimersAndConstants_t311    = 0;
-  libconfig_int     ue_TimersAndConstants_n310    = 0;
-  libconfig_int     ue_TimersAndConstants_n311    = 0;
-  libconfig_int     ue_TransmissionMode           = 0;
-
-
-  libconfig_int     srb1_timer_poll_retransmit    = 0;
-  libconfig_int     srb1_timer_reordering         = 0;
-  libconfig_int     srb1_timer_status_prohibit    = 0;
-  libconfig_int     srb1_poll_pdu                 = 0;
-  libconfig_int     srb1_poll_byte                = 0;
-  libconfig_int     srb1_max_retx_threshold       = 0;
-
-  libconfig_int     my_int;
+  char*       pucch_deltaF_Format1b         = NULL;
+  char*       pucch_deltaF_Format2          = NULL;
+  char*       pucch_deltaF_Format2a         = NULL;
+  char*       pucch_deltaF_Format2b         = NULL;
+  int32_t     rach_numberOfRA_Preambles     = 0;
+  char*       rach_preamblesGroupAConfig    = NULL;
+  int32_t     rach_sizeOfRA_PreamblesGroupA = 0;
+  int32_t     rach_messageSizeGroupA        = 0;
+  char*       rach_messagePowerOffsetGroupB = NULL;
+  int32_t     rach_powerRampingStep         = 0;
+  int32_t     rach_preambleInitialReceivedTargetPower    = 0;
+  int32_t     rach_preambleTransMax         = 0;
+  int32_t     rach_raResponseWindowSize     = 0;
+  int32_t     rach_macContentionResolutionTimer = 0;
+  int32_t     rach_maxHARQ_Msg3Tx           = 0;
+  int32_t     pcch_defaultPagingCycle       = 0;
+  char*       pcch_nB                       = NULL;
+  int32_t     bcch_modificationPeriodCoeff  = 0;
+  int32_t     ue_TimersAndConstants_t300    = 0;
+  int32_t     ue_TimersAndConstants_t301    = 0;
+  int32_t     ue_TimersAndConstants_t310    = 0;
+  int32_t     ue_TimersAndConstants_t311    = 0;
+  int32_t     ue_TimersAndConstants_n310    = 0;
+  int32_t     ue_TimersAndConstants_n311    = 0;
+  int32_t     ue_TransmissionMode           = 0;
+
+
+  int32_t     srb1_timer_poll_retransmit    = 0;
+  int32_t     srb1_timer_reordering         = 0;
+  int32_t     srb1_timer_status_prohibit    = 0;
+  int32_t     srb1_poll_pdu                 = 0;
+  int32_t     srb1_poll_byte                = 0;
+  int32_t     srb1_max_retx_threshold       = 0;
+
+  int32_t     my_int;
 
 
-  const char*       active_enb[MAX_ENB];
-  char             *astring                       = NULL;
+  
+/* 
+  char*             flexran_agent_interface_name      = NULL;
+  char*             flexran_agent_ipv4_address        = NULL;
+  int32_t     flexran_agent_port                = 0;
+  char*             flexran_agent_cache               = NULL;
+  int32_t     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;
   (void)my_int;
+  paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
+  
+  paramdef_t ENBParams[]  = ENBPARAMS_DESC;
+  paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};  
 
-  memset((char*)active_enb,     0 , MAX_ENB * sizeof(char*));
+  paramdef_t CCsParams[] = CCPARAMS_DESC;
+  paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0};
+  
+  paramdef_t SRB1Params[] = SRB1PARAMS_DESC;  
 
-  config_init(&cfg);
+  
 
-  if (RC.config_file_name != NULL) {
-    // Read the file. If there is an error, report it and exit. 
-    if (! config_read_file(&cfg, RC.config_file_name)) {
-      config_destroy(&cfg);
-      AssertFatal (0, "Failed to parse eNB configuration file %s!\n", RC.config_file_name);
-    }
-  } else {
-    config_destroy(&cfg);
-    AssertFatal (0, "No eNB configuration file provided!\n");
-  }
 
+/* get global parameters, defined outside any section in the config file */
+  
+  config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); 
+  num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
+  AssertFatal (i<num_enbs,
+   	       "Failed to parse config file no %ith element in %s \n",i, ENB_CONFIG_STRING_ACTIVE_ENBS);
+  
 #if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
 
-  if (  (config_lookup_string( &cfg, ENB_CONFIG_STRING_ASN1_VERBOSITY, (const char **)&astring) )) {
-    if (strcasecmp(astring , ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
+
+    if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
       asn_debug      = 0;
       asn1_xer_print = 0;
-    } else if (strcasecmp(astring , ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
+    } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
       asn_debug      = 1;
       asn1_xer_print = 1;
-    } else if (strcasecmp(astring , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
+    } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
       asn_debug      = 1;
       asn1_xer_print = 2;
     } else {
       asn_debug      = 0;
       asn1_xer_print = 0;
     }
-  }
 
-#endif
 
-  // Get list of active eNBs, (only these will be configured)
-  setting = config_lookup(&cfg, ENB_CONFIG_STRING_ACTIVE_ENBS);
-
-  if (setting != NULL) {
-    num_enbs = config_setting_length(setting);
-    setting_enb   = config_setting_get_elem(setting, i);
-    active_enb[i] = config_setting_get_string (setting_enb);
-    AssertFatal (active_enb[i] != NULL,
-		 "Failed to parse config file %s, %uth attribute %s \n",
-		 RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
-    active_enb[i] = strdup(active_enb[i]);
-  }
+#endif
   
+
   
   if (num_enbs>0) {
     // Output a list of all eNBs.
-    setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST);
+    config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); 
+    
     
-    if (setting != NULL) {
-      num_enbs = config_setting_length(setting);
       
-
-      setting_enb = config_setting_get_elem(setting, i);
       
-      if (! config_setting_lookup_int(setting_enb, ENB_CONFIG_STRING_ENB_ID, &enb_id)) {
+      if (ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr == NULL) {
 	// Calculate a default eNB ID
 # if defined(ENABLE_USE_MME)
 	uint32_t hash;
@@ -1147,48 +588,25 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 # else
 	enb_id = i;
 # endif
+      } else {
+          enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr);
       }
 
-      if (  !(       config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_CELL_TYPE,           &cell_type)
-		     && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_ENB_NAME,            &enb_name)
-		     && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_TRACKING_AREA_CODE,  &tac)
-		     && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, &mcc)
-		     && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, &mnc)
-		     && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE, (const char **)&tr_s_preference)
-		     )
-	    ) {
-	AssertFatal (0,
-		     "Failed to parse eNB configuration file %s, %u th enb\n",
-		     RC.config_file_name, i);
-      }
       
-      printf("RRC %d: Southbound Transport %s\n",j,tr_s_preference);
+      printf("RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr));
 	    
-      if (strcmp(tr_s_preference, "local_mac") == 0) {
+      if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "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)
-		&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_LOCAL_S_ADDRESS,        (const char **)&ipv4_s)
-		&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_REMOTE_S_ADDRESS,       (const char **)&ipv4_s_remote)
-		&& config_setting_lookup_int   (setting_enb, ENB_CONFIG_STRING_LOCAL_S_PORTC,          &local_s_portc)
-		&& config_setting_lookup_int   (setting_enb, ENB_CONFIG_STRING_REMOTE_S_PORTC,         &remote_s_portc)
-		&& config_setting_lookup_int   (setting_enb, ENB_CONFIG_STRING_LOCAL_S_PORTD,          &local_s_portd)
-		&& config_setting_lookup_int   (setting_enb, ENB_CONFIG_STRING_REMOTE_S_PORTD,         &remote_s_portd)	
-		)
-	    ) {
-	  AssertFatal (0,
-		       "Failed to parse eNB configuration file %s, %u th enb\n",
-		       RC.config_file_name, i);
-	}
-	rrc->eth_params_s.local_if_name            = strdup(if_name_s);
-	rrc->eth_params_s.my_addr                  = strdup(ipv4_s);
-	rrc->eth_params_s.remote_addr              = strdup(ipv4_s_remote);
-	rrc->eth_params_s.my_portc                 = local_s_portc;
-	rrc->eth_params_s.remote_portc             = remote_s_portc;
-	rrc->eth_params_s.my_portd                 = local_s_portd;
-	rrc->eth_params_s.remote_portd             = remote_s_portd;
+      else if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) {
+	rrc->eth_params_s.local_if_name            = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_IF_NAME_IDX].strptr));
+	rrc->eth_params_s.my_addr                  = strdup(*(ENBParamList.paramarray[i][ENB_LOCAL_S_ADDRESS_IDX].strptr));
+	rrc->eth_params_s.remote_addr              = strdup(*(ENBParamList.paramarray[i][ENB_REMOTE_S_ADDRESS_IDX].strptr));
+	rrc->eth_params_s.my_portc                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTC_IDX].uptr);
+	rrc->eth_params_s.remote_portc             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTC_IDX].uptr);
+	rrc->eth_params_s.my_portd                 = *(ENBParamList.paramarray[i][ENB_LOCAL_S_PORTD_IDX].uptr);
+	rrc->eth_params_s.remote_portd             = *(ENBParamList.paramarray[i][ENB_REMOTE_S_PORTD_IDX].uptr);
 	rrc->eth_params_s.transp_preference        = ETH_UDP_MODE;
       }
       
@@ -1197,116 +615,104 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 
       // search if in active list
 
-      for (j=0; j < num_enbs; j++) {
-	if (strcmp(active_enb[j], enb_name) == 0) {
+     
+   
+   
+ 
+
+      for (k=0; k <num_enbs ; k++) {
+	if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[k], *(ENBParamList.paramarray[i][ENB_ENB_NAME_IDX].strptr) )== 0) {
+	  char enbpath[MAX_OPTNAME_SIZE + 8];
+
 	  
 	  RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id;
 	  
-
-	  RRC_CONFIGURATION_REQ (msg_p).tac              = (uint16_t)atoi(tac);
-	  RRC_CONFIGURATION_REQ (msg_p).mcc              = (uint16_t)atoi(mcc);
-	  RRC_CONFIGURATION_REQ (msg_p).mnc              = (uint16_t)atoi(mnc);
-	  RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = strlen(mnc);
+	  /*    
+		if (strcmp(*(ENBParamList.paramarray[i][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_MACRO_ENB;
+		} else  if (strcmp(cell_type, "CELL_HOME_ENB") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cell_type = CELL_HOME_ENB;
+		} else {
+		AssertFatal (0,
+		"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
+		lib_config_file_name_pP, i, cell_type);
+		}
+		
+		enb_properties_loc.properties[enb_properties_loc_index]->eNB_name         = strdup(enb_name);
+	  */
+	  RRC_CONFIGURATION_REQ (msg_p).tac              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].strptr) );
+	  RRC_CONFIGURATION_REQ (msg_p).mcc              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX].strptr) );
+	  RRC_CONFIGURATION_REQ (msg_p).mnc              = (uint16_t)atoi( *(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr) );
+	  RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
 	  AssertFatal((RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 2) ||
 		      (RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length == 3),
 		      "BAD MNC DIGIT LENGTH %d",
 		      RRC_CONFIGURATION_REQ (msg_p).mnc_digit_length);
 	  
-	  LOG_I(RRC,"RRC config (%s,%s,%s)\n",mcc,mnc,tac);
+	
 	  // Parse optional physical parameters
+	  sprintf(enbpath,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k),
+	  config_getlist( &CCsParamList,NULL,0,enbpath); 
 	  
-	  
-	  setting_component_carriers = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_COMPONENT_CARRIERS);
-	  nb_cc = 0;
-	  
-	  if (setting_component_carriers != NULL) {
+	  LOG_I(RRC,"num component carriers %d \n", num_component_carriers);  
+	  if ( CCsParamList.numelt> 0) {
+	    char ccspath[MAX_OPTNAME_SIZE*2 + 16];
 	    
-	    num_component_carriers     = config_setting_length(setting_component_carriers);
-	    LOG_I(RRC,"num component carriers %d \n", num_component_carriers);
+
+	    
+
 	    
 	    //enb_properties_loc.properties[enb_properties_loc_index]->nb_cc = num_component_carriers;
-	    for (j = 0; j < num_component_carriers ;j++) { // && j < MAX_NUM_CCs; j++) {
-	      component_carrier = config_setting_get_elem(setting_component_carriers, j);
-	      
-	      //printf("Component carrier %d\n",component_carrier);
-	      if (!(config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_FRAME_TYPE, &frame_type)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_TDD_CONFIG, &tdd_config)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_TDD_CONFIG_S, &tdd_config_s)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PREFIX_TYPE, &prefix_type)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PBCH_REPETITION, &pbch_repetition)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_EUTRA_BAND, &eutra_band)
-		    && config_setting_lookup_int64(component_carrier, ENB_CONFIG_STRING_DOWNLINK_FREQUENCY, &downlink_frequency)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET, &uplink_frequency_offset)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_NID_CELL, &Nid_cell)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_N_RB_DL, &N_RB_DL)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_CELL_MBSFN, &Nid_cell_mbsfn)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_NB_ANT_PORTS, &nb_antenna_ports)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PRACH_ROOT, &prach_root)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PRACH_CONFIG_INDEX, &prach_config_index)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PRACH_HIGH_SPEED, &prach_high_speed)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION, &prach_zero_correlation)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PRACH_FREQ_OFFSET, &prach_freq_offset)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT, &pucch_delta_shift)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_NRB_CQI, &pucch_nRB_CQI)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_NCS_AN, &pucch_nCS_AN)
-#if !defined(Rel10) && !defined(Rel14)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_N1_AN, &pucch_n1_AN)
-#endif
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PDSCH_RS_EPRE, &pdsch_referenceSignalPower)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PDSCH_PB, &pdsch_p_b)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUSCH_N_SB, &pusch_n_SB)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE, &pusch_hoppingMode)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET, &pusch_hoppingOffset)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM, &pusch_enable64QAM)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN, &pusch_groupHoppingEnabled)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT, &pusch_groupAssignment)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN, &pusch_sequenceHoppingEnabled)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUSCH_NDMRS1, &pusch_nDMRS1)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PHICH_DURATION, &phich_duration)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PHICH_RESOURCE, &phich_resource)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_SRS_ENABLE, &srs_enable)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUSCH_PO_NOMINAL, &pusch_p0_Nominal)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUSCH_ALPHA, &pusch_alpha)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PUCCH_PO_NOMINAL, &pucch_p0_Nominal)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE, &msg3_delta_Preamble)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1, &pucch_deltaF_Format1)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b, &pucch_deltaF_Format1b)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2, &pucch_deltaF_Format2)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A, &pucch_deltaF_Format2a)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B, &pucch_deltaF_Format2b)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES, &rach_numberOfRA_Preambles)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG, &rach_preamblesGroupAConfig)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP, &rach_powerRampingStep)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER, &rach_preambleInitialReceivedTargetPower)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX, &rach_preambleTransMax)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE, &rach_raResponseWindowSize)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER, &rach_macContentionResolutionTimer)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX, &rach_maxHARQ_Msg3Tx)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX, &bcch_modificationPeriodCoeff)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE,  &pcch_defaultPagingCycle)
-		    && config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_PCCH_NB,  &pcch_nB)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF,  &bcch_modificationPeriodCoeff)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UETIMERS_T300,  &ue_TimersAndConstants_t300)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UETIMERS_T301,  &ue_TimersAndConstants_t301)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UETIMERS_T310,  &ue_TimersAndConstants_t310)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UETIMERS_T311,  &ue_TimersAndConstants_t311)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UETIMERS_N310,  &ue_TimersAndConstants_n310)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UETIMERS_N311,  &ue_TimersAndConstants_n311)
-		    && config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_UE_TRANSMISSION_MODE,  &ue_TransmissionMode)
-		    
-#if defined(Rel10) || defined(Rel14)
+
+
+	    for (j = 0; j < CCsParamList.numelt ;j++) { 
+
+	      sprintf(ccspath,"%s.%s.[%i]",enbpath,ENB_CONFIG_STRING_COMPONENT_CARRIERS,j);
+	      config_get( CCsParams,sizeof(CCsParams)/sizeof(paramdef_t),ccspath);	      
+
+
+	      //printf("Component carrier %d\n",component_carrier);	     
+
 		    
 
-#endif
-		    )) {
-		AssertFatal (0,
-			     "Failed to parse eNB configuration file %s, Component Carrier %d!\n",
-			     RC.config_file_name, nb_cc++);
-		continue; // FIXME this prevents segfaults below, not sure what happens after function exit
-	      }
-	      
 	      nb_cc++;
-
+	      /*
+		if (strcmp(cc_node_function, "eNodeB_3GPP") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP;
+		} else if (strcmp(cc_node_function, "eNodeB_3GPP_BBU") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = eNodeB_3GPP_BBU;
+		} else if (strcmp(cc_node_function, "NGFI_RCC_IF4p5") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RCC_IF4p5;
+		} else if (strcmp(cc_node_function, "NGFI_RAU_IF4p5") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RAU_IF4p5;
+		} else if (strcmp(cc_node_function, "NGFI_RRU_IF4p5") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF4p5;
+		} else if (strcmp(cc_node_function, "NGFI_RRU_IF5") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_function[j] = NGFI_RRU_IF5;
+		} else {
+		AssertError (0, parse_errors ++,
+		"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: eNodeB_3GPP or eNodeB_3GPP_BBU or NGFI_IF4_RCC or NGFI_IF4_RRU or NGFI_IF5_RRU !\n",
+		lib_config_file_name_pP, i, cc_node_function);
+		}
+		
+		if (strcmp(cc_node_timing, "synch_to_ext_device") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_ext_device;
+		} else if (strcmp(cc_node_timing, "synch_to_other") == 0) {
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_timing[j] = synch_to_other;
+		} else {
+		AssertError (0, parse_errors ++,
+		"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for node_function choice: SYNCH_TO_DEVICE or SYNCH_TO_OTHER !\n",
+		lib_config_file_name_pP, i, cc_node_timing);
+		}
+		
+		if ((cc_node_synch_ref >= -1) && (cc_node_synch_ref < num_component_carriers)) {  
+		enb_properties_loc.properties[enb_properties_loc_index]->cc_node_synch_ref[j] = (int16_t) cc_node_synch_ref; 
+		} else {
+		AssertError (0, parse_errors ++,
+		"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for node_synch_ref choice: valid CC_id or -1 !\n",
+		lib_config_file_name_pP, i, cc_node_synch_ref);
+		}
+	      */
 	      
 	      RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config;
 	      
@@ -1638,14 +1044,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 			       RC.config_file_name, i, srs_enable);
 
 		if (RRC_CONFIGURATION_REQ (msg_p).srs_enable[j] == TRUE) {
-		  if (!(config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG, &srs_BandwidthConfig)
-			&& config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG, &srs_SubframeConfig)
-			&& config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG, &srs_ackNackST)
-			&& config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_SRS_MAXUPPTS, &srs_MaxUpPts)
-			))
-		    AssertFatal(0,
-				"Failed to parse eNB configuration file %s, enb %d unknown values for srs_BandwidthConfig, srs_SubframeConfig, srs_ackNackST, srs_MaxUpPts\n",
-				RC.config_file_name, i);
 
 		  RRC_CONFIGURATION_REQ (msg_p).srs_BandwidthConfig[j] = srs_BandwidthConfig;
 
@@ -1814,12 +1212,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 		if (strcmp(rach_preamblesGroupAConfig, "ENABLE") == 0) {
 		  RRC_CONFIGURATION_REQ (msg_p).rach_preamblesGroupAConfig[j] = TRUE;
 
-		  if (!(config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA, &rach_sizeOfRA_PreamblesGroupA)
-			&& config_setting_lookup_int(component_carrier, ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA, &rach_messageSizeGroupA)
-			&& config_setting_lookup_string(component_carrier, ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB, &rach_messagePowerOffsetGroupB)))
-		    AssertFatal (0,
-				 "Failed to parse eNB configuration file %s, enb %d  rach_sizeOfRA_PreamblesGroupA, messageSizeGroupA,messagePowerOffsetGroupB!\n",
-				 RC.config_file_name, i);
 
 		  RRC_CONFIGURATION_REQ (msg_p).rach_sizeOfRA_PreamblesGroupA[j] = (rach_sizeOfRA_PreamblesGroupA/4)-1;
 
@@ -2376,21 +1768,10 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 		}
 	      }
 	    }
-
-	    setting_srb1 = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_SRB1);
-
-	    if (setting_srb1 != NULL) {
-	      if (!(config_setting_lookup_int(setting_srb1, ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT, &srb1_timer_poll_retransmit)
-		    && config_setting_lookup_int(setting_srb1, ENB_CONFIG_STRING_SRB1_TIMER_REORDERING,      &srb1_timer_reordering)
-		    && config_setting_lookup_int(setting_srb1, ENB_CONFIG_STRING_SRB1_TIMER_STATUS_PROHIBIT, &srb1_timer_status_prohibit)
-		    && config_setting_lookup_int(setting_srb1, ENB_CONFIG_STRING_SRB1_MAX_RETX_THRESHOLD,    &srb1_max_retx_threshold)
-		    && config_setting_lookup_int(setting_srb1, ENB_CONFIG_STRING_SRB1_POLL_PDU,              &srb1_poll_pdu)
-		    && config_setting_lookup_int(setting_srb1, ENB_CONFIG_STRING_SRB1_POLL_BYTE,             &srb1_poll_byte)))
-		AssertFatal (0,
-			     "Failed to parse eNB configuration file %s, enb %d  timer_poll_retransmit, timer_reordering, "
-			     "timer_status_prohibit, poll_pdu, poll_byte, max_retx_threshold !\n",
-			     RC.config_file_name, i);
-
+	    char srb1path[MAX_OPTNAME_SIZE*2 + 8];
+	    sprintf(srb1path,"%s.%s",enbpath,ENB_CONFIG_STRING_SRB1);
+	    int npar = config_get( SRB1Params,sizeof(SRB1Params)/sizeof(paramdef_t), srb1path);
+	    if (npar == sizeof(SRB1Params)/sizeof(paramdef_t)) {
 	      switch (srb1_max_retx_threshold) {
 	      case 1:
 		rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t1;
@@ -2696,76 +2077,346 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 	      rrc->srb1_poll_byte             = PollByte_kBinfinity;
 	      rrc->srb1_max_retx_threshold    = UL_AM_RLC__maxRetxThreshold_t8;
 	    }
+	    /*
+	    // Network Controller 
+	    subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG);
+
+	    if (subsetting != NULL) {
+	      if (  (
+		     config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME,
+						   (const char **)&flexran_agent_interface_name)
+		     && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS,
+						      (const char **)&flexran_agent_ipv4_address)
+		     && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT,
+						  &flexran_agent_port)
+		     && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE,
+						      (const char **)&flexran_agent_cache)
+		     )
+		    ) {
+		enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_interface_name = strdup(flexran_agent_interface_name);
+		cidr = flexran_agent_ipv4_address;
+		address = strtok(cidr, "/");
+		//enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address = strdup(address);
+		if (address) {
+		  IPV4_STR_ADDR_TO_INT_NWBO (address, enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB Agent !\n" );
+		}
+
+		enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_port = flexran_agent_port;
+		enb_properties_loc.properties[enb_properties_loc_index]->flexran_agent_cache = strdup(flexran_agent_cache);
+	      }
+	    }
+	    */	  
+
+	    /*
+	    // OTG _CONFIG
+	    setting_otg = config_setting_get_member (setting_enb, ENB_CONF_STRING_OTG_CONFIG);
+
+	    if (setting_otg != NULL) {
+	      num_otg_elements  = config_setting_length(setting_otg);
+	      printf("num otg elements %d \n", num_otg_elements);
+	      enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements = 0;
+
+	      for (j = 0; j < num_otg_elements; j++) {
+		subsetting_otg=config_setting_get_elem(setting_otg, j);
+
+		if (config_setting_lookup_int(subsetting_otg, ENB_CONF_STRING_OTG_UE_ID, &otg_ue_id)) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = otg_ue_id;
+		} else {
+		  enb_properties_loc.properties[enb_properties_loc_index]->otg_ue_id[j] = 1;
+		}
+
+		if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_APP_TYPE, (const char **)&otg_app_type)) {
+		  if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = map_str_to_int(otg_app_type_names,otg_app_type))== -1) {
+		    enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = BCBR;
+		  }
+		} else {
+		  enb_properties_loc.properties[enb_properties_loc_index]->otg_app_type[j] = NO_PREDEFINED_TRAFFIC; // 0
+		}
+
+		if (config_setting_lookup_string(subsetting_otg, ENB_CONF_STRING_OTG_BG_TRAFFIC, (const char **)&otg_bg_traffic)) {
+
+		  if ((enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = map_str_to_int(switch_names,otg_bg_traffic)) == -1) {
+		    enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j]=0;
+		  }
+		} else {
+		  enb_properties_loc.properties[enb_properties_loc_index]->otg_bg_traffic[j] = 0;
+		  printf("otg bg %s\n", otg_bg_traffic);
+		}
+
+		enb_properties_loc.properties[enb_properties_loc_index]->num_otg_elements+=1;
+
+	      }
+	    }
+
+	    // log_config
+	    subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_LOG_CONFIG);
+
+	    if (subsetting != NULL) {
+	      // global
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL, (const char **)  &glog_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_level = map_str_to_int(log_level_names, glog_level)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO;
+		}
+
+		//printf( "\tGlobal log level :\t%s->%d\n",glog_level, enb_properties_loc.properties[enb_properties_loc_index]->glog_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->glog_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY,(const char **)  &glog_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = map_str_to_int(log_verbosity_names, glog_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED;
+		}
+
+		//printf( "\tGlobal log verbosity:\t%s->%d\n",glog_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity = LOG_MED;
+	      }
+
+	      // HW
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_LEVEL, (const char **) &hw_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = map_str_to_int(log_level_names,hw_log_level)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO;
+		}
+
+		//printf( "\tHW log level :\t%s->%d\n",hw_log_level,enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_HW_LOG_VERBOSITY, (const char **) &hw_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = map_str_to_int(log_verbosity_names,hw_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tHW log verbosity:\t%s->%d\n",hw_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity = LOG_MED;
+	      }
+
+	      // phy
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_LEVEL,(const char **) &phy_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = map_str_to_int(log_level_names,phy_log_level)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO;
+		}
+
+		//printf( "\tPHY log level :\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PHY_LOG_VERBOSITY, (const char **)&phy_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = map_str_to_int(log_verbosity_names,phy_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tPHY log verbosity:\t%s->%d\n",phy_log_level,enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity = LOG_MED;
+	      }
+
+	      //mac
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_LEVEL, (const char **)&mac_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = map_str_to_int(log_level_names,mac_log_level)) == -1 ) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO;
+		}
+
+		//printf( "\tMAC log level :\t%s->%d\n",mac_log_level,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_MAC_LOG_VERBOSITY, (const char **)&mac_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = map_str_to_int(log_verbosity_names,mac_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tMAC log verbosity:\t%s->%d\n",mac_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity = LOG_MED;
+	      }
+
+	      //rlc
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_LEVEL, (const char **)&rlc_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = map_str_to_int(log_level_names,rlc_log_level)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO;
+		}
+
+		//printf( "\tRLC log level :\t%s->%d\n",rlc_log_level, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RLC_LOG_VERBOSITY, (const char **)&rlc_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = map_str_to_int(log_verbosity_names,rlc_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tRLC log verbosity:\t%s->%d\n",rlc_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity = LOG_MED;
+	      }
+
+	      //pdcp
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_LEVEL, (const char **)&pdcp_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = map_str_to_int(log_level_names,pdcp_log_level)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO;
+		}
+
+		//printf( "\tPDCP log level :\t%s->%d\n",pdcp_log_level, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY, (const char **)&pdcp_log_verbosity)) {
+		enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = map_str_to_int(log_verbosity_names,pdcp_log_verbosity);
+		//printf( "\tPDCP log verbosity:\t%s->%d\n",pdcp_log_verbosity, enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED;
+	      }
+
+	      //rrc
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_LEVEL, (const char **)&rrc_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = map_str_to_int(log_level_names,rrc_log_level)) == -1 ) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO;
+		}
+
+		//printf( "\tRRC log level :\t%s->%d\n",rrc_log_level,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_RRC_LOG_VERBOSITY, (const char **)&rrc_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = map_str_to_int(log_verbosity_names,rrc_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tRRC log verbosity:\t%s->%d\n",rrc_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity = LOG_MED;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_LEVEL, (const char **)&gtpu_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = map_str_to_int(log_level_names,gtpu_log_level)) == -1 ) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO;
+		}
+
+		//printf( "\tGTPU log level :\t%s->%d\n",gtpu_log_level,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY, (const char **)&gtpu_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = map_str_to_int(log_verbosity_names,gtpu_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tGTPU log verbosity:\t%s->%d\n",gtpu_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_LEVEL, (const char **)&udp_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = map_str_to_int(log_level_names,udp_log_level)) == -1 ) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO;
+		}
+
+		//printf( "\tUDP log level :\t%s->%d\n",udp_log_level,enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_UDP_LOG_VERBOSITY, (const char **)&udp_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = map_str_to_int(log_verbosity_names,udp_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tUDP log verbosity:\t%s->%d\n",udp_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity = LOG_MED;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_LEVEL, (const char **)&osa_log_level)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = map_str_to_int(log_level_names,osa_log_level)) == -1 ) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO;
+		}
+
+		//printf( "\tOSA log level :\t%s->%d\n",osa_log_level,enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level = LOG_INFO;
+	      }
+
+	      if (config_setting_lookup_string(subsetting, ENB_CONFIG_STRING_OSA_LOG_VERBOSITY, (const char **)&osa_log_verbosity)) {
+		if ((enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = map_str_to_int(log_verbosity_names,osa_log_verbosity)) == -1) {
+		  enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED;
+		}
+
+		//printf( "\tOSA log verbosity:\t%s->%d\n",osa_log_verbosity,enb_properties_loc.properties[enb_properties_loc_index]->gosa_log_verbosity);
+	      } else {
+		enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity = LOG_MED;
+	      }
 
+	    } else { // not configuration is given
+	      enb_properties_loc.properties[enb_properties_loc_index]->glog_level         = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->glog_verbosity     = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->hw_log_level       = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->hw_log_verbosity   = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->phy_log_level      = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->phy_log_verbosity  = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->mac_log_level      = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->mac_log_verbosity  = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_level      = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->rlc_log_verbosity  = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_level     = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->pdcp_log_verbosity = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_level      = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->rrc_log_verbosity  = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_level     = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->gtpu_log_verbosity = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->udp_log_level      = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->udp_log_verbosity  = LOG_MED;
+	      enb_properties_loc.properties[enb_properties_loc_index]->osa_log_level      = LOG_INFO;
+	      enb_properties_loc.properties[enb_properties_loc_index]->osa_log_verbosity  = LOG_MED;
+	    }
+	    */
 	    break;
 	}
-      }
+      
     }
   }
+return 0;
 }
 
-int RCconfig_gtpu(void) {
-  config_t          cfg;
-  config_setting_t *setting                       = NULL;
-  config_setting_t *subsetting                    = NULL;
-  config_setting_t *setting_enb                   = NULL;
+int RCconfig_gtpu(void ) {
+
   int               num_enbs                      = 0;
 
 
 
   char*             enb_interface_name_for_S1U    = NULL;
   char*             enb_ipv4_address_for_S1U      = NULL;
-  libconfig_int     enb_port_for_S1U              = 0;
+  uint32_t          enb_port_for_S1U              = 0;
   char             *address                       = NULL;
   char             *cidr                          = NULL;
-  char             *astring                       = NULL;
-
-  // for no gcc warnings 
-  (void)astring;
-
+  char gtpupath[MAX_OPTNAME_SIZE*2 + 8];
+	  
 
+  paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
+  
+  paramdef_t GTPUParams[]  = GTPUPARAMS_DESC;
   LOG_I(GTPU,"Configuring GTPu\n");
 
-  config_init(&cfg);
+/* get number of active eNodeBs */
+  config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); 
+  num_enbs = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
+  AssertFatal (num_enbs >0,
+   	       "Failed to parse config file no active eNodeBs in %s \n", ENB_CONFIG_STRING_ACTIVE_ENBS);
 
-  if (RC.config_file_name != NULL) {
-    // Read the file. If there is an error, report it and exit. 
-    if (! config_read_file(&cfg, RC.config_file_name)) {
-      config_destroy(&cfg);
-      AssertFatal (0, "Failed to parse eNB configuration file %s!\n", RC.config_file_name);
-    }
-  } else {
-    config_destroy(&cfg);
-    AssertFatal (0, "No eNB configuration file provided!\n");
-  }
 
-  // Get list of active eNBs, (only these will be configured)
-  setting = config_lookup(&cfg, ENB_CONFIG_STRING_ACTIVE_ENBS);
-
-  if (setting != NULL) {
-    num_enbs = config_setting_length(setting);
-    setting_enb   = config_setting_get_elem(setting, 0);
-  }
-  
-  if (num_enbs>0) {
-    // Output a list of all eNBs.
-    setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST);
-    
-    if (setting != NULL) {
+  sprintf(gtpupath,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,0,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+  config_get( GTPUParams,sizeof(GTPUParams)/sizeof(paramdef_t),gtpupath);    
 
 
-      setting_enb = config_setting_get_elem(setting, 0);
-      subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
-
-      if (subsetting != NULL) {
-	if (  (config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U,
-					     (const char **)&enb_interface_name_for_S1U)
-	       && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U,
-						(const char **)&enb_ipv4_address_for_S1U)
-	       && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_ENB_PORT_FOR_S1U,
-					    &enb_port_for_S1U)
-	       )
-	      ) {
 
 	  cidr = enb_ipv4_address_for_S1U;
 	  address = strtok(cidr, "/");
@@ -2778,207 +2429,145 @@ int RCconfig_gtpu(void) {
 	  }
 
 	  RC.gtpv1u_data_g->enb_port_for_S1u_S12_S4_up = enb_port_for_S1U;
-
-	}
-      }
-    }
-  }
+return 0;
 }
 
 
-void RCconfig_S1(MessageDef *msg_p, uint32_t i) {
-  config_t          cfg;
-  config_setting_t *setting                       = NULL;
-  config_setting_t *subsetting                    = NULL;
-  config_setting_t *setting_mme_addresses         = NULL;
-  config_setting_t *setting_mme_address           = NULL;
-  config_setting_t *setting_enb                   = NULL;
-  int               num_enbs                      = 0;
-  int               num_mme_address               = 0;
-  int               j                             = 0;
-  libconfig_int     enb_id                        = 0;
-
+int RCconfig_S1(MessageDef *msg_p, uint32_t i) {
 
-  const char*       cell_type                     = NULL;
-  const char*       tac                           = 0;
-  const char*       enb_name                      = NULL;
-  const char*       mcc                           = 0;
-  const char*       mnc                           = 0;
+  int               j,k                           = 0;
+  
+  
+  int enb_id;
 
-  libconfig_int     my_int;
+  int32_t     my_int;
 
 
-  char*             ipv4                          = NULL;
-  char*             ipv4_remote                   = NULL;
-  char*             ipv6                          = NULL;
-  char*             preference                    = NULL;
-  char*             active                        = NULL;
 
   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;
+
 
   // for no gcc warnings 
-  (void)astring;
+
   (void)my_int;
 
   memset((char*)active_enb,     0 , MAX_ENB * sizeof(char*));
 
-  config_init(&cfg);
-
-  if (RC.config_file_name != NULL) {
-    // Read the file. If there is an error, report it and exit. 
-    if (! config_read_file(&cfg, RC.config_file_name)) {
-      config_destroy(&cfg);
-      AssertFatal (0, "Failed to parse eNB configuration file %s!\n", RC.config_file_name);
-    }
-  } else {
-    config_destroy(&cfg);
-    AssertFatal (0, "No eNB configuration file provided!\n");
-  }
+  paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
+  
+  paramdef_t ENBParams[]  = ENBPARAMS_DESC;
+  paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};
 
+/* get global parameters, defined outside any section in the config file */
+  
+  config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); 
 #if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
-
-  if (  (config_lookup_string( &cfg, ENB_CONFIG_STRING_ASN1_VERBOSITY, (const char **)&astring) )) {
-    if (strcasecmp(astring , ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
+    if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) {
       asn_debug      = 0;
       asn1_xer_print = 0;
-    } else if (strcasecmp(astring , ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
+    } else if (strcasecmp( *(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr), ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) {
       asn_debug      = 1;
       asn1_xer_print = 1;
-    } else if (strcasecmp(astring , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
+    } else if (strcasecmp(*(ENBSParams[ENB_ASN1_VERBOSITY_IDX].strptr) , ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) {
       asn_debug      = 1;
       asn1_xer_print = 2;
     } else {
       asn_debug      = 0;
       asn1_xer_print = 0;
     }
-  }
 
 #endif
 
-  // Get list of active eNBs, (only these will be configured)
-  setting = config_lookup(&cfg, ENB_CONFIG_STRING_ACTIVE_ENBS);
-
-  if (setting != NULL) {
-    num_enbs = config_setting_length(setting);
-    setting_enb   = config_setting_get_elem(setting, i);
-    active_enb[i] = config_setting_get_string (setting_enb);
-    AssertFatal (active_enb[i] != NULL,
+    AssertFatal (i<ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
 		 "Failed to parse config file %s, %uth attribute %s \n",
 		 RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
-    active_enb[i] = strdup(active_enb[i]);
-  }
-  
+    
   
-  if (num_enbs>0) {
+  if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt>0) {
     // Output a list of all eNBs.
-    setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST);
+       config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); 
+    
     
-    if (setting != NULL) {
-      num_enbs = config_setting_length(setting);
       
-      for (i = 0; i < num_enbs; i++) {
-	setting_enb = config_setting_get_elem(setting, i);
-	
-	if (! config_setting_lookup_int(setting_enb, ENB_CONFIG_STRING_ENB_ID, &enb_id)) {
+      
+    
+    if (ENBParamList.numelt > 0) {
+      for (k = 0; k < ENBParamList.numelt; k++) {
+	if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
 	  // Calculate a default eNB ID
 
 # if defined(ENABLE_USE_MME)
 	  uint32_t hash;
 	  
 	  hash = s1ap_generate_eNB_id ();
-	  enb_id = i + (hash & 0xFFFF8);
+	  enb_id = k + (hash & 0xFFFF8);
 # else
-	  enb_id = i;
+	  enb_id = k;
 # endif
-	}
+	} else {
+          enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
+        }
 	
-	if (  !(       config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_CELL_TYPE,           &cell_type)
-		       && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_ENB_NAME,            &enb_name)
-		       && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_TRACKING_AREA_CODE,  &tac)
-		       && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, &mcc)
-		       && config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, &mnc)
-		       
-		       
-		       )
-	      ) {
-	  AssertFatal (0,
-		       "Failed to parse eNB configuration file %s, %u th enb\n",
-		       RC.config_file_name, i);
-	  continue; // FIXME this prevents segfaults below, not sure what happens after function exit
-	}
 	
 	// search if in active list
-	for (j=0; j < num_enbs; j++) {
-	  if (strcmp(active_enb[j], enb_name) == 0) {
+	for (j=0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
+	  if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
+             paramdef_t S1Params[]  = S1PARAMS_DESC;
+             paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0};
+
+             paramdef_t SCTPParams[]  = SCTPPARAMS_DESC;
+             paramdef_t NETParams[]  =  NETPARAMS_DESC;
+             char aprefix[MAX_OPTNAME_SIZE*2 + 8];
 	    
 	    S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
 	    
-	    if (strcmp(cell_type, "CELL_MACRO_ENB") == 0) {
+	    if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
 	      S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
-	    } else  if (strcmp(cell_type, "CELL_HOME_ENB") == 0) {
+	    } else  if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
 	      S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
 	    } else {
 	      AssertFatal (0,
 			   "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
-			   RC.config_file_name, i, cell_type);
+			   RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
 	    }
 	    
-	    S1AP_REGISTER_ENB_REQ (msg_p).eNB_name         = strdup(enb_name);
-	    S1AP_REGISTER_ENB_REQ (msg_p).tac              = (uint16_t)atoi(tac);
-	    S1AP_REGISTER_ENB_REQ (msg_p).mcc              = (uint16_t)atoi(mcc);
-	    S1AP_REGISTER_ENB_REQ (msg_p).mnc              = (uint16_t)atoi(mnc);
-	    S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = strlen(mnc);
+	    S1AP_REGISTER_ENB_REQ (msg_p).eNB_name         = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
+	    S1AP_REGISTER_ENB_REQ (msg_p).tac              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].strptr));
+	    S1AP_REGISTER_ENB_REQ (msg_p).mcc              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX].strptr));
+	    S1AP_REGISTER_ENB_REQ (msg_p).mnc              = (uint16_t)atoi(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
+	    S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = strlen(*(ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX].strptr));
 	    S1AP_REGISTER_ENB_REQ (msg_p).default_drx      = 0;
 	    AssertFatal((S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 2) ||
 			(S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length == 3),
 			"BAD MNC DIGIT LENGTH %d",
 			S1AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length);
 	    
+	    sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
+            config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix); 
 	    
-
-	    setting_mme_addresses = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_MME_IP_ADDRESS);
-	    num_mme_address     = config_setting_length(setting_mme_addresses);
 	    S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0;
 
-	    for (j = 0; j < num_mme_address; j++) {
-	      setting_mme_address = config_setting_get_elem(setting_mme_addresses, j);
-
-	      if (  !(
-		      config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV4_ADDRESS, (const char **)&ipv4)
-		      && config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV6_ADDRESS, (const char **)&ipv6)
-		      && config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, (const char **)&active)
-		      && config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, (const char **)&preference)
-		      )
-		    ) {
-		AssertFatal (0,
-			     "Failed to parse eNB configuration file %s, %u th enb %u th mme address !\n",
-			     RC.config_file_name, i, j);
-		continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
-	      }
+	    for (int l = 0; l < S1ParamList.numelt; l++) {
 
 	      S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1;
 
-	      strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4_address,ipv4);
-	      strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6_address,ipv6);
+	      strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][ENB_MME_IPV4_ADDRESS_IDX].strptr));
+	      strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][ENB_MME_IPV6_ADDRESS_IDX].strptr));
 
-	      if (strcmp(active, "yes") == 0) {
+	      if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_ACTIVE_IDX].strptr), "yes") == 0) {
 #if defined(ENABLE_USE_MME)
 		EPC_MODE_ENABLED = 1;
 #endif
 	      } 
-	      if (strcmp(preference, "ipv4") == 0) {
+	      if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
 		S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1;
-	      } else if (strcmp(preference, "ipv6") == 0) {
+	      } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
 		S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1;
-	      } else if (strcmp(preference, "no") == 0) {
+	      } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
 		S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv4 = 1;
 		S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[j].ipv6 = 1;
 	      }
@@ -2989,38 +2578,18 @@ void RCconfig_S1(MessageDef *msg_p, uint32_t i) {
 	    S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
 	    S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams  = SCTP_IN_STREAMS;
 # if defined(ENABLE_USE_MME)
-	    subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_SCTP_CONFIG);
-
-	    if (subsetting != NULL) {
-	      if ( (config_setting_lookup_int( subsetting, ENB_CONFIG_STRING_SCTP_INSTREAMS, &my_int) )) {
-            	S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)my_int;
-	      }
-
-	      if ( (config_setting_lookup_int( subsetting, ENB_CONFIG_STRING_SCTP_OUTSTREAMS, &my_int) )) {
-            	S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)my_int;
-	      }
-	    }
+	    sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
+            config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); 
+            S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
+            S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
 #endif
 
+            sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
 	    // NETWORK_INTERFACES
-	    subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+            config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); 
 
-	    if (subsetting != NULL) {
-	      if (  (
-		     config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME,
-						   (const char **)&enb_interface_name_for_S1_MME)
-		     && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME,
-						      (const char **)&enb_ipv4_address_for_S1_MME)
-		     && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U,
-						      (const char **)&enb_interface_name_for_S1U)
-		     && config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U,
-						      (const char **)&enb_ipv4_address_for_S1U)
-		     && config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_ENB_PORT_FOR_S1U,
-						  &enb_port_for_S1U)
-		     )
-		    ) {
 		//		S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U);
-		cidr = enb_ipv4_address_for_S1U;
+		cidr = *(NETParams[ENB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr);
 		address = strtok(cidr, "/");
 
 		S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0;
@@ -3028,8 +2597,24 @@ void RCconfig_S1(MessageDef *msg_p, uint32_t i) {
 
 		strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, address);
 
-	      }
-	    }
+		/*
+		in_addr_t  ipv4_address;
+
+				if (address) {
+		  IPV4_STR_ADDR_TO_INT_NWBO ( address, ipv4_address, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
+		}
+		strcpy(S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv4_address, inet_ntoa(ipv4_address));
+		//		S1AP_REGISTER_ENB_REQ (msg_p).enb_port_for_S1U = enb_port_for_S1U;
+
+
+		S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME);
+		cidr = enb_ipv4_address_for_S1_MME;
+		address = strtok(cidr, "/");
+		
+		if (address) {
+		  IPV4_STR_ADDR_TO_INT_NWBO ( address, S1AP_REGISTER_ENB_REQ(msg_p).enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" );
+		}
+*/
 	  
 
 
@@ -3040,58 +2625,47 @@ void RCconfig_S1(MessageDef *msg_p, uint32_t i) {
       }
     }
   }
+return 0;
 }
 
-void RCConfig(const char *config_file_name) {
+void RCConfig(void) {
 
-  config_t          cfg;
-  config_setting_t *setting                       = NULL;
-  config_setting_t *setting_enb                   = NULL;
-  config_setting_t *setting_component_carriers    = NULL;
-  config_init(&cfg);
+  paramlist_def_t MACRLCParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0};
+  paramlist_def_t L1ParamList = {CONFIG_STRING_L1_LIST,NULL,0};
+  paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0};
+  paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
+  paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS,NULL,0};
+  
+  char aprefix[MAX_OPTNAME_SIZE*2 + 8];  
+  
 
-  if (config_file_name != NULL) {
 
-    RC.config_file_name = config_file_name;
-    if (! config_read_file(&cfg, RC.config_file_name)) {
-      config_destroy(&cfg);
-      AssertFatal (0, "Failed to parse eNB configuration file %s!\n", RC.config_file_name);
-    }
-    // Get num eNB instances
-    setting = config_lookup(&cfg, ENB_CONFIG_STRING_ACTIVE_ENBS);
-    
-    if (setting != NULL) RC.nb_inst = config_setting_length(setting);
-    if (RC.nb_inst > 0) {
-      printf("Number of eNB RRC instances %d\n",RC.nb_inst);
-      setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST);
-      RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int));
-      for (int i=0;i<RC.nb_inst;i++) {
-	setting_enb                  = config_setting_get_elem(setting, i);
-	setting_component_carriers   = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_COMPONENT_CARRIERS);
-	AssertFatal(setting_component_carriers != NULL, "No component carrier definitions in %s\n",RC.config_file_name); 
-	RC.nb_CC[i]                = config_setting_length(setting_component_carriers);
-	printf("Setting nb_CC to %d for instance %d\n",RC.nb_CC[i],i);
-
-      }
+/* get global parameters, defined outside any section in the config file */
+  
+  config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); 
+  RC.nb_inst = ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt;
+ 
+  if (RC.nb_inst > 0) {
+    RC.nb_CC = (int *)malloc((1+RC.nb_inst)*sizeof(int));
+    for (int i=0;i<RC.nb_inst;i++) {
+      sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,i);
+      config_getlist( &CCsParamList,NULL,0, aprefix);
+      RC.nb_CC[i]		 = CCsParamList.numelt;
     }
+  }
 
     // Get num MACRLC instances
-    setting = config_lookup(&cfg, CONFIG_STRING_MACRLC_LIST);
-    if (setting != NULL) RC.nb_macrlc_inst = config_setting_length(setting);
-
+    
+ 
+    config_getlist( &MACRLCParamList,NULL,0, NULL);
+    RC.nb_macrlc_inst  = MACRLCParamList.numelt;
     // Get num L1 instances
-    setting = config_lookup(&cfg, CONFIG_STRING_L1_LIST);
-    if (setting != NULL) RC.nb_L1_inst = config_setting_length(setting);
+    config_getlist( &L1ParamList,NULL,0, NULL);
+    RC.nb_L1_inst = L1ParamList.numelt;
 
     // Get num RU instances
-    setting = config_lookup(&cfg, CONFIG_STRING_RU_LIST);
-    if (setting != NULL) RC.nb_RU     = config_setting_length(setting); 
-    printf("RC.nb_RU may have been set to:%d setting:%p\n", RC.nb_RU, setting);
-  }
-  else {
-    config_destroy(&cfg);
-    AssertFatal(0,"Configuration file is null\n");
-  }
+    config_getlist( &RUParamList,NULL,0, NULL);  
+    RC.nb_RU     = RUParamList.numelt; 
+ 
 
-  return;
 }
diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h
index a3f0cc786b087995c5ed483c9a2207692bc0021b..b41545bcecea1036cb271d9ac27947e6af8de079 100644
--- a/openair2/ENB_APP/enb_config.h
+++ b/openair2/ENB_APP/enb_config.h
@@ -91,7 +91,11 @@ typedef struct ru_config_s {
   uint8_t   if_compress;
 } ru_config_t;
 
-
+extern void RCconfig_RU(void);
+extern void RCconfig_L1(void);
+extern void RCconfig_macrlc(void);
+extern int  RCconfig_gtpu(void );
+extern void RCConfig(void);
 
 void                          enb_config_display(void);
 void                          ru_config_display(void);
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index 439b70c364152b48e0152b06aeac34a84a767c27..6a03687fab8917be9fdab8bd99f6da4451a1a039 100755
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -51,28 +51,7 @@
 #define ENB_CONF_STRING_OTG_APP_TYPE                       "app_type"
 #define ENB_CONF_STRING_OTG_BG_TRAFFIC                     "bg_traffic"
 
-// per eNB configuration
-#define ENB_CONFIG_STRING_LOG_CONFIG                       "log_config"
-#define ENB_CONFIG_STRING_GLOBAL_LOG_LEVEL                 "global_log_level"
-#define ENB_CONFIG_STRING_GLOBAL_LOG_VERBOSITY             "global_log_verbosity"
-#define ENB_CONFIG_STRING_HW_LOG_LEVEL                     "hw_log_level"
-#define ENB_CONFIG_STRING_HW_LOG_VERBOSITY                 "hw_log_verbosity"
-#define ENB_CONFIG_STRING_PHY_LOG_LEVEL                    "phy_log_level"
-#define ENB_CONFIG_STRING_PHY_LOG_VERBOSITY                "phy_log_verbosity"
-#define ENB_CONFIG_STRING_MAC_LOG_LEVEL                    "mac_log_level"
-#define ENB_CONFIG_STRING_MAC_LOG_VERBOSITY                "mac_log_verbosity"
-#define ENB_CONFIG_STRING_RLC_LOG_LEVEL                    "rlc_log_level"
-#define ENB_CONFIG_STRING_RLC_LOG_VERBOSITY                "rlc_log_verbosity"
-#define ENB_CONFIG_STRING_PDCP_LOG_LEVEL                   "pdcp_log_level"
-#define ENB_CONFIG_STRING_PDCP_LOG_VERBOSITY               "pdcp_log_verbosity"
-#define ENB_CONFIG_STRING_RRC_LOG_LEVEL                    "rrc_log_level"
-#define ENB_CONFIG_STRING_RRC_LOG_VERBOSITY                "rrc_log_verbosity"
-#define ENB_CONFIG_STRING_GTPU_LOG_LEVEL                   "gtpu_log_level"
-#define ENB_CONFIG_STRING_GTPU_LOG_VERBOSITY               "gtpu_log_verbosity"
-#define ENB_CONFIG_STRING_UDP_LOG_LEVEL                    "udp_log_level"
-#define ENB_CONFIG_STRING_UDP_LOG_VERBOSITY                "udp_log_verbosity"
-#define ENB_CONFIG_STRING_OSA_LOG_LEVEL                    "osa_log_level"
-#define ENB_CONFIG_STRING_OSA_LOG_VERBOSITY                "osa_log_verbosity"
+
 
 
 
@@ -149,9 +128,12 @@ typedef enum {
 
 
 #define CONFIG_STRING_ACTIVE_RUS                   "Active_RUs"
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+/*    RUs  configuration section name */
 #define CONFIG_STRING_RU_LIST                      "RUs"
-
 #define CONFIG_STRING_RU_CONFIG                   "ru_config"
+
+/*    RUs configuration parameters name   */
 #define CONFIG_STRING_RU_LOCAL_IF_NAME            "local_if_name"
 #define CONFIG_STRING_RU_LOCAL_ADDRESS            "local_address"
 #define CONFIG_STRING_RU_REMOTE_ADDRESS           "remote_address"
@@ -195,42 +177,53 @@ typedef enum {
 
 static int DEFBANDS[] = {7};
 static int DEFENBS[] = {0};
-#define RUPARAMS_DESC {                                                                                           \
-{CONFIG_STRING_RU_LOCAL_IF_NAME,         "",   NULL,   0,   strptr:NULL,   defstrval:"lo",	  TYPE_STRING,  0}, \
-{CONFIG_STRING_RU_LOCAL_ADDRESS,         "",   NULL,   0,   strptr:NULL, defstrval:"127.0.0.2",   TYPE_STRING,  0}, \
-{CONFIG_STRING_RU_REMOTE_ADDRESS,        "",   NULL,   0,   strptr:NULL, defstrval:"127.0.0.1",   TYPE_STRING,  0}, \
-{CONFIG_STRING_RU_LOCAL_PORTC,           "",   NULL,   0,   uptr:NULL,   defuintval:50000,	  TYPE_UINT,	0}, \
-{CONFIG_STRING_RU_REMOTE_PORTC,          "",   NULL,   0,   uptr:NULL,   defuintval:50000,	  TYPE_UINT,	0}, \
-{CONFIG_STRING_RU_LOCAL_PORTD,           "",   NULL,   0,   uptr:NULL,   defuintval:50001,	  TYPE_UINT,	0}, \
-{CONFIG_STRING_RU_REMOTE_PORTD,          "",   NULL,   0,   uptr:NULL,   defuintval:50001,	  TYPE_UINT,	0}, \
-{CONFIG_STRING_RU_TRANSPORT_PREFERENCE,  "",   NULL,   0,   strptr:NULL, defstrval:"udp_if4p5",   TYPE_STRING,  0}, \
-{CONFIG_STRING_RU_LOCAL_RF,              "",   NULL,   0,   strptr:NULL, defstrval:"yes",	  TYPE_STRING,  0}, \
-{CONFIG_STRING_RU_NB_TX,                 "",   NULL,   0,   uptr:NULL,   defuintval:1,  	  TYPE_UINT,	0}, \
-{CONFIG_STRING_RU_NB_RX,                 "",   NULL,   0,   uptr:NULL,   defuintval:1,  	  TYPE_UINT,	0}, \
-{CONFIG_STRING_RU_MAX_RS_EPRE,           "",   NULL,   0,   iptr:NULL,   defintval:-29, 	  TYPE_INT,	0}, \
-{CONFIG_STRING_RU_MAX_RXGAIN,            "",   NULL,   0,   iptr:NULL,   defintval:120, 	  TYPE_INT,	0}, \
-{CONFIG_STRING_RU_BAND_LIST,             "",   NULL,   0,   uptr:NULL,   defintarrayval:DEFBANDS, TYPE_INTARRAY,1}, \
-{CONFIG_STRING_RU_ENB_LIST,              "",   NULL,   0,   uptr:NULL,   defintarrayval:DEFENBS,  TYPE_INTARRAY,1}, \
-{CONFIG_STRING_RU_ATT_TX,                "",   NULL,   0,   uptr:NULL,   defintval:0,             TYPE_UINT,    0}, \
-{CONFIG_STRING_RU_ATT_RX,                "",   NULL,   0,   uptr:NULL,   defintval:0,             TYPE_UINT,    0}  \
-}
 
 
+/*-----------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            RU configuration parameters                                                                  */
+/*   optname                                   helpstr   paramflags    XXXptr        defXXXval                   type           numelt     */
+/*-----------------------------------------------------------------------------------------------------------------------------------------*/
+#define RUPARAMS_DESC { \
+{CONFIG_STRING_RU_LOCAL_IF_NAME,            	 NULL,       0,       strptr:NULL,     defstrval:"lo",  	TYPE_STRING,	  0}, \
+{CONFIG_STRING_RU_LOCAL_ADDRESS,            	 NULL,       0,       strptr:NULL,     defstrval:"127.0.0.2",	TYPE_STRING,	  0}, \
+{CONFIG_STRING_RU_REMOTE_ADDRESS,           	 NULL,       0,       strptr:NULL,     defstrval:"127.0.0.1",	TYPE_STRING,	  0}, \
+{CONFIG_STRING_RU_LOCAL_PORTC,              	 NULL,       0,       uptr:NULL,       defuintval:50000,	TYPE_UINT,	  0}, \
+{CONFIG_STRING_RU_REMOTE_PORTC,             	 NULL,       0,       uptr:NULL,       defuintval:50000,	TYPE_UINT,	  0}, \
+{CONFIG_STRING_RU_LOCAL_PORTD,              	 NULL,       0,       uptr:NULL,       defuintval:50001,	TYPE_UINT,	  0}, \
+{CONFIG_STRING_RU_REMOTE_PORTD,             	 NULL,       0,       uptr:NULL,       defuintval:50001,	TYPE_UINT,	  0}, \
+{CONFIG_STRING_RU_TRANSPORT_PREFERENCE,     	 NULL,       0,       strptr:NULL,     defstrval:"udp_if5",	TYPE_STRING,	  0}, \
+{CONFIG_STRING_RU_LOCAL_RF,                 	 NULL,       0,       strptr:NULL,     defstrval:"yes", 	TYPE_STRING,	  0}, \
+{CONFIG_STRING_RU_NB_TX,                    	 NULL,       0,       uptr:NULL,       defuintval:1,		TYPE_UINT,	  0}, \
+{CONFIG_STRING_RU_NB_RX,                    	 NULL,       0,       uptr:NULL,       defuintval:1,		TYPE_UINT,	  0}, \
+{CONFIG_STRING_RU_MAX_RS_EPRE,              	 NULL,       0,       iptr:NULL,       defintval:-29,		TYPE_INT,	  0}, \
+{CONFIG_STRING_RU_MAX_RXGAIN,               	 NULL,       0,       iptr:NULL,       defintval:120,		TYPE_INT,	  0}, \
+{CONFIG_STRING_RU_BAND_LIST,                	 NULL,       0,       uptr:NULL,       defintarrayval:DEFBANDS, TYPE_INTARRAY,    1}, \
+{CONFIG_STRING_RU_ENB_LIST,                 	 NULL,       0,       uptr:NULL,       defintarrayval:DEFENBS,  TYPE_INTARRAY,    1}, \
+{CONFIG_STRING_RU_ATT_TX,                   	 NULL,       0,       uptr:NULL,       defintval:0,		TYPE_UINT,	  0}, \
+{CONFIG_STRING_RU_ATT_RX,                   	 NULL,       0,       uptr:NULL,       defintval:0,		TYPE_UINT,	  0}  \
+}
+
+/*---------------------------------------------------------------------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------------------------------------------------------------------*/
+/* value definitions for ASN1 verbosity parameter */
 #define ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE              "none"
 #define ENB_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING          "annoying"
 #define ENB_CONFIG_STRING_ASN1_VERBOSITY_INFO              "info"
  
-#define ENB_ASN1_VERBOSITY_IDX                     0
-#define ENB_ACTIVE_ENBS_IDX                        1
 
+/* global parameters, not under a specific section   */
 #define ENB_CONFIG_STRING_ASN1_VERBOSITY           "Asn1_verbosity"
 #define ENB_CONFIG_STRING_ACTIVE_ENBS              "Active_eNBs"
-
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            global configuration parameters                                                                                   */
+/*   optname                                   helpstr   paramflags    XXXptr        defXXXval                                        type           numelt     */
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define ENBSPARAMS_DESC {                                                                                             \
-{ENB_CONFIG_STRING_ASN1_VERBOSITY,"",   "",   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,      0},   \
-{ENB_CONFIG_STRING_ACTIVE_ENBS,   "",   "",   0,   uptr:NULL,   defstrval:NULL,                                    TYPE_STRINGLIST,  0}    \
+{ENB_CONFIG_STRING_ASN1_VERBOSITY,             NULL,     0,        uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,      0},   \
+{ENB_CONFIG_STRING_ACTIVE_ENBS,                NULL,     0,        uptr:NULL,   defstrval:NULL, 				   TYPE_STRINGLIST,  0}    \
 }
-
+#define ENB_ASN1_VERBOSITY_IDX                     0
+#define ENB_ACTIVE_ENBS_IDX                        1
 
 
 /*
@@ -240,26 +233,14 @@ static int DEFENBS[] = {0};
 {ENB_CONFIG_STRING_CC_NODE_SYNCH_REF,"",   "",   0,   uptr:NULL,defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,TYPE_STRING,0},           \
 */
 
-#define ENB_ENB_ID_IDX                  0
-#define ENB_CELL_TYPE_IDX               1
-#define ENB_ENB_NAME_IDX                2
-#define ENB_TRACKING_AREA_CODE_IDX      3
-#define ENB_MOBILE_COUNTRY_CODE_IDX     4
-#define ENB_MOBILE_NETWORK_CODE_IDX     5
-#define ENB_TRANSPORT_S_PREFERENCE_IDX  6
-#define ENB_LOCAL_S_IF_NAME_IDX         7
-#define ENB_LOCAL_S_ADDRESS_IDX         8
-#define ENB_REMOTE_S_ADDRESS_IDX        9
-#define ENB_LOCAL_S_PORTC_IDX           10
-#define ENB_REMOTE_S_PORTC_IDX          11
-#define ENB_LOCAL_S_PORTD_IDX           12
-#define ENB_REMOTE_S_PORTD_IDX          13
-
-
 
 
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+/*    cell configuration section name */
 #define ENB_CONFIG_STRING_ENB_LIST                      "eNBs"
 
+/* cell configuration parameters names */
 #define ENB_CONFIG_STRING_ENB_ID                        "eNB_ID"
 #define ENB_CONFIG_STRING_CELL_TYPE                     "cell_type"
 #define ENB_CONFIG_STRING_ENB_NAME                      "eNB_name"
@@ -275,29 +256,47 @@ static int DEFENBS[] = {0};
 #define ENB_CONFIG_STRING_LOCAL_S_PORTD                 "local_s_portd"
 #define ENB_CONFIG_STRING_REMOTE_S_PORTD                "remote_s_portd"
 
-#define ENBPARAMS_DESC {                                                                                                \
-{ENB_CONFIG_STRING_ENB_ID,                 "",   NULL,   0,   uptr:NULL,   defintval:0, 		TYPE_UINT,   0},  \
-{ENB_CONFIG_STRING_CELL_TYPE,              "",   NULL,   0,   strptr:NULL, defstrval:"CELL_MACRO_ENB",  TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_ENB_NAME,               "",   NULL,   0,   strptr:NULL, defstrval:"OAIeNodeB",	TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_TRACKING_AREA_CODE,     "",   NULL,   0,   strptr:NULL, defstrval:"0", 		TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE,    "",   NULL,   0,   strptr:NULL, defstrval:"0", 		TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE,    "",   NULL,   0,   strptr:NULL, defstrval:"0",               TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE, "",   NULL,   0,   strptr:NULL, defstrval:"local_mac", 	TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_LOCAL_S_IF_NAME,        "",   NULL,   0,   strptr:NULL, defstrval:"lo",		TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_LOCAL_S_ADDRESS,        "",   NULL,   0,   strptr:NULL, defstrval:"127.0.0.1",	TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_REMOTE_S_ADDRESS,       "",   NULL,   0,   strptr:NULL, defstrval:"127.0.0.2",	TYPE_STRING, 0},  \
-{ENB_CONFIG_STRING_LOCAL_S_PORTC,          "",   NULL,   0,   uptr:NULL,   defuintval:50000,		TYPE_UINT,   0}, \
-{ENB_CONFIG_STRING_REMOTE_S_PORTC,         "",   NULL,   0,   uptr:NULL,   defuintval:50000,		TYPE_UINT,   0}, \
-{ENB_CONFIG_STRING_LOCAL_S_PORTD,          "",   NULL,   0,   uptr:NULL,   defuintval:50001,		TYPE_UINT,   0}, \
-{ENB_CONFIG_STRING_REMOTE_S_PORTD,         "",   NULL,   0,   uptr:NULL,   defuintval:50001,		TYPE_UINT,   0}, \
-}
-
-
-		  
+/*-----------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            cell configuration parameters                                                                */
+/*   optname                                   helpstr   paramflags    XXXptr        defXXXval                   type           numelt     */
+/*-----------------------------------------------------------------------------------------------------------------------------------------*/
+#define ENBPARAMS_DESC {\
+{ENB_CONFIG_STRING_ENB_ID,                       NULL,   0,            uptr:NULL,   defintval:0,                 TYPE_UINT,      0},  \
+{ENB_CONFIG_STRING_CELL_TYPE,                    NULL,   0,            strptr:NULL, defstrval:"CELL_MACRO_ENB",  TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_ENB_NAME,                     NULL,   0,            strptr:NULL, defstrval:"OAIeNodeB",       TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_TRACKING_AREA_CODE,           NULL,   0,            strptr:NULL, defstrval:"0",               TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE,          NULL,   0,            strptr:NULL, defstrval:"0",               TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_MOBILE_NETWORK_CODE,          NULL,   0,            strptr:NULL, defstrval:"0",               TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_TRANSPORT_S_PREFERENCE,       NULL,   0,            strptr:NULL, defstrval:"local_mac",       TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_LOCAL_S_IF_NAME,              NULL,   0,            strptr:NULL, defstrval:"lo",              TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_LOCAL_S_ADDRESS,              NULL,   0,            strptr:NULL, defstrval:"127.0.0.1",       TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_REMOTE_S_ADDRESS,             NULL,   0,            strptr:NULL, defstrval:"127.0.0.2",       TYPE_STRING,    0},  \
+{ENB_CONFIG_STRING_LOCAL_S_PORTC,                NULL,   0,            uptr:NULL,   defuintval:50000,            TYPE_UINT,      0},  \
+{ENB_CONFIG_STRING_REMOTE_S_PORTC,               NULL,   0,            uptr:NULL,   defuintval:50000,            TYPE_UINT,      0},  \
+{ENB_CONFIG_STRING_LOCAL_S_PORTD,                NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
+{ENB_CONFIG_STRING_REMOTE_S_PORTD,               NULL,   0,            uptr:NULL,   defuintval:50001,            TYPE_UINT,      0},  \
+}															     	
+#define ENB_ENB_ID_IDX                  0
+#define ENB_CELL_TYPE_IDX               1
+#define ENB_ENB_NAME_IDX                2
+#define ENB_TRACKING_AREA_CODE_IDX      3
+#define ENB_MOBILE_COUNTRY_CODE_IDX     4
+#define ENB_MOBILE_NETWORK_CODE_IDX     5
+#define ENB_TRANSPORT_S_PREFERENCE_IDX  6
+#define ENB_LOCAL_S_IF_NAME_IDX         7
+#define ENB_LOCAL_S_ADDRESS_IDX         8
+#define ENB_REMOTE_S_ADDRESS_IDX        9
+#define ENB_LOCAL_S_PORTC_IDX           10
+#define ENB_REMOTE_S_PORTC_IDX          11
+#define ENB_LOCAL_S_PORTD_IDX           12
+#define ENB_REMOTE_S_PORTD_IDX          13
+/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------------------------------------------------------------------------------*/		  
 
-		
+/* component carriers configuration section name */		
 #define ENB_CONFIG_STRING_COMPONENT_CARRIERS                            "component_carriers"		 
 
+/* component carries configuration parameters name */
 #define ENB_CONFIG_STRING_FRAME_TYPE                                    "frame_type"
 #define ENB_CONFIG_STRING_PBCH_REPETITION                               "pbch_repetition"
 #define ENB_CONFIG_STRING_TDD_CONFIG                                    "tdd_config"
@@ -373,82 +372,87 @@ static int DEFENBS[] = {0};
 #define ENB_CONFIG_STRING_UETIMERS_N311                                 "ue_TimersAndConstants_n311"
 #define ENB_CONFIG_STRING_UE_TRANSMISSION_MODE                          "ue_TransmissionMode"
 		
-
-#define CCPARAMS_DESC {                                                                                                  \
-{ENB_CONFIG_STRING_FRAME_TYPE,                             "",   NULL,   0,   strptr:&frame_type,			      defstrval:"FDD",  	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_TDD_CONFIG,                             "",   NULL,   0,   iptr:&tdd_config, 			      defintval:3,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_TDD_CONFIG_S,                           "",   NULL,   0,   iptr:&tdd_config_s,			      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PREFIX_TYPE,                            "",   NULL,   0,   strptr:&prefix_type,			      defstrval:"NORMAL",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PBCH_REPETITION,                        "",   NULL,   0,   strptr:&pbch_repetition,  		      defstrval:"FALSE",	 TYPE_STRING,	 0}, \
-{ENB_CONFIG_STRING_EUTRA_BAND,                             "",   NULL,   0,   iptr:&eutra_band, 			      defintval:7,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY,                     "",   NULL,   0,   i64ptr:(int64_t *)&downlink_frequency,	      defint64val:2680000000,	 TYPE_UINT64,  0}, \
-{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET,                "",   NULL,   0,   iptr:&uplink_frequency_offset,		      defintval:-120000000,	 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_NID_CELL,                               "",   NULL,   0,   iptr:&Nid_cell,				      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_N_RB_DL,                                "",   NULL,   0,   iptr:&N_RB_DL,				      defintval:25,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_CELL_MBSFN,                             "",   NULL,   0,   iptr:&Nid_cell_mbsfn,			      defintval:0,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_NB_ANT_PORTS,                           "",   NULL,   0,   iptr:&nb_antenna_ports,			      defintval:1,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PRACH_ROOT,                             "",   NULL,   0,   iptr:&prach_root, 			      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PRACH_CONFIG_INDEX,                     "",   NULL,   0,   iptr:&prach_config_index, 		      defintval:0,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_PRACH_HIGH_SPEED,                       "",   NULL,   0,   strptr:&prach_high_speed, 		      defstrval:"DISABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION,                 "",   NULL,   0,   iptr:&prach_zero_correlation,		      defintval:1,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PRACH_FREQ_OFFSET,                      "",   NULL,   0,   iptr:&prach_freq_offset,  		      defintval:2,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT,                      "",   NULL,   0,   iptr:&pucch_delta_shift,  		      defintval:1,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PUCCH_NRB_CQI,                          "",   NULL,   0,   iptr:&pucch_nRB_CQI,			      defintval:1,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PUCCH_NCS_AN,                           "",   NULL,   0,   iptr:&pucch_nCS_AN,			      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PUCCH_N1_AN,                            "",   NULL,   0,   iptr:&pucch_n1_AN,			      defintval:32,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PDSCH_RS_EPRE,                          "",   NULL,   0,   iptr:&pdsch_referenceSignalPower, 	      defintval:-29,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_PDSCH_PB,                               "",   NULL,   0,   iptr:&pdsch_p_b,  			      defintval:0,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_PUSCH_N_SB,                             "",   NULL,   0,   iptr:&pusch_n_SB, 			      defintval:1,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_PUSCH_HOPPINGMODE,                      "",   NULL,   0,   strptr:&pusch_hoppingMode,		      defstrval:"interSubFrame", TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET,                    "",   NULL,   0,   iptr:&pusch_hoppingOffset,		      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PUSCH_ENABLE64QAM,                      "",   NULL,   0,   strptr:&pusch_enable64QAM,		      defstrval:"DISABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN,                 "",   NULL,   0,   strptr:&pusch_groupHoppingEnabled,	      defstrval:"ENABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT,                 "",   NULL,   0,   iptr:&pusch_groupAssignment,		      defintval:0,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN,              "",   NULL,   0,   strptr:&pusch_sequenceHoppingEnabled,	      defstrval:"DISABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUSCH_NDMRS1,                           "",   NULL,   0,   iptr:&pusch_nDMRS1,			      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PHICH_DURATION,                         "",   NULL,   0,   strptr:&phich_duration,			      defstrval:"NORMAL",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PHICH_RESOURCE,                         "",   NULL,   0,   strptr:&phich_resource,			      defstrval:"ONESIXTH",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_SRS_ENABLE,                             "",   NULL,   0,   strptr:&srs_enable,			      defstrval:"DISABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG,                   "",   NULL,   0,   iptr:&srs_BandwidthConfig,		      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG,                    "",   NULL,   0,   iptr:&srs_SubframeConfig, 		      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG,                   "",   NULL,   0,   strptr:&srs_ackNackST,			      defstrval:"DISABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_SRS_MAXUPPTS,                           "",   NULL,   0,   strptr:&srs_MaxUpPts,			      defstrval:"DISABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUSCH_PO_NOMINAL,                       "",   NULL,   0,   iptr:&pusch_p0_Nominal,			      defintval:-90,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_PUSCH_ALPHA,                            "",   NULL,   0,   strptr:&pusch_alpha,			      defstrval:"AL1",  	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUCCH_PO_NOMINAL,                       "",   NULL,   0,   iptr:&pucch_p0_Nominal,			      defintval:-96,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE,                    "",   NULL,   0,   iptr:&msg3_delta_Preamble,		      defintval:6,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1,                   "",   NULL,   0,   strptr:&pucch_deltaF_Format1,		      defstrval:"DELTAF2",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b,                  "",   NULL,   0,   strptr:&pucch_deltaF_Format1b,		      defstrval:"deltaF3",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2,                   "",   NULL,   0,   strptr:&pucch_deltaF_Format2,		      defstrval:"deltaF0",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A,                  "",   NULL,   0,   strptr:&pucch_deltaF_Format2a,		      defstrval:"deltaF0",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B,                  "",   NULL,   0,   strptr:&pucch_deltaF_Format2b,		      defstrval:"deltaF0",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES,                  "",   NULL,   0,   iptr:&rach_numberOfRA_Preambles,  	      defintval:4,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG,             "",   NULL,   0,   strptr:&rach_preamblesGroupAConfig,	      defstrval:"DISABLE",	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA,          "",   NULL,   0,   iptr:&rach_sizeOfRA_PreamblesGroupA,	      defintval:0,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA,                 "",   NULL,   0,   iptr:&rach_messageSizeGroupA,		      defintval:56,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB,          "",   NULL,   0,   strptr:&rach_messagePowerOffsetGroupB,	      defstrval:"minusinfinity", TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP,                  "",   NULL,   0,   iptr:&rach_powerRampingStep,		      defintval:4,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER,"",   NULL,   0,   iptr:&rach_preambleInitialReceivedTargetPower,  defintval:-100,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX,                  "",   NULL,   0,   iptr:&rach_preambleTransMax,		      defintval:10,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE,              "",   NULL,   0,   iptr:&rach_raResponseWindowSize,  	      defintval:10,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER,      "",   NULL,   0,   iptr:&rach_macContentionResolutionTimer,        defintval:48,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX,                     "",   NULL,   0,   iptr:&rach_maxHARQ_Msg3Tx,		      defintval:4,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE,              "",   NULL,   0,   iptr:&pcch_defaultPagingCycle,		      defintval:128,		 TYPE_INT,     0}, \
-{ENB_CONFIG_STRING_PCCH_NB,                                "",   NULL,   0,   strptr:&pcch_nB,  			      defstrval:"oneT", 	 TYPE_STRING,  0}, \
-{ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF,           "",   NULL,   0,   iptr:&bcch_modificationPeriodCoeff,	      defintval:2,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_UETIMERS_T300,                          "",   NULL,   0,   iptr:&ue_TimersAndConstants_t300, 	      defintval:1000,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_UETIMERS_T301,                          "",   NULL,   0,   iptr:&ue_TimersAndConstants_t301, 	      defintval:1000,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_UETIMERS_T310,                          "",   NULL,   0,   iptr:&ue_TimersAndConstants_t310, 	      defintval:1000,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_UETIMERS_T311,                          "",   NULL,   0,   iptr:&ue_TimersAndConstants_t311, 	      defintval:10000,  	 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_UETIMERS_N310,                          "",   NULL,   0,   iptr:&ue_TimersAndConstants_n310, 	      defintval:20,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_UETIMERS_N311,                          "",   NULL,   0,   iptr:&ue_TimersAndConstants_n311, 	      defintval:1,		 TYPE_UINT,    0}, \
-{ENB_CONFIG_STRING_UE_TRANSMISSION_MODE,                   "",   NULL,   0,   iptr:&ue_TransmissionMode,		      defintval:1,		 TYPE_UINT,    0}  \
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                     component carriers configuration parameters                                                                                                     */
+/*   optname                                                   helpstr   paramflags    XXXptr                                        defXXXval                    type         numelt  */
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CCPARAMS_DESC { \
+{ENB_CONFIG_STRING_FRAME_TYPE,                                   NULL,   0,           strptr:&frame_type,                             defstrval:"FDD",           TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_TDD_CONFIG,                                   NULL,   0,           iptr:&tdd_config,                               defintval:3,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_TDD_CONFIG_S,                                 NULL,   0,           iptr:&tdd_config_s,                             defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PREFIX_TYPE,                                  NULL,   0,           strptr:&prefix_type,                            defstrval:"NORMAL",        TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PBCH_REPETITION,                              NULL,   0,           strptr:&pbch_repetition,                        defstrval:"FALSE",         TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_EUTRA_BAND,                                   NULL,   0,           iptr:&eutra_band,                               defintval:7,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_DOWNLINK_FREQUENCY,                           NULL,   0,           i64ptr:(int64_t *)&downlink_frequency,          defint64val:2680000000,    TYPE_UINT64,     0},  \
+{ENB_CONFIG_STRING_UPLINK_FREQUENCY_OFFSET,                      NULL,   0,           iptr:&uplink_frequency_offset,                  defintval:-120000000,      TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_NID_CELL,                                     NULL,   0,           iptr:&Nid_cell,                                 defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_N_RB_DL,                                      NULL,   0,           iptr:&N_RB_DL,                                  defintval:25,              TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_CELL_MBSFN,                                   NULL,   0,           iptr:&Nid_cell_mbsfn,                           defintval:0,               TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_NB_ANT_PORTS,                                 NULL,   0,           iptr:&nb_antenna_ports,                         defintval:1,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PRACH_ROOT,                                   NULL,   0,           iptr:&prach_root,                               defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PRACH_CONFIG_INDEX,                           NULL,   0,           iptr:&prach_config_index,                       defintval:0,               TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_PRACH_HIGH_SPEED,                             NULL,   0,           strptr:&prach_high_speed,                       defstrval:"DISABLE",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PRACH_ZERO_CORRELATION,                       NULL,   0,           iptr:&prach_zero_correlation,                   defintval:1,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PRACH_FREQ_OFFSET,                            NULL,   0,           iptr:&prach_freq_offset,                        defintval:2,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT,                            NULL,   0,           iptr:&pucch_delta_shift,                        defintval:1,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PUCCH_NRB_CQI,                                NULL,   0,           iptr:&pucch_nRB_CQI,                            defintval:1,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PUCCH_NCS_AN,                                 NULL,   0,           iptr:&pucch_nCS_AN,                             defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PUCCH_N1_AN,                                  NULL,   0,           iptr:&pucch_n1_AN,                              defintval:32,              TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PDSCH_RS_EPRE,                                NULL,   0,           iptr:&pdsch_referenceSignalPower,               defintval:-29,             TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_PDSCH_PB,                                     NULL,   0,           iptr:&pdsch_p_b,                                defintval:0,               TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_PUSCH_N_SB,                                   NULL,   0,           iptr:&pusch_n_SB,                               defintval:1,               TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_PUSCH_HOPPINGMODE,                            NULL,   0,           strptr:&pusch_hoppingMode,                      defstrval:"interSubFrame", TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUSCH_HOPPINGOFFSET,                          NULL,   0,           iptr:&pusch_hoppingOffset,                      defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PUSCH_ENABLE64QAM,                            NULL,   0,           strptr:&pusch_enable64QAM,                      defstrval:"DISABLE",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN,                       NULL,   0,           strptr:&pusch_groupHoppingEnabled,              defstrval:"ENABLE",        TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUSCH_GROUP_ASSIGNMENT,                       NULL,   0,           iptr:&pusch_groupAssignment,                    defintval:0,               TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN,                    NULL,   0,           strptr:&pusch_sequenceHoppingEnabled,           defstrval:"DISABLE",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUSCH_NDMRS1,                                 NULL,   0,           iptr:&pusch_nDMRS1,                             defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PHICH_DURATION,                               NULL,   0,           strptr:&phich_duration,                         defstrval:"NORMAL",        TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PHICH_RESOURCE,                               NULL,   0,           strptr:&phich_resource,                         defstrval:"ONESIXTH",      TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_SRS_ENABLE,                                   NULL,   0,           strptr:&srs_enable,                             defstrval:"DISABLE",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_SRS_BANDWIDTH_CONFIG,                         NULL,   0,           iptr:&srs_BandwidthConfig,                      defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_SRS_SUBFRAME_CONFIG,                          NULL,   0,           iptr:&srs_SubframeConfig,                       defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_SRS_ACKNACKST_CONFIG,                         NULL,   0,           strptr:&srs_ackNackST,                          defstrval:"DISABLE",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_SRS_MAXUPPTS,                                 NULL,   0,           strptr:&srs_MaxUpPts,                           defstrval:"DISABLE",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUSCH_PO_NOMINAL,                             NULL,   0,           iptr:&pusch_p0_Nominal,                         defintval:-90,             TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_PUSCH_ALPHA,                                  NULL,   0,           strptr:&pusch_alpha,                            defstrval:"AL1",           TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUCCH_PO_NOMINAL,                             NULL,   0,           iptr:&pucch_p0_Nominal,                         defintval:-96,             TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_MSG3_DELTA_PREAMBLE,                          NULL,   0,           iptr:&msg3_delta_Preamble,                      defintval:6,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1,                         NULL,   0,           strptr:&pucch_deltaF_Format1,                   defstrval:"DELTAF2",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT1b,                        NULL,   0,           strptr:&pucch_deltaF_Format1b,                  defstrval:"deltaF3",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2,                         NULL,   0,           strptr:&pucch_deltaF_Format2,                   defstrval:"deltaF0",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2A,                        NULL,   0,           strptr:&pucch_deltaF_Format2a,                  defstrval:"deltaF0",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_PUCCH_DELTAF_FORMAT2B,                        NULL,   0,           strptr:&pucch_deltaF_Format2b,                  defstrval:"deltaF0",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_RACH_NUM_RA_PREAMBLES,                        NULL,   0,           iptr:&rach_numberOfRA_Preambles,                defintval:4,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_RACH_PREAMBLESGROUPACONFIG,                   NULL,   0,           strptr:&rach_preamblesGroupAConfig,             defstrval:"DISABLE",       TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_RACH_SIZEOFRA_PREAMBLESGROUPA,                NULL,   0,           iptr:&rach_sizeOfRA_PreamblesGroupA,            defintval:0,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_RACH_MESSAGESIZEGROUPA,                       NULL,   0,           iptr:&rach_messageSizeGroupA,                   defintval:56,              TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_RACH_MESSAGEPOWEROFFSETGROUPB,                NULL,   0,           strptr:&rach_messagePowerOffsetGroupB,          defstrval:"minusinfinity", TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_RACH_POWERRAMPINGSTEP,                        NULL,   0,           iptr:&rach_powerRampingStep,                    defintval:4,               TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_RACH_PREAMBLEINITIALRECEIVEDTARGETPOWER,      NULL,   0,           iptr:&rach_preambleInitialReceivedTargetPower,  defintval:-100,            TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_RACH_PREAMBLETRANSMAX,                        NULL,   0,           iptr:&rach_preambleTransMax,                    defintval:10,              TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_RACH_RARESPONSEWINDOWSIZE,                    NULL,   0,           iptr:&rach_raResponseWindowSize,                defintval:10,              TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_RACH_MACCONTENTIONRESOLUTIONTIMER,            NULL,   0,           iptr:&rach_macContentionResolutionTimer,        defintval:48,              TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_RACH_MAXHARQMSG3TX,                           NULL,   0,           iptr:&rach_maxHARQ_Msg3Tx,                      defintval:4,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_PCCH_DEFAULT_PAGING_CYCLE,                    NULL,   0,           iptr:&pcch_defaultPagingCycle,                  defintval:128,             TYPE_INT,        0},  \
+{ENB_CONFIG_STRING_PCCH_NB,                                      NULL,   0,           strptr:&pcch_nB,                                defstrval:"oneT",          TYPE_STRING,     0},  \
+{ENB_CONFIG_STRING_BCCH_MODIFICATIONPERIODCOEFF,                 NULL,   0,           iptr:&bcch_modificationPeriodCoeff,             defintval:2,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_UETIMERS_T300,                                NULL,   0,           iptr:&ue_TimersAndConstants_t300,               defintval:1000,            TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_UETIMERS_T301,                                NULL,   0,           iptr:&ue_TimersAndConstants_t301,               defintval:1000,            TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_UETIMERS_T310,                                NULL,   0,           iptr:&ue_TimersAndConstants_t310,               defintval:1000,            TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_UETIMERS_T311,                                NULL,   0,           iptr:&ue_TimersAndConstants_t311,               defintval:10000,           TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_UETIMERS_N310,                                NULL,   0,           iptr:&ue_TimersAndConstants_n310,               defintval:20,              TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_UETIMERS_N311,                                NULL,   0,           iptr:&ue_TimersAndConstants_n311,               defintval:1,               TYPE_UINT,       0},  \
+{ENB_CONFIG_STRING_UE_TRANSMISSION_MODE,                         NULL,   0,           iptr:&ue_TransmissionMode,                      defintval:1,               TYPE_UINT,       0}   \
 }
 
-
-
+/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* SRB1 configuration parameters section name */
 #define ENB_CONFIG_STRING_SRB1                                          "srb1_parameters"
 
+/* SRB1 configuration parameters names   */
 #define ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT                    "timer_poll_retransmit"
 #define ENB_CONFIG_STRING_SRB1_TIMER_REORDERING                         "timer_reordering"
 #define ENB_CONFIG_STRING_SRB1_TIMER_STATUS_PROHIBIT                    "timer_status_prohibit"
@@ -456,54 +460,72 @@ static int DEFENBS[] = {0};
 #define ENB_CONFIG_STRING_SRB1_POLL_BYTE                                "poll_byte"
 #define ENB_CONFIG_STRING_SRB1_MAX_RETX_THRESHOLD                       "max_retx_threshold"
 
-
+/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            SRB1 configuration parameters                                                                                  */
+/*   optname                                          helpstr   paramflags    XXXptr                             defXXXval         type           numelt     */
+/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define SRB1PARAMS_DESC {                                                                                                \
-{ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT,   "",   NULL,   0,   iptr:&srb1_timer_poll_retransmit,	defintval:80,	  TYPE_UINT,0}, 	  \
-{ENB_CONFIG_STRING_SRB1_TIMER_REORDERING,        "",   NULL,   0,   iptr:&srb1_timer_reordering,	defintval:35,	  TYPE_UINT,0}, 	  \
-{ENB_CONFIG_STRING_SRB1_TIMER_STATUS_PROHIBIT,   "",   NULL,   0,   iptr:&srb1_timer_status_prohibit,	defintval:0,	  TYPE_UINT,0}, 	  \
-{ENB_CONFIG_STRING_SRB1_POLL_PDU,                "",   NULL,   0,   iptr:&srb1_poll_pdu,		defintval:4,	  TYPE_UINT,0}, 	  \
-{ENB_CONFIG_STRING_SRB1_POLL_BYTE,               "",   NULL,   0,   iptr:&srb1_poll_byte,		defintval:99999,  TYPE_UINT,0}, 	  \
-{ENB_CONFIG_STRING_SRB1_MAX_RETX_THRESHOLD,      "",   NULL,   0,   iptr:&srb1_max_retx_threshold,	defintval:4,	  TYPE_UINT,0}  	 \
+{ENB_CONFIG_STRING_SRB1_TIMER_POLL_RETRANSMIT,         NULL,   0,            iptr:&srb1_timer_poll_retransmit,   defintval:80,     TYPE_UINT,      0},       \
+{ENB_CONFIG_STRING_SRB1_TIMER_REORDERING,              NULL,   0,            iptr:&srb1_timer_reordering,        defintval:35,     TYPE_UINT,      0},       \
+{ENB_CONFIG_STRING_SRB1_TIMER_STATUS_PROHIBIT,         NULL,   0,            iptr:&srb1_timer_status_prohibit,   defintval:0,      TYPE_UINT,      0},       \
+{ENB_CONFIG_STRING_SRB1_POLL_PDU,                      NULL,   0,            iptr:&srb1_poll_pdu,                defintval:4,      TYPE_UINT,      0},       \
+{ENB_CONFIG_STRING_SRB1_POLL_BYTE,                     NULL,   0,            iptr:&srb1_poll_byte,               defintval:99999,  TYPE_UINT,      0},       \
+{ENB_CONFIG_STRING_SRB1_MAX_RETX_THRESHOLD,            NULL,   0,            iptr:&srb1_max_retx_threshold,      defintval:4,      TYPE_UINT,      0}        \
 }
+/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
 
-
+/* MME configuration parameters section name */
 #define ENB_CONFIG_STRING_MME_IP_ADDRESS                "mme_ip_address"
 
+/* SRB1 configuration parameters names   */
 
-#define ENB_MME_IPV4_ADDRESS_IDX          0
-#define ENB_MME_IPV6_ADDRESS_IDX          1
-#define ENB_MME_IP_ADDRESS_ACTIVE_IDX     2
-#define ENB_MME_IP_ADDRESS_PREFERENCE_IDX 3
 
 #define ENB_CONFIG_STRING_MME_IPV4_ADDRESS              "ipv4"
 #define ENB_CONFIG_STRING_MME_IPV6_ADDRESS              "ipv6"
 #define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE         "active"
 #define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE     "preference"
 
+
+/*-------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            MME configuration parameters                                                             */
+/*   optname                                          helpstr   paramflags    XXXptr       defXXXval         type           numelt     */
+/*-------------------------------------------------------------------------------------------------------------------------------------*/
 #define S1PARAMS_DESC {  \
-{ENB_CONFIG_STRING_MME_IPV4_ADDRESS,               "",   NULL,   0,   uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},    \
-{ENB_CONFIG_STRING_MME_IPV6_ADDRESS,               "",   NULL,   0,   uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},    \
-{ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE,          "",   NULL,   0,   uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},    \
-{ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE,      "",   NULL,   0,   uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},    \
+{ENB_CONFIG_STRING_MME_IPV4_ADDRESS,                   NULL,      0,         uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},          \
+{ENB_CONFIG_STRING_MME_IPV6_ADDRESS,                   NULL,      0,         uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},          \
+{ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE,              NULL,      0,         uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},          \
+{ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE,          NULL,      0,         uptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},          \
 }
 
-
-
+#define ENB_MME_IPV4_ADDRESS_IDX          0
+#define ENB_MME_IPV6_ADDRESS_IDX          1
+#define ENB_MME_IP_ADDRESS_ACTIVE_IDX     2
+#define ENB_MME_IP_ADDRESS_PREFERENCE_IDX 3
+/*---------------------------------------------------------------------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------------------------------------------------------------------*/
+/* SCTP configuration parameters section name */
 #define ENB_CONFIG_STRING_SCTP_CONFIG                    "SCTP"
 
+/* SCTP configuration parameters names   */
 #define ENB_CONFIG_STRING_SCTP_INSTREAMS                 "SCTP_INSTREAMS"
 #define ENB_CONFIG_STRING_SCTP_OUTSTREAMS                "SCTP_OUTSTREAMS"
 
-#define ENB_SCTP_INSTREAMS_IDX          0
-#define ENB_SCTP_OUTSTREAMS_IDX         1
 
+
+/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            SRB1 configuration parameters                                                                                  */
+/*   optname                                          helpstr   paramflags    XXXptr                             defXXXval         type           numelt     */
+/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define SCTPPARAMS_DESC {  \
-{ENB_CONFIG_STRING_SCTP_INSTREAMS,                 "",   NULL,   0,   strptr:NULL,   defstrval:ENB_CONFIG_STRING_SCTP_INSTREAMS,    TYPE_STRING,   0},   \
-{ENB_CONFIG_STRING_SCTP_OUTSTREAMS,                "",   NULL,   0,   strptr:NULL,   defstrval:ENB_CONFIG_STRING_SCTP_OUTSTREAMS,   TYPE_STRING,   0}    \
+{ENB_CONFIG_STRING_SCTP_INSTREAMS,                       NULL,   0,   uptr:NULL,   defintval:-1,    TYPE_UINT,   0},       \
+{ENB_CONFIG_STRING_SCTP_OUTSTREAMS,                      NULL,   0,   uptr:NULL,   defintval:-1,    TYPE_UINT,   0}        \
 }
 
-
-
+#define ENB_SCTP_INSTREAMS_IDX          0
+#define ENB_SCTP_OUTSTREAMS_IDX         1
+/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*-----------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* S1 interface configuration parameters section name */
 #define ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG     "NETWORK_INTERFACES"
 
 #define ENB_INTERFACE_NAME_FOR_S1_MME_IDX          0
@@ -512,52 +534,46 @@ static int DEFENBS[] = {0};
 #define ENB_IPV4_ADDR_FOR_S1U_IDX                  3
 #define ENB_PORT_FOR_S1U_IDX                       4
 
+/* S1 interface configuration parameters names   */
 #define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME"
 #define ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME   "ENB_IPV4_ADDRESS_FOR_S1_MME"
 #define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U    "ENB_INTERFACE_NAME_FOR_S1U"
 #define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U         "ENB_IPV4_ADDRESS_FOR_S1U"
 #define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U              "ENB_PORT_FOR_S1U"
 
+/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            S1 interface configuration parameters                                                                 */
+/*   optname                                            helpstr   paramflags    XXXptr              defXXXval             type           numelt     */
+/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define NETPARAMS_DESC {  \
-{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME,  "",   NULL,   0,   strptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},	   \
-{ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME,    "",   NULL,   0,   strptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},	   \
-{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U,     "",   NULL,   0,   strptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},	   \
-{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U,          "",   NULL,   0,   strptr:NULL,   defstrval:NULL,   TYPE_STRING,   0},	   \
-{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U,               "",   NULL,   0,   uptr:NULL,     defintval:2152L,  TYPE_UINT,     0}	   \
+{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME,        NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
+{ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME,          NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
+{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U,           NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
+{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U,                NULL,      0,         strptr:NULL,         defstrval:NULL,      TYPE_STRING,      0},      \
+{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U,                     NULL,      0,         uptr:NULL,           defintval:2152L,     TYPE_UINT,        0}       \
 }   
 
-#define GTPUPARAMS_DESC { \
-{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U,      "",  NULL,    0,   strptr:&enb_interface_name_for_S1U,   defstrval:"lo",		TYPE_STRING,   0},	     \
-{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U,           "",  NULL,    0,   strptr:&enb_ipv4_address_for_S1U,     defstrval:"127.0.0.1",	TYPE_STRING,   0},	     \
-{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U,                "",  NULL,    0,   uptr:&enb_port_for_S1U,  	     defintval:2152,		TYPE_UINT,     0}	     \
-}
-
 
 
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            GTPU  configuration parameters                                                                                                      */
+/*   optname                                            helpstr   paramflags    XXXptr              defXXXval                                           type           numelt     */
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define GTPUPARAMS_DESC { \
+{ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U,           NULL,    0,            strptr:&enb_interface_name_for_S1U,      defstrval:"lo",                TYPE_STRING,   0},        \
+{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U,                NULL,    0,            strptr:&enb_ipv4_address_for_S1U,        defstrval:"127.0.0.1",         TYPE_STRING,   0},        \
+{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U,                     NULL,    0,            uptr:&enb_port_for_S1U,                  defintval:2152,                TYPE_UINT,     0}         \
+}
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
 
-
-#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG         "NETWORK_CONTROLLER"
-
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME      "FLEXRAN_AGENT_INTERFACE_NAME"
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS        "FLEXRAN_AGENT_IPV4_ADDRESS"
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT                "FLEXRAN_AGENT_PORT"
-#define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE               "FLEXRAN_AGENT_CACHE"
-
-
+/* L1 configuration section names   */
 #define CONFIG_STRING_L1_LIST                              "L1s"
 #define CONFIG_STRING_L1_CONFIG                            "l1_config"
 
-#define L1_CC_IDX                                          0
-#define L1_TRANSPORT_N_PREFERENCE_IDX                      1
-#define L1_LOCAL_N_IF_NAME_IDX                             2
-#define L1_LOCAL_N_ADDRESS_IDX                             3
-#define L1_REMOTE_N_ADDRESS_IDX                            4
-#define L1_LOCAL_N_PORTC_IDX                               5
-#define L1_REMOTE_N_PORTC_IDX                              6
-#define L1_LOCAL_N_PORTD_IDX                               7
-#define L1_REMOTE_N_PORTD_IDX                              8
 
 
+/* L1 configuration parameters names   */
 #define CONFIG_STRING_L1_CC                                "num_cc"
 #define CONFIG_STRING_L1_LOCAL_N_IF_NAME                   "local_n_if_name"
 #define CONFIG_STRING_L1_LOCAL_N_ADDRESS                   "local_n_address"
@@ -568,49 +584,55 @@ static int DEFENBS[] = {0};
 #define CONFIG_STRING_L1_REMOTE_N_PORTD                    "remote_n_portd"
 #define CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE            "tr_n_preference"
 
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            L1 configuration parameters                                                                             */
+/*   optname                                         helpstr   paramflags    XXXptr              defXXXval                  type           numelt     */
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define L1PARAMS_DESC { \
-{CONFIG_STRING_L1_CC,                          "",   NULL,   0,   uptr:NULL,		    defintval:1,	       TYPE_UINT,     0},	    \
-{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE,      "",   NULL,   0,   strptr:NULL,  	    defstrval:"local_mac",     TYPE_STRING,   0},	    \
-{CONFIG_STRING_L1_LOCAL_N_IF_NAME,             "",   NULL,   0,   strptr:NULL,  	    defstrval:"lo",	       TYPE_STRING,   0},	    \
-{CONFIG_STRING_L1_LOCAL_N_ADDRESS,             "",   NULL,   0,   strptr:NULL,  	    defstrval:"127.0.0.1",     TYPE_STRING,   0},	    \
-{CONFIG_STRING_L1_REMOTE_N_ADDRESS,            "",   NULL,   0,   strptr:NULL,  	    defstrval:"127.0.0.2",     TYPE_STRING,   0},	    \
-{CONFIG_STRING_L1_LOCAL_N_PORTC,               "",   NULL,   0,   uptr:NULL,		    defintval:50030,	       TYPE_UINT,     0},	    \
-{CONFIG_STRING_L1_REMOTE_N_PORTC,              "",   NULL,   0,   uptr:NULL,		    defintval:50030,	       TYPE_UINT,     0},	    \
-{CONFIG_STRING_L1_LOCAL_N_PORTD,               "",   NULL,   0,   uptr:NULL,		    defintval:50031,	       TYPE_UINT,     0},	    \
-{CONFIG_STRING_L1_REMOTE_N_PORTD,              "",   NULL,   0,   uptr:NULL,		    defintval:50031,	       TYPE_UINT,     0},	    \
+{CONFIG_STRING_L1_CC,                                NULL,      0,         uptr:NULL,           defintval:1,               TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_TRANSPORT_N_PREFERENCE,            NULL,      0,         strptr:NULL,         defstrval:"local_mac",     TYPE_STRING,   0},         \
+{CONFIG_STRING_L1_LOCAL_N_IF_NAME,                   NULL,      0,         strptr:NULL,         defstrval:"lo",            TYPE_STRING,   0},         \
+{CONFIG_STRING_L1_LOCAL_N_ADDRESS,                   NULL,      0,         strptr:NULL,         defstrval:"127.0.0.1",     TYPE_STRING,   0},         \
+{CONFIG_STRING_L1_REMOTE_N_ADDRESS,                  NULL,      0,         strptr:NULL,         defstrval:"127.0.0.2",     TYPE_STRING,   0},         \
+{CONFIG_STRING_L1_LOCAL_N_PORTC,                     NULL,      0,         uptr:NULL,           defintval:50030,           TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_REMOTE_N_PORTC,                    NULL,      0,         uptr:NULL,           defintval:50030,           TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_LOCAL_N_PORTD,                     NULL,      0,         uptr:NULL,           defintval:50031,           TYPE_UINT,     0},         \
+{CONFIG_STRING_L1_REMOTE_N_PORTD,                    NULL,      0,         uptr:NULL,           defintval:50031,           TYPE_UINT,     0},         \
 }
+#define L1_CC_IDX                                          0
+#define L1_TRANSPORT_N_PREFERENCE_IDX                      1
+#define L1_LOCAL_N_IF_NAME_IDX                             2
+#define L1_LOCAL_N_ADDRESS_IDX                             3
+#define L1_REMOTE_N_ADDRESS_IDX                            4
+#define L1_LOCAL_N_PORTC_IDX                               5
+#define L1_REMOTE_N_PORTC_IDX                              6
+#define L1_LOCAL_N_PORTD_IDX                               7
+#define L1_REMOTE_N_PORTD_IDX                              8
 
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define ENB_CONFIG_STRING_NETWORK_CONTROLLER_CONFIG         "NETWORK_CONTROLLER"
+
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME      "FLEXRAN_AGENT_INTERFACE_NAME"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS        "FLEXRAN_AGENT_IPV4_ADDRESS"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT                "FLEXRAN_AGENT_PORT"
+#define ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE               "FLEXRAN_AGENT_CACHE"
 
 #define FLEXRANPARAMS_DESC { \
-{ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME,   "",   NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0},	   \
-{ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS,     "",   NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0},	   \
-{ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT,             "",   NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0},	   \
-{ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE,            "",   NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0} 	   \
+{ENB_CONFIG_STRING_FLEXRAN_AGENT_INTERFACE_NAME,         NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0},           \
+{ENB_CONFIG_STRING_FLEXRAN_AGENT_IPV4_ADDRESS,           NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0},           \
+{ENB_CONFIG_STRING_FLEXRAN_AGENT_PORT,                   NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0},           \
+{ENB_CONFIG_STRING_FLEXRAN_AGENT_CACHE,                  NULL,   0,   uptr:NULL,   defstrval:ENB_CONFIG_STRING_ASN1_VERBOSITY_NONE,   TYPE_STRING,   0}            \
 }
 
-
-
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
+/* MACRLC configuration section names   */
 #define CONFIG_STRING_MACRLC_LIST                          "MACRLCs"
 #define CONFIG_STRING_MACRLC_CONFIG                        "macrlc_config"
 
-#define MACRLC_CC_IDX                                          0
-#define MACRLC_TRANSPORT_N_PREFERENCE_IDX                      1
-#define MACRLC_LOCAL_N_IF_NAME_IDX                             2
-#define MACRLC_LOCAL_N_ADDRESS_IDX                             3
-#define MACRLC_REMOTE_N_ADDRESS_IDX                            4
-#define MACRLC_LOCAL_N_PORTC_IDX                               5
-#define MACRLC_REMOTE_N_PORTC_IDX                              6
-#define MACRLC_LOCAL_N_PORTD_IDX                               7
-#define MACRLC_REMOTE_N_PORTD_IDX                              8
-#define MACRLC_TRANSPORT_S_PREFERENCE_IDX                      9
-#define MACRLC_LOCAL_S_IF_NAME_IDX                             10
-#define MACRLC_LOCAL_S_ADDRESS_IDX                             11
-#define MACRLC_REMOTE_S_ADDRESS_IDX                            12
-#define MACRLC_LOCAL_S_PORTC_IDX                               13
-#define MACRLC_REMOTE_S_PORTC_IDX                              14
-#define MACRLC_LOCAL_S_PORTD_IDX                               15
-#define MACRLC_REMOTE_S_PORTD_IDX                              16
 
+/* MACRLC configuration parameters names   */
 #define CONFIG_STRING_MACRLC_CC                            "num_cc"
 #define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE        "tr_n_preference"
 #define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME               "local_n_if_name"
@@ -630,23 +652,44 @@ static int DEFENBS[] = {0};
 #define CONFIG_STRING_MACRLC_REMOTE_S_PORTD                "remote_s_portd"
 
 
-
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            MacRLC  configuration parameters                                                                           */
+/*   optname                                            helpstr   paramflags    XXXptr              defXXXval                  type           numelt     */
+/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
 #define MACRLCPARAMS_DESC { \
-{CONFIG_STRING_MACRLC_CC,                          "",   NULL,   0,   uptr:NULL,		defintval:50011,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE,      "",   NULL,   0,   strptr:NULL,		defstrval:"local_L1",	   TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME,             "",   NULL,   0,   strptr:NULL,		defstrval:"lo", 	   TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS,             "",   NULL,   0,   strptr:NULL,		defstrval:"127.0.0.1",     TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS,            "",   NULL,   0,   uptr:NULL,		defstrval:"127.0.0.2",     TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_LOCAL_N_PORTC,               "",   NULL,   0,   uptr:NULL,		defintval:50010,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_REMOTE_N_PORTC,              "",   NULL,   0,   uptr:NULL,		defintval:50010,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_LOCAL_N_PORTD,               "",   NULL,   0,   uptr:NULL,		defintval:50011,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_REMOTE_N_PORTD,              "",   NULL,   0,   uptr:NULL,		defintval:50011,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE,      "",   NULL,   0,   strptr:NULL,		defstrval:"local_RRC",     TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME,             "",   NULL,   0,   strptr:NULL,		defstrval:"lo", 	   TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS,             "",   NULL,   0,   uptr:NULL,		defstrval:"127.0.0.1",     TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS,            "",   NULL,   0,   uptr:NULL,		defstrval:"127.0.0.2",     TYPE_STRING,   0},		\
-{CONFIG_STRING_MACRLC_LOCAL_S_PORTC,               "",   NULL,   0,   uptr:NULL,		defintval:50020,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_REMOTE_S_PORTC,              "",   NULL,   0,   uptr:NULL,		defintval:50020,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_LOCAL_S_PORTD,               "",   NULL,   0,   uptr:NULL,		defintval:50021,	   TYPE_UINT,	  0},		\
-{CONFIG_STRING_MACRLC_REMOTE_S_PORTD,              "",   NULL,   0,   uptr:NULL,		defintval:50021,	   TYPE_UINT,	  0},		\
+{CONFIG_STRING_MACRLC_CC,                                NULL,     0,          uptr:NULL,           defintval:50011,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE,            NULL,     0,          strptr:NULL,         defstrval:"local_L1",      TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME,                   NULL,     0,          strptr:NULL,         defstrval:"lo",            TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS,                   NULL,     0,          strptr:NULL,         defstrval:"127.0.0.1",     TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS,                  NULL,     0,          uptr:NULL,           defstrval:"127.0.0.2",     TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_LOCAL_N_PORTC,                     NULL,     0,          uptr:NULL,           defintval:50010,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_REMOTE_N_PORTC,                    NULL,     0,          uptr:NULL,           defintval:50010,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_LOCAL_N_PORTD,                     NULL,     0,          uptr:NULL,           defintval:50011,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_REMOTE_N_PORTD,                    NULL,     0,          uptr:NULL,           defintval:50011,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_TRANSPORT_S_PREFERENCE,            NULL,     0,          strptr:NULL,         defstrval:"local_RRC",     TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_LOCAL_S_IF_NAME,                   NULL,     0,          strptr:NULL,         defstrval:"lo",            TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_LOCAL_S_ADDRESS,                   NULL,     0,          uptr:NULL,           defstrval:"127.0.0.1",     TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_REMOTE_S_ADDRESS,                  NULL,     0,          uptr:NULL,           defstrval:"127.0.0.2",     TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_LOCAL_S_PORTC,                     NULL,     0,          uptr:NULL,           defintval:50020,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_REMOTE_S_PORTC,                    NULL,     0,          uptr:NULL,           defintval:50020,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_LOCAL_S_PORTD,                     NULL,     0,          uptr:NULL,           defintval:50021,           TYPE_UINT,     0},        \
+{CONFIG_STRING_MACRLC_REMOTE_S_PORTD,                    NULL,     0,          uptr:NULL,           defintval:50021,           TYPE_UINT,     0},        \
 }
+#define MACRLC_CC_IDX                                          0
+#define MACRLC_TRANSPORT_N_PREFERENCE_IDX                      1
+#define MACRLC_LOCAL_N_IF_NAME_IDX                             2
+#define MACRLC_LOCAL_N_ADDRESS_IDX                             3
+#define MACRLC_REMOTE_N_ADDRESS_IDX                            4
+#define MACRLC_LOCAL_N_PORTC_IDX                               5
+#define MACRLC_REMOTE_N_PORTC_IDX                              6
+#define MACRLC_LOCAL_N_PORTD_IDX                               7
+#define MACRLC_REMOTE_N_PORTD_IDX                              8
+#define MACRLC_TRANSPORT_S_PREFERENCE_IDX                      9
+#define MACRLC_LOCAL_S_IF_NAME_IDX                             10
+#define MACRLC_LOCAL_S_ADDRESS_IDX                             11
+#define MACRLC_REMOTE_S_ADDRESS_IDX                            12
+#define MACRLC_LOCAL_S_PORTC_IDX                               13
+#define MACRLC_REMOTE_S_PORTC_IDX                              14
+#define MACRLC_LOCAL_S_PORTD_IDX                               15
+#define MACRLC_REMOTE_S_PORTD_IDX                              16
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 759b22b38ba43c3ea56afc21a32738177ed94425..d062be4001c0cbe712d8891fa9937b3fa7d0ea48 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -58,7 +58,7 @@
 
 extern RAN_CONTEXT_t RC;
 extern int l2_init_eNB(void);
-extern int mac_top_init_eNB(void);
+extern void mac_top_init_eNB(void);
 extern void mac_init_cell_params(int Mod_idP,int CC_idP);
 extern void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
 
@@ -494,6 +494,7 @@ void config_sib2(int Mod_idP,
     struct PRACH_ConfigSIB_v1310 *ext4_prach=radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; 
 
     PRACH_ParametersListCE_r13_t	 *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
+
     PRACH_ParametersCE_r13_t *p;
     cfg->emtc_config.prach_ce_level_0_enable.value=0;
     cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG;
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index cee4688fe68b4d22e2cf76b1adfb48dafa00742b..7ca049f38ce71f78c2780ab62699021fd68ee752 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -515,8 +515,6 @@ typedef struct {
   uint8_t harq_pid;
   /// harq rounf
   uint8_t harq_round;
-  /// DL Wideband CQI index (2 TBs)
-  uint8_t dl_cqi;
   /// total available number of PRBs for a new transmission
   uint16_t rbs_used;
   /// total available number of PRBs for a retransmission
@@ -648,6 +646,10 @@ typedef struct {
   uint8_t oldmcs2[8];
   /// NDI from last UL scheduling
   uint8_t oldNDI_UL[8];
+  /// mcs from last UL scheduling
+  uint8_t mcs_UL[8];
+  /// TBS from last UL scheduling
+  uint8_t TBS_UL[8];
   /// Flag to indicate UL has been scheduled at least once
   boolean_t ul_active;
   /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received)
@@ -815,8 +817,11 @@ typedef struct {
   int32_t       phr_received;
   uint8_t       periodic_ri_received[NFAPI_CC_MAX];
   uint8_t       aperiodic_ri_received[NFAPI_CC_MAX];
+  uint8_t       pucch1_cqi_update[NFAPI_CC_MAX];
   uint8_t       pucch1_snr[NFAPI_CC_MAX];
+  uint8_t       pucch2_cqi_update[NFAPI_CC_MAX];
   uint8_t       pucch2_snr[NFAPI_CC_MAX];
+  uint8_t       pucch3_cqi_update[NFAPI_CC_MAX];
   uint8_t       pucch3_snr[NFAPI_CC_MAX];
   uint8_t       pusch_snr[NFAPI_CC_MAX];
   uint16_t      feedback_cnt[NFAPI_CC_MAX];
@@ -836,6 +841,7 @@ typedef struct {
   uint8_t       aperiodic_wideband_pmi[NFAPI_CC_MAX];
   uint8_t       aperiodic_wideband_cqi1[NFAPI_CC_MAX];
   uint8_t       aperiodic_wideband_pmi1[NFAPI_CC_MAX];
+  uint8_t       dl_cqi[NFAPI_CC_MAX];
 } UE_sched_ctrl;
 /*! \brief eNB template for the Random access information */
 typedef struct {
@@ -877,6 +883,8 @@ typedef struct {
   uint8_t generate_Msg4;
   /// Flag to indicate that eNB is waiting for ACK that UE has received Msg3.
   uint8_t wait_ack_Msg4;
+  /// harq_pid used for Msg4 transmission
+  uint8_t harq_pid;
   /// UE RNTI allocated during RAR
   rnti_t rnti;
   /// RA RNTI allocated from received PRACH
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index d71730059a9ea92f5c9b094a294254bb29df99ab..e26cd7b1e54660b52386c3bfa36456140f997f9b 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -231,6 +231,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]) {
@@ -265,18 +266,27 @@ void schedule_SR(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) {
 
       // if we get here there is some PUCCH1 reception to schedule for SR
 
-      int ul_ulsch_only=0;
+      int skip_ue=0;
       // check that there is no existing UL grant for ULSCH which overrides the SR
       for (int i=0;i<ul_req->number_of_pdus;i++)
-	if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) &&
+	if (((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)||
+	     (ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE)||
+	     (ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)||
+	     (ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE))&&
 	    (ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) {
-	    ul_ulsch_only=1;
+	    skip_ue=1;
 	    break;
 	}
+	else if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE)&&
+		 (ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti))
+	  skip_ue=1;
 
       // drop the allocation because ULSCH with handle it with BSR
-      if (ul_ulsch_only==1) continue;
-      
+      if (skip_ue==1) continue;
+
+      // drop the allocation if the UE hasn't send RRCConnectionSetupComplete yet
+      if (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED) continue;
+       
       // if we get here then there is no UL grant so program the SR
       ul_req->ul_config_pdu_list[ul_req->number_of_pdus].pdu_type                                                 = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE;
       ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.tl.tag     = NFAPI_UL_CONFIG_REQUEST_UE_INFORMATION_REL8_TAG;
@@ -315,7 +325,6 @@ void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id,
   UE_list_t                           *UE_list      = &RC.mac[module_idP]->UE_list;
   nfapi_dl_config_request_t           *DL_req       = &RC.mac[module_idP]->DL_req[0];
   uint16_t                            rnti          = UE_RNTI(module_idP,UE_id);
-  eNB_UE_STATS                        *eNB_UE_stats = &RC.mac[module_idP]->UE_list.eNB_UE_stats[CC_id][UE_id];
   COMMON_channels_t                   *cc           = RC.mac[module_idP]->common_channels;
 
   // check uplink failure
@@ -333,7 +342,7 @@ void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id,
       dl_config_pdu->pdu_size                                         = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format            = NFAPI_DL_DCI_FORMAT_1A;
-      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level     = get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->dl_cqi,format1A);
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level     = get_aggregation(get_bw_index(module_idP,CC_id),UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],format1A);
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                  = rnti;
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type             = 1;    // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power    = 6000; // equal to RS power
@@ -373,8 +382,6 @@ void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id,
   
 }
 
-void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP);
-
 void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP) {
 
   nfapi_dl_config_request_t *DL_req         = &eNB->DL_req[0];
@@ -390,7 +397,7 @@ void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_fra
   DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti                   = 0;
   DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich           = 6000;
   
-  HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf                            = subframeP + (frameP<<3);
+  HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf                            = subframeP + (frameP<<4);
   HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci                    = 0;
   
   
@@ -435,12 +442,6 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
   int mbsfn_status[MAX_NUM_CCs];
   protocol_ctxt_t   ctxt;
 
-#if defined(ENABLE_ITTI)
-  MessageDef   *msg_p;
-  const char         *msg_name;
-  instance_t    instance;
-  int           result;
-#endif
   int CC_id,i; //,next_i;
   UE_list_t *UE_list=&RC.mac[module_idP]->UE_list;
   rnti_t rnti;
@@ -485,7 +486,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
       LOG_D(MAC,"UE  rnti %x : %s, PHR %d dB CQI %d\n", rnti,
             UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync",
             UE_list->UE_template[CC_id][i].phr_info,
-            eNB_UE_stats->dl_cqi);
+            UE_list->UE_sched_ctrl[i].dl_cqi[CC_id]);
     }
 
     RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63;
@@ -495,7 +496,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
     RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
 
     RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++;
-    LOG_I(MAC,"UE %d/%x : ul_inactivity %d, cqi_req %d\n",i,rnti, 
+    LOG_D(MAC,"UE %d/%x : ul_inactivity %d, cqi_req %d\n",i,rnti, 
 	  RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer,
 	  RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
     check_ul_failure(module_idP,CC_id,i,frameP,subframeP);
@@ -528,9 +529,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame
   schedule_SI(module_idP,frameP,subframeP);
   // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
   schedule_RA(module_idP,frameP,subframeP);
-
   // copy previously scheduled UL resources (ULSCH + HARQ)
-
   copy_ulreq(module_idP,frameP,subframeP);
   // This schedules SRS in subframeP
   schedule_SRS(module_idP,frameP,subframeP);
@@ -545,10 +544,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_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 6ffbe389b788d92ad8d9aee888dbb1c6fbf1db11..ded5014aed5c6d8d9801974a1018dac7308ba262 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -66,7 +66,7 @@ void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_
 
   eNB_MAC_INST                    *eNB = RC.mac[module_idP];
   COMMON_channels_t               *cc  = &eNB->common_channels[CC_id];
-  uint8_t                         i,j;
+  uint8_t                         j;
   nfapi_ul_config_request_t      *ul_req;
   nfapi_ul_config_request_pdu_t  *ul_config_pdu;
   nfapi_ul_config_request_body_t *ul_req_body;
@@ -83,8 +83,8 @@ void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_
 
 #ifdef Rel14
   if (RA_template->rach_resource_type>0) {
-    LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d CE level %d is active, Msg3 in (%d,%d)\n",
-	  module_idP,frameP,subframeP,CC_id,i,RA_template->rach_resource_type-1,
+    LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n",
+	  module_idP,frameP,subframeP,CC_id,RA_template->rach_resource_type-1,
 	  RA_template->Msg3_frame,RA_template->Msg3_subframe);
     LOG_D(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
 	  frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
@@ -122,8 +122,8 @@ void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_
   else
 #endif
     {
-      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA %d is active, Msg3 in (%d,%d)\n",
-	    module_idP,frameP,subframeP,CC_id,i,RA_template->Msg3_frame,RA_template->Msg3_subframe);
+      LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n",
+	    module_idP,frameP,subframeP,CC_id,RA_template->Msg3_frame,RA_template->Msg3_subframe);
 	    
       LOG_D(MAC,"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d)\n",
 	    frameP,subframeP,RA_template->Msg3_frame,RA_template->Msg3_subframe);
@@ -169,8 +169,8 @@ void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_
 	// save UL scheduling information for preprocessor
 	for (j=0;j<RA_template->msg3_nb_rb;j++) cc->vrb_map_UL[RA_template->msg3_first_rb+j]=1;
 	
-	LOG_D(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA %d (mcs %d, first rb %d, nb_rb %d,round %d)\n",
-	      module_idP,RA_template->rnti,CC_id,frameP,subframeP,i,10,
+	LOG_D(MAC,"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA (mcs %d, first rb %d, nb_rb %d,round %d)\n",
+	      module_idP,RA_template->rnti,CC_id,frameP,subframeP,10,
 	      1,1,
 	      RA_template->msg3_round-1);
       } //       if (RA_template->msg3_round != 0) { // program HI too
@@ -434,7 +434,7 @@ void generate_Msg2(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding                  = getRIV(N_RB_DL,first_rb,4);      
 
 	// This checks if the above DCI allocation is feasible in current subframe
-	if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) {
+	if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->RA_rnti)) {
 	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n",
 		frameP,subframeP,RA_template->RA_rnti);
 	  dl_req->number_dci++;
@@ -518,7 +518,6 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
   nfapi_ul_config_request_body_t *ul_req;
   uint8_t                         lcid;
   uint8_t                         offset;
-  int harq_pid;
 
 
 #ifdef Rel14
@@ -587,8 +586,8 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
   
   // set HARQ process round to 0 for this UE
   
-  if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
-  else harq_pid = ((frameP*10)+subframeP)&7;
+  if (cc->tdd_Config) RA_template->harq_pid = ((frameP*10)+subframeP)%10;
+  else RA_template->harq_pid = ((frameP*10)+subframeP)&7;
 
   
   // Get RRCConnectionSetup for Piggyback
@@ -662,7 +661,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pdsch_reptition_levels                        = 4; // fix to 4 for now
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.redundancy_version                            = 0;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.new_data_indicator                            = 0;
-      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = harq_pid;
+      dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.harq_process                                  = RA_template->harq_pid;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi_length                                   = 0;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.tpmi                                          = 0;
       dl_config_pdu->mpdcch_pdu.mpdcch_pdu_rel13.pmi_flag                                      = 0;
@@ -754,7 +753,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 
 	lcid=0;
 	
-	UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0;
+	UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid] = 0;
 	msg4_header = 1+6+1;  // CR header, CR CE, SDU header
 	
 	if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
@@ -784,7 +783,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 	       rrc_sdu_length);
 	
 	// DL request
-	eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<3)+subframeP;
+	eNB->TX_req[CC_idP].sfn_sf                                             = (frameP<<4)+subframeP;
         eNB->TX_req[CC_idP].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
         eNB->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST;
 	TX_req                                                                = &eNB->TX_req[CC_idP].tx_request_body.tx_pdu_list[eNB->TX_req[CC_idP].tx_request_body.number_of_pdus]; 		     	      
@@ -841,7 +840,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 #endif
     { // This is normal LTE case
       if ((RA_template->Msg4_frame == frameP) && (RA_template->Msg4_subframe == subframeP)) {	      
-	LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
+	LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RNTI %x)\n",
 	      module_idP, CC_idP, frameP, subframeP,RA_template->rnti);
 	
 	/// Choose first 4 RBs for Msg4, should really check that these are free!
@@ -880,7 +879,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 			     4,                           // aggregation_level
 			     RA_template->rnti,           // rnti
 			     1,                           // rnti_type, CRNTI
-			     harq_pid,                    // harq_process
+			     RA_template->harq_pid,       // harq_process
 			     1,                           // tpc, none
 			     getRIV(N_RB_DL,first_rb,4),  // resource_block_coding
 			     RA_template->msg4_mcs,       // mcs
@@ -888,22 +887,30 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 			     0,                           // rv
 			     0);                          // vrb_flag
 	
-	if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
+	if (!CCE_allocation_infeasible(module_idP,CC_idP,1,
+				       subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
+				       RA_template->rnti)) {
 	  dl_req->number_dci++;
 	  dl_req->number_pdu++;
           dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
 	  
 	  RA_template->generate_Msg4=0;
 	  RA_template->wait_ack_Msg4=1;
-	  RA_template->Msg4_frame++;
+	  
+	  // increment Absolute subframe by 8 for Msg4 retransmission
+	  LOG_I(MAC,"Frame %d, Subframe %d: Preparing for Msg4 retransmission currently %d.%d\n",
+		frameP,subframeP,RA_template->Msg4_frame,RA_template->Msg4_subframe);
+	  if (RA_template->Msg4_subframe > 1) RA_template->Msg4_frame++;
 	  RA_template->Msg4_frame&=1023;
-
+	  RA_template->Msg4_subframe = (RA_template->Msg4_subframe+8)%10;
+	  LOG_I(MAC,"Frame %d, Subframe %d: Msg4 retransmission in %d.%d\n",
+		frameP,subframeP,RA_template->Msg4_frame,RA_template->Msg4_subframe);
 	  lcid=0;
 	  
-	  // put HARQ process 0 round to IDLE
-	  if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
-	  else harq_pid = ((frameP*10)+subframeP)&7;
-	  UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid] = 0;
+	  // put HARQ process round to 0
+	  if (cc->tdd_Config) RA_template->harq_pid = ((frameP*10)+subframeP)%10;
+	  else RA_template->harq_pid = ((frameP*10)+subframeP)&7;
+	  UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid] = 0;
 	  
 	  if ((RA_template->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
 	    msg4_padding = RA_template->msg4_TBsize - rrc_sdu_length - msg4_header;
@@ -965,6 +972,7 @@ void generate_Msg4(module_id_t module_idP,int CC_idP,frame_t frameP,sub_frame_t
 							 eNB->UE_list.DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); 
           eNB->TX_req[CC_idP].header.message_id = NFAPI_TX_REQUEST;
 
+	  LOG_D(MAC,"Filling UCI ACK/NAK information, cce_idx %d\n",dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
 	  // Program PUCCH1a for ACK/NAK
 	  // Program ACK/NAK for Msg4 PDSCH
 	  fill_nfapi_uci_acknak(module_idP,
@@ -1002,7 +1010,7 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,
   UE_list_t                       *UE_list=&eNB->UE_list;
   nfapi_dl_config_request_body_t *dl_req;
 
-  int                             round,harq_pid;
+  int                             round;
   /*
 #ifdef Rel14
   COMMON_channels_t               *cc  = eNB->common_channels;
@@ -1042,18 +1050,16 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,
   
   UE_id = find_UE_id(module_idP,RA_template->rnti);
   AssertFatal(UE_id>=0,"Can't find UE for t-crnti\n");
-  if (cc[CC_idP].tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
-  else harq_pid = ((frameP*10)+subframeP)&7;
 
-  round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][harq_pid];
+  round = UE_list->UE_sched_ctrl[UE_id].round[CC_idP][RA_template->harq_pid];
   vrb_map       = cc[CC_idP].vrb_map;
   
   dl_req        = &eNB->DL_req[CC_idP].dl_config_request_body;
   dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
   N_RB_DL       = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
   
-  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 was acknowledged (round %d)\n",
-	module_idP,CC_idP,frameP,subframeP,round);
+  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Checking if Msg4 for harq_pid %d was acknowledged (round %d)\n",
+	module_idP,CC_idP,frameP,subframeP,RA_template->harq_pid,round);
 
   if (round!=8) {
     
@@ -1079,25 +1085,48 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,
 			       4,                           // aggregation_level
 			       RA_template->rnti,           // rnti
 			       1,                           // rnti_type, CRNTI
-			       0,                           // harq_process
+			       RA_template->harq_pid,       // harq_process
 			       1,                           // tpc, none
 			       getRIV(N_RB_DL,first_rb,4),  // resource_block_coding
 			       RA_template->msg4_mcs,       // mcs
 			       1,                           // ndi
-			       round,                       // rv
+			       round&3,                       // rv
 			       0);                          // vrb_flag
 	  
-	  if (!CCE_allocation_infeasible(module_idP,CC_idP,0,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
+	  if (!CCE_allocation_infeasible(module_idP,CC_idP,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,RA_template->rnti)) {
 	    dl_req->number_dci++;
 	    dl_req->number_pdu++;
             dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
 	    
 	    LOG_D(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d\n", RA_template->rnti, round, frameP, subframeP);
+	    	  // DLSCH Config
+	    fill_nfapi_dlsch_config(eNB,
+				    dl_req,
+				    RA_template->msg4_TBsize,
+				    eNB->pdu_index[CC_idP]++,
+				    RA_template->rnti,
+				    2,                           // resource_allocation_type : format 1A/1B/1D
+				    0,                           // virtual_resource_block_assignment_flag : localized
+				    getRIV(N_RB_DL,first_rb,4),  // resource_block_coding : RIV, 4 PRB
+				    2,                           // modulation: QPSK
+				    round&3,                     // redundancy version
+				    1,                           // transport_blocks
+				    0,                           // transport_block_to_codeword_swap_flag (0)
+				    (cc->p_eNB==1 ) ? 0 : 1,     // transmission_scheme
+				    1,                           // number of layers
+				    1,                           // number of subbands
+				    //0,                         // codebook index 
+				    1,                           // ue_category_capacity
+				    4,                           // pa: 0 dB
+				    0,                           // delta_power_offset_index
+				    0,                           // ngap
+				    1,                           // NPRB = 3 like in DCI
+				    (cc->p_eNB==1 ) ? 1 : 2,     // transmission mode
+				    1,                           // num_bf_prb_per_subband
+				    1);                          // num_bf_vector
 	  }
 	  else
 	    LOG_D(MAC,"msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n", RA_template->rnti, round, frameP, subframeP);
-	  LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n",
-		module_idP,CC_idP,frameP,subframeP,RA_template->rnti);
 	  
 	  
 	  // Program PUCCH1a for ACK/NAK
@@ -1109,12 +1138,17 @@ void check_Msg4_retransmission(module_id_t module_idP,int CC_idP,frame_t frameP,
 				dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
 	  
 	  // prepare frame for retransmission
-	  RA_template->Msg4_frame++;
+	  if (RA_template->Msg4_subframe>1) RA_template->Msg4_frame++;
 	  RA_template->Msg4_frame&=1023;
+	  RA_template->Msg4_subframe=(RA_template->Msg4_subframe+8)%10;
+
+	  LOG_W(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission round %d in %d.%d)\n",
+		module_idP,CC_idP,frameP,subframeP,RA_template->rnti,round,RA_template->Msg4_frame,RA_template->Msg4_subframe);
+
 	} // Msg4 frame/subframe
       } // regular LTE case
   } else {
-    LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP);
+    LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,CC_idP,frameP,subframeP);
     RA_template->wait_ack_Msg4=0;
     RA_template->RA_active=FALSE;
     UE_id = find_UE_id(module_idP,RA_template->rnti);
@@ -1189,7 +1223,7 @@ void initiate_ra_proc(module_id_t module_idP,
     ext4_prach=cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
     prach_ParametersListCE_r13= &ext4_prach->prach_ParametersListCE_r13;
   }
-  LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,subframeP,preamble_index);
+  LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  Initiating RA procedure for preamble index %d\n",module_idP,CC_id,frameP,subframeP,preamble_index);
 #ifdef Rel14
   LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d  PRACH resource type %d\n",module_idP,CC_id,frameP,subframeP,rach_resource_type);
 #endif
@@ -1237,7 +1271,7 @@ void initiate_ra_proc(module_id_t module_idP,
       if (loop == 100) { printf("%s:%d:%s: FATAL ERROR! contact the authors\n", __FILE__, __LINE__, __FUNCTION__); abort(); }
       RA_template[i].RA_rnti        = ra_rnti;
       RA_template[i].preamble_index = preamble_index;
-      LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, RA_active %d\n",
+      LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, RA_active %d\n",
             module_idP,CC_id,frameP,
 	    RA_template[i].Msg2_frame,
 	    RA_template[i].Msg2_subframe,
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
index 9da9f5e1208c0cc753a757c4d261fe681feb608f..47a56800e8ea1b5693fa416ccf46e40a3afd3eed 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c
@@ -711,7 +711,7 @@ schedule_SI(
 	
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                = 0;
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                         = 1; // no TPC
-	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1        = 1;
+	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1        = 0;
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1                       = mcs;
 	dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1        = 0;
 	
@@ -721,7 +721,11 @@ schedule_SI(
 	
         LOG_D(MAC, "%s() mcs:%d bcch_sdu_length:%d N_RB_DL:%d first_rb:%d resource_block_coding:%d\n", __FUNCTION__, mcs, bcch_sdu_length, N_RB_DL, first_rb, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding);
 
-	if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,SI_RNTI)) {
+	if (!CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,
+				       dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,SI_RNTI)) {
+	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for S_RNTI\n",
+		frameP,subframeP);
+	  dl_req->number_dci++;
 	  dl_req->number_pdu++;
 	  dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
 
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 096898afa47c1986dd57e1971e44fa842f7c6f8d..081c485979d79ab739216d19d60e0e6ca83aec87
--- 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;
@@ -455,7 +456,6 @@ schedule_ue_spec(
   int                            N_RBG[MAX_NUM_CCs];
   nfapi_dl_config_request_body_t *dl_req;
   nfapi_dl_config_request_pdu_t  *dl_config_pdu;
-  nfapi_tx_request_pdu_t         *TX_req;
   int                            tdd_sfa;
 
 #if 0
@@ -502,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++) {
@@ -535,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);
 
@@ -567,12 +567,12 @@ schedule_ue_spec(
         case 2:
         case 7:
 	  aggregation = get_aggregation(get_bw_index(module_idP,CC_id), 
-					eNB_UE_stats->dl_cqi,
+					ue_sched_ctl->dl_cqi[CC_id],
 					format1);
 	  break;
         case 3:
 	  aggregation = get_aggregation(get_bw_index(module_idP,CC_id), 
-					eNB_UE_stats->dl_cqi,
+					ue_sched_ctl->dl_cqi[CC_id],
 					format2A);
 	  break;
         default:
@@ -582,7 +582,7 @@ schedule_ue_spec(
       } /* if (continue_flag != 1 */
 
       if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) ||  // no RBs allocated 
-	  CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)
+	  CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,aggregation,rnti)
 	  ) {
         LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
               module_idP, frameP, UE_id, CC_id);
@@ -608,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;
@@ -627,12 +642,12 @@ schedule_ue_spec(
       DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)),
       eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE);
       */
-      eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->dl_cqi];
+      eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
       eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1;//cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
 
 
       // store stats
-      UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
+      //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
 
       // initializing the rb allocation indicator for each UE
       for(j=0; j<N_RBG[CC_id]; j++) {
@@ -641,7 +656,7 @@ schedule_ue_spec(
 
       LOG_D(MAC,"[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
             module_idP, frameP, UE_id,CC_id,rnti,harq_pid, round,nb_available_rb,
-            eNB_UE_stats->dl_cqi, eNB_UE_stats->dlsch_mcs1,
+            ue_sched_ctl->dl_cqi[CC_id], eNB_UE_stats->dlsch_mcs1,
 	    UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);
 
 
@@ -671,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) &&
@@ -707,7 +723,7 @@ schedule_ue_spec(
 	    dl_config_pdu->pdu_size                                               = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
 	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                      = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
 	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                  = NFAPI_DL_DCI_FORMAT_1;
-	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level           = get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->dl_cqi,format1);
+	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level           = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1);
 	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                        = rnti;
 	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type                   = 1;    // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
 	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power          = 6000; // equal to RS power
@@ -774,6 +790,7 @@ schedule_ue_spec(
 	    }
 	  }
 
+
 	  add_ue_dlsch_info(module_idP,
 			    CC_id,
 			    UE_id,
@@ -1150,16 +1167,17 @@ schedule_ue_spec(
 	  // do PUCCH power control
           // this is the normalized RX power
 	  eNB_UE_stats =  &UE_list->eNB_UE_stats[CC_id][UE_id];
-	  normalized_rx_power = eNB_UE_stats->Po_PUCCH_dBm; 
-	  target_rx_power = cc[CC_id].radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUCCH + 20;
+
+	  normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id];
+	  target_rx_power = 20;
 	    
           // this assumes accumulated tpc
 	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
 	  int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe;
           if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case
 	      ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around
-	    if (eNB_UE_stats->Po_PUCCH_update == 1) { 
-	      eNB_UE_stats->Po_PUCCH_update = 0;
+	    if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { 
+	      ue_sched_ctl->pucch1_cqi_update[CC_id] = 0;
 
 	      UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP;
 	      UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP;
@@ -1173,10 +1191,10 @@ schedule_ue_spec(
 	      } else {
 		tpc = 1; //0
 	      }
-	      /*	      
-	      LOG_I(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
+	      	      
+	      LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
 		    module_idP,frameP, subframeP,harq_pid,tpc,
-		    tpc_accumulated,normalized_rx_power,target_rx_power);*/
+		    tpc_accumulated,normalized_rx_power,target_rx_power);
 
 	    } // Po_PUCCH has been updated 
 	    else {
@@ -1192,7 +1210,7 @@ schedule_ue_spec(
 	  dl_config_pdu->pdu_size                                               = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
 	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag                      = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
 	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                  = NFAPI_DL_DCI_FORMAT_1;
-	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level           = get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->dl_cqi,format1);
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level           = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1);
 	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                        = rnti;
 	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type                   = 1;    // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
 	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power          = 6000; // equal to RS power
@@ -1216,6 +1234,7 @@ schedule_ue_spec(
 		  module_idP,CC_id,harq_pid,mcs);
 	    
 	  }
+	  LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu);
 	  if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) {
 
 
@@ -1263,7 +1282,7 @@ schedule_ue_spec(
 							  (frameP*10)+subframeP,
 							  TBS,
 							  &eNB->pdu_index[CC_id],
-							  eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[harq_pid]);
+							  eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]);
 	    
 	    LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",eNB->pdu_index[CC_id]);
 
@@ -1287,6 +1306,7 @@ schedule_ue_spec(
     } // UE_id loop
   }  // CC_id loop
 
+
      
   fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_flag);
 
@@ -1323,7 +1343,6 @@ fill_DLSCH_dci(
   int               N_RBG;
   int               N_RB_DL;
   COMMON_channels_t *cc;
-  eNB_UE_STATS      *eNB_UE_stats;
 
   start_meas(&eNB->fill_DLSCH_dci);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,VCD_FUNCTION_IN);
@@ -1351,7 +1370,6 @@ fill_DLSCH_dci(
 	else harq_pid = ((frameP*10)+subframeP)&7;
         nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
 
-	eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; 
 
 	
         /// Synchronizing rballoc with rballoc_sub
@@ -1433,6 +1451,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 9f507e349d50411516ff9b8b2bd7d0146e75dcd6..e2668dfd40a434eb6a8e13d3632f06ee981a25d2 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
 
@@ -777,13 +779,12 @@ void get_csi_params(COMMON_channels_t *cc,struct CQI_ReportPeriodic *cqi_ReportP
 }
 
 
-uint8_t get_dl_cqi_pmi_size_pusch(UE_sched_ctrl *sched_ctl,COMMON_channels_t *cc,uint8_t tmode,uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic) {
+uint8_t get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc,uint8_t tmode,uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic) {
 
   int Ntab[6]       = {0,4,7,9,10,13};
-  int Ntab_uesel[6] = {0,8,13,17,19,25};
-  int N             = Ntab[cc->p_eNB];
+  int N             = Ntab[cc->mib->message.dl_Bandwidth];
   int Ltab_uesel[6] = {0,6,9,13,15,18};
-  int L             = Ltab_uesel[cc->p_eNB];
+  int L             = Ltab_uesel[cc->mib->message.dl_Bandwidth];
 
   AssertFatal(cqi_ReportModeAperiodic != NULL,"cqi_ReportPeriodic is null!\n");
 
@@ -847,7 +848,8 @@ uint8_t get_dl_cqi_pmi_size_pusch(UE_sched_ctrl *sched_ctl,COMMON_channels_t *cc
 
     break;
   }
-
+  AssertFatal(1==0,"Shouldn't get here\n");
+  return(0);
 }
 
 uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,int CC_idP,COMMON_channels_t *cc,uint8_t tmode, struct CQI_ReportPeriodic *cqi_ReportPeriodic) {
@@ -975,14 +977,15 @@ void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t
     case NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE:
     case NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE:
       if (use_simultaneous_pucch_pusch==1) {
-	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE,
-		    "Cannot be NFAPI_UL_CONFIG_ULSCH_PDU_TYPE, simultaneous_pucch_pusch is active\n");
+	AssertFatal(ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE,
+		    "Cannot be NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE, simultaneous_pucch_pusch is active\n");
 	// Convert it to an NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE 
 	harq_information = &ul_config_pdu->ulsch_uci_harq_pdu.harq_information;
 	ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE;
+	LOG_D(MAC,"Frame %d, Subframe %d: Switched UCI HARQ to ULSCH UCI HARQ\n",frameP,subframeP); 
       }
       else {
-	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE,
+	AssertFatal(ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_UCI_HARQ_PDU_TYPE,
 		    "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_PDU_TYPE, simultaneous_pucch_pusch is inactive\n");
 	// Convert it to an NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE 
 	ulsch_harq_information = &ul_config_pdu->ulsch_harq_pdu.harq_information;
@@ -991,6 +994,7 @@ void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t
 	ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial=0; // last symbol not punctured
 	ul_config_pdu->ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks=
 	  ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks; // we don't change the number of resource blocks across retransmissions yet
+	LOG_D(MAC,"Frame %d, Subframe %d: Switched UCI HARQ to ULSCH HARQ\n",frameP,subframeP); 
       }
       break;
     case NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE:
@@ -998,8 +1002,8 @@ void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t
     case NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE:
     case NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE:
       if (use_simultaneous_pucch_pusch==1) {
-	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE||
-		    ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE,
+	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE ||
+		    ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE,
 		    "Cannot be NFAPI_UL_CONFIG_ULSCH_CQI_RI_xxx_PDU_TYPE, simultaneous_pucch_pusch is active\n");
 	// convert it to an NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE
 	harq_information = &ul_config_pdu->ulsch_csi_uci_harq_pdu.harq_information;
@@ -1007,8 +1011,8 @@ void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t
 	
       }
       else { 
-	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_UCI_CSI_PDU_TYPE ||
-		    ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CSI_UCI_HARQ_PDU_TYPE,
+	AssertFatal(ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE ||
+		    ul_config_pdu->pdu_type==NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE,
 		    "Cannot be NFAPI_UL_CONFIG_ULSCH_UCI_xxx_PDU_TYPE, simultaneous_pucch_pusch is inactive\n");
 	// Convert it to an NFAPI_UL_CONFIG_ULSCH_CQI_RI_HARQ_PDU_TYPE 
 	ulsch_harq_information = &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information;
@@ -1239,7 +1243,8 @@ uint16_t fill_nfapi_uci_acknak(module_id_t module_idP,
 			      absSFP,
 			      &ul_config_pdu->uci_harq_pdu.harq_information,
 			      cce_idxP);
-  LOG_D(MAC,"Filled in HARQ for rnti %x, cce_idxP %d-> n1_pucch %d\n",rntiP,cce_idxP,ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0);
+  LOG_D(MAC,"Filled in UCI HARQ request for rnti %x SF %d.%d acknakSF %d.%d, cce_idxP %d-> n1_pucch %d\n",rntiP,
+	absSFP/10,absSFP%10,ackNAK_absSF/10,ackNAK_absSF%10,cce_idxP,ul_config_pdu->uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0);
 
   ul_req->number_of_pdus++;
   ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
@@ -1320,7 +1325,106 @@ uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,uint16_t absSF,u
 
   return(((absSF/10)<<4) + (absSF%10));
 }
+
+void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t  *ul_config_pdu,
+					  uint8_t                        cqi_req,
+					  COMMON_channels_t              *cc,
+					  struct PhysicalConfigDedicated  *physicalConfigDedicated,
+					  uint8_t                        tmode,
+					  uint32_t                       handle,
+					  uint16_t                       rnti,
+					  uint8_t                        resource_block_start,
+					  uint8_t                        number_of_resource_blocks,
+					  uint8_t                        mcs,
+					  uint8_t                        cyclic_shift_2_for_drms,
+					  uint8_t                        frequency_hopping_enabled_flag,
+					  uint8_t                        frequency_hopping_bits,
+					  uint8_t                        new_data_indication,
+					  uint8_t                        redundancy_version,
+					  uint8_t                        harq_process_number,
+					  uint8_t                        ul_tx_mode,
+					  uint8_t                        current_tx_nb,
+					  uint8_t                        n_srs,
+					  uint16_t                       size
+					  ) {
+
+
+  memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
+  if (cqi_req==0)
+    ul_config_pdu->pdu_type                                                      = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
+  else
+    ul_config_pdu->pdu_type                                                      = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; 
+  ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                                 = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = handle;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = rnti;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = resource_block_start;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = number_of_resource_blocks;
+  if      (mcs<11) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 2;
+  else if (mcs<21) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 4;
+  else             ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 6;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = cyclic_shift_2_for_drms;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = frequency_hopping_enabled_flag;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = frequency_hopping_bits;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = new_data_indication;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = redundancy_version;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = harq_process_number;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = ul_tx_mode;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = current_tx_nb;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = n_srs;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = size;
+  
+  if (cqi_req == 1) {
+    // Add CQI portion 
+
+    
+    ul_config_pdu->pdu_type                                                           = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; 
+    ul_config_pdu->pdu_size                                                           = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu));
+    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag                  = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG;
+    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type             = 1;
+    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1;
+    LOG_D(MAC,"report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type);
+    
+    if (cc->p_eNB<=2 && (tmode==3||tmode==4||tmode==8||tmode==9||tmode==10))
+      ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1;
+    else if (cc->p_eNB<=2) 
+      ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0;
+    else if (cc->p_eNB==4)
+      ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2;
+    
+    AssertFatal(physicalConfigDedicated->cqi_ReportConfig!=NULL,"physicalConfigDedicated->cqi_ReportConfig is null!\n");
+    AssertFatal(physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic!=NULL,"physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n");
+    AssertFatal(physicalConfigDedicated->pusch_ConfigDedicated!=NULL,"physicalConfigDedicated->puschConfigDedicated is null!\n");
+    
+    for (int ri=0;
+	 ri<(1<<ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size);
+	 ri++)
+      ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = 
+	get_dl_cqi_pmi_size_pusch(cc,
+				  tmode,
+				  1+ri,
+				  physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic);
+    
+    ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi        = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index;
+    ((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri         = physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;
+  }
+}
+
 #ifdef Rel14
+void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t  *ul_config_pdu,
+					  uint8_t ue_type,
+					  uint16_t total_number_of_repetitions,
+					  uint16_t repetition_number,
+					  uint16_t initial_transmission_sf_io) {
+  // Re13 fields
+  
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag                                = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type                               = ue_type;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions           = total_number_of_repetitions;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number                     = repetition_number;
+  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io            = initial_transmission_sf_io;
+  
+}
 
 int get_numnarrowbands(long dl_Bandwidth) {
   int nb_tab[6] = {1,2,4,8,12,16};
@@ -1994,8 +2098,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)
 {
@@ -2024,7 +2126,7 @@ uint8_t UE_is_to_be_scheduled(module_id_t module_idP,int CC_id,uint8_t UE_id)
        (mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) // every Frame when not RRC_CONNECTED
     { 
 
-      LOG_I(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 %d,SR %d)\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id),
+      LOG_D(MAC,"[eNB %d][PUSCH] UE %d/%x should be scheduled (BSR0 %d,SR %d)\n",module_idP,UE_id,UE_RNTI(module_idP,UE_id),
 	    UE_template->bsr_info[LCGID0],
 	    UE_template->ul_SR);
     return(1);
@@ -2429,7 +2531,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;
         }
@@ -2630,17 +2733,20 @@ int allocate_CCEs(int module_idP,
   int i,j,idci;
   int nCCE=0;
 
-  LOG_D(MAC,"Allocate CCEs subframe %d, test %d : (DL %d,UL %d)\n",subframeP,test_onlyP,DL_req->number_dci,HI_DCI0_req->number_of_dci);
+
+  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;
 
 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)&&
-	(dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type==2)) {
+	(dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti_type==2)
+	) {
       LOG_D(MAC,"Trying to allocate COMMON DCI %d/%d (%d,%d) : rnti %x, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
 	    idci,DL_req->number_dci+HI_DCI0_req->number_of_dci,
 	    DL_req->number_dci,HI_DCI0_req->number_of_dci,
@@ -2651,6 +2757,7 @@ try_again:
       if (nCCE + (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) {
 	if (DL_req->number_pdcch_ofdm_symbols == 3)
 	  goto failed;
+	LOG_D(MAC,"Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n",DL_req->number_pdcch_ofdm_symbols); 
 	DL_req->number_pdcch_ofdm_symbols++;
 	nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP],DL_req->number_pdcch_ofdm_symbols,subframeP);
 	goto try_again;
@@ -2680,6 +2787,8 @@ try_again:
 	  //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L);
 	  goto failed;
 	}
+	LOG_D(MAC,"Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n",DL_req->number_pdcch_ofdm_symbols); 
+
 	DL_req->number_pdcch_ofdm_symbols++;
 	nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP],DL_req->number_pdcch_ofdm_symbols,subframeP);
 	goto try_again;
@@ -2711,6 +2820,8 @@ try_again:
       if (nCCE + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level) > nCCE_max) {
 	if (DL_req->number_pdcch_ofdm_symbols == 3)
 	  goto failed;
+	LOG_D(MAC,"Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n",DL_req->number_pdcch_ofdm_symbols); 
+
 	DL_req->number_pdcch_ofdm_symbols++;
 	nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP],DL_req->number_pdcch_ofdm_symbols,subframeP);
 	goto try_again;
@@ -2720,7 +2831,7 @@ try_again:
       fCCE = get_nCCE_offset(CCE_table,
 			     hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level,
 			     nCCE_max,
-			     1,
+			     0,
 			     hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti,
 			     subframeP);
       if (fCCE == -1) {
@@ -2740,6 +2851,8 @@ try_again:
 	  //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L);
 	  goto failed;
 	}
+	LOG_D(MAC,"Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n",DL_req->number_pdcch_ofdm_symbols); 
+
 	DL_req->number_pdcch_ofdm_symbols++;
 	nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP],DL_req->number_pdcch_ofdm_symbols,subframeP);
 	goto try_again;
@@ -2769,6 +2882,8 @@ try_again:
       if (nCCE + (dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level) > nCCE_max) {
 	if (DL_req->number_pdcch_ofdm_symbols == 3)
 	  goto failed;
+	LOG_D(MAC,"Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n",DL_req->number_pdcch_ofdm_symbols); 
+
 	DL_req->number_pdcch_ofdm_symbols++;
 	nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP],DL_req->number_pdcch_ofdm_symbols,subframeP);
 	goto try_again;
@@ -2778,7 +2893,7 @@ try_again:
       fCCE = get_nCCE_offset(CCE_table,
 			     dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
 			     nCCE_max,
-			     1,
+			     0,
 			     dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti,
 			     subframeP);
       if (fCCE == -1) {
@@ -2798,6 +2913,8 @@ try_again:
 	  //dump_CCE_table(CCE_table,nCCE_max,subframeP,dci_alloc->rnti,1<<dci_alloc->L);
 	  goto failed;
 	}
+	LOG_D(MAC,"Can't fit DCI allocations with %d PDCCH symbols (rnti condition), increasing by 1\n",DL_req->number_pdcch_ofdm_symbols); 
+
 	DL_req->number_pdcch_ofdm_symbols++;
 	nCCE_max = get_nCCE_max(&RC.mac[module_idP]->common_channels[CC_idP],DL_req->number_pdcch_ofdm_symbols,subframeP);
 	goto try_again;
@@ -2816,6 +2933,7 @@ try_again:
 
   return 0;
 
+
  failed:
   return -1;
 }
@@ -2858,15 +2976,17 @@ uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subfram
 }
 */
  
-nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,uint16_t subframeP,uint16_t rnti) {
+nfapi_ul_config_request_pdu_t* has_ul_grant(module_id_t module_idP,int CC_idP,uint16_t absSFP,uint16_t rnti) {
 
   nfapi_ul_config_request_body_t *ul_req;            
   nfapi_ul_config_request_pdu_t *ul_config_pdu; 
 		
-  ul_req        = &RC.mac[module_idP]->UL_req_tmp[CC_idP][subframeP].ul_config_request_body;
+  ul_req        = &RC.mac[module_idP]->UL_req_tmp[CC_idP][absSFP%10].ul_config_request_body;
   ul_config_pdu = &ul_req->ul_config_pdu_list[0];
+  LOG_D(MAC,"Checking for rnti %x UL grant in subframeP %d (num pdu %d)\n",rnti,absSFP%10,ul_req->number_of_pdus);
 
   for (int i=0; i<ul_req->number_of_pdus;i++){
+    LOG_D(MAC,"PDU %d : type %d,rnti %x\n",i,ul_config_pdu[i].pdu_type,rnti);
     if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE)&&
 	(ul_config_pdu[i].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti)) return(&ul_config_pdu[i]);
     if ((ul_config_pdu[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE)&&
@@ -2909,37 +3029,55 @@ boolean_t CCE_allocation_infeasible(int module_idP,
 				    int format_flag,
 				    int subframe,
 				    int aggregation,
-				    int rnti) {
-
-  nfapi_dl_config_request_body_t *DL_req       = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body;
-  nfapi_dl_config_request_pdu_t* dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
-  nfapi_hi_dci0_request_body_t *HI_DCI0_req    = &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body;
-  nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu     = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; 
-  //DCI_ALLOC_t *dci_alloc;
+				    int rnti)
+{
+  nfapi_dl_config_request_body_t *DL_req        = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body;
+  nfapi_dl_config_request_pdu_t  *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
+  nfapi_hi_dci0_request_body_t   *HI_DCI0_req   = &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body;
+  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; 
   int ret;
-  boolean_t res=FALSE;
-
-  if (format_flag!=2) { // DL DCI
-    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag            = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
-    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;
-    DL_req->number_pdu++;
-    ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
-    if (ret==-1)
-      res = TRUE;
-    DL_req->number_pdu--;
-  }
-  else if (format_flag == 2) { // ue-specific UL DCI
-    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag           = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
-    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti             = rnti;
-    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
-    HI_DCI0_req->number_of_dci++;
-    ret = allocate_CCEs(module_idP,CC_idP,subframe,1);
-    if (ret==-1)
-      res = TRUE;
-    HI_DCI0_req->number_of_dci--;
-  }
-  return(res);
+  boolean_t res = FALSE;
+
+  if (format_flag != 2) { // DL DCI
+    if (DL_req->number_pdu == MAX_NUM_DL_PDU) {
+      LOG_W(MAC, "Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n",
+            subframe, rnti);
+    } else {
+      dl_config_pdu->pdu_type                                     = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag            = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti              = rnti;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type         = (format_flag == 0)?2:1;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation;
+      DL_req->number_pdu++;
+      LOG_D(MAC,"Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n",
+	subframe,format_flag,rnti,aggregation,
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type);
+      ret = allocate_CCEs(module_idP,CC_idP,subframe,0);
+      if (ret==-1)
+        res = TRUE;
+      DL_req->number_pdu--;
+    }
+  }
+  else { // ue-specific UL DCI
+    if (HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi == MAX_NUM_HI_DCI0_PDU) {
+      LOG_W(MAC, "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n",
+            subframe, rnti);
+    } else {
+      hi_dci0_pdu->pdu_type                               = NFAPI_HI_DCI0_DCI_PDU_TYPE;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag            = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti              = rnti;
+      hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
+      HI_DCI0_req->number_of_dci++;
+      ret = allocate_CCEs(module_idP,CC_idP,subframe,0);
+      if (ret==-1)
+        res = TRUE;
+      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) {
@@ -3006,14 +3144,15 @@ void extract_harq(module_id_t mod_idP,int CC_idP,int UE_id,frame_t frameP,sub_fr
 	  // single ACK/NAK bit
 	  AssertFatal(num_ack_nak==1,"num_ack_nak %d > 1 for 1 CC and single-layer transmission\n",num_ack_nak);
 	  AssertFatal(sched_ctl->round[CC_idP][harq_pid]<8,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",harq_pid,UE_id,rnti);
-	  AssertFatal(pdu[0] == 1 || pdu[0] == 2, "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n",pdu[0],harq_pid,UE_id,rnti);
+	  AssertFatal(pdu[0] == 1 || pdu[0] == 2 || pdu[0] == 4,
+                      "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n",pdu[0],harq_pid,UE_id,rnti);
 	  LOG_D(MAC,"Received %d for harq_pid %d\n",pdu[0],harq_pid);
 
 	  if (pdu[0] == 1) { // ACK
 	    sched_ctl->round[CC_idP][harq_pid]=8; // release HARQ process
 	    sched_ctl->tbcnt[CC_idP][harq_pid]=0;
 	  }
-	  else if (pdu[0] == 2) // NAK
+	  else if (pdu[0] == 2 || pdu[0] == 4) // NAK (treat DTX as NAK)
 	    sched_ctl->round[CC_idP][harq_pid]++; // increment round
 	}
 	else {
@@ -3296,6 +3435,7 @@ void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,
   int v[6];
   int i;
   uint64_t p = *(uint64_t*)pdu;
+  int curbyte, curbit;
   CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic;
 
   AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
@@ -3303,7 +3443,7 @@ void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,
   AssertFatal((cqi_ReportModeAperiodic = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic)!=NULL,
 	      "cqi_ReportModeAperiodic is null for UE %d\n",UE_id);
 
-  int N     = Ntab[cc->p_eNB];
+  int N     = Ntab[cc->mib->message.dl_Bandwidth];
   int tmode = get_tmode(mod_idP,CC_idP,UE_id);
   int ri    = sched_ctl->aperiodic_ri_received[CC_idP];
   int r,diffcqi0=0,diffcqi1=0,pmi_uesel=0;
@@ -3313,6 +3453,7 @@ void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,
   switch(*cqi_ReportModeAperiodic) {
 
   case CQI_ReportModeAperiodic_rm12:
+    AssertFatal(0==1, "to be fixed, don't use p but pdu directly\n");
     // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6)
     AssertFatal(tmode==4 || tmode==6 || tmode==8|| tmode==9 || tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm12\n",tmode);
     if (tmode <= 6) { //Table 5.2.2.6.1-1 36.213
@@ -3353,6 +3494,7 @@ void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,
 
    break;
   case CQI_ReportModeAperiodic_rm20:
+    AssertFatal(0==1, "to be fixed, don't use p but pdu directly\n");
     // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 
     AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm20\n",tmode);
 
@@ -3363,6 +3505,7 @@ void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,
     for (m=0;m<Mtab_uesel[bw];m++) sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0;
     break;
   case CQI_ReportModeAperiodic_rm22:
+    AssertFatal(0==1, "to be fixed, don't use p but pdu directly\n");
     // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213
 
     AssertFatal(tmode==4 || tmode==6 || tmode==8|| tmode==9 || tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm22\n",tmode);
@@ -3397,13 +3540,21 @@ void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,
   case CQI_ReportModeAperiodic_rm30:
     //subband CQI no PMI (TM1/2/3/7)
     AssertFatal(tmode==1 || tmode==2 || tmode==3 || tmode==7,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm30\n",tmode);
-    sched_ctl->aperiodic_wideband_cqi0[CC_idP] = (uint8_t)(p&0x0F); p>>=4;
+    sched_ctl->aperiodic_wideband_cqi0[CC_idP] = pdu[0]>>4;
+    curbyte = 0;
+    curbit = 3;
     for (i=0;i<N;i++) {
-      sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (uint8_t)(p&0x03);
-      p>>=2;
+      sched_ctl->aperiodic_subband_diffcqi0[CC_idP][i] = (pdu[curbyte] >> (curbit-1)) & 0x03;
+      curbit -= 2;
+      if (curbit < 0) {
+        curbit = 7;
+        curbyte++;
+      }
     }
+    sched_ctl->dl_cqi[CC_idP] = sched_ctl->aperiodic_wideband_cqi0[CC_idP];
     break;
   case CQI_ReportModeAperiodic_rm31:
+    AssertFatal(0==1, "to be fixed, don't use p but pdu directly\n");
     //subband CQI single PMI (TM4/5/6)
     AssertFatal(tmode==4 || tmode==5 || tmode==6 || tmode==8|| tmode==9|| tmode==10,"Illegal transmission mode %d for CQI_ReportModeAperiodic_rm31\n",tmode);
 
@@ -3507,13 +3658,20 @@ 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;
  
   if (UE_id  != -1) {
     if (mac_eNB_get_rrc_status(mod_idP,UE_RNTI(mod_idP,UE_id)) < RRC_CONNECTED)
-      LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
+      LOG_I(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d\n",mod_idP,rntiP,frameP,subframeP, UE_id,cc_idP);
+
+    UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+
+    sched_ctl->pucch1_snr[cc_idP]        = ul_cqi;
+    sched_ctl->pucch1_cqi_update[cc_idP] = 1;
+
     UE_list->UE_template[cc_idP][UE_id].ul_SR = 1;
     UE_list->UE_template[cc_idP][UE_id].ul_active = TRUE;
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION,1);
@@ -3555,9 +3713,11 @@ void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_
   UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
   COMMON_channels_t *cc    = &RC.mac[mod_idP]->common_channels[CC_idP];
     // extract HARQ Information
-  LOG_D(MAC,"Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x\n",frameP,subframeP,channel,UE_id,rnti);
+  LOG_D(MAC,"Frame %d, subframe %d: Received harq indication (%d) from UE %d/%x, ul_cqi %d\n",frameP,subframeP,channel,UE_id,rnti,ul_cqi);
   if (cc->tdd_Config) extract_harq(mod_idP,CC_idP,UE_id,frameP,subframeP,(void*)&harq_pdu->harq_indication_tdd_rel13,channel);
   else                extract_harq(mod_idP,CC_idP,UE_id,frameP,subframeP,(void*)&harq_pdu->harq_indication_fdd_rel13,channel);
-  if (channel == 0)     sched_ctl->pucch1_snr[CC_idP] = ul_cqi;
-
+  if (channel == 0) {
+    sched_ctl->pucch1_snr[CC_idP]       = ul_cqi;
+    sched_ctl->pucch1_cqi_update[CC_idP] = 1;
+  }
 }
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 28279033cf5cb2c1531f7a4dcbc1924adba0f342..7418721e8a5200282f60f4d22c6547161647b232 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -63,7 +63,7 @@
 extern void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP);
 
 // This table holds the allowable PRB sizes for ULSCH transmissions
-uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100};
+uint8_t rb_table[34] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,64,72,75,80,81,90,96,100};
 
 void rx_sdu(const module_id_t enb_mod_idP,
 	    const int         CC_idP,
@@ -108,8 +108,12 @@ void rx_sdu(const module_id_t enb_mod_idP,
 
   if (UE_id!=-1) {
 
-    LOG_D(MAC,"[eNB %d] CC_id %d Received ULSCH sdu from PHY (rnti %x, UE_id %d)\n",enb_mod_idP,CC_idP,rntiP,UE_id);
+    LOG_I(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
+	  UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
+	  rntiP,UE_id,ul_cqi);
 
+    AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8,
+		"round >= 8\n");
     UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
     UE_list->UE_sched_ctrl[UE_id].ul_failure_timer    = 0;
     UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
@@ -123,11 +127,17 @@ void rx_sdu(const module_id_t enb_mod_idP,
     }
 
     if (sduP==NULL) { // we've got an error
-      LOG_D(MAC,"[eNB %d] CC_id %d ULSCH in error in round %d\n",enb_mod_idP,CC_idP,UE_list->UE_sched_ctrl[UE_id].round_UL[harq_pid][CC_idP]);
+      LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
+	    UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi);
       //      AssertFatal(1==0,"ulsch in error\n");
-      if (UE_list->UE_sched_ctrl[UE_id].round_UL[harq_pid][CC_idP] == 7)
+      if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) {
 	UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
+	UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]=0;
+	// here we increment error statistics
+      }
+      else UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
       return;
+
     }
   }
   else { // Check if this is an RA process for the rnti
@@ -167,7 +177,7 @@ void rx_sdu(const module_id_t enb_mod_idP,
   eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP;
   eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1;
 
-  UE_list->UE_sched_ctrl[UE_id].round_UL[harq_pid][CC_idP] = 0;
+  UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0;
 
   // control element
   for (i=0; i<num_ce; i++) {
@@ -806,7 +816,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);
 
 }
@@ -825,11 +834,9 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
   rnti_t            rnti           = -1;
   uint8_t           round          = 0;
   uint8_t           harq_pid       = 0;
-  eNB_UE_STATS      *eNB_UE_stats   = NULL;
   uint8_t           status         = 0; 
   uint8_t           rb_table_index = -1;
-  uint16_t          TBS = 0;
-  uint32_t          cqi_req,cshift,ndi,mcs=0,tpc;
+  uint32_t          cqi_req,cshift,ndi,tpc;
   int32_t           normalized_rx_power;
   int32_t           target_rx_power=-90;
   static int32_t    tpc_accumulated=0;
@@ -844,6 +851,7 @@ void schedule_ulsch_rnti(module_id_t   module_idP,
   UE_sched_ctrl     *UE_sched_ctrl;
   int               tmode;
   int               sched_frame=frameP;
+  int               rvidx_tab[4] = {0,2,3,1};
 
   if (sched_subframeP<subframeP) sched_frame++;
 
@@ -928,23 +936,27 @@ abort();
       // This is the actual CC_id in the list
       CC_id        = UE_list->ordered_ULCCids[n][UE_id];
       N_RB_UL      = to_prb(cc[CC_id].ul_Bandwidth);
-      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
 
-      
+      /*
       aggregation=get_aggregation(get_bw_index(module_idP,CC_id), 
 				  eNB_UE_stats->dl_cqi,
 				  format0);
-      
+      */
 
-      if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) {
+      if (CCE_allocation_infeasible(module_idP,CC_id,2,subframeP,aggregation,rnti)) {
         LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
         continue; // break;
-      } else{
-	LOG_D(MAC,"[eNB %d] frame %d subframe %d,Scheduling PUSCH for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", 
-	      module_idP,frameP,subframeP,UE_id,rnti,CC_id, aggregation,N_RB_UL);
+      } 
+
+      /* 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
 
       UE_template   = &UE_list->UE_template[CC_id][UE_id];
@@ -952,23 +964,16 @@ abort();
       harq_pid      = subframe2harqpid(&cc[CC_id],sched_frame,sched_subframeP);
       round         = UE_sched_ctrl->round_UL[CC_id][harq_pid];
       AssertFatal(round<8,"round %d > 7 for UE %d/%x\n",round,UE_id,rnti);
-      /*      
-      if (get_UL_harq_info(module_idP,CC_id,frameP,subframeP,&harq_pid,&round)<0) {
-	LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
-	      module_idP,frameP,subframeP, UE_id, CC_id, rnti);
-	continue;
-      } else
-	LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d  round %d (rnti %x)\n",
-	      module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,rnti);
-      */
+      LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", 
+	    module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL);
 
       RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer;
       VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]);	
-      if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0))
+      if (UE_is_to_be_scheduled(module_idP,CC_id,UE_id) > 0 || round > 0)// || ((frameP%10)==0))
 	// if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames
         {
-	  LOG_I(MAC,"[eNB %d][PUSCH] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
-		module_idP,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR,
+	  LOG_I(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
+		module_idP,harq_pid,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR,
 		UE_sched_ctrl->ul_inactivity_timer,
 
 		UE_sched_ctrl->ul_failure_timer,
@@ -986,12 +991,13 @@ abort();
 	  else
 	    cqi_req = 0;
 	  
+
           //power control
           //compute the expected ULSCH RX power (for the stats)
 	  
           // this is the normalized RX power and this should be constant (regardless of mcs
-          normalized_rx_power = eNB_UE_stats->UL_rssi;
-          target_rx_power = cc[CC_id].radioResourceConfigCommon->uplinkPowerControlCommon.p0_NominalPUSCH;//get_target_pusch_rx_power(module_idP,CC_id);
+          normalized_rx_power = UE_sched_ctrl->pusch_snr[CC_id];
+          target_rx_power = 20;
 	  
           // this assumes accumulated tpc
 	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
@@ -1013,7 +1019,7 @@ abort();
 	    } else {
             tpc = 1; //0
           }
-	  
+	  tpc = 1;
 	  if (tpc!=1) {
 	    LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
 		  module_idP,frameP,subframeP,harq_pid,tpc,
@@ -1028,16 +1034,17 @@ abort();
 	    UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
 	    UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
 	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
-            mcs = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
+            UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
             if (UE_template->pre_allocated_rb_table_index_ul >=0) {
               rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
             } else {
-	      mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs);
+	      UE_template->mcs_UL[harq_pid]=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs);
               rb_table_index=5; // for PHR
 	    }
 	    
-            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs;
+            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)) &&
@@ -1045,24 +1052,22 @@ abort();
               rb_table_index--;
             }
 	    
-            TBS = get_TBS_UL(mcs,rb_table[rb_table_index]);
+            UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]);
 	    UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index];
-	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS;
+	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid];
 	    //            buffer_occupancy -= TBS;
             	    
             T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
-              T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
-              T_INT(TBS), T_INT(ndi));
+              T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
+              T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi));
 	    
 	    if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
 	      LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
-		    module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
+		    module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,UE_template->mcs_UL[harq_pid],
 		    first_rb[CC_id],rb_table[rb_table_index],
-		    rb_table_index,TBS,harq_pid);
+		    rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid);
 	    
 	    // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
-            // increment for next UE allocation
-            first_rb[CC_id]+=rb_table[rb_table_index];
             //store for possible retransmission
             UE_template->nb_rb_ul[harq_pid]    = rb_table[rb_table_index];
             UE_template->first_rb_ul[harq_pid] = first_rb[CC_id];
@@ -1072,9 +1077,9 @@ abort();
 	      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled);
 	    
 	    // adjust total UL buffer status by TBS, wait for UL sdus to do final update
-	    LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,TBS);
-	    if (UE_template->ul_total_buffer > TBS)
-	      UE_template->ul_total_buffer -= TBS;
+	    LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,UE_template->TBS_UL[harq_pid]);
+	    if (UE_template->ul_total_buffer > UE_template->TBS_UL[harq_pid])
+	      UE_template->ul_total_buffer -= UE_template->TBS_UL[harq_pid];
 	    else
 	      UE_template->ul_total_buffer = 0;
 	    LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);
@@ -1082,6 +1087,7 @@ abort();
 	    cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
 	    // save it for a potential retransmission
             UE_template->cshift[harq_pid] = cshift;	    
+
 	    hi_dci0_pdu                                                         = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi]; 	
 	    memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
 	    hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_DCI_PDU_TYPE; 
@@ -1093,7 +1099,7 @@ abort();
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power                = 6000;
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start              = first_rb[CC_id];
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block          = rb_table[rb_table_index];
-	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1                             = mcs;
+	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1                             = UE_template->mcs_UL[harq_pid];
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms           = cshift;
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag    = 0;
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1             = ndi;
@@ -1101,96 +1107,49 @@ abort();
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request                   = cqi_req;
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index               = UE_template->DAI_ul[sched_subframeP];
 
-	    if (!CCE_allocation_infeasible(module_idP,CC_id,2,subframeP,
-					   aggregation,
-					   rnti)) {
-
-	      eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++;
-
-	      LOG_I(MAC,"Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
-		    frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP);
-
-	      // Add UL_config PDUs
-	      ul_config_pdu                                                                  = &ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus]; 
-	      
-	      memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
-	      if (cqi_req==0)
-		ul_config_pdu->pdu_type                                                      = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE; 
-	      else
-		ul_config_pdu->pdu_type                                                      = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; 
-	      ul_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_pdu));
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag                                 = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle                                 = eNB->ul_handle++;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti                                   = rnti;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start                   = first_rb[CC_id];
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks              = rb_table[rb_table_index];
-	      if      (mcs<11) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 2;
-	      else if (mcs<21) ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 4;
-	      else             ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type       = 6;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms                = cshift;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag         = 0;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits                 = 0;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication                    = ndi;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version                     = 0;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number                    = harq_pid;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode                             = 0;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb                          = 0;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs                                  = 0;
-	      ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size                                   = get_TBS_UL(mcs,
-													  rb_table[rb_table_index]);
+	    
+	    eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++;
+	    
+	    LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
+		  harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP);
+	    
+	    // Add UL_config PDUs
+	    fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
+						 cqi_req,
+						 cc,
+						 UE_template->physicalConfigDedicated,
+						 get_tmode(module_idP,CC_id,UE_id),
+						 eNB->ul_handle,
+						 rnti,
+						 first_rb[CC_id], // resource_block_start
+						 rb_table[rb_table_index], // number_of_resource_blocks
+						 UE_template->mcs_UL[harq_pid],
+						 cshift, // cyclic_shift_2_for_drms
+						 0, // frequency_hopping_enabled_flag
+						 0, // frequency_hopping_bits
+						 ndi, // new_data_indication
+						 0, // redundancy_version
+						 harq_pid, // harq_process_number
+						 0, // ul_tx_mode
+						 0, // current_tx_nb
+						 0, // n_srs
+						 get_TBS_UL(UE_template->mcs_UL[harq_pid],
+							    rb_table[rb_table_index])
+						 );
 #ifdef Rel14
-	      // Re13 fields
-	      if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.tl.tag                                = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL13_TAG;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type                               = UE_template->rach_resource_type>2 ? 2 : 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions           = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number                     = 1;
-		ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io            = (frameP*10)+subframeP;
-	      }
+	    if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation
+	      fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
+						   UE_template->rach_resource_type>2 ? 2 : 1,
+						   1, //total_number_of_repetitions
+						   1, //repetition_number
+						   (frameP*10)+subframeP);
+	    }
 #endif
-	      ul_req_tmp->number_of_pdus++;
-	      ul_req_tmp->tl.tag=NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
-	      
-	      if (cqi_req == 1) {
-		// Add CQI portion 
-		tmode = get_tmode(module_idP,CC_id,UE_id);
-						
-		ul_config_pdu->pdu_type                                                           = NFAPI_UL_CONFIG_ULSCH_CQI_RI_PDU_TYPE; 
-		ul_config_pdu->pdu_size                                                           = (uint8_t)(2+sizeof(nfapi_ul_config_ulsch_cqi_ri_pdu));
-		ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.tl.tag = NFAPI_UL_CONFIG_REQUEST_CQI_RI_INFORMATION_REL9_TAG;
-		ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type             = 1;
-		ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.number_of_cc = 1;
-		LOG_I(MAC,"report_type %d\n",ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.report_type);
-
-		if (cc->p_eNB<=2 && (tmode==3||tmode==4||tmode==8||tmode==9||tmode==10))
-		  ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 1;
-		else if (cc->p_eNB<=2) 
-		  ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 0;
-		else if (cc->p_eNB==4)
-		  ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size = 2;
-
-		AssertFatal(UE_template->physicalConfigDedicated->cqi_ReportConfig!=NULL,"physicalConfigDedicated->cqi_ReportConfig is null!\n");
-		AssertFatal(UE_template->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic!=NULL,"physicalConfigDedicated->cqi_ReportModeAperiodic is null!\n");
-		AssertFatal(UE_template->physicalConfigDedicated->pusch_ConfigDedicated!=NULL,"physicalConfigDedicated->puschConfigDedicated is null!\n");
-
-		for (int ri=0;
-		     ri<(1<<ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].ri_size);
-		     ri++)
-		  ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[ri] = 
-		    get_dl_cqi_pmi_size_pusch(&UE_list->UE_sched_ctrl[UE_id],
-					      cc,
-					      tmode,
-					      1+ri,
-					      UE_template->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportModeAperiodic);
-
-		ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.delta_offset_cqi        = UE_template->physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index;
-		((nfapi_ul_config_ulsch_cqi_ri_pdu*)ul_config_pdu)->cqi_ri_information.cqi_ri_information_rel9.delta_offset_ri         = UE_template->physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_RI_Index;
-		LOG_I(MAC,"Frame %d, Subframe %d: Requesting CQI information for UE %d/%x => O_r1 %d, betaCQI %d\n",
-		      frameP,subframeP,UE_id,rnti,
-		      ul_config_pdu->ulsch_cqi_ri_pdu.cqi_ri_information.cqi_ri_information_rel9.aperiodic_cqi_pmi_ri_report.cc[0].dl_cqi_pmi_size[0],
-		      UE_template->physicalConfigDedicated->pusch_ConfigDedicated->betaOffset_CQI_Index);
-	      }
-	    }	
+	    ul_req_tmp->number_of_pdus++;
+	    eNB->ul_handle++;
+	    
+	    
+	  	
 	    add_ue_ulsch_info(module_idP,
 			      CC_id,
 			      UE_id,
@@ -1198,15 +1157,19 @@ abort();
 			      S_UL_SCHEDULED);
 	    
 	    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];
 	    
-          }
+	  }
 	  else { // round > 0 => retransmission
             T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
-              T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
+              T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
               T_INT(round));
 
 	    // fill in NAK information
-
+	    
 	    hi_dci0_pdu                                                         = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; 	
 	    memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
 	    hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE; 
@@ -1218,9 +1181,45 @@ abort();
 	    hi_dci0_req->number_of_hi++;
             hi_dci0_req->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
             LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, TBS %d, harq_pid %d,round %d)\n",
-                  module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
+                  module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,UE_template->mcs_UL[harq_pid],
                   UE_template->first_rb_ul[harq_pid], UE_template->nb_rb_ul[harq_pid],
-                  TBS,harq_pid,round);
+                  UE_template->TBS_UL[harq_pid],round);
+	    // Add UL_config PDUs
+	    LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
+		  harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP);
+	    fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
+						 cqi_req,
+						 cc,
+						 UE_template->physicalConfigDedicated,
+						 get_tmode(module_idP,CC_id,UE_id),
+						 eNB->ul_handle,
+						 rnti,
+						 UE_template->first_rb_ul[harq_pid], // resource_block_start
+						 UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
+						 UE_template->mcs_UL[harq_pid],
+						 cshift, // cyclic_shift_2_for_drms
+						 0, // frequency_hopping_enabled_flag
+						 0, // frequency_hopping_bits
+						 UE_template->oldNDI_UL[harq_pid], // new_data_indication
+						 rvidx_tab[round&3], // redundancy_version
+						 harq_pid, // harq_process_number
+						 0, // ul_tx_mode
+						 0, // current_tx_nb
+						 0, // n_srs
+						 UE_template->TBS_UL[harq_pid]
+						 );
+#ifdef Rel14
+	    if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation
+	      fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
+						   UE_template->rach_resource_type>2 ? 2 : 1,
+						   1, //total_number_of_repetitions
+						   1, //repetition_number
+						   (frameP*10)+subframeP);
+	    }
+#endif
+	      ul_req_tmp->number_of_pdus++;
+	      eNB->ul_handle++;
+
 	  }/* 
 	  else if (round > 0) { //we schedule a retransmission
 
diff --git a/openair2/LAYER2/MAC/extern.h b/openair2/LAYER2/MAC/extern.h
index 591fce4b4b3e97fd423539bd054d468d862c7cee..77e6e761a88deceb30d72028023ef9627a95c8ed 100644
--- a/openair2/LAYER2/MAC/extern.h
+++ b/openair2/LAYER2/MAC/extern.h
@@ -77,7 +77,7 @@ extern int cqi_to_mcs[16];
 
 extern uint32_t RRC_CONNECTION_FLAG;
 
-extern uint8_t rb_table[33];
+extern uint8_t rb_table[34];
 
 extern DCI0_5MHz_TDD_1_6_t       UL_alloc_pdu;
 
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 5d668ff3041f42e1132809b4aebd40a21a4648db..e04dc5b3a8dc6ee1e0a0a9289d4bf4053234f013 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -61,7 +61,7 @@ void dl_phy_sync_success(module_id_t   module_idP,
 #endif
 
   if (first_sync==1 && !(mme_enabled==1)) {
-    //DJP layer2_init_UE(module_idP);
+    //layer2_init_UE(module_idP);
     openair_rrc_ue_init(module_idP,eNB_index);
   } else
   {
@@ -79,14 +79,8 @@ void mac_UE_out_of_sync_ind(module_id_t module_idP, frame_t frameP, uint16_t eNB
 int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active)
 {
 
-  module_id_t    Mod_id,i,j;
-  RA_TEMPLATE *RA_template;
-  UE_TEMPLATE *UE_template;
-  int size_bytes1,size_bytes2,size_bits1,size_bits2;
-  int CC_id;
-  int list_el;
-  UE_list_t *UE_list;
-  COMMON_channels_t   *cc;
+  int i;
+
   LOG_I(MAC,"[MAIN] Init function start:Nb_UE_INST=%d\n",NB_UE_INST);
 
   if (NB_UE_INST>0) {
@@ -107,36 +101,6 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
   }
 
 
-  if (NB_eNB_INST>0) {
-    RC.mac = (eNB_MAC_INST**)malloc16(NB_eNB_INST*sizeof(eNB_MAC_INST*));
-    for (i=0;i<NB_eNB_INST;i++)
-      RC.mac[i] = (eNB_MAC_INST*)malloc16(sizeof(eNB_MAC_INST));
-    AssertFatal(RC.mac != NULL,
-		"[MAIN] can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",NB_eNB_INST*sizeof(eNB_MAC_INST*),NB_eNB_INST,sizeof(eNB_MAC_INST));
-    LOG_D(MAC,"[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n",sizeof(eNB_MAC_INST),NB_eNB_INST,RC.mac);
-    for (i=0;i<NB_eNB_INST;i++) bzero(RC.mac[i],sizeof(eNB_MAC_INST));
-  } else {
-    RC.mac = NULL;
-  }
-
-  // Initialize Linked-List for Active UEs
-  for(Mod_id=0; Mod_id<NB_eNB_INST; Mod_id++) {
-    UE_list = &RC.mac[Mod_id]->UE_list;
-
-    UE_list->num_UEs=0;
-    UE_list->head=-1;
-    UE_list->head_ul=-1;
-    UE_list->avail=0;
-
-    for (list_el=0; list_el<NUMBER_OF_UE_MAX-1; list_el++) {
-      UE_list->next[list_el]=list_el+1;
-      UE_list->next_ul[list_el]=list_el+1;
-    }
-
-    UE_list->next[list_el]=-1;
-    UE_list->next_ul[list_el]=-1;
-  }
-
   LOG_I(MAC,"[MAIN] calling RRC\n");
   openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active,HO_active);
 
@@ -148,10 +112,10 @@ int mac_top_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
 }
 
 
-int mac_top_init_eNB(void)
+void mac_top_init_eNB(void)
 {
 
-  module_id_t    Mod_id,i,j;
+  module_id_t    i,j;
   int list_el;
   UE_list_t *UE_list;
   eNB_MAC_INST *mac;
@@ -171,7 +135,7 @@ int mac_top_init_eNB(void)
 		  RC.nb_macrlc_inst*sizeof(eNB_MAC_INST*),RC.nb_macrlc_inst,sizeof(eNB_MAC_INST));
       LOG_D(MAC,"[MAIN] ALLOCATE %zu Bytes for %d eNB_MAC_INST @ %p\n",sizeof(eNB_MAC_INST),RC.nb_macrlc_inst,RC.mac);
       bzero(RC.mac[i],sizeof(eNB_MAC_INST));
-      RC.mac[i]->Mod_id = Mod_id;
+      RC.mac[i]->Mod_id = i;
       for (j=0;j<MAX_NUM_CCs;j++) {
 	RC.mac[i]->DL_req[j].dl_config_request_body.dl_config_pdu_list      = RC.mac[i]->dl_config_pdu_list[j];
 	RC.mac[i]->UL_req[j].ul_config_request_body.ul_config_pdu_list      = RC.mac[i]->ul_config_pdu_list[j];
@@ -194,11 +158,11 @@ int mac_top_init_eNB(void)
   }
   
   // Initialize Linked-List for Active UEs
-  for(Mod_id=0; Mod_id<RC.nb_macrlc_inst; Mod_id++) {
-    mac = RC.mac[Mod_id];
+  for(i=0; i<RC.nb_macrlc_inst; i++) {
+    mac = RC.mac[i];
 
 
-    mac->if_inst                = IF_Module_init(Mod_id);
+    mac->if_inst                = IF_Module_init(i);
 
     UE_list = &mac->UE_list;
 
@@ -383,7 +347,6 @@ int l2_init_eNB(void)
 {
 
 
-  int i;
 
   LOG_I(MAC,"[MAIN] MAC_INIT_GLOBAL_PARAM IN...\n");
 
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index 0aeeeb8d351ecdc1f356a688210add47449bf7a5..d536c8b3378e976f39333f05cc2da89de1d6b269 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -196,7 +196,7 @@ void assign_rbs_required (module_id_t Mod_id,
       CC_id = UE_list->ordered_CCids[n][UE_id];
       eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
 
-      eNB_UE_stats->dlsch_mcs1=cqi_to_mcs[eNB_UE_stats->dl_cqi];
+      eNB_UE_stats->dlsch_mcs1=cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
 
     }
 
@@ -288,22 +288,19 @@ int maxround(module_id_t Mod_id,uint16_t rnti,int frame,sub_frame_t subframe,uin
 // it returns -1 if the UE is not found in PHY layer (get_eNB_UE_stats gives NULL)
 int maxcqi(module_id_t Mod_id,int32_t UE_id)
 {
-
-  eNB_UE_STATS *eNB_UE_stats = NULL;
   UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
   int CC_id,n;
   int CQI = 0;
 
   for (n=0; n<UE_list->numactiveCCs[UE_id]; n++) {
     CC_id = UE_list->ordered_CCids[n][UE_id];
-    eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
 
-    if (eNB_UE_stats->dl_cqi > CQI) {
-      CQI = eNB_UE_stats->dl_cqi;
+    if (UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id] > CQI) {
+      CQI = UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id];
     }
   }
 
-  return(CQI);
+  return CQI;
 }
 
 struct sort_ue_dl_params {
@@ -596,7 +593,7 @@ void dlsch_scheduler_pre_processor (module_id_t   Mod_id,
       average_rbs_per_user[CC_id]=0;
 
 
-      if(round>0) {
+      if(round != 8) {
         nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
       }
 
@@ -606,7 +603,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 +637,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 +664,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 +864,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 +882,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 +956,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 +1050,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 +1075,6 @@ void dlsch_scheduler_pre_processor_allocate (module_id_t   Mod_id,
       } // dl_pow_off[CC_id][UE_id] ! = 0
     }
   }
-
 }
 
 
@@ -1301,7 +1319,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 +1365,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/proto.h b/openair2/LAYER2/MAC/proto.h
index ac969cc02c4c768ed836e97fd7bd1a7d4667f670..7e9c036f265fa457abadc01cf7ac7ac2bc74488f 100644
--- a/openair2/LAYER2/MAC/proto.h
+++ b/openair2/LAYER2/MAC/proto.h
@@ -141,10 +141,16 @@ int8_t get_deltaP_rampup(module_id_t module_idP,uint8_t CC_id);
 
 uint16_t mac_computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs);
 
+void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP);
+
 //main.c
 
 int mac_top_init(int eMBMS_active, char *uecap_xer,uint8_t cba_group_active, uint8_t HO_active);
 
+void mac_top_init_eNB(void);
+
+void mac_init_cell_params(int Mod_idP,int CC_idP);
+
 char layer2_init_UE(module_id_t module_idP);
 
 char layer2_init_eNB(module_id_t module_idP, uint8_t Free_ch_index);
@@ -157,6 +163,8 @@ void mac_top_cleanup(void);
 
 void mac_UE_out_of_sync_ind(module_id_t module_idP,frame_t frameP, uint16_t eNB_index);
 
+void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP);
+
 void dlsch_scheduler_pre_processor_reset (int module_idP,int UE_id,
     uint8_t  CC_id,
     int frameP,
@@ -307,6 +315,27 @@ void SR_indication(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t s
 */
 void UL_failure_indication(module_id_t Mod_id,int CC_id,frame_t frameP,rnti_t rnti,sub_frame_t subframe);
 
+/* \brief Function to indicate an HARQ ACK/NAK.
+@param Mod_id Instance ID of eNB
+@param CC_id Component carrier
+@param frameP Frame index
+@param subframeP subframe index
+@param harq_pdu NFAPI HARQ PDU descriptor
+*/
+void harq_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, nfapi_harq_indication_pdu_t *harq_pdu);
+
+/* \brief Function to indicate a received CQI pdu
+@param Mod_id Instance ID of eNB
+@param CC_id Component carrier
+@param frameP Frame index
+@param subframeP subframe index
+@param rntiP RNTI of incoming CQI information
+@param ul_cqi_information NFAPI UL CQI measurement
+*/
+void cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, rnti_t rntiP, 
+		    nfapi_cqi_indication_rel9_t *rel9,uint8_t *pdu,
+		    nfapi_ul_cqi_information_t *ul_cqi_information);
+
 uint8_t *get_dlsch_sdu(module_id_t module_idP,int CC_id,frame_t frameP,rnti_t rnti,uint8_t TBindex);
 
 /* \brief Function to retrieve MCH transport block and MCS used for MCH in this MBSFN subframe.  Returns null if no MCH is to be transmitted
@@ -916,13 +945,43 @@ void get_csi_params(COMMON_channels_t *cc,struct CQI_ReportPeriodic *cqi_PMI_Con
 
 uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl *sched_ctl,int CC_idP,COMMON_channels_t *cc,uint8_t tmode, struct CQI_ReportPeriodic *cqi_ReportPeriodic);
 
-uint8_t get_dl_cqi_pmi_size_pusch(UE_sched_ctrl *sched_ctl,COMMON_channels_t *cc,uint8_t tmode, uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic);
+uint8_t get_dl_cqi_pmi_size_pusch(COMMON_channels_t *cc,uint8_t tmode, uint8_t ri, CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic);
 void extract_pucch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP, uint8_t *pdu, uint8_t length);
 
 void extract_pusch_csi(module_id_t mod_idP,int CC_idP,int UE_id, frame_t frameP,sub_frame_t subframeP,uint8_t *pdu, uint8_t length);
 
 uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t *tx_req_body,uint16_t absSF,uint16_t pdu_length, uint16_t *pdu_index, uint8_t *pdu );
 
+void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t  *ul_config_pdu,
+					  uint8_t                        cqi_req,
+					  COMMON_channels_t              *cc,
+					  struct PhysicalConfigDedicated *physicalConfigDedicated,
+					  uint8_t                        tmode,
+					  uint32_t                       handle,
+					  uint16_t                       rnti,
+					  uint8_t                        resource_block_start,
+					  uint8_t                        number_of_resource_blocks,
+					  uint8_t                        mcs,
+					  uint8_t                        cyclic_shift_2_for_drms,
+					  uint8_t                        frequency_hopping_enabled_flag,
+					  uint8_t                        frequency_hopping_bits,
+					  uint8_t                        new_data_indication,
+					  uint8_t                        redundancy_version,
+					  uint8_t                        harq_process_number,
+					  uint8_t                        ul_tx_mode,
+					  uint8_t                        current_tx_nb,
+					  uint8_t                        n_srs,
+					  uint16_t                       size
+					  );
+
+#ifdef Rel14
+void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t  *ul_config_pdu,
+					  uint8_t ue_type,
+					  uint16_t total_number_of_repetitions,
+					  uint16_t repetition_number,
+					  uint16_t initial_transmission_sf_io);
+#endif
+
 void program_dlsch_acknak(module_id_t module_idP, int CC_idP,int UE_idP, frame_t frameP, sub_frame_t subframeP,uint8_t cce_idx);
 
 void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB, nfapi_dl_config_request_body_t *dl_req,
@@ -997,6 +1056,8 @@ int narrowband_to_first_rb(COMMON_channels_t *cc, int nb_index);
 
 #endif
 
+int l2_init_eNB(void);
+
 
 
 #endif
diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c
index a225037e3b3f266bf86d9a8b2a31ac9a357137bf..ce8d4f7a23c06e133e2626b1a97a01acbcbe5355 100644
--- a/openair2/LAYER2/MAC/rar_tools.c
+++ b/openair2/LAYER2/MAC/rar_tools.c
@@ -137,8 +137,8 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
   RA_HEADER_RAPID *rarh = (RA_HEADER_RAPID *)dlsch_buffer;
   COMMON_channels_t *cc = &eNB->common_channels[CC_id];
   uint8_t *rar = (uint8_t *)(dlsch_buffer+1);
-  int i;
-  uint8_t nb,rballoc,reps;
+  //  uint8_t nb,reps;
+  uint8_t rballoc;
   uint8_t mcs,TPC,ULdelay,cqireq;
   int input_buffer_length;
 
@@ -168,11 +168,11 @@ unsigned short fill_rar_br(eNB_MAC_INST *eNB,
     rar[4] = (uint8_t)(RA_template->rnti>>8);
     rar[5] = (uint8_t)(RA_template->rnti&0xff);
     //cc->RA_template[ra_idx].timing_offset = 0;
-    nb      = 0;
+    //    nb      = 0;
     rballoc = mac_computeRIV(6,1+ce_level,1); // one PRB only for UL Grant in position 1+ce_level within Narrowband
     rar[1] |= (rballoc&15)<<(4-N_NB_index); // Hopping = 0 (bit 3), 3 MSBs of rballoc
 
-    reps    = 4;
+    //    reps    = 4;
     mcs     = 7;
     TPC     = 3; // no power increase
     ULdelay = 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/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c
index 90174d8c8a4372888da31894f8df519549aeba1f..10a4059950c79844b064b53c141a97ffe153e480 100644
--- a/openair2/LAYER2/openair2_proc.c
+++ b/openair2/LAYER2/openair2_proc.c
@@ -175,7 +175,7 @@ int dump_eNB_l2_stats(char *buffer, int length)
                        UE_id,
                        map_int_to_str(rrc_status_names, UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status),
                        UE_list->eNB_UE_stats[CC_id][UE_id].crnti,
-                       UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi,
+                       UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id],
                        UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1,
                        UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2,
                        UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used,
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index 143f246e923d04fea06951a1b6208d9f6b7a1635..fe9fb40547efa747f67a481845f60410419ce62c 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -102,41 +102,46 @@ void handle_harq(UL_IND_t *UL_info) {
 
 void handle_ulsch(UL_IND_t *UL_info) {
 
-  int i;
+  int i,j;
 
   for (i=0;i<UL_info->rx_ind.number_of_pdus;i++) {
 
-    LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu \n",UL_info->frame,UL_info->subframe);
-    rx_sdu(UL_info->module_id,
-	   UL_info->CC_id,
-	   UL_info->frame,
-	   UL_info->subframe,
-	   UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti,
-	   UL_info->rx_ind.rx_pdu_list[i].data,
-	   UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.length,
-	   UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.timing_advance,
-	   UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
-  }
+    for (j=0;j<UL_info->crc_ind.number_of_crcs;j++) {
+      // find crc_indication j corresponding rx_indication i
+      if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti ==
+	  UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti) {
+	if (UL_info->crc_ind.crc_pdu_list[j].crc_indication_rel8.crc_flag == 1) { // CRC error indication
+	  LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe);
+	  rx_sdu(UL_info->module_id,
+		 UL_info->CC_id,
+		 UL_info->frame,
+		 UL_info->subframe,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti,
+		 (uint8_t *)NULL,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.length,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.timing_advance,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
+	}
+	else {
+	  LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->subframe);
+	  rx_sdu(UL_info->module_id,
+		 UL_info->CC_id,
+		 UL_info->frame,
+		 UL_info->subframe,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti,
+		 UL_info->rx_ind.rx_pdu_list[i].data,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.length,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.timing_advance,
+		 UL_info->rx_ind.rx_pdu_list[i].rx_indication_rel8.ul_cqi);
+	}
+	break;
+      } //if (UL_info->crc_ind.crc_pdu_list[j].rx_ue_information.rnti ==
+	//    UL_info->rx_ind.rx_pdu_list[i].rx_ue_information.rnti) {
+    } //    for (j=0;j<UL_info->crc_ind.number_of_crcs;j++) {
+    AssertFatal(j<UL_info->crc_ind.number_of_crcs,"Couldn't find matchin CRC indication\n");
+  } //   for (i=0;i<UL_info->rx_ind.number_of_pdus;i++) {
     
   UL_info->rx_ind.number_of_pdus=0;
-  
-  for (i=0;i<UL_info->crc_ind.number_of_crcs;i++) {
-    
-    if (UL_info->crc_ind.crc_pdu_list[i].crc_indication_rel8.crc_flag == 1) { // CRC error indication
-      LOG_D(MAC,"Frame %d, Subframe %d Calling rx_sdu (CRC error) \n",UL_info->frame,UL_info->subframe);
-      rx_sdu(UL_info->module_id,
-	     UL_info->CC_id,
-	     UL_info->frame,
-	     UL_info->subframe,
-	     UL_info->crc_ind.crc_pdu_list[i].rx_ue_information.rnti,
-	     (uint8_t *)NULL,
-	     0,
-	     0,
-	     0);
-    }
-    
-    
-  }
   UL_info->crc_ind.number_of_crcs=0;
 }
 
@@ -188,14 +193,14 @@ void UL_indication(UL_IND_t *UL_info)
   if (ifi->CC_mask == ((1<<MAX_NUM_CCs)-1)) {
 
     eNB_dlsch_ulsch_scheduler(module_id,
-			      UL_info->frame+((UL_info->subframe>5)?1:0),
+			      (UL_info->frame+((UL_info->subframe>5)?1:0)) % 1024,
 			      (UL_info->subframe+4)%10);
 
     ifi->CC_mask            = 0;
 
     sched_info->module_id   = module_id;
     sched_info->CC_id       = CC_id;
-    sched_info->frame       = UL_info->frame + ((UL_info->subframe>5) ? 1 : 0);
+    sched_info->frame       = (UL_info->frame + ((UL_info->subframe>5) ? 1 : 0)) % 1024;
     sched_info->subframe    = (UL_info->subframe+4)%10;
     sched_info->DL_req      = &mac->DL_req[CC_id];
     sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id];
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index 0f475c4ae6736658804045ed56a9090e661668a0..c378e4766375827068e564774ab585e8ef3d4d29 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -196,7 +196,8 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich
   asn_enc_rval_t enc_rval;
   BCCH_BCH_Message_t *mib=&carrier->mib ;
   uint8_t sfn = (uint8_t)((frame>>2)&0xff);
-  uint16_t spare=0;
+  uint16_t *spare= calloc(1, sizeof(uint16_t));
+  if (spare == NULL) abort();
 
   switch (N_RB_DL) {
 
@@ -240,7 +241,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich
   mib->message.systemFrameNumber.buf = &sfn;
   mib->message.systemFrameNumber.size = 1;
   mib->message.systemFrameNumber.bits_unused=0;
-  mib->message.spare.buf = (uint8_t *)&spare;
+  mib->message.spare.buf = (uint8_t *)spare;
 #ifndef Rel14
   mib->message.spare.size = 2;
   mib->message.spare.bits_unused = 6;  // This makes a spare of 10 bits
@@ -252,8 +253,8 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich
 
   enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message,
                                    (void*)mib,
-                                   &carrier->MIB,
-                                   100);
+                                   carrier->MIB,
+                                   24);
   AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
                enc_rval.failed_type->name, enc_rval.encoded);
 
@@ -1554,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/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index 85b12c431e94987240586f9f830534b191f274d7..d4fd70dca1803379297f63c709942b0a08796c27 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -127,8 +127,6 @@ init_SI(
 )
 //-----------------------------------------------------------------------------
 {
-  uint8_t                             SIwindowsize = 1;
-  uint16_t                            SIperiod = 8;
 #if defined(Rel10) || defined(Rel14)
   int                                 i;
 #endif
@@ -147,10 +145,10 @@ init_SI(
 #ifdef Rel14
   RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id];
 #endif
-  LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %ld,phich_Duration %ld)\n", 
-	configuration->N_RB_DL[CC_id],
-	configuration->phich_resource[CC_id],
-	configuration->phich_duration[CC_id]);
+  LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", 
+	(int)configuration->N_RB_DL[CC_id],
+	(int)configuration->phich_resource[CC_id],
+	(int)configuration->phich_duration[CC_id]);
   do_MIB(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],
 #ifdef ENABLE_ITTI
 	 configuration->N_RB_DL[CC_id],
@@ -271,14 +269,16 @@ init_SI(
   if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) && 
       (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR!=NULL)) {
       AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL,
-		  "sib2_br->nonCriticalExtension is null (v9.2)\n");
+		  "sib2_br->nonCriticalExtension is null (v8.9)\n");
       AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL,
-		  "sib2_br->nonCriticalExtension is null (v11.3)\n");
+		  "sib2_br->nonCriticalExtension is null (v9.2)\n");
       AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
-		  "sib2_br->nonCriticalExtension is null (v12.5)\n");
+		  "sib2_br->nonCriticalExtension is null (v11.3)\n");
       AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
+		  "sib2_br->nonCriticalExtension is null (v12.5)\n");
+      AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL,
 		  "sib2_br->nonCriticalExtension is null (v13.10)\n");
-      sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
+      sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension;
   }
 #endif
 
diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h
index 35e79b60b903371a74e0359076ac88f54912e0b8..8475536639f9b1ab1e97d1453f236143a9f4429e 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
@@ -265,8 +268,9 @@ int  set_comp_log(int component, int level, int verbosity, int interval);
 int  set_log(int component, int level, int interval);
 void set_glog(int level, int verbosity);
 void set_log_syslog(int enable);
-void set_log_onlinelog(int enable);
-void set_log_filelog(int enable);
+void set_glog_onlinelog(int enable);
+void set_glog_filelog(int enable);
+
 void set_component_filelog(int comp);
 int  map_str_to_int(mapping *map, const char *str);
 char *map_int_to_str(mapping *map, int val);
@@ -294,7 +298,28 @@ void *log_thread_function(void * list);
 #endif
 /* @}*/
 
-
+/*----------------macro definitions for reading log configuration from the config module */
+#define CONFIG_STRING_LOG_PREFIX                           "log_config"
+
+#define LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL                 "global_log_level"
+#define LOG_CONFIG_STRING_GLOBAL_LOG_VERBOSITY             "global_log_verbosity"
+#define LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE                "global_log_online"
+#define LOG_CONFIG_STRING_GLOBAL_LOG_INFILE                "global_log_infile"
+
+#define LOG_CONFIG_LEVEL_FORMAT                            "%s_log_level"
+#define LOG_CONFIG_VERBOSITY_FORMAT                        "%s_log_verbosity"
+#define LOG_CONFIG_LOGFILE_FORMAT                          "%s_log_infile"
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                       LOG globalconfiguration parameters										        */
+/*   optname                              helpstr   paramflags    XXXptr	             defXXXval				      type	     numelt	*/
+/*--------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define LOG_GLOBALPARAMS_DESC { \
+{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL,    NULL,	    0,  	 strptr:(char **)&gloglevel, defstrval:log_level_names[2].name,       TYPE_STRING,  sizeof(gloglevel)}, \
+{LOG_CONFIG_STRING_GLOBAL_LOG_VERBOSITY,NULL,	    0,  	 strptr:(char **)&glogverbo, defstrval:log_verbosity_names[2].name,   TYPE_STRING,  sizeof(glogverbo)}, \
+{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE,   NULL,	    0,  	 iptr:&(g_log->onlinelog),   defintval:1,                             TYPE_INT,      0,              }, \
+{LOG_CONFIG_STRING_GLOBAL_LOG_INFILE,   NULL,	    0,  	 iptr:&(g_log->filelog),     defintval:0,                             TYPE_INT,      0,              }, \
+}
+/*----------------------------------------------------------------------------------*/
 /** @defgroup _debugging debugging macros
  *  @ingroup _macro
  *  @brief Macro used to call logIt function with different message levels
@@ -315,30 +340,43 @@ void *log_thread_function(void * list);
 #    define LOG_N(c, x...) /* */
 #    define LOG_F(c, x...) /* */
 #  else /* T_TRACER */
-extern log_t *g_log;
-#if 0
-#    define LOG_G(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_EMERG   > g_log->log_component[c].level || LOG_EMERG   > g_log->level) logIt(c, LOG_EMERG, x); } while(0)
-#    define LOG_A(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_ALERT   > g_log->log_component[c].level || LOG_ALERT   > g_log->level) logIt(c, LOG_ALERT, x); } while(0)
-#    define LOG_C(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_CRIT    > g_log->log_component[c].level || LOG_CRIT    > g_log->level) logIt(c, LOG_CRIT, x); } while(0)
-#    define LOG_E(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_ERR     > g_log->log_component[c].level || LOG_ERR     > g_log->level) logIt(c, LOG_ERR, x); } while(0)
-#    define LOG_W(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_WARNING > g_log->log_component[c].level || LOG_WARNING > g_log->level) logIt(c, LOG_WARNING, x); } while(0)
-#    define LOG_N(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_NOTICE  > g_log->log_component[c].level || LOG_NOTICE  > g_log->level) logIt(c, LOG_NOTICE, x); } while(0)
-#    define LOG_I(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_INFO    > g_log->log_component[c].level || LOG_INFO    > g_log->level) logIt(c, LOG_INFO, x); } while(0)
-#    define LOG_D(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_DEBUG   > g_log->log_component[c].level || LOG_DEBUG   > g_log->level) logIt(c, LOG_DEBUG, x); } while(0)
-#    define LOG_F(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_FILE    > g_log->log_component[c].level || LOG_FILE    > g_log->level) logIt(c, LOG_FILE, x); } while(0)
-#    define LOG_T(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_TRACE   > g_log->log_component[c].level || LOG_TRACE   > g_log->level) logIt(c, LOG_TRACE, x); } while(0)
+#    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*/
+#if      0
+         extern log_t *g_log;
+#        define LOG_G(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_EMERG   > g_log->log_component[c].level || LOG_EMERG   > g_log->level) logIt(c, LOG_EMERG, x); } while(0)
+#        define LOG_A(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_ALERT   > g_log->log_component[c].level || LOG_ALERT   > g_log->level) logIt(c, LOG_ALERT, x); } while(0)
+#        define LOG_C(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_CRIT    > g_log->log_component[c].level || LOG_CRIT    > g_log->level) logIt(c, LOG_CRIT, x); } while(0)
+#        define LOG_E(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_ERR     > g_log->log_component[c].level || LOG_ERR     > g_log->level) logIt(c, LOG_ERR, x); } while(0)
+#        define LOG_W(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_WARNING > g_log->log_component[c].level || LOG_WARNING > g_log->level) logIt(c, LOG_WARNING, x); } while(0)
+#        define LOG_N(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_NOTICE  > g_log->log_component[c].level || LOG_NOTICE  > g_log->level) logIt(c, LOG_NOTICE, x); } while(0)
+#        define LOG_I(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_INFO    > g_log->log_component[c].level || LOG_INFO    > g_log->level) logIt(c, LOG_INFO, x); } while(0)
+#        define LOG_D(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_DEBUG   > g_log->log_component[c].level || LOG_DEBUG   > g_log->level) logIt(c, LOG_DEBUG, x); } while(0)
+#        define LOG_F(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_FILE    > g_log->log_component[c].level || LOG_FILE    > g_log->level) logIt(c, LOG_FILE, x); } while(0)
+#        define LOG_T(c, x...) do { if (g_log->log_component[c].level > g_log->level || LOG_TRACE   > g_log->log_component[c].level || LOG_TRACE   > g_log->level) logIt(c, LOG_TRACE, x); } while(0)
 #else
-#    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
+#        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 /* 0 */
+#    endif /*DISABLE_LOG_X*/
 #  endif /* T_TRACER */
 #else /* USER_MODE */
 #  define LOG_G(c, x...) printk(x)
@@ -422,7 +460,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 ccf8bccb029372f2006f9628a0f7767ee1f0ed10..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 */
@@ -359,7 +361,7 @@ struct openair0_device_t {
    * \param idx RU index
    * \param arg pointer to capabilities or configuration
    */
-  int (*configure_rru)(int idx, void* arg);
+  void (*configure_rru)(int idx, void* arg);
 };
 
 /* type of device init function, implemented in shared lib */
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index 897d527297cb43c186393de05ee3f85055ccbb76..38c56b2c3377c35caae4f0a6fb3b0806ed5587ca 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;
 
@@ -592,10 +791,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)) {
@@ -718,8 +920,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);
@@ -761,6 +961,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.50PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
index 2b2c2a603467f77441f6da2de6bf324de114b1c2..ebedbcf353e9f85f7a69d57298487f07671960a3 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf
@@ -159,15 +159,19 @@ eNBs =
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
-    log_config :
-    {
+
+  }
+);
+
+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_level                         ="debug";
       mac_log_verbosity                     ="high";
       rlc_log_level                         ="info";
       rlc_log_verbosity                     ="medium";
@@ -175,9 +179,7 @@ eNBs =
       pdcp_log_verbosity                    ="medium";
       rrc_log_level                         ="info";
       rrc_log_verbosity                     ="medium";
-   };
-  }
-);
+}
 
 MACRLCs = (
 	{
@@ -207,3 +209,5 @@ RUs = (
 	eNB_instances  = [0];
     }
 );  
+
+
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/oaiL1.nfapi.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
index f7dac83e48cb5c9c6c6988bb0083292983829200..b3198565732e468a959c924c6ecaabbe643cb64e 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/oaiL1.nfapi.usrpb210.conf
@@ -1,3 +1,23 @@
+    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";
+   };
+
+/* eNBs = (); */
+
 L1s = (
     	{
 	num_cc = 1;
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/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
index ca76f42ee0aadb82b0017668b953b97fd46b5888..10f9a059aa76de21ffb81ac8530ae4e35dc590d2 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf
@@ -161,26 +161,26 @@ eNBs =
         ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
     };
 
-    log_config :
-    {
-      global_log_level                      ="debug";
-      global_log_verbosity                  ="high";
-      hw_log_level                          ="info";
-      hw_log_verbosity                      ="medium";
-      phy_log_level                         ="trace";
-      phy_log_verbosity                     ="high";
-      mac_log_level                         ="debug";
-      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";
-   };
   }
 );
 
+log_config = {
+  global_log_level                      ="info";
+  global_log_verbosity                  ="high";
+  hw_log_level                          ="info";
+  hw_log_verbosity                      ="medium";
+  phy_log_level                         ="info";
+  phy_log_verbosity                     ="high";
+  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";
+};
+
 MACRLCs = (
 	{
 	num_cc = 1;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
index 11abf64431734d84b34b7a3752cfcdd086c88270..e877e4d1ddd969ac8a0a509ae8655a7e0100190c 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.lo.conf
@@ -5,6 +5,9 @@ Asn1_verbosity = "none";
 eNBs =
 (
  {
+    # real_time choice in {hard, rt-preempt, no}
+    real_time       =  "no";
+
     ////////// Identification parameters:
     eNB_ID    =  0xe00;
 
@@ -156,24 +159,6 @@ eNBs =
         ENB_IPV4_ADDRESS_FOR_S1U                 = "127.0.0.5/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";
-   };
   }
 );
 
@@ -210,3 +195,20 @@ RUs = (
 	eNB_instances  = [0];
     }
 );  
+
+log_config = { 
+      global_log_level                      ="debug";
+      global_log_verbosity                  ="medium";
+      hw_log_level                          ="info";
+      hw_log_verbosity                      ="medium";
+      phy_log_level                         ="debug";
+      phy_log_verbosity                     ="medium";
+      mac_log_level                         ="debug";
+      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/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index e4d98eb0986d587bea06c37376c144fa1e66ccf2..29eac86c69ecc16daa65168ba3b68f79375c29f1 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -30,6 +30,8 @@
  * \warning
  */
 
+#define _GNU_SOURCE
+#include <pthread.h>
 
 #include "time_utils.h"
 
@@ -143,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);
@@ -166,6 +169,9 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
 
   // ****************************************
   // Common RX procedures subframe n
+
+  T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx));
+
   // if this is IF5 or 3GPP_eNB
   if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) {
     LOG_D(PHY,"%s:%s() %u/%u Before wakeup_prach_eNB() proc->instance_cnt_rxtx:%d\n", thread_name, __FUNCTION__, proc->frame_tx, proc->subframe_tx, proc->instance_cnt_rxtx);
@@ -276,8 +282,8 @@ static void* eNB_thread_rxtx( void* param ) {
 }
 
 
-#if defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
-/* Wait for eNB application initialization to be complete (eNB registration to MME) */
+#if 0 //defined(ENABLE_ITTI) && defined(ENABLE_USE_MME)
+// Wait for eNB application initialization to be complete (eNB registration to MME)
 static void wait_system_ready (char *message, volatile int *start_flag) {
   
   static char *indicator[] = {".    ", "..   ", "...  ", ".... ", ".....",
@@ -299,25 +305,17 @@ static void wait_system_ready (char *message, volatile int *start_flag) {
 
 
 
-void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) {
-
-
+void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string)
+{
   eNB_proc_t *proc           = &eNB->proc;
   eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0];
 
-
-
-
   proc->frame_rx    = frame_rx;
   proc->subframe_rx = subframe_rx;
-  
-  if (!oai_exit) {
-
 
+  if (!oai_exit) {
     LOG_D(PHY,"eNB_top in %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n",
-	  pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
- 
-
+	  (void*)pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
 
     T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
 
@@ -330,9 +328,8 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string) {
 
     if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id);
     LOG_D(PHY,"eNB_top out %p (proc %p, CC_id %d), frame %d, subframe %d, instance_cnt_prach %d\n",
-	  pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
+	  (void*)pthread_self(), proc, eNB->CC_id, proc->frame_rx,proc->subframe_rx,proc->instance_cnt_prach);
   }
-  
 }
 
 
@@ -371,15 +368,17 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
   wait.tv_sec=0;
   wait.tv_nsec=5000000L;
 
+#if 0
   /* accept some delay in processing - up to 5ms */
   for (i = 0; i < 10 && proc_rxtx->instance_cnt_rxtx == 0; i++) {
-    LOG_W( PHY,"[eNB] Frame %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->instance_cnt_rxtx);
+    LOG_W( PHY,"[eNB] Frame %d Subframe %d, eNB RXn-TXnp4 thread busy!! (cnt_rxtx %i)\n", proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx);
     usleep(500);
   }
   if (proc_rxtx->instance_cnt_rxtx == 0) {
-    exit_fun( "TX thread busy" );
+    //exit_fun( "TX thread busy" ); - DJP - this is commented out just whilst I work out what has gone wrong
     return(-1);
   }
+#endif
 
   // wake up TX for subframe n+4
   // lock the TX mutex and make sure the thread is ready
@@ -390,7 +389,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) {
   }
   
   ++proc_rxtx->instance_cnt_rxtx;
-  LOG_E(PHY,"%s() %u/%u Just incremented proc->instance_cnt_rxtx:%d\n", __FUNCTION__, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx);
+  LOG_D(PHY,"%s() %u/%u Just incremented proc->instance_cnt_rxtx:%d\n", __FUNCTION__, proc_rxtx->frame_tx, proc_rxtx->subframe_tx, proc_rxtx->instance_cnt_rxtx);
   
   // We have just received and processed the common part of a subframe, say n. 
   // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired 
@@ -435,7 +434,7 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
     }
     if (proc->RU_mask_prach != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
       pthread_mutex_unlock(&proc->mutex_RU_PRACH);
-      return(0);
+      return;
     }
     else { // all RUs have provided their information so continue on and wakeup eNB processing
       proc->RU_mask_prach = 0;
@@ -495,7 +494,7 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
     }
     if (proc->RU_mask_prach_br != (1<<eNB->num_RU)-1) {  // not all RUs have provided their information so return
       pthread_mutex_unlock(&proc->mutex_RU_PRACH_br);
-      return(0);
+      return;
     }
     else { // all RUs have provided their information so continue on and wakeup eNB processing
       proc->RU_mask_prach_br = 0;
@@ -553,11 +552,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");
@@ -627,7 +627,8 @@ void init_eNB_proc(int inst) {
   PHY_VARS_eNB *eNB;
   eNB_proc_t *proc;
   eNB_rxtx_proc_t *proc_rxtx;
-  pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_FH=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_single=NULL,*attr_fep=NULL,*attr_td=NULL,*attr_te=NULL,*attr_synch=NULL;
+  pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL;
+    //*attr_td=NULL,*attr_te=NULL;
 #ifdef Rel14
   pthread_attr_t *attr_prach_br=NULL;
 #endif
@@ -669,9 +670,8 @@ void init_eNB_proc(int inst) {
 
     pthread_attr_init( &proc->attr_prach);
     pthread_attr_init( &proc->attr_asynch_rxtx);
-    pthread_attr_init( &proc->attr_single);
-    pthread_attr_init( &proc->attr_td);
-    pthread_attr_init( &proc->attr_te);
+    //    pthread_attr_init( &proc->attr_td);
+    //    pthread_attr_init( &proc->attr_te);
     pthread_attr_init( &proc_rxtx[0].attr_rxtx);
     pthread_attr_init( &proc_rxtx[1].attr_rxtx);
 #ifdef Rel14
@@ -690,10 +690,8 @@ void init_eNB_proc(int inst) {
     attr_prach_br  = &proc->attr_prach_br;
 #endif
 
-    attr_asynch = &proc->attr_asynch_rxtx;
-    attr_single = &proc->attr_single;
-    attr_td     = &proc->attr_td;
-    attr_te     = &proc->attr_te; 
+    //    attr_td     = &proc->attr_td;
+    //    attr_te     = &proc->attr_te; 
 #endif
 
     LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag);
@@ -789,9 +787,9 @@ void kill_eNB_proc(int inst) {
     int i;
     if (eNB->single_thread_flag==0) {
       for (i=0;i<2;i++) {
-	LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n");
+	LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i);
 	pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status );
-	LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n");
+	LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i);
 	pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx );
 	pthread_cond_destroy( &proc_rxtx[i].cond_rxtx );
       }
@@ -889,6 +887,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
   fp->pucch_config_common.deltaPUCCH_Shift = 1;
     
 } 
+
 void init_eNB_afterRU(void) {
 
   int inst,CC_id,ru_id,i,aa;
@@ -908,10 +907,10 @@ void init_eNB_afterRU(void) {
       if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id);
       LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id);
       eNB->frame_parms.nb_antennas_rx       = 0;
-      eNB->prach_vars.rxsigF[0] = (int16_t*)malloc16(64*sizeof(int16_t*));
+      eNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*));
 #ifdef Rel14
       for (int ce_level=0;ce_level<4;ce_level++)
-	eNB->prach_vars_br.rxsigF[ce_level] = (int16_t*)malloc16(64*sizeof(int16_t*));
+	eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*));
 #endif
 
       LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU);
@@ -929,7 +928,11 @@ void init_eNB_afterRU(void) {
 
 	for (i=0;i<eNB->RU_list[ru_id]->nb_rx;aa++,i++) { 
 	  LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa);
-	  eNB->prach_vars.rxsigF[aa]       =  eNB->RU_list[ru_id]->prach_rxsigF[i];
+	  eNB->prach_vars.rxsigF[0][aa]    =  eNB->RU_list[ru_id]->prach_rxsigF[i];
+#ifdef Rel14
+	  for (int ce_level=0;ce_level<4;ce_level++)
+	    eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i];
+#endif
 	  eNB->common_vars.rxdataF[aa]     =  eNB->RU_list[ru_id]->common.rxdataF[i];
 	}
       }
@@ -957,7 +960,7 @@ void init_eNB_afterRU(void) {
       LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx);
 
       init_transport(eNB);
-      init_precoding_weights(RC.eNB[inst][CC_id]);
+      //init_precoding_weights(RC.eNB[inst][CC_id]);
     }
     printf("RC.nb_CC[inst:%d]:%d CC_id:%d AFTER LOOP - About to init_eNB_proc\n", inst, RC.nb_CC[inst], CC_id);
     init_eNB_proc(inst);
@@ -985,7 +988,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
   int inst;
   PHY_VARS_eNB *eNB;
 
-  LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated\n");
+  LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]);
 
   if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **));
   LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n");
@@ -998,6 +1001,7 @@ void init_eNB(int single_thread_flag,int wait_for_sync) {
       eNB->single_thread_flag = single_thread_flag;
 
 
+      LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag);
 #ifndef OCP_FRAMEWORK
       LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id);
 #endif
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 8b90528879ff610b26bee5f6a16af66b8f2dd5ee..d3c747073d32d556263e9c04e79c10f88b1f391f 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -115,7 +115,7 @@ extern volatile int                    oai_exit;
 
 extern void  phy_init_RU(RU_t*);
 
-void init_RU(const char*);
+void init_RU(char*);
 void stop_RU(RU_t *ru);
 void do_ru_sync(RU_t *ru);
 
@@ -133,7 +133,7 @@ int connect_rau(RU_t *ru);
 /*************************************************************/
 /* Functions to attach and configure RRU                     */
 
-extern void wait_eNBs();
+extern void wait_eNBs(void);
 
 int attach_rru(RU_t *ru) {
   
@@ -141,7 +141,7 @@ int attach_rru(RU_t *ru) {
   RRU_CONFIG_msg_t rru_config_msg;
   int received_capabilities=0;
 
-  wait_eNBs(ru);
+  wait_eNBs();
   // Wait for capabilities
   while (received_capabilities==0) {
     
@@ -480,7 +480,7 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) {
   RU_proc_t *proc       = &ru->proc;
 
   uint16_t packet_type;
-  uint32_t symbol_number,symbol_mask,symbol_mask_full,prach_rx;
+  uint32_t symbol_number,symbol_mask,prach_rx;
   uint32_t got_prach_info=0;
 
   symbol_number = 0;
@@ -761,10 +761,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
   VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff );
   
   if (rxs != fp->samples_per_tti)
-    exit_fun( "problem receiving samples" );
-  
-
-  
+  {
+    //exit_fun( "problem receiving samples" );
+  }
 }
 
 
@@ -776,6 +775,9 @@ void tx_rf(RU_t *ru) {
   unsigned int txs;
   int i;
 
+  T(T_ENB_PHY_OUTPUT_SIGNAL, T_INT(0), T_INT(0), T_INT(proc->frame_tx), T_INT(proc->subframe_tx),
+    T_INT(0), T_BUFFER(&ru->common.txdata[0][proc->subframe_tx * fp->samples_per_tti], fp->samples_per_tti * 4));
+
   lte_subframe_t SF_type     = subframe_select(fp,proc->subframe_tx%10);
   lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_tx+9)%10);
   lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_tx+1)%10);
@@ -881,11 +883,8 @@ void tx_rf(RU_t *ru) {
 				      ru->nb_tx,
 				      flags);
     
-    if (0 && proc->frame_tx % 10 ==0 && proc->subframe_tx==0) 
-      LOG_E(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d flags:%d siglen:%d\n",
-          ru->idx,
-          proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx, flags, siglen);
-
+    LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, subframe %d\n",ru->idx,
+	  (long long unsigned int)proc->timestamp_tx,proc->frame_tx,proc->frame_tx_unwrap,proc->subframe_tx);
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
     
     
@@ -1192,7 +1191,7 @@ void wakeup_eNBs(RU_t *ru) {
   else {
 
     for (i=0;i<ru->num_eNB;i++)
-      if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru->proc.frame_rx,ru->proc.subframe_rx) < 0)
+      if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0)
 	LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx);
   }
 }
@@ -1258,7 +1257,143 @@ static inline int wakeup_prach_ru_br(RU_t *ru) {
 #endif
 
 void oai_subframe_ind(uint16_t frame, uint16_t subframe);
-void check_dlsch(char *file, int line);
+
+// this is for RU with local RF unit
+void fill_rf_config(RU_t *ru, char *rf_config_file) {
+
+  int i;
+
+  LTE_DL_FRAME_PARMS *fp   = &ru->frame_parms;
+  openair0_config_t *cfg   = &ru->openair0_cfg;
+
+  if(fp->N_RB_DL == 100) {
+    if (fp->threequarter_fs) {
+      cfg->sample_rate=23.04e6;
+      cfg->samples_per_frame = 230400; 
+      cfg->tx_bw = 10e6;
+      cfg->rx_bw = 10e6;
+    }
+    else {
+      cfg->sample_rate=30.72e6;
+      cfg->samples_per_frame = 307200; 
+      cfg->tx_bw = 10e6;
+      cfg->rx_bw = 10e6;
+    }
+  } else if(fp->N_RB_DL == 50) {
+    cfg->sample_rate=15.36e6;
+    cfg->samples_per_frame = 153600;
+    cfg->tx_bw = 5e6;
+    cfg->rx_bw = 5e6;
+  } else if (fp->N_RB_DL == 25) {
+    cfg->sample_rate=7.68e6;
+    cfg->samples_per_frame = 76800;
+    cfg->tx_bw = 2.5e6;
+    cfg->rx_bw = 2.5e6;
+  } else if (fp->N_RB_DL == 6) {
+    cfg->sample_rate=1.92e6;
+    cfg->samples_per_frame = 19200;
+    cfg->tx_bw = 1.5e6;
+    cfg->rx_bw = 1.5e6;
+  }
+  else AssertFatal(1==0,"Unknown N_RB_DL %d\n",fp->N_RB_DL);
+
+  if (fp->frame_type==TDD)
+    cfg->duplex_mode = duplex_mode_TDD;
+  else //FDD
+    cfg->duplex_mode = duplex_mode_FDD;
+
+  cfg->Mod_id = 0;
+  cfg->num_rb_dl=fp->N_RB_DL;
+  cfg->tx_num_channels=ru->nb_tx;
+  cfg->rx_num_channels=ru->nb_rx;
+  
+  for (i=0; i<ru->nb_tx; i++) {
+    
+    cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
+    cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
+
+    cfg->tx_gain[i] = (double)fp->att_tx;
+    cfg->rx_gain[i] = ru->max_rxgain-(double)fp->att_rx;
+
+    cfg->configFilename = rf_config_file;
+    printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n",
+	   i, cfg->tx_gain[i],
+	   cfg->rx_gain[i],
+	   cfg->tx_freq[i],
+	   cfg->rx_freq[i]);
+  }
+}
+
+/* this function maps the RU tx and rx buffers to the available rf chains.
+   Each rf chain is is addressed by the card number and the chain on the card. The
+   rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple
+   antennas are mapped to successive RF chains on the same card. */
+int setup_RU_buffers(RU_t *ru) {
+
+  int i,j; 
+  int card,ant;
+
+  //uint16_t N_TA_offset = 0;
+
+  LTE_DL_FRAME_PARMS *frame_parms;
+  
+  if (ru) {
+    frame_parms = &ru->frame_parms;
+    printf("setup_RU_buffers: frame_parms = %p\n",frame_parms);
+  } else {
+    printf("RU[%d] not initialized\n", ru->idx);
+    return(-1);
+  }
+  
+  /*
+    if (frame_parms->frame_type == TDD) {
+    if (frame_parms->N_RB_DL == 100)
+    N_TA_offset = 624;
+    else if (frame_parms->N_RB_DL == 50)
+    N_TA_offset = 624/2;
+    else if (frame_parms->N_RB_DL == 25)
+    N_TA_offset = 624/4;
+    }
+  */
+  
+  
+  if (ru->openair0_cfg.mmapped_dma == 1) {
+    // replace RX signal buffers with mmaped HW versions
+    
+    for (i=0; i<ru->nb_rx; i++) {
+      card = i/4;
+      ant = i%4;
+      printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
+      free(ru->common.rxdata[i]);
+      ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant];
+      
+      printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]);
+      for (j=0; j<16; j++) {
+	printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]);
+	ru->common.rxdata[i][j] = 16-j;
+      }
+    }
+    
+    for (i=0; i<ru->nb_tx; i++) {
+      card = i/4;
+      ant = i%4;
+      printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
+      free(ru->common.txdata[i]);
+      ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant];
+      
+      printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]);
+      
+      for (j=0; j<16; j++) {
+	printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]);
+	ru->common.txdata[i][j] = 16-j;
+      }
+    }
+  }
+  else {  // not memory-mapped DMA 
+    //nothing to do, everything already allocated in lte_init
+  }
+  return(0);
+}
 
 static void* ru_thread( void* param ) {
 
@@ -1295,10 +1430,10 @@ static void* ru_thread( void* param ) {
         phy_init_RU(ru);
  //     }
 
-ru->openair0_cfg.tx_gain[0]=0.0;
-ru->openair0_cfg.tx_gain[1]=0.0;
-ru->openair0_cfg.tx_gain[2]=0.0;
-ru->openair0_cfg.tx_gain[3]=0.0;
+//ru->openair0_cfg.tx_gain[0]=0.0;
+//ru->openair0_cfg.tx_gain[1]=0.0;
+//ru->openair0_cfg.tx_gain[2]=0.0;
+//ru->openair0_cfg.tx_gain[3]=0.0;
 
       ret = openair0_device_load(&ru->rfdevice,&ru->openair0_cfg);
       if (setup_RU_buffers(ru)!=0) {
@@ -1370,12 +1505,8 @@ ru->openair0_cfg.tx_gain[3]=0.0;
     if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe);
     else AssertFatal(1==0, "No fronthaul interface at south port");
 
-    check_dlsch(__FILE__, __LINE__);
-
     oai_subframe_ind(frame, subframe);
 
-    check_dlsch(__FILE__, __LINE__);
-
     LOG_D(PHY,"RU thread (do_prach %d, is_prach_subframe %d), received frame %d, subframe %d\n",
 	  ru->do_prach,
 	  is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx),
@@ -1383,7 +1514,6 @@ ru->openair0_cfg.tx_gain[3]=0.0;
  
     if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) { 
       wakeup_prach_ru(ru);
-      check_dlsch(__FILE__, __LINE__);
     }
 #ifdef Rel14
     else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) {
@@ -1398,40 +1528,30 @@ ru->openair0_cfg.tx_gain[3]=0.0;
     // do RX front-end processing (frequency-shift, dft) if needed
     if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); 
     if (ru->feprx) ru->feprx(ru);
-    check_dlsch(__FILE__, __LINE__);
-
-    T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx));
 
     // At this point, all information for subframe has been received on FH interface
     // If this proc is to provide synchronization, do so
     wakeup_slaves(proc);
-    check_dlsch(__FILE__, __LINE__);
 
     //LOG_E(PHY,"RU %d/%d frame_tx %d, subframe_tx %d\n",0,ru->idx,proc->frame_tx,proc->subframe_tx);
     // wakeup all eNB processes waiting for this RU
     if (ru->num_eNB>0) wakeup_eNBs(ru);
-    check_dlsch(__FILE__, __LINE__);
 
     //LOG_E(PHY,"%s() Before wait_on_condition()\n", __FUNCTION__);
     // wait until eNBs are finished subframe RX n and TX n+4
     wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
-    check_dlsch(__FILE__, __LINE__);
     //LOG_E(PHY,"%s() AFTER wait_on_condition() ru->feptx_prec:%p ru->fh_north_asynch_in:%p ru->feptx_ofdm:%p ru->fh_south_out:%p ru->fh_north_out:%p\n", 
     //__FUNCTION__, ru->feptx_prec, ru->fh_north_asynch_in, ru->feptx_ofdm, ru->fh_south_out, ru->fh_north_out);
 
     // do TX front-end processing if needed (precoding and/or IDFTs)
     if (ru->feptx_prec) ru->feptx_prec(ru);
-    check_dlsch(__FILE__, __LINE__);
    
     // do OFDM if needed
     if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
-    check_dlsch(__FILE__, __LINE__);
     // do outgoing fronthaul (south) if needed
     if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
-    check_dlsch(__FILE__, __LINE__);
  
     if (ru->fh_north_out) ru->fh_north_out(ru);
-    check_dlsch(__FILE__, __LINE__);
     if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 0 ); 
   }
   
@@ -1627,152 +1747,6 @@ void init_RU_proc(RU_t *ru) {
 
   
   
-}
-
-/* this function maps the RU tx and rx buffers to the available rf chains.
-   Each rf chain is is addressed by the card number and the chain on the card. The
-   rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple
-   antennas are mapped to successive RF chains on the same card. */
-int setup_RU_buffers(RU_t *ru) {
-
-  int i,j; 
-  int card,ant;
-
-  //uint16_t N_TA_offset = 0;
-
-  LTE_DL_FRAME_PARMS *frame_parms;
-  
-  if (ru) {
-    frame_parms = &ru->frame_parms;
-    printf("setup_RU_buffers: frame_parms = %p\n",frame_parms);
-  } else {
-    printf("RU[%d] not initialized\n", ru->idx);
-    return(-1);
-  }
-  
-  /*
-    if (frame_parms->frame_type == TDD) {
-    if (frame_parms->N_RB_DL == 100)
-    N_TA_offset = 624;
-    else if (frame_parms->N_RB_DL == 50)
-    N_TA_offset = 624/2;
-    else if (frame_parms->N_RB_DL == 25)
-    N_TA_offset = 624/4;
-    }
-  */
-  
-  
-  printf("%s() nb_rx:%d dma:%d\n", __FUNCTION__, ru->nb_rx, ru->openair0_cfg.mmapped_dma);
-
-  if (ru->openair0_cfg.mmapped_dma == 1) {
-    // replace RX signal buffers with mmaped HW versions
-    
-    for (i=0; i<ru->nb_rx; i++) {
-      card = i/4;
-      ant = i%4;
-      printf("Mapping RU id %d, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
-      free(ru->common.rxdata[i]);
-      ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant];
-      
-      printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]);
-      for (j=0; j<16; j++) {
-	printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]);
-	ru->common.rxdata[i][j] = 16-j;
-      }
-    }
-    
-    for (i=0; i<ru->nb_tx; i++) {
-      card = i/4;
-      ant = i%4;
-      printf("Mapping RU id %d, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant);
-      free(ru->common.txdata[i]);
-      ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant];
-      
-      printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]);
-      
-      for (j=0; j<16; j++) {
-	printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]);
-	ru->common.txdata[i][j] = 16-j;
-      }
-    }
-  }
-  else {  // not memory-mapped DMA 
-    //nothing to do, everything already allocated in lte_init
-    printf("%s() Not memory-mapped DMA - nothing to do\n", __FUNCTION__);
-  }
-  return(0);
-}
-
-
-// this is for RU with local RF unit
-void fill_rf_config(RU_t *ru,const char *rf_config_file) {
-
-  int i;
-
-  LTE_DL_FRAME_PARMS *fp   = &ru->frame_parms;
-  openair0_config_t *cfg   = &ru->openair0_cfg;
-
-  if(fp->N_RB_DL == 100) {
-    if (fp->threequarter_fs) {
-      cfg->sample_rate=23.04e6;
-      cfg->samples_per_frame = 230400; 
-      cfg->tx_bw = 10e6;
-      cfg->rx_bw = 10e6;
-    }
-    else {
-      cfg->sample_rate=30.72e6;
-      cfg->samples_per_frame = 307200; 
-      cfg->tx_bw = 10e6;
-      cfg->rx_bw = 10e6;
-    }
-  } else if(fp->N_RB_DL == 50) {
-    cfg->sample_rate=15.36e6;
-    cfg->samples_per_frame = 153600;
-    cfg->tx_bw = 5e6;
-    cfg->rx_bw = 5e6;
-  } else if (fp->N_RB_DL == 25) {
-    cfg->sample_rate=7.68e6;
-    cfg->samples_per_frame = 76800;
-    cfg->tx_bw = 2.5e6;
-    cfg->rx_bw = 2.5e6;
-  } else if (fp->N_RB_DL == 6) {
-    cfg->sample_rate=1.92e6;
-    cfg->samples_per_frame = 19200;
-    cfg->tx_bw = 1.5e6;
-    cfg->rx_bw = 1.5e6;
-  }
-  else AssertFatal(1==0,"Unknown N_RB_DL %d\n",fp->N_RB_DL);
-
-  if (fp->frame_type==TDD)
-    cfg->duplex_mode = duplex_mode_TDD;
-  else //FDD
-    cfg->duplex_mode = duplex_mode_FDD;
-
-  cfg->Mod_id = 0;
-  cfg->num_rb_dl=fp->N_RB_DL;
-  cfg->tx_num_channels=ru->nb_tx;
-  cfg->rx_num_channels=ru->nb_rx;
-  
-  for (i=0; i<ru->nb_tx; i++) {
-    
-    cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
-    cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
-
-//fp->att_tx = 0;
-//printf("%s() DJP - HARD CODE ALERT - fp->att_tx:%d\n", __FUNCTION__);
-
-    cfg->tx_gain[i] = (double)fp->att_tx;
-    cfg->rx_gain[i] = ru->max_rxgain-(double)fp->att_rx;
-
-    cfg->configFilename = rf_config_file;
-    printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f configFilename:%s fp->att_tx:%d\n",
-	   i, cfg->tx_gain[i],
-	   cfg->rx_gain[i],
-	   cfg->tx_freq[i],
-	   cfg->rx_freq[i],
-           cfg->configFilename,
-           fp->att_tx);
-  }
 }
 
 int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) {
@@ -1815,6 +1789,7 @@ int check_capabilities(RU_t *ru,RRU_capabilities_t *cap) {
     return(-1);
   }
 
+  return(-1);
 }
 
 
@@ -1836,41 +1811,40 @@ void configure_ru(int idx,
 
 
   if (capabilities->FH_fmt < MAX_FH_FMTs) LOG_I(PHY, "RU FH options %s\n",rru_format_options[capabilities->FH_fmt]);
-  if ((ret=check_capabilities(ru,capabilities)) == 0) {
-    // Pass configuration to RRU
-    LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->frame_parms.eutra_band);
-    // wait for configuration 
-    config->FH_fmt                 = ru->if_south;
-    config->num_bands              = 1;
-    config->band_list[0]           = ru->frame_parms.eutra_band;
-    config->tx_freq[0]             = ru->frame_parms.dl_CarrierFreq;      
-    config->rx_freq[0]             = ru->frame_parms.ul_CarrierFreq;      
-    config->att_tx[0]              = ru->att_tx;
-    config->att_rx[0]              = ru->att_rx;
-    config->N_RB_DL[0]             = ru->frame_parms.N_RB_DL;
-    config->N_RB_UL[0]             = ru->frame_parms.N_RB_UL;
-    config->threequarter_fs[0]     = ru->frame_parms.threequarter_fs;
-    if (ru->if_south==REMOTE_IF4p5) {
-      config->prach_FreqOffset[0]  = ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
-      config->prach_ConfigIndex[0] = ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
-      LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n",
-	    config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);
 
+  AssertFatal((ret=check_capabilities(ru,capabilities)) == 0,
+	      "Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret);
+  // Pass configuration to RRU
+  LOG_I(PHY, "Using %s fronthaul (%d), band %d \n",ru_if_formats[ru->if_south],ru->if_south,ru->frame_parms.eutra_band);
+  // wait for configuration 
+  config->FH_fmt                 = ru->if_south;
+  config->num_bands              = 1;
+  config->band_list[0]           = ru->frame_parms.eutra_band;
+  config->tx_freq[0]             = ru->frame_parms.dl_CarrierFreq;      
+  config->rx_freq[0]             = ru->frame_parms.ul_CarrierFreq;      
+  config->att_tx[0]              = ru->att_tx;
+  config->att_rx[0]              = ru->att_rx;
+  config->N_RB_DL[0]             = ru->frame_parms.N_RB_DL;
+  config->N_RB_UL[0]             = ru->frame_parms.N_RB_UL;
+  config->threequarter_fs[0]     = ru->frame_parms.threequarter_fs;
+  if (ru->if_south==REMOTE_IF4p5) {
+    config->prach_FreqOffset[0]  = ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset;
+    config->prach_ConfigIndex[0] = ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
+    LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n",
+	  config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);
+    
 #ifdef Rel14
-      for (i=0;i<4;i++) {
-	config->emtc_prach_CElevel_enable[0][i]  = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i];
-	config->emtc_prach_FreqOffset[0][i]      = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i];
-	config->emtc_prach_ConfigIndex[0][i]     = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i];
-      }
-#endif
+    for (i=0;i<4;i++) {
+      config->emtc_prach_CElevel_enable[0][i]  = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i];
+      config->emtc_prach_FreqOffset[0][i]      = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i];
+      config->emtc_prach_ConfigIndex[0][i]     = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[i];
     }
-    // take antenna capabilities of RRU
-    ru->nb_tx                      = capabilities->nb_tx[0];
-    ru->nb_rx                      = capabilities->nb_rx[0];
-  }
-  else {
-    LOG_I(PHY,"Cannot configure RRU %d, check_capabilities returned %d\n", idx,ret);
+#endif
   }
+  // take antenna capabilities of RRU
+  ru->nb_tx                      = capabilities->nb_tx[0];
+  ru->nb_rx                      = capabilities->nb_rx[0];
+
 
   init_frame_parms(&ru->frame_parms,1);
   phy_init_RU(ru);
@@ -1942,7 +1916,9 @@ void init_precoding_weights(PHY_VARS_eNB *eNB) {
   }
 }
 
-void init_RU(const char *rf_config_file) {
+extern void RCconfig_RU(void);
+
+void init_RU(char *rf_config_file) {
   
   int ru_id;
   RU_t *ru;
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index c39f42a962876f0ff12b0c04824d46f5bceb16df..f89a7adfc19791b26bca3758e69d2260145ba14e 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -30,7 +30,10 @@
  * \warning
  */
 
-#include "lte-softmodem.h"
+
+#define _GNU_SOURCE             /* See feature_test_macros(7) */
+#include <sched.h>
+
 
 #include "T.h"
 
@@ -46,7 +49,8 @@
 
 #include "PHY/defs.h"
 #include "common/ran_context.h"
-
+#include "common/config/config_userapi.h"
+#include "common/utils/load_module_shlib.h"
 #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
 //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
 
@@ -95,7 +99,7 @@ unsigned short config_frames[4] = {2,9,11,13};
 #include "PHY/TOOLS/lte_phy_scope.h"
 #include "stats.h"
 #endif
-
+#include "lte-softmodem.h"
 
 #ifdef XFORMS
 // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
@@ -139,7 +143,7 @@ uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
 int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
 
 
-static char                    *conf_config_file_name = NULL;
+
 #if defined(ENABLE_ITTI)
 static char                    *itti_dump_file = NULL;
 #endif
@@ -174,6 +178,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;
 
@@ -181,7 +188,7 @@ char ref[128] = "internal";
 char channels[128] = "0";
 
 int                      rx_input_level_dBm;
-static int                      online_log_messages=0;
+
 #ifdef XFORMS
 extern int                      otg_enabled;
 static char                     do_forms=0;
@@ -204,35 +211,7 @@ extern void print_opp_meas(void);
 
 int transmission_mode=1;
 
-int16_t           glog_level         = LOG_INFO;
-int16_t           glog_verbosity     = LOG_MED;
-int16_t           hw_log_level       = LOG_INFO;
-int16_t           hw_log_verbosity   = LOG_MED;
-int16_t           phy_log_level      = LOG_DEBUG;
-int16_t           phy_log_verbosity  = LOG_FULL;
-int16_t           rach_log_level      = LOG_DEBUG;
-int16_t           rach_log_verbosity  = LOG_FULL;
-int16_t           mac_log_level      = LOG_DEBUG;
-int16_t           mac_log_verbosity  = LOG_FULL;
-int16_t           rlc_log_level      = LOG_INFO;
-int16_t           rlc_log_verbosity  = LOG_MED;
-int16_t           pdcp_log_level     = LOG_INFO;
-int16_t           pdcp_log_verbosity = LOG_MED;
-int16_t           rrc_log_level      = LOG_INFO;
-int16_t           rrc_log_verbosity  = LOG_MED;
-int16_t           opt_log_level      = LOG_INFO;
-int16_t           opt_log_verbosity  = LOG_MED;
 
-# if defined(ENABLE_USE_MME)
-int16_t           gtpu_log_level     = LOG_DEBUG;
-int16_t           gtpu_log_verbosity = LOG_MED;
-int16_t           udp_log_level      = LOG_DEBUG;
-int16_t           udp_log_verbosity  = LOG_MED;
-#endif
-#if defined (ENABLE_SECURITY)
-int16_t           osa_log_level      = LOG_INFO;
-int16_t           osa_log_verbosity  = LOG_MED;
-#endif
 
 /* struct for ethernet specific parameters given in eNB conf file */
 eth_params_t *eth_params;
@@ -245,7 +224,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
@@ -328,58 +307,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)
@@ -456,7 +383,6 @@ static void *scope_thread(void *arg) {
 # ifdef ENABLE_XFORMS_WRITE_STATS
   FILE *UE_stats, *eNB_stats;
 # endif
-  int len = 0;
   struct sched_param sched_param;
   int UE_id, CC_id;
   int ue_cnt=0;
@@ -477,7 +403,7 @@ static void *scope_thread(void *arg) {
 
   while (!oai_exit) {
     if (UE_flag==1) {
-      len = dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm);
+      dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm);
       //fl_set_object_label(form_stats->stats_text, stats_buffer);
       fl_clear_browser(form_stats->stats_text);
       fl_add_browser_line(form_stats->stats_text, stats_buffer);
@@ -630,474 +556,145 @@ void *l2l1_task(void *arg) {
 #endif
 
 
-
-
-static void get_options (int argc, char **argv) {
-  int c;
-  //  char                          line[1000];
-  //  int                           l;
-  int k,i;//,j,k;
-#if defined(OAI_USRP) || defined(CPRIGW)
-  int clock_src;
-#endif
+static void get_options(void) {
   int CC_id;
+  int tddflag;
+  char *loopfile=NULL;
+  int dumpframe;
+  uint32_t online_log_messages;
+  uint32_t glog_level, glog_verbosity;
+  uint32_t start_telnetsrv;
 
+  paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
+  paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
 
+  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); 
 
-  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':
+  if (strlen(in_path) > 0) {
+      opt_type = OPT_PCAP;
+      opt_enabled=1;
+      printf("Enabling OPT for PCAP  with the following file %s \n",in_path);
+  }
+  if (strlen(in_ip) > 0) {
       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;
+  config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
+  if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
+      set_glog_onlinelog(online_log_messages);
+  }
+  if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
+      set_glog(glog_level, -1);
+  }
+  if(config_isparamset(cmdline_logparams,CMDLINE_GLOGVERBO_IDX)) {
+      set_glog(-1, glog_verbosity);
+  }
+  if (start_telnetsrv) {
+     load_module_shlib("telnetsrv");
+  }
 
-	case 25:
-	  frame_parms[CC_id]->N_RB_DL=25;
-	  frame_parms[CC_id]->N_RB_UL=25;
-	  break;
+  
+  if (UE_flag > 0) {
+     paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
+     paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC;
 
-	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;
-	}
+     config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
+     config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
+      if (loopfile != NULL) {
+  	  printf("Input file for hardware emulation: %s",loopfile);
+  	  mode=loop_through_memory;
+  	  input_fd = fopen(loopfile,"r");
+  	  AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
       }
+      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
+      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
+      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
+      if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
+      if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0)  mode = no_L2_connect;
+      if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; 
+      if (dumpframe  > 0)  mode = rx_dump_frame;
+      
+      if ( downlink_frequency[0][0] > 0) {
+  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
+  	    downlink_frequency[CC_id][1] = downlink_frequency[0][0];
+  	    downlink_frequency[CC_id][2] = downlink_frequency[0][0];
+  	    downlink_frequency[CC_id][3] = downlink_frequency[0][0];
+  	    printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
+  	  }
+      UE_scan=0;
+      } 
 
-      break;
+      if (tddflag > 0) {
+         for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
+	     frame_parms[CC_id]->frame_type = TDD;
+      }
 
-    case 's':
-#if defined(OAI_USRP) || defined(CPRIGW)
+      if (frame_parms[0]->N_RB_DL !=0) {
+  	  if ( frame_parms[0]->N_RB_DL < 6 ) {
+  	     frame_parms[0]->N_RB_DL = 6;
+  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL);
+  	  }
+  	  if ( frame_parms[0]->N_RB_DL > 100 ) {
+  	     frame_parms[0]->N_RB_DL = 100;
+  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL);
+  	  }
+  	  if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) {
+  	     frame_parms[0]->N_RB_DL = 50;
+  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL);
+  	  }
+  	  if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) {
+  	     frame_parms[0]->N_RB_DL = 25;
+  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL);
+  	  }
+  	  UE_scan = 0;
+  	  frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL;
+  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
+  	      frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL;
+  	      frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL;
+  	  }
+      }
 
-      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);
+      for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++) {
+  	    tx_max_power[CC_id]=tx_max_power[0];
+	    rx_gain[0][CC_id] = rx_gain[0][0];
+	    tx_gain[0][CC_id] = tx_gain[0][0];
       }
-
-#else
-      printf("Note: -s not defined for ExpressMIMO2\n");
+  } /* UE_flag > 0 */
+#if T_TRACER
+  paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
+  config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);   
 #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 ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
+    if (UE_flag == 0) {
+      memset((void*)&RC,0,sizeof(RC));
+      /* Read RC configuration file */
+      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);
     }
-  }
-
-  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;
+  } 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  */
+}
 
-    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 */
+int T_nowait = 0;     /* by default we wait for the tracer */
 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]) {
 
@@ -1239,7 +836,7 @@ void init_openair0() {
 }
 
 
-void wait_RUs() {
+void wait_RUs(void) {
 
   LOG_I(PHY,"Waiting for RUs to be configured ...\n");
 
@@ -1255,7 +852,7 @@ void wait_RUs() {
   LOG_I(PHY,"RUs configured\n");
 }
 
-void wait_eNBs() {
+void wait_eNBs(void) {
 
   int i,j;
   int waiting=1;
@@ -1297,12 +894,11 @@ uint8_t nfapi_pnf = 0;
 
 int main( int argc, char **argv )
 {
-  int i,j,k,aa,re;
+  int i;
 #if defined (XFORMS)
   void *status;
 #endif
 
-  int inst;
   int CC_id;
   int ru_id;
   uint8_t  abstraction_flag=0;
@@ -1313,7 +909,10 @@ int main( int argc, char **argv )
 #endif
 
   start_background_system();
-
+  if ( load_configmodule(argc,argv) == NULL) {
+    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
+  } 
+      
 #ifdef DEBUG_CONSOLE
   setvbuf(stdout, NULL, _IONBF, 0);
   setvbuf(stderr, NULL, _IONBF, 0);
@@ -1335,17 +934,19 @@ int main( int argc, char **argv )
   logInit();
 
   printf("Reading in command-line options\n");
-  // get options and fill parameters from configuration file
-  get_options (argc, argv); //Command-line options, enb_properties
 
+  get_options (); 
+  if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
+      fprintf(stderr,"Getting configuration failed\n");
+      exit(-1);
+  }
 
 
 #if T_TRACER
-  T_init(T_port, T_wait, T_dont_fork);
+  T_init(T_port, 1-T_nowait, T_dont_fork);
 #endif
 
-  // initialize the log (see log.h for details)
-  set_glog(glog_level, glog_verbosity);
+
 
   //randominit (0);
   set_taus_seed (0);
@@ -1370,37 +971,6 @@ int main( int argc, char **argv )
   } else {
     printf("configuring for RAU/RRU\n");
 
-    set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
-    set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
-    if (opt_enabled == 1 )
-      set_comp_log(OPT,   opt_log_level,      opt_log_verbosity, 1);
-    set_comp_log(MAC,     mac_log_level,  mac_log_verbosity, 1);
-    set_comp_log(RLC,     rlc_log_level,   rlc_log_verbosity, 1);
-    set_comp_log(PDCP,    pdcp_log_level,  pdcp_log_verbosity, 1);
-    set_comp_log(RRC,     rrc_log_level,  rrc_log_verbosity, 1);
-#if defined(ENABLE_ITTI)
-    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
-# if defined(ENABLE_USE_MME)
-    set_comp_log(UDP_,    udp_log_level,   udp_log_verbosity, 1);
-    set_comp_log(GTPU,    gtpu_log_level,   gtpu_log_verbosity, 1);
-    set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
-    set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
-# endif
-#if defined(ENABLE_SECURITY)
-    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
-#endif
-#endif
-#ifdef LOCALIZATION
-    set_comp_log(LOCALIZE, LOG_DEBUG, LOG_LOW, 1);
-    set_component_filelog(LOCALIZE);
-#endif
-    set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
-    set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
-
-    if (online_log_messages == 1) {
-      set_component_filelog(RRC);
-      set_component_filelog(PDCP);
-    }
   }
 
   if (ouput_vcd) {
@@ -1478,8 +1048,10 @@ int main( int argc, char **argv )
 
 
   printf("Before CC \n");
+
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
 
+
     if (UE_flag==1) {     
       NB_UE_INST=1;     
       NB_INST=1;     
@@ -1583,7 +1155,7 @@ int main( int argc, char **argv )
   LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
 #endif
   
-  openair0_cfg[0].log_level = glog_level;
+
   
   
 #if defined(ENABLE_ITTI)
@@ -1687,13 +1259,31 @@ int main( int argc, char **argv )
   
   rt_sleep_ns(10*100000000ULL);
   
-  printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
-  pthread_cond_init(&sync_cond,NULL);
-  pthread_mutex_init(&sync_mutex, NULL);
+  if (nfapi_pnf)
+  {
+    printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
+    pthread_cond_init(&sync_cond,NULL);
+    pthread_mutex_init(&sync_mutex, NULL);
+  }
   
+  const char *nfapi_mode_str = "<UNKNOWN>";
+
+  switch(nfapi_pnf)
+  {
+    case 0:
+      nfapi_mode_str = "MONOLITHIC";
+    case 1:
+      nfapi_mode_str = "PNF";
+      break;
+    case 2:
+      nfapi_mode_str = "VNF";
+      break;
+  }
+  printf("NFAPI MODE:%s (1-PNF 2-VNF)\n", nfapi_mode_str);
+
   if (nfapi_pnf==2) // VNF
     wait_nfapi_init("main?");
-  
+
   printf("START MAIN THREADS\n");
   
   // start the main threads
@@ -1709,8 +1299,9 @@ int main( int argc, char **argv )
   }
   else { 
     number_of_cards = 1;    
+    printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
     if (RC.nb_L1_inst > 0) {
-      printf("Initializing eNB threads\n");
+      printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync);
       init_eNB(single_thread_flag,wait_for_sync);
       //      for (inst=0;inst<RC.nb_L1_inst;inst++)
       //	for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
@@ -1795,7 +1386,8 @@ int main( int argc, char **argv )
   sync_var=0;
   pthread_cond_broadcast(&sync_cond);
   pthread_mutex_unlock(&sync_mutex);
-  
+  end_configmodule();
+
   // wait for end of program
   printf("TYPE <CTRL-C> TO TERMINATE\n");
   //getchar();
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index 667b70dcaf9419a0be60308d7b80c6691562d1e4..28003f75db4b56c31c4a5ae035a9b57c47eca74f 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -40,6 +40,172 @@
 #endif
 #endif
 
+/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
+#define CONFIG_HLP_RFCFGF        "Configuration file for front-end (e.g. LMS7002M)\n"
+#define CONFIG_HLP_ULMAXE        "set the eNodeB max ULSCH erros\n"
+#define CONFIG_HLP_CALUER        "set UE RX calibration\n"
+#define CONFIG_HLP_CALUERM       ""
+#define CONFIG_HLP_CALUERB       ""
+#define CONFIG_HLP_DBGUEPR       "UE run normal prach power ramping, but don't continue random-access\n"
+#define CONFIG_HLP_CALPRACH      "UE run normal prach with maximum power, but don't continue random-access\n"
+#define CONFIG_HLP_NOL2CN        "bypass L2 and upper layers\n"
+#define CONFIG_HLP_UERXG         "set UE RX gain\n"
+#define CONFIG_HLP_UERXGOFF      "external UE amplifier offset\n"
+#define CONFIG_HLP_UETXG         "set UE TX gain\n"
+#define CONFIG_HLP_UENANTR       "set UE number of rx antennas\n"
+#define CONFIG_HLP_UENANTT       "set UE number of tx antennas\n"
+#define CONFIG_HLP_UESCAN        "set UE to scan around carrier\n"
+#define CONFIG_HLP_DUMPFRAME     "dump UE received frame to rxsig_frame0.dat and exit\n" 
+#define CONFIG_HLP_DLSHIFT       "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
+#define CONFIG_HLP_UELOOP        "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
+#define CONFIG_HLP_PHYTST        "test UE phy layer, mac disabled\n"
+#define CONFIG_HLP_DMAMAP        "sets flag for improved EXMIMO UE performance\n"  
+#define CONFIG_HLP_EXCCLK        "tells hardware to use an external clock reference\n"
+#define CONFIG_HLP_USIM          "use XOR autentication algo in case of test usim mode\n" 
+#define CONFIG_HLP_NOSNGLT       "Disables single-thread mode in lte-softmodem\n" 
+#define CONFIG_HLP_TADV          "Set timing_advance\n"
+#define CONFIG_HLP_DLF           "Set the downlink frequency for all component carriers\n"
+#define CONFIG_HLP_CHOFF         "Channel id offset"
+#define CONFIG_HLP_SOFTS         "Enable soft scope and L1 and L2 stats (Xforms)\n"
+#define CONFIG_HLP_EXMCAL        "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
+#define CONFIG_HLP_ITTIL         "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
+#define CONFIG_HLP_DLMCS         "Set the maximum downlink MCS\n"
+#define CONFIG_HLP_STMON         "Enable processing timing measurement of lte softmodem on per subframe basis \n"
+#define CONFIG_HLP_PRB           "Set the PRB, valid values: 6, 25, 50, 100  \n"    
+#define CONFIG_HLP_MSLOTS        "Skip the missed slots/subframes \n"    
+#define CONFIG_HLP_ULMCS         "Set the maximum uplink MCS\n"
+#define CONFIG_HLP_TDD           "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
+#define CONFIG_HLP_UE            "Set the lte softmodem as a UE\n"
+#define CONFIG_HLP_L2MONW        "Enable L2 wireshark messages on localhost \n"
+#define CONFIG_HLP_L2MONP        "Enable L2 pcap  messages on localhost \n"
+#define CONFIG_HLP_VCD           "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"
+#define CONFIG_HLP_TQFS          "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
+#define CONFIG_HLP_TPORT         "tracer port\n"
+#define CONFIG_HLP_NOTWAIT       "don't wait for tracer, start immediately\n"
+#define CONFIG_HLP_TNOFORK       "to ease debugging with gdb\n"
+
+
+/***************************************************************************************************************************************/
+/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument 
+   when calling config_get or config_getlist functions                                                                                 */
+
+
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters defining UE running mode                                              */
+/*   optname                     helpstr                paramflags                      XXXptr        defXXXval         type       numelt   */
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CMDLINE_UEMODEPARAMS_DESC {  \
+{"calib-ue-rx",                 CONFIG_HLP_CALUER,     0,		 iptr:&rx_input_level_dBm,   defintval:0,	 TYPE_INT,   0},    \
+{"calib-ue-rx-med",             CONFIG_HLP_CALUERM,    0,		 iptr:&rx_input_level_dBm,   defintval:0,	 TYPE_INT,   0},    \
+{"calib-ue-rx-byp",             CONFIG_HLP_CALUERB,    0,		 iptr:&rx_input_level_dBm,   defintval:0,	 TYPE_INT,   0},    \
+{"debug-ue-prach",              CONFIG_HLP_DBGUEPR,    PARAMFLAG_BOOL,   uptr:NULL,		     defuintval:1,	 TYPE_INT,   0},    \
+{"no-L2-connect",               CONFIG_HLP_NOL2CN,     PARAMFLAG_BOOL,   uptr:NULL,		     defuintval:1,	 TYPE_INT,   0},    \
+{"calib-prach-tx",              CONFIG_HLP_CALPRACH,   PARAMFLAG_BOOL,   uptr:NULL,		     defuintval:1,	 TYPE_INT,   0},    \
+{"loop-memory",                 CONFIG_HLP_UELOOP,     0,		 strptr:&loopfile,	     defstrval:"iqs.in", TYPE_STRING,0},    \
+{"ue-dump-frame",               CONFIG_HLP_DUMPFRAME,  PARAMFLAG_BOOL,   iptr:&dumpframe,	     defintval:0,	 TYPE_INT,   0},    \
+}  
+#define CMDLINE_CALIBUERX_IDX                   0
+#define CMDLINE_CALIBUERXMED_IDX                1
+#define CMDLINE_CALIBUERXBYP_IDX                2
+#define CMDLINE_DEBUGUEPRACH_IDX                3
+#define CMDLINE_NOL2CONNECT_IDX                 4
+#define CMDLINE_CALIBPRACHTX_IDX                5
+#define CMDLINE_MEMLOOP_IDX                     6
+#define CMDLINE_DUMPMEMORY_IDX                  7
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters specific to UE                                                                */
+/*   optname                     helpstr             paramflags                      XXXptr                  defXXXval       type          numelt   */
+/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CMDLINE_UEPARAMS_DESC {  \
+{"ue-rxgain",        	       CONFIG_HLP_UERXG,      0,		dblptr:&(rx_gain[0][0]),	    defdblval:0,    TYPE_DOUBLE,   0},     \
+{"ue-rxgain-off",    	       CONFIG_HLP_UERXGOFF,   0,		dblptr:&rx_gain_off,		    defdblval:0,    TYPE_DOUBLE,   0},     \
+{"ue-txgain",        	       CONFIG_HLP_UETXG,      0,		dblptr:&(tx_gain[0][0]),	    defdblval:0,    TYPE_DOUBLE,   0},     \
+{"ue-nb-ant-rx",     	       CONFIG_HLP_UENANTR,    0,		u8ptr:&nb_antenna_rx,		    defuintval:1,   TYPE_UINT8,    0},     \
+{"ue-nb-ant-tx",     	       CONFIG_HLP_UENANTT,    0,		u8ptr:&nb_antenna_tx,		    defuintval:1,   TYPE_UINT8,    0},     \
+{"ue-scan-carrier",  	       CONFIG_HLP_UESCAN,     PARAMFLAG_BOOL,	iptr:&UE_scan_carrier,  	    defintval:0,    TYPE_INT,	   0},     \
+{"ue-max-power",     	       NULL,		      0,		iptr:&(tx_max_power[0]),	    defintval:90,   TYPE_INT,	   0},     \
+{"r"  ,                        CONFIG_HLP_PRB,        0,                u8ptr:&(frame_parms[0]->N_RB_DL),   defintval:0,    TYPE_UINT8,    0},     \
+}
+
+
+extern int16_t dlsch_demod_shift;
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters common to eNodeB and UE                                                                                */
+/*   optname                     helpstr                paramflags                      XXXptr                  defXXXval                            type           numelt   */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CMDLINE_PARAMS_DESC {  \
+{"rf-config-file",        	 CONFIG_HLP_RFCFGF,	0,		  strptr:(char **)&rf_config_file,	defstrval:NULL, 		   TYPE_STRING,   sizeof(rf_config_file)}, \
+{"ulsch-max-errors",      	 CONFIG_HLP_ULMAXE,	0,		  uptr:&ULSCH_max_consecutive_errors,	defuintval:0,			   TYPE_UINT,	  0},			   \
+{"phy-test",              	 CONFIG_HLP_PHYTST,	PARAMFLAG_BOOL,   iptr:&phy_test,			defintval:0,			   TYPE_INT,	  0},			   \
+{"usim-test",             	 CONFIG_HLP_USIM,	PARAMFLAG_BOOL,   u8ptr:&usim_test,			defintval:0,			   TYPE_UINT8,    0},			   \
+{"mmapped-dma",           	 CONFIG_HLP_DMAMAP,	PARAMFLAG_BOOL,   uptr:&mmapped_dma,			defintval:0,			   TYPE_INT,	  0},			   \
+{"external-clock",        	 CONFIG_HLP_EXCCLK,	PARAMFLAG_BOOL,   uptr:&clock_source,			defintval:0,			   TYPE_INT,	  0},			   \
+{"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},			   \
+{"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},			   \
+{"a" ,  		  	 CONFIG_HLP_CHOFF,	0,		  iptr:&chain_offset,			defintval:0,			   TYPE_INT,	  0},			   \
+{"d" ,  		  	 CONFIG_HLP_SOFTS,	PARAMFLAG_BOOL,	  uptr:(uint32_t *)&do_forms,		defintval:0,			   TYPE_INT8,	  0},			   \
+{"E" ,  		  	 CONFIG_HLP_TQFS,	PARAMFLAG_BOOL,   i8ptr:&threequarter_fs,		defintval:0,			   TYPE_INT8,	  0},			   \
+{"K" ,  		  	 CONFIG_HLP_ITTIL,	PARAMFLAG_NOFREE, strptr:&itti_dump_file,		defstrval:"/tmp/itti.dump",	   TYPE_STRING,   0},			   \
+{"U" ,  		  	 CONFIG_HLP_UE, 	PARAMFLAG_BOOL,   i8ptr:&UE_flag,			defintval:0,			   TYPE_INT8,	  0},			   \
+{"m" ,  		  	 CONFIG_HLP_DLMCS,	0,		  uptr:&target_dl_mcs,  		defintval:0,			   TYPE_UINT,	  0},			   \
+{"t" ,  		  	 CONFIG_HLP_ULMCS,	0,		  uptr:&target_ul_mcs,  		defintval:0,			   TYPE_UINT,	  0},			   \
+{"W" ,  		  	 CONFIG_HLP_L2MONW,	0,		  strptr:(char **)&in_ip,		defstrval:"127.0.0.1",  	   TYPE_STRING,   sizeof(in_ip)},	   \
+{"P" ,  		  	 CONFIG_HLP_L2MONP,	0,		  strptr:(char **)&in_path,		defstrval:"/tmp/oai_opt.pcap",     TYPE_STRING,   sizeof(in_path)},	   \
+{"V" ,  		  	 CONFIG_HLP_VCD,	PARAMFLAG_BOOL,   iptr:&ouput_vcd,			defintval:0,			   TYPE_INT,	  0},			   \
+{"q" ,  		  	 CONFIG_HLP_STMON,	PARAMFLAG_BOOL,   iptr:&opp_enabled,			defintval:0,			   TYPE_INT,	  0},			   \
+{"S" ,  		  	 CONFIG_HLP_MSLOTS,	PARAMFLAG_BOOL,   u8ptr:&exit_missed_slots,		defintval:1,			   TYPE_UINT8,    0},			   \
+{"T" ,  		  	 CONFIG_HLP_TDD,	PARAMFLAG_BOOL,   iptr:&tddflag,			defintval:0,			   TYPE_INT,	  0}			   \
+}
+
+#define CONFIG_HLP_FLOG          "Enable online log \n"
+#define CONFIG_HLP_LOGL          "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
+#define CONFIG_HLP_LOGV          "Set the global log verbosity \n"
+#define CONFIG_HLP_TELN          "Start embedded telnet server \n"
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters for LOG utility                                                                                        */
+/*   optname                     helpstr                paramflags                      XXXptr                  defXXXval                            type           numelt   */
+/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CMDLINE_LOGPARAMS_DESC {  \
+{"R" ,  		  	 CONFIG_HLP_FLOG,	0,                uptr:&online_log_messages,		defintval:1,			   TYPE_INT,	  0},			   \
+{"g" ,  		  	 CONFIG_HLP_LOGL,	0,		  uptr:&glog_level,			defintval:0,			   TYPE_UINT,     0},			   \
+{"G" ,                           CONFIG_HLP_LOGV,	0,		  uptr:&glog_verbosity,		        defintval:0,			   TYPE_UINT16,   0},			   \
+{"telnetsrv",    		 CONFIG_HLP_TELN,	PARAMFLAG_BOOL,	  uptr:&start_telnetsrv,		defintval:0,			   TYPE_UINT,     0},			   \
+}
+#define CMDLINE_ONLINELOG_IDX     0 
+#define CMDLINE_GLOGLEVEL_IDX     1
+#define CMDLINE_GLOGVERBO_IDX     2              
+#define CMDLINE_STARTTELN_IDX     3
+
+
+extern int T_port;
+extern int T_nowait;
+extern int T_dont_fork;
+
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+/*                                            command line parameters for TTRACE utility                                                    */
+/*   optname                     helpstr                paramflags           XXXptr           defXXXval         type       numelt           */
+/*------------------------------------------------------------------------------------------------------------------------------------------*/
+#define CMDLINE_TTRACEPARAMS_DESC {  \
+{"T_port",                     CONFIG_HLP_TPORT,      0,		uptr:&T_port,	     defuintval:0,	TYPE_UINT,   0},	   \
+{"T_nowait",                   CONFIG_HLP_NOTWAIT,    PARAMFLAG_BOOL,	uptr:&T_nowait,      defuintval:0,	TYPE_UINT,   0},	   \
+{"T_dont_fork",                CONFIG_HLP_TNOFORK,    PARAMFLAG_BOOL,	uptr:&T_dont_fork,   defuintval:1,	TYPE_UINT,   0},	   \
+} 
+
+
+/***************************************************************************************************************************************/  
+/*  */
 extern pthread_cond_t sync_cond;
 extern pthread_mutex_t sync_mutex;
 extern int sync_var;
@@ -82,7 +248,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 fdeeaea9a527d71d8e609fc718d31981a24cb106..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,7 +720,9 @@ void *UE_thread(void *arg) {
     void* rxp[NB_ANTENNAS_RX], *txp[NB_ANTENNAS_TX];
     int start_rx_stream = 0;
     int i;
-    char threadname[128];
+    int th_id;
+
+    static uint8_t thread_idx = 0;
 
     cpu_set_t cpuset;
     CPU_ZERO(&cpuset);
@@ -761,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++)
@@ -773,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
@@ -790,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 ==
@@ -808,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++)
@@ -875,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);
@@ -888,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);
@@ -923,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) {
@@ -941,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);