diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index d112660f18caa2405edb249262e69ce088deedad..4f449fbc122f9c36980efdda99813cf345720a9f 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -632,6 +632,10 @@ add_boolean_option(MESSAGE_CHART_GENERATOR False         "For generating sequenc
 add_boolean_option(MESSAGE_CHART_GENERATOR_RLC_MAC False "trace RLC-MAC exchanges in sequence diagrams")
 add_boolean_option(MESSAGE_CHART_GENERATOR_PHY     False "trace some PHY exchanges in sequence diagrams")
 
+add_boolean_option(UE_EXPANSION             False         "enable UE_EXPANSION with max 256 UE")
+add_boolean_option(PHY_TX_THREAD            False         "enable UE_EXPANSION with max 256 UE")
+add_boolean_option(PRE_SCD_THREAD           False         "enable UE_EXPANSION with max 256 UE")
+
 ########################
 # Include order
 ##########################
@@ -1093,6 +1097,7 @@ set(PHY_SRC_COMMON
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/prach_common.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pucch_common.c
   ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_scrambling.c
+  ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_gold_generic.c
   ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/srs_modulation.c
   ${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
   ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c
@@ -1334,6 +1339,7 @@ set (MAC_SRC
   ${MAC_DIR}/eNB_scheduler_bch.c
   ${MAC_DIR}/eNB_scheduler_primitives.c
   ${MAC_DIR}/eNB_scheduler_RA.c
+  ${MAC_DIR}/eNB_scheduler_fairRR.c
   ${MAC_DIR}/eNB_scheduler_phytest.c
   ${MAC_DIR}/pre_processor.c
   ${MAC_DIR}/config.c
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 0994acdf9de168ddf746784ad837f23dcda68001..e2ea056ea17c1ab0a31c597d057eaf01bb9426a9 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
@@ -49,7 +49,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -24;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
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 5e8cd8007ea7550c2838aac43ae21aad78b18c0d..b2ac3ccf4224581389dc09d43d992ea4039bf502 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
@@ -49,7 +49,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -24;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
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 53eae1d531f80bd133b6ba5060262fa452c5145e..006d59d2a54ca908d9b2dde9fb9141b9cf086bb5 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
@@ -49,7 +49,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -24;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
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 d30a57041c1818b9fb1abd96a9f630abfc10bac0..8c76d95d4c86d978198e922168888d368838b6fa 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
@@ -49,7 +49,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -24;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
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 e90eb3fe518c751e471632f30400026d9a0ce1e3..0d2bb27dcc7c18c3b8446699a87357a529567611 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
@@ -49,7 +49,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -24;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
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 5dbecd3813f90eabcd4568d2dc3c2116c6726d5c..c418f355f20903326675577272da21d6dc8230e1 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
@@ -49,7 +49,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 0;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -24;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
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 1397184cc7994da3aa3d41c6d977aa3d53998a5d..89e06d2b1e4511f212507069db0d074b87adeb9f 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
@@ -49,7 +49,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -29;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
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 caebb36eb27af79b81f4d5e97775e308673f2045..c8e6c861e0fddc61ec4a0cb7c9ce169bb36eaf20 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
@@ -49,7 +49,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -29;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
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 fe90cdb338f1796733f554999c79ff71497d357e..cc00f4f3ea584d662e58bfdeb7f95ea3073bc9ac 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
@@ -49,7 +49,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -29;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
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 5d9027ce150c8926b8bdedaf833b87cddc5536cf..6e1e776fed0da4bf219f6525b82db0accd8be758 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
@@ -49,7 +49,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -29;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
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 539f0bd744cf91222e11f0a3467eaa3f8f319f25..7e7c3c185d41be1f6b7ed09fca0cec75d7fd3e85 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
@@ -49,7 +49,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -29;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
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 58b088002fb37a396183cc6a51ef455d2aee6862..3098660c8de40e967d5e4adf7dc870b31d3ee1c3 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
@@ -49,7 +49,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -29;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index b1fc933e966979b4c67601ba7e57dcf256168cb5..9cfe6941a28968e6148b5d617f669ccb0a360fe9 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -42,6 +42,7 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf
 
 MSC_GEN="False"
 XFORMS="True"
+UE_EXPANSION="False"
 PRINT_STATS="False"
 VCD_TIMING="False"
 DEADLINE_SCHEDULER_FLAG_USER="False"
@@ -214,8 +215,12 @@ function main() {
             UE=1
             echo_info "Will compile UE"
             shift;;
+       --mu)
+            UE_EXPANSION="True"
+            echo_info "Will compile with UE_EXPANSION"
+            shift;;
        --UE-conf-nvram)
-            conf_nvram_path=$(readlink -f "$1")
+            conf_nvram_path=$(readlink -f $2)
             shift 2;;
         --UE-gen-nvram)
             gen_nvram_path=$(readlink -f $2)
@@ -540,6 +545,9 @@ function main() {
     echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
     echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >>  $cmake_file
     echo "set ( XFORMS $XFORMS )"                  >>  $cmake_file
+    echo "set ( UE_EXPANSION $UE_EXPANSION )"      >>  $cmake_file
+    echo "set ( PHY_TX_THREAD $UE_EXPANSION )"     >>  $cmake_file
+    echo "set ( PRE_SCD_THREAD $UE_EXPANSION )"    >>  $cmake_file
     echo "set ( RRC_ASN1_VERSION \"${REL}\")"      >>  $cmake_file
     echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )"     >>  $cmake_file
     echo "set ( RF_BOARD \"${HW}\")"               >>  $cmake_file
@@ -707,6 +715,9 @@ function main() {
     echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
     echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >>  $cmake_file
     echo "set ( XFORMS $XFORMS )" >>  $cmake_file
+    echo "set ( UE_EXPANSION $UE_EXPANSION )"      >>  $cmake_file
+    echo "set ( PHY_TX_THREAD $UE_EXPANSION )"     >>  $cmake_file
+    echo "set ( PRE_SCD_THREAD $UE_EXPANSION )"    >>  $cmake_file
     echo "set ( PRINT_STATS $PRINT_STATS )" >>  $cmake_file
     echo "set ( RRC_ASN1_VERSION \"${REL}\")" >>  $cmake_file
     echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >>  $cmake_file
@@ -794,6 +805,9 @@ function main() {
     cp $DIR/oaisim_mme_build_oai/CMakeLists.template $cmake_file
     echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file
     echo "set ( XFORMS $XFORMS )" >>  $cmake_file
+    echo "set ( UE_EXPANSION $UE_EXPANSION )"      >>  $cmake_file
+    echo "set ( PHY_TX_THREAD $UE_EXPANSION )"     >>  $cmake_file
+    echo "set ( PRE_SCD_THREAD $UE_EXPANSION )"    >>  $cmake_file
     echo "set ( RRC_ASN1_VERSION \"${REL}\")" >>  $cmake_file
     echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >>  $cmake_file
     echo "set ( T_TRACER $T_TRACER )"        >>  $cmake_file
diff --git a/cmake_targets/tools/init_nas_nos1 b/cmake_targets/tools/init_nas_nos1
index f7347e55083c19c85e7a51f5b159a389808d2afa..5766020d70629c7d17f9b1dbc57786705838c272 100755
--- a/cmake_targets/tools/init_nas_nos1
+++ b/cmake_targets/tools/init_nas_nos1
@@ -48,7 +48,7 @@ if [ "$1" = "eNB" ]; then
 else
     if [ "$1" = "UE" ]; then 
        echo "bring up oai0 interface for UE"
-       sudo ifconfig oai0 10.0.1.9 netmask 255.255.255.0 broadcast 10.0.1.255
+       sudo ifconfig oai0 10.0.1.2 netmask 255.255.255.0 broadcast 10.0.1.255
        $OPENAIR_DIR/targets/bin/rb_tool -a -c0 -i0 -z0 -s 10.0.1.2 -t 10.0.1.1 -r 1
     fi
 fi  
diff --git a/cmake_targets/tools/init_nas_s1 b/cmake_targets/tools/init_nas_s1
old mode 100644
new mode 100755
diff --git a/common/utils/hashtable/hashtable.c b/common/utils/hashtable/hashtable.c
index 6322b1dea634b7063f6057e339b8fbde2fe7b652..2c7b35744ca7cf766044f7efc2341aff5b9a2fb5 100644
--- a/common/utils/hashtable/hashtable.c
+++ b/common/utils/hashtable/hashtable.c
@@ -95,7 +95,7 @@ hash_table_t *hashtable_create(const hash_size_t sizeP, hash_size_t (*hashfuncP)
  * Cleanup
  * The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the hash_table_t.
  */
-hashtable_rc_t hashtable_destroy(hash_table_t * const hashtblP)
+hashtable_rc_t hashtable_destroy(hash_table_t * hashtblP)
 {
     hash_size_t n;
     hash_node_t *node, *oldnode;
@@ -117,6 +117,7 @@ hashtable_rc_t hashtable_destroy(hash_table_t * const hashtblP)
     }
     free(hashtblP->nodes);
     free(hashtblP);
+    hashtblP=NULL;
     return HASH_TABLE_OK;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
diff --git a/common/utils/itti/assertions.h b/common/utils/itti/assertions.h
index bb6c27cbab358db0b8ed54478beb70d4110ce8ed..803c3d001e7853520cc57573634474d203bc7abf 100644
--- a/common/utils/itti/assertions.h
+++ b/common/utils/itti/assertions.h
@@ -35,9 +35,11 @@
 #ifndef ASSERTIONS_H_
 #define ASSERTIONS_H_
 
+void output_log_mem(void);
 #define _Assert_Exit_                           \
 {                                               \
     fprintf(stderr, "\nExiting execution\n");   \
+    output_log_mem();                           \
     display_backtrace();                        \
     fflush(stdout);                             \
     fflush(stderr);                             \
diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c
index 21a3304e202b6910ce27145b5c807c72b4552912..05e5e8c3dc224242b09518394acf255c63150bd8 100644
--- a/common/utils/itti/intertask_interface.c
+++ b/common/utils/itti/intertask_interface.c
@@ -736,6 +736,15 @@ void itti_mark_task_ready(task_id_t task_id)
   /* Mark the thread as using LFDS queue */
   lfds611_queue_use(itti_desc.tasks[task_id].message_queue);
 
+#if defined(UE_EXPANSION) || defined(RTAI)
+  /* Assign low priority to created threads */
+  {
+    struct sched_param sched_param;
+    sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO) + 1;
+    sched_setscheduler(0, SCHED_FIFO, &sched_param);
+  }
+#endif
+
   itti_desc.threads[thread_id].task_state = TASK_STATE_READY;
   itti_desc.ready_tasks ++;
 
diff --git a/common/utils/itti/signals.c b/common/utils/itti/signals.c
index 9767ba3f67b01a29166c07ce86bae598317905e0..4804e6b731206914a47d02348a1a0796f31e31eb 100644
--- a/common/utils/itti/signals.c
+++ b/common/utils/itti/signals.c
@@ -117,16 +117,19 @@ int signal_handle(int *end)
     case SIGUSR1:
       SIG_DEBUG("Received SIGUSR1\n");
       *end = 1;
+      output_log_mem();
       break;
 
     case SIGSEGV:   /* Fall through */
     case SIGABRT:
       SIG_DEBUG("Received SIGABORT\n");
+      output_log_mem();
       backtrace_handle_signal(&info);
       break;
 
     case SIGINT:
       printf("Received SIGINT\n");
+      output_log_mem();
       itti_send_terminate_message(TASK_UNKNOWN);
       *end = 1;
       break;
diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c
index dee4e8d310023fba1c22cc073800c1c2c1f2003c..09f37b994567f4664134cb99cf314f41819cd606 100644
--- a/nfapi/oai_integration/nfapi_pnf.c
+++ b/nfapi/oai_integration/nfapi_pnf.c
@@ -871,7 +871,11 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request
         AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
         LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0];
         //LTE_eNB_DLSCH_t *dlsch1 = eNB->dlsch[UE_id][1];
-        int harq_pid = dlsch0->harq_ids[sf];
+        int harq_pid = dlsch0->harq_ids[sfn%2][sf];
+        if(harq_pid >= dlsch0->Mdlharq) {
+          LOG_E(PHY,"pnf_phy_dl_config_req illegal harq_pid %d\n", harq_pid);
+          return(-1);
+        }
         uint8_t *dlsch_sdu = tx_pdus[UE_id][harq_pid];
         
         memcpy(dlsch_sdu, tx_pdu->segments[0].segment_data, tx_pdu->segments[0].segment_length);
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
index f665d11c8916f2ce82cea65080f3fad005284e4c..282739e31597782fd46a1e5e50f154d01c801708 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_interface.h
@@ -1308,7 +1308,7 @@ typedef struct {
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint16_t transmission_power;
 } nfapi_dl_config_bch_pdu_rel8_t;
 #define NFAPI_DL_CONFIG_REQUEST_BCH_PDU_REL8_TAG 0x2004
@@ -1320,7 +1320,7 @@ typedef struct {
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint16_t rnti;
 	uint8_t resource_allocation_type;
 	uint32_t resource_block_coding;
@@ -1344,7 +1344,7 @@ typedef struct {
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint16_t rnti;
 	uint8_t resource_allocation_type;
 	uint8_t virtual_resource_block_assignment_flag;
@@ -1429,7 +1429,7 @@ typedef struct {
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint16_t p_rnti;
 	uint8_t resource_allocation_type;
 	uint8_t virtual_resource_block_assignment_flag;
@@ -1595,7 +1595,7 @@ typedef struct {
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint16_t transmission_power;
 	uint16_t hyper_sfn_2_lsbs;
 } nfapi_dl_config_nbch_pdu_rel13_t;
@@ -1609,7 +1609,7 @@ typedef struct {
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint8_t ncce_index;
 	uint8_t aggregation_level;
 	uint8_t start_symbol;
@@ -1642,7 +1642,7 @@ typedef struct {
 typedef struct {
 	nfapi_tl_t tl;
 	uint16_t length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint8_t start_symbol;
 	uint8_t rnti_type;
 	uint16_t rnti;
@@ -2218,6 +2218,7 @@ typedef struct {
 	uint8_t dl_assignment_index;
 	uint32_t tpc_bitmap;
 	uint16_t transmission_power;
+	uint8_t harq_pid;
 } nfapi_hi_dci0_dci_pdu_rel8_t;
 #define NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG 0x2020
 
@@ -2361,7 +2362,7 @@ typedef struct {
 #define NFAPI_TX_MAX_SEGMENTS 32
 typedef struct {
 	uint16_t pdu_length;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 	uint8_t num_segments;
 	struct {
 		uint32_t segment_length;
@@ -2902,7 +2903,7 @@ typedef struct {
 
 typedef struct {
 	uint8_t sub_error_code;
-	uint16_t pdu_index;
+	int16_t pdu_index;
 } nfapi_error_indication_msg_tx_err;
 
 // 
diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c
index 55ac76d2f6e8002457d173c34301c2f6a43cf73c..b9522e050ce34b570f507598d28c20aa8bcb790e 100644
--- a/openair1/PHY/INIT/lte_init.c
+++ b/openair1/PHY/INIT/lte_init.c
@@ -259,7 +259,7 @@ void phy_config_request(PHY_Config_t *phy_config) {
   AssertFatal(fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0] > 0,
 	      "prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]==0\n");
 #else
-  LOG_E(PHY,"***DJP*** removed assert on preamble fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]:%d expecting >0 %s:%d\n\n\n", fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], __FILE__, __LINE__);
+  LOG_D(PHY,"***DJP*** removed assert on preamble fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0]:%d expecting >0 %s:%d\n\n\n", fp->prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[0], __FILE__, __LINE__);
 #endif
   fp->prach_emtc_config_common.prach_ConfigInfo.prach_ConfigIndex[0]                     = cfg->emtc_config.prach_ce_level_0_configuration_index.value;
   fp->prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[0]                      = cfg->emtc_config.prach_ce_level_0_frequency_offset.value;
@@ -471,7 +471,7 @@ void phy_config_sib2_eNB(uint8_t Mod_id,
 }
 */
 
-void phy_config_sib13_eNB(uint8_t Mod_id,int CC_id,int mbsfn_Area_idx,
+void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx,
                           long mbsfn_AreaId_r9)
 {
 
@@ -491,8 +491,7 @@ void phy_config_sib13_eNB(uint8_t Mod_id,int CC_id,int mbsfn_Area_idx,
 
 void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB)
 {
-
-  uint8_t UE_id;
+  uint16_t UE_id;
   struct PhysicalConfigDedicated *physicalConfigDedicated;
   LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
 
diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c
index b06e4c40af772f457fafa47852b7a7aba38747ef..c6ac0819cd615fbe9f3ab22ed0f0d57c88bbab53 100644
--- a/openair1/PHY/INIT/lte_init_ru.c
+++ b/openair1/PHY/INIT/lte_init_ru.c
@@ -109,7 +109,7 @@ int phy_init_RU(RU_t *ru) {
     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);
+    LOG_D(PHY,"[INIT] %s() RC.nb_L1_inst:%d \n", __FUNCTION__, RC.nb_L1_inst);
 
     for (i=0; i<RC.nb_L1_inst; i++) {
       for (p=0;p<15;p++) {
diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c
index f8fc634b94b9e4d78e7491a928b885132ab5a953..8b6acc65f0ed15145a1b782cbe537bf8165190a4 100644
--- a/openair1/PHY/INIT/lte_init_ue.c
+++ b/openair1/PHY/INIT/lte_init_ue.c
@@ -37,7 +37,7 @@
 uint8_t dmrs1_tab_ue[8] = {0,2,3,4,6,8,9,10};
 extern uint8_t nfapi_mode;
 
-void phy_config_sib1_ue(uint8_t Mod_id,int CC_id,
+void phy_config_sib1_ue(module_id_t Mod_id,int CC_id,
                         uint8_t eNB_id,
                         TDD_Config_t *tdd_Config,
                         uint8_t SIwindowsize,
@@ -55,7 +55,7 @@ void phy_config_sib1_ue(uint8_t Mod_id,int CC_id,
   fp->SIPeriod      = SIperiod;
 }
 
-void phy_config_sib2_ue(uint8_t Mod_id,int CC_id,
+void phy_config_sib2_ue(module_id_t Mod_id,int CC_id,
                         uint8_t eNB_id,
                         RadioResourceConfigCommonSIB_t *radioResourceConfigCommon,
                         ARFCN_ValueEUTRA_t *ul_CarrierFreq,
@@ -179,7 +179,7 @@ void phy_config_sib2_ue(uint8_t Mod_id,int CC_id,
 
 }
 
-void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx,
+void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx,
                          long mbsfn_AreaId_r9)
 {
 
@@ -201,7 +201,7 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_
 /*
  * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover
  */
-void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed)
+void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed)
 {
 
   if(mobilityControlInfo!=NULL) {
@@ -324,7 +324,7 @@ void phy_config_afterHO_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobility
   }
 }
 
-void phy_config_meas_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id)
+void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8_t n_adj_cells,unsigned int *adj_cell_id)
 {
 
   PHY_MEASUREMENTS *phy_meas = &PHY_vars_UE_g[Mod_id][CC_id]->measurements;
@@ -353,7 +353,7 @@ void phy_config_dedicated_scell_ue(uint8_t Mod_id,
 #endif
 
 
-void phy_config_harq_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
+void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
                         uint16_t max_harq_tx )
 {
 
@@ -363,7 +363,7 @@ void phy_config_harq_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
 
 extern uint16_t beta_cqi[16];
 
-void phy_config_dedicated_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,
+void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,
                              struct PhysicalConfigDedicated *physicalConfigDedicated )
 {
 
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
index 2b7873cc29658acfcd83a9a83b278a22eb77be95..e268a5b061c0e06031681909be23cfbb4acc87cd 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c
@@ -34,7 +34,7 @@
 
 void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
                       PHY_VARS_UE *ue,
-                      unsigned char eNB_id,
+                      module_id_t eNB_id,
 					  uint8_t subframe,
                       unsigned char clear,
                       short coef)
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
index 3bf4c40adeab61602225124d9d53d8f3ff73e851..f893b70baf7bf42f2d828fa8edef06c9470c12ae 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_eNB.c
@@ -112,7 +112,7 @@ int lte_est_timing_advance(LTE_DL_FRAME_PARMS *frame_parms,
 }
 
 
-int lte_est_timing_advance_pusch(PHY_VARS_eNB* eNB,uint8_t UE_id)
+int lte_est_timing_advance_pusch(PHY_VARS_eNB* eNB,module_id_t UE_id)
 {
   int temp, i, aa, max_pos=0, max_val=0;
   short Re,Im;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
index 06ef4a5d1a16fd68083c4f03b973ed5a215ef079..74d6248d1502029b7d0001a155bb306690f8a904 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c
@@ -35,7 +35,7 @@
 
 void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms,
                       PHY_VARS_UE *ue,
-                      unsigned char eNB_id,
+                      module_id_t eNB_id,
 					  uint8_t subframe,
                       unsigned char clear,
                       short coef)
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 8d1fb20d6b79b828130666254a629c9cd255b355..a406e246a6264066c299669fe3df5ddf7d1f7c97 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c
@@ -28,7 +28,7 @@
 //#define DEBUG_BF_CH
 
 int lte_dl_bf_channel_estimation(PHY_VARS_UE *phy_vars_ue,
-                                 uint8_t eNB_id,
+                                 module_id_t eNB_id,
                                  uint8_t eNB_offset,
                                  unsigned char Ns,
                                  unsigned char p,
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
index a72563f7e6d58754111b3657ea50ec7fa7230576..f7c4a3ead3156cb0b2e49ad7db1b837d6ecd5ec6 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.c
@@ -29,7 +29,7 @@
 #include "SCHED_UE/sched_UE.h"
 
 int lte_dl_channel_estimation(PHY_VARS_UE *ue,
-                              uint8_t eNB_id,
+                              module_id_t eNB_id,
                               uint8_t eNB_offset,
                               unsigned char Ns,
                               unsigned char p,
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 c4fc80a8c11635868e1a7d97590ff048553500ef..1a0611b9626ac960b6c228d798b72c4c8369b543 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.c
@@ -26,7 +26,7 @@
 
 //#define DEBUG_CH
 int lte_dl_mbsfn_channel_estimation(PHY_VARS_UE *ue,
-                                    uint8_t eNB_id,
+                                    module_id_t eNB_id,
                                     uint8_t eNB_offset,
                                     int subframe,
                                     unsigned char l)
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
index b416ff9e79ba3148552b8f57c1931ebfdad4b9a4..a881773910c70a2719fc47cd178d786372e23e93 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
@@ -34,7 +34,7 @@ int32_t rx_power_avg_eNB[3];
 
 void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
 			     int subframe,
-                             unsigned char eNB_id,
+                             module_id_t eNB_id,
                              unsigned char clear)
 {
 
@@ -115,8 +115,8 @@ void lte_eNB_I0_measurements(PHY_VARS_eNB *eNB,
 }
 
 void lte_eNB_srs_measurements(PHY_VARS_eNB *eNB,
-                              unsigned char eNB_id,
-                              unsigned char UE_id,
+                              module_id_t eNB_id,
+                              module_id_t UE_id,
                               unsigned char init_averaging)
 {
   LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
index 199fc2d846def40512bf97215c6e43928d082cfc..bf228021452834bb65f3dddf8bfa3a168b367c95 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ue_measurements.c
@@ -55,7 +55,7 @@ void print_ints(char *s,int *x)
 
 }
 
-int16_t get_PL(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+int16_t get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 {
 
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
@@ -81,7 +81,7 @@ int16_t get_PL(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 }
 
 
-uint8_t get_n_adj_cells (uint8_t Mod_id,uint8_t CC_id)
+uint8_t get_n_adj_cells (module_id_t Mod_id,uint8_t CC_id)
 {
 
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
@@ -92,7 +92,7 @@ uint8_t get_n_adj_cells (uint8_t Mod_id,uint8_t CC_id)
     return 0;
 }
 
-uint32_t get_rx_total_gain_dB (uint8_t Mod_id,uint8_t CC_id)
+uint32_t get_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id)
 {
 
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
@@ -102,7 +102,7 @@ uint32_t get_rx_total_gain_dB (uint8_t Mod_id,uint8_t CC_id)
 
   return 0xFFFFFFFF;
 }
-uint32_t get_RSSI (uint8_t Mod_id,uint8_t CC_id)
+uint32_t get_RSSI (module_id_t Mod_id,uint8_t CC_id)
 {
 
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
@@ -112,7 +112,7 @@ uint32_t get_RSSI (uint8_t Mod_id,uint8_t CC_id)
 
   return 0xFFFFFFFF;
 }
-double get_RSRP(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+double get_RSRP(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 {
 
   AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is null\n");
@@ -128,7 +128,7 @@ double get_RSRP(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
   return -140.0;
 }
 
-uint32_t get_RSRQ(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+uint32_t get_RSRQ(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 {
 
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
@@ -139,7 +139,7 @@ uint32_t get_RSRQ(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
   return 0xFFFFFFFF;
 }
 
-int8_t set_RSRP_filtered(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrp)
+int8_t set_RSRP_filtered(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrp)
 {
 
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
@@ -153,7 +153,7 @@ int8_t set_RSRP_filtered(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rs
   return -1;
 }
 
-int8_t set_RSRQ_filtered(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrq)
+int8_t set_RSRQ_filtered(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,float rsrq)
 {
 
   PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
index 74ef6798c78c57baaada40d1044b137988a60774..2d3acfce9b1f678b31e4a7fd5be285e808fbdafd 100644
--- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
+++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
@@ -37,7 +37,7 @@ static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32
 
 int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB,
 				  eNB_rxtx_proc_t *proc,
-                                  uint8_t UE_id,
+                                  module_id_t UE_id,
                                   unsigned char l,
                                   unsigned char Ns) {
 
diff --git a/openair1/PHY/LTE_REFSIG/lte_gold.c b/openair1/PHY/LTE_REFSIG/lte_gold.c
index 78fae8b8f3304a69a1d2c0d67cac522e08209135..c5e48d83643a7782ff43e49dc12ffd827c258ef5 100644
--- a/openair1/PHY/LTE_REFSIG/lte_gold.c
+++ b/openair1/PHY/LTE_REFSIG/lte_gold.c
@@ -44,7 +44,6 @@ N_{ID}^{cell = 0..503
 
 void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14],uint16_t Nid_cell)
 {
-
   unsigned char ns,l,Ncp=1-frame_parms->Ncp;
   unsigned int n,x1,x2;//,x1tmp,x2tmp;
 
@@ -54,7 +53,7 @@ void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14]
 
       x2 = Ncp +
            (Nid_cell<<1) +
-	(((1+(Nid_cell<<1))*(1 + (((frame_parms->Ncp==0)?4:3)*l) + (7*(1+ns))))<<10); //cinit
+       (((1+(Nid_cell<<1))*(1 + (((frame_parms->Ncp==0)?4:3)*l) + (7*(1+ns))))<<10); //cinit
       //x2 = frame_parms->Ncp + (Nid_cell<<1) + (1+(Nid_cell<<1))*(1 + (3*l) + (7*(1+ns))); //cinit
       //n = 0
       x1 = 1+ (1<<31);
@@ -81,7 +80,7 @@ void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14]
   }
 }
 
-void lte_gold_ue_spec(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_cell, uint16_t *n_idDMRS)
+void lte_gold_ue_spec(uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_cell, uint16_t *n_idDMRS)
 {
 
   unsigned char ns,l;
@@ -169,41 +168,6 @@ void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_
   }
 }
 
-/*! \brief gold sequenquence generator
-\param x1
-\param x2 this should be set to c_init if reset=1
-\param reset resets the generator
-\return 32 bits of the gold sequence
-*/
-unsigned int lte_gold_generic(unsigned int *x1, unsigned int *x2, unsigned char reset)
-{
-  int n;
-
-  if (reset) {
-    *x1 = 1+ (1<<31);
-    *x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
-
-    // skip first 50 double words (1600 bits)
-    //      printf("n=0 : x1 %x, x2 %x\n",x1,x2);
-    for (n=1; n<50; n++) {
-      *x1 = (*x1>>1) ^ (*x1>>4);
-      *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
-      *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
-      *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
-    }
-  }
-
-  *x1 = (*x1>>1) ^ (*x1>>4);
-  *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
-  *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
-  *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
-  return(*x1^*x2);
-  //  printf("n=%d : c %x\n",n,x1^x2);
-
-}
-
-
-
 #ifdef LTE_GOLD_MAIN
 main()
 {
diff --git a/openair1/PHY/LTE_REFSIG/lte_refsig.h b/openair1/PHY/LTE_REFSIG/lte_refsig.h
index 27788e5e1a92c2266b23cad399af48f2506a2580..1bac0d14fc8322e26bf8ca519e28e653685b1554 100644
--- a/openair1/PHY/LTE_REFSIG/lte_refsig.h
+++ b/openair1/PHY/LTE_REFSIG/lte_refsig.h
@@ -36,7 +36,7 @@
 \param reset resets the generator
 \return 32 bits of the gold sequence
 */
-unsigned int lte_gold_generic(unsigned int *x1, unsigned int *x2, unsigned char reset);
+uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset);
 
 
 /*!\brief This function generates the LTE Gold sequence (36-211, Sec 7.2), specifically for DL reference signals.
@@ -45,8 +45,7 @@ unsigned int lte_gold_generic(unsigned int *x1, unsigned int *x2, unsigned char
 @param Nid_cell Cell Id (to compute sequences for local and adjacent cells) */
 
 void lte_gold(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table[20][2][14],uint16_t Nid_cell);
-
-void lte_gold_ue_spec(LTE_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_cell, uint16_t *n_idDMRS);
+void lte_gold_ue_spec(uint32_t lte_gold_uespec_table[2][20][2][21],uint16_t Nid_cell, uint16_t *n_idDMRS);
 
 void lte_gold_ue_spec_port5(uint32_t lte_gold_uespec_port5_table[20][38],uint16_t Nid_cell, uint16_t n_rnti);
 
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 048eb200683208c4f624cd497da72355c58084ef..47ad00f099d10737c2441d16738d020cf4c644da 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -48,10 +48,10 @@
 #include "dci_tools_common_extern.h"
 #include "transport_proto.h"
 
-int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
+int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
 {
-  uint8_t i;
-  int8_t first_free_index=-1;
+  uint16_t i;
+  int16_t first_free_index=-1;
 
   AssertFatal(eNB!=NULL,"eNB is null\n");
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
@@ -68,10 +68,10 @@ int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
   return first_free_index;
 }
 
-int8_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
+int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
 {
-  uint8_t i;
-  int8_t first_free_index=-1;
+  uint16_t i;
+  int16_t first_free_index=-1;
 
   AssertFatal(eNB!=NULL,"eNB is null\n");
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
@@ -265,8 +265,12 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
   if ((rel8->rnti_type == 2 ) && (rel8->rnti != SI_RNTI) && (rel8->rnti != P_RNTI)) dci_alloc->ra_flag = 1;
 
   UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
-  AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
-  AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+  if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){
+    LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel8->rnti,UE_id);
+    return;
+  }
+  //AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
+  //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];
 
@@ -298,7 +302,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
   }
   dlsch0_harq->ndi = rel8->new_data_indicator_1;
 
+#ifdef PHY_TX_THREAD
+  dlsch0->active[subframe]        = 1;
+#else
   dlsch0->active        = 1;
+#endif
   if (rel8->rnti_type == 2)
       dlsch0_harq->round    = 0;
 
@@ -475,10 +483,14 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
     dlsch0_harq->mcs             = rel8->mcs_1;
     dlsch0_harq->Qm              = 2;
     dlsch0_harq->TBS             = TBStable[I_mcs][NPRB-1];
-    dlsch0->harq_ids[subframe]   = rel8->harq_process;
+    dlsch0->harq_ids[frame%2][subframe]   = rel8->harq_process;
+#ifdef PHY_TX_THREAD
+    dlsch0->active[subframe]     = 1;
+#else
     dlsch0->active               = 1;
+#endif
     dlsch0->rnti                 = rel8->rnti;
-    dlsch0->harq_ids[subframe]   = rel8->harq_process;
+    //dlsch0->harq_ids[subframe]   = rel8->harq_process;
     if (dlsch0_harq->round == 0)
       dlsch0_harq->status = ACTIVE;
 
@@ -490,7 +502,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
   case NFAPI_DL_DCI_FORMAT_1:
 
     dci_alloc->format           = format1;
+#ifdef PHY_TX_THREAD
+    dlsch0->active[subframe]    = 1;
+#else
     dlsch0->active              = 1;
+#endif
 
     LOG_D(PHY,"SFN/SF:%04d%d proc:TX:SFN/SF:%04d%d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",frame,subframe,proc->frame_tx,subframe,rel8->harq_process);
 
@@ -635,7 +651,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
 
     dlsch0_harq->dl_power_off = 1;
 
+#ifdef PHY_TX_THREAD
+    dlsch0->active[subframe] = 1;
+#else
     dlsch0->active = 1;
+#endif
 
 
 
@@ -651,7 +671,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
     }
 
     LOG_D(PHY,"DCI: Set harq_ids[%d] to %d (%p)\n",subframe,rel8->harq_process,dlsch0);
-    dlsch0->harq_ids[subframe] = rel8->harq_process;
+    dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process;
 
     dlsch0->harq_mask          |= (1<<rel8->harq_process);
 
@@ -818,8 +838,8 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
 
     dlsch0->subframe_tx[subframe] = 1;
 
-    dlsch0->harq_ids[subframe] = rel8->harq_process;
-    dlsch1->harq_ids[subframe] = rel8->harq_process;
+    dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process;
+    dlsch1->harq_ids[frame%2][subframe] = rel8->harq_process;
     //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);
 
 
@@ -846,19 +866,32 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
     // assume both TBs are active
     dlsch0_harq->Nl        = 1;
     dlsch1_harq->Nl        = 1;
+#ifdef PHY_TX_THREAD
+    dlsch0->active[subframe] = 1;
+    dlsch1->active[subframe] = 1;
+#else
     dlsch0->active = 1;
     dlsch1->active = 1;
+#endif
     dlsch0->harq_mask                         |= (1<<rel8->harq_process);
     dlsch1->harq_mask                         |= (1<<rel8->harq_process);
 
     // check if either TB is disabled (see 36-213 V11.3 Section )
     if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
+#ifdef PHY_TX_THREAD
+      dlsch0->active[subframe] = 0;
+#else
       dlsch0->active = 0;
+#endif
       dlsch0->harq_mask                         &= ~(1<<rel8->harq_process);
     }
 
     if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
+#ifdef PHY_TX_THREAD
+      dlsch1->active[subframe]= 0;
+#else
       dlsch1->active = 0;
+#endif
       dlsch1->harq_mask                         &= ~(1<<rel8->harq_process);
     }
 
@@ -870,8 +903,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
       dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
       dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
 
+#ifdef PHY_TX_THREAD
+      if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) {
+#else
       if ((dlsch0->active==1) && (dlsch1->active==1)) {
-
+#endif
         dlsch0_harq->mimo_mode = LARGE_CDD;
         dlsch1_harq->mimo_mode = LARGE_CDD;
         dlsch0_harq->dl_power_off = 1;
@@ -881,7 +917,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
         dlsch1_harq->mimo_mode   = ALAMOUTI;
       }
     } else if (fp->nb_antenna_ports_eNB == 4) { // 4 antenna case
+#ifdef PHY_TX_THREAD
+      if ((dlsch0->active[subframe]==1) && (dlsch1->active[subframe]==1)) {
+#else
       if ((dlsch0->active==1) && (dlsch1->active==1)) {
+#endif
         switch (rel8->precoding_information) {
         case 0: // one layer per transport block
           dlsch0_harq->mimo_mode   = LARGE_CDD;
@@ -921,7 +961,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
           LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
           break;
         }
+#ifdef PHY_TX_THREAD
+      } else if (dlsch0->active[subframe] == 1) {
+#else
       } else if (dlsch0->active == 1) {
+#endif
         switch (rel8->precoding_information) {
         case 0: // one layer per transport block
           dlsch0_harq->mimo_mode   = ALAMOUTI;
@@ -941,7 +985,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
           LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",rel8->precoding_information);
           break;
         }
+#ifdef PHY_TX_THREAD
+      } else if (dlsch1->active[subframe] == 1) {
+#else
       } else if (dlsch1->active == 1) {
+#endif
         switch (rel8->precoding_information) {
         case 0: // one layer per transport block
           dlsch0_harq->mimo_mode   = ALAMOUTI;
@@ -967,10 +1015,18 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
     }
 
     // reset HARQ process if this is the first transmission
+#ifdef PHY_TX_THREAD
+    if ((dlsch0->active[subframe]==1) && (dlsch0_harq->round == 0))
+#else
     if ((dlsch0->active==1) && (dlsch0_harq->round == 0))
+#endif
       dlsch0_harq->status = ACTIVE;
 
+#ifdef PHY_TX_THREAD
+    if ((dlsch1->active[subframe]==1) && (dlsch1_harq->round == 0))
+#else
     if ((dlsch1->active==1) && (dlsch1_harq->round == 0))
+#endif
       dlsch1_harq->status = ACTIVE;
 
     dlsch0->rnti = rel8->rnti;
@@ -1144,8 +1200,13 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
     printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rel8->redundancy_version_1, rel8->redundancy_version_2, rel8->mcs_1, rel8->mcs_2);
 #endif
     if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==0) {
+#ifdef PHY_TX_THREAD
+      dlsch0->active[subframe] = 1;
+      dlsch1->active[subframe] = 1;
+#else
       dlsch0->active = 1;
       dlsch1->active = 1;
+#endif
       dlsch0->harq_mask                         |= (1<<rel8->harq_process);
       dlsch1->harq_mask                         |= (1<<rel8->harq_process);
       dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
@@ -1167,8 +1228,13 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
     else if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==1) {
       dlsch0 = eNB->dlsch[UE_id][1];
       dlsch1 = eNB->dlsch[UE_id][0];
+#ifdef PHY_TX_THREAD
+      dlsch0->active[subframe] = 1;
+      dlsch1->active[subframe] = 1;
+#else
       dlsch0->active = 1;
       dlsch1->active = 1;
+#endif
 
       dlsch0->harq_mask                         |= (1<<rel8->harq_process);
       dlsch1->harq_mask                         |= (1<<rel8->harq_process);
@@ -1186,7 +1252,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
       dlsch1_harq->codeword=0;
     }
     else if (TB0_active && (TB1_active==0)) {
+#ifdef PHY_TX_THREAD
+      dlsch0->active[subframe] = 1;
+#else
       dlsch0->active = 1;
+#endif
       dlsch0->harq_mask                         |= (1<<rel8->harq_process);
       dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
       dlsch0_harq->mcs = rel8->mcs_1;
@@ -1201,7 +1271,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
 #endif
     }
     else if ((TB0_active==0) && TB1_active) {
+#ifdef PHY_TX_THREAD
+      dlsch1->active[subframe] = 1;
+#else
       dlsch1->active = 1;
+#endif
       dlsch1->harq_mask                         |= (1<<rel8->harq_process);
       dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
       dlsch1_harq->mcs = rel8->mcs_2;
@@ -1219,11 +1293,11 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t
     if (dlsch0 != NULL){
       dlsch0->subframe_tx[subframe] = 1;
 
-      dlsch0->harq_ids[subframe] = rel8->harq_process;
+      dlsch0->harq_ids[frame%2][subframe] = rel8->harq_process;
     }
 
     if (dlsch1_harq != NULL){
-      dlsch1->harq_ids[subframe] = rel8->harq_process;
+      dlsch1->harq_ids[frame%2][subframe] = rel8->harq_process;
     }
 
 
@@ -1434,6 +1508,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL;
   int UE_id;
   int subframe = proc->subframe_tx;
+  int frame = proc->frame_tx;
 
   dci_alloc->firstCCE                   = rel13->ecce_index;
   dci_alloc->L                          = rel13->aggregation_level;
@@ -1452,8 +1527,12 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
   if (rel13->rnti_type == 2 ) dci_alloc->ra_flag = 1;
 
   UE_id = find_dlsch(rel13->rnti,eNB,SEARCH_EXIST_OR_FREE);
-  AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
-  AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+  if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){
+    LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel13->rnti,UE_id);
+    return;
+  }
+  //AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
+  //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];
   dlsch0_harq                               = dlsch0->harq_processes[rel13->harq_process];
 
@@ -1465,7 +1544,11 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
 
   case 10:  // Format 6-1A
     dci_alloc->format     = format6_1A;
+#ifdef PHY_TX_THREAD
+    dlsch0->active[subframe]       = 1;
+#else
     dlsch0->active       = 1;
+#endif
     switch (fp->N_RB_DL) {
 
     case 25:
@@ -1521,7 +1604,11 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
     break;
   case 11:  // Format 6-1B
     dci_alloc->format     = format6_1B;
+#ifdef PHY_TX_THREAD
+    dlsch0->active[subframe]       = 1;
+#else
     dlsch0->active       = 1;
+#endif
     switch (fp->N_RB_DL) {
 
     case 25:
@@ -1564,7 +1651,11 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
     }
   case 12: // Format 6-2
     dci_alloc->format     = format6_2;
+#ifdef PHY_TX_THREAD
+    dlsch0->active[subframe]       = 1;
+#else
     dlsch0->active       = 1;
+#endif
     switch (fp->N_RB_DL) {
     case 25:
       dci_alloc->dci_length                 = sizeof_DCI6_2_5MHz_t; 
@@ -1647,8 +1738,12 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
     //LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
   
   dlsch0_harq->dl_power_off = 1;
-  
+
+#ifdef PHY_TX_THREAD
+  dlsch0->active[subframe] = 1;
+#else
   dlsch0->active = 1;
+#endif
   dlsch0->harq_mask                         |= (1<<rel13->harq_process);  
   
   
@@ -1661,7 +1756,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
     
   }
   
-  dlsch0->harq_ids[subframe] = rel13->harq_process;
+  dlsch0->harq_ids[frame%2][subframe] = rel13->harq_process;
   
   
   
@@ -1692,6 +1787,8 @@ void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
 
   uint32_t ndi     = pdu->dci_pdu_rel8.new_data_indication_1;
 
+  uint16_t UE_id   = -1;
+
 #ifdef T_TRACER
   T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
     T_INT(pdu->dci_pdu_rel8.rnti), T_INT(((frame*10+subframe+4) % 8) /* TODO: correct harq pid */),
@@ -1837,16 +1934,23 @@ void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,
     DevParam (frame_parms->N_RB_DL, 0, 0);
     break;
   }
+
+  if(frame_parms->frame_type == TDD){
+     UE_id = find_ulsch(pdu->dci_pdu_rel8.rnti, eNB,SEARCH_EXIST_OR_FREE);
+     if(UE_id != -1){
+       eNB->ulsch[UE_id]->harq_processes[pdu->dci_pdu_rel8.harq_pid]->V_UL_DAI = dai +1;
+     }
+  }
 }
 
-void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe)
+void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe)
 {
   uint8_t harq_pid;
-  uint8_t UE_id;
+  //uint8_t UE_id;
   boolean_t new_ulsch = (find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST)==-1) ? TRUE : FALSE;
 
-  AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
-	      "No existing/free UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti);
+  //AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
+  //        "No existing/free 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;
@@ -1864,7 +1968,10 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
   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");
+  //AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");
+  if(ulsch->harq_processes[harq_pid]->nb_rb == 0){
+    LOG_E(PHY, "fill_ulsch UE_id %d nb_rb = 0\n", UE_id);
+  }
 
   ulsch->harq_processes[harq_pid]->dci_alloc                             = 1;
   ulsch->harq_processes[harq_pid]->rar_alloc                             = 0;
@@ -1899,6 +2006,7 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
 	ulsch_pdu->ulsch_pdu_rel8.redundancy_version);
   
   ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version;
+  if(ulsch_pdu->ulsch_pdu_rel8.modulation_type!=0)
   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;
@@ -1919,9 +2027,12 @@ void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame
     // 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++;
-
+  }
+  else {
+      ulsch->harq_processes[harq_pid]->round++;
+      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->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
   LOG_D(PHY,"Filling ULSCH %x (UE_id %d) (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, status %d, handled %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
 	ulsch->rnti,
diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
index 8f0f8a6cab6fc308be46b61e562c149de5f74f66..1b5773320071d8d11eb975575ce27f25eee9bbe0 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c
@@ -979,28 +979,23 @@ uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t
   } else {
 
     switch (frame_parms->tdd_config) {
-
     case 1:
-      if ((subframe==2) ||
-          (subframe==3) ||
-          (subframe==7) ||
-          (subframe==8))
-        switch (subframe) {
-        case 2:
-        case 3:
-          ret = (subframe-2);
-          break;
+      switch (subframe) {
+      case 2:
+      case 3:
+        ret = (subframe-2);
+        break;
 
-        case 7:
-        case 8:
-          ret = (subframe-5);
-          break;
+      case 7:
+      case 8:
+        ret = (subframe-5);
+        break;
 
-        default:
-          LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
-          ret = (255);
-          break;
-        }
+      default:
+        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
+        ret = (255);
+        break;
+      }
 
       break;
 
@@ -1052,10 +1047,13 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
   uint8_t ul_subframe = 255;
 
   if ((frame_parms->frame_type == TDD) &&
-      (frame_parms->tdd_config == 1) &&
-      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
-    ul_subframe = ((n+6)%10);
-  else if ((frame_parms->frame_type == TDD) &&
+      (frame_parms->tdd_config == 1)) {
+    if ((n==1)||(n==6)) { // tdd_config 0,1 SF 1,5
+      ul_subframe = ((n+6)%10);
+    } else if ((n==4)||(n==9)) {
+      ul_subframe = ((n+4)%10);
+    }
+  } else if ((frame_parms->frame_type == TDD) &&
            (frame_parms->tdd_config == 6) &&
            ((n==0)||(n==1)||(n==5)||(n==6)))
     ul_subframe = ((n+7)%10);
@@ -1063,10 +1061,10 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
            (frame_parms->tdd_config == 6) &&
            (n==9)) // tdd_config 6 SF 9
     ul_subframe = ((n+5)%10);
-  else 
+  else
     ul_subframe = ((n+4)%10);
 
-  AssertFatal(frame_parms->frame_type == FDD || subframe_select(frame_parms,ul_subframe) == SF_UL,"illegal ul_subframe %d (n %d)\n",ul_subframe,n);
+  if ( (subframe_select(frame_parms,ul_subframe) != SF_UL) && (frame_parms->frame_type == TDD)) return(255);
 
   LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe);
   return ul_subframe;
@@ -1075,10 +1073,13 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
 uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
 {
   if ((frame_parms->frame_type == TDD) &&
-      (frame_parms->tdd_config == 1) &&
-      ((n==7)||(n==2))) // tdd_config 0,1 SF 1,5
-    return((n==7)? 1 : 6);
-  else if ((frame_parms->frame_type == TDD) &&
+      (frame_parms->tdd_config == 1)) {
+    if ((n==7)||(n==2)) { // tdd_config 0,1 SF 1,5
+      return((n==7)? 1 : 6);
+    } else if ((n==3)||(n==8)) {
+      return((n==3)? 9 : 4);
+    }
+  } else if ((frame_parms->frame_type == TDD) &&
            (frame_parms->tdd_config == 6) &&
            ((n==7)||(n==8)||(n==2)||(n==3)))
     return((n+3)%10);
@@ -1095,10 +1096,11 @@ uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, ui
   uint32_t ul_frame;
 
   if ((frame_parms->frame_type == TDD) &&
-      (frame_parms->tdd_config == 1) &&
-      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
-    ul_frame = (frame + (n==1 ? 0 : 1));
-  else if ((frame_parms->frame_type == TDD) &&
+      (frame_parms->tdd_config == 1)) {
+    if ((n==1)||(n==6)||(n==4)||(n==9)) { // tdd_config 0,1 SF 1,5
+      ul_frame = (frame + (n < 5 ? 0 : 1));
+    }
+  } else if ((frame_parms->frame_type == TDD) &&
            (frame_parms->tdd_config == 6) &&
            ((n==0)||(n==1)||(n==5)||(n==6)))
     ul_frame = (frame + (n>=5 ? 1 : 0));
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
index a726621022743e5daebaaee5cae84d536da3f267..55795243e933f82f76821c7800b79d7fbb8c4e0b 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c
@@ -148,8 +148,8 @@ LTE_eNB_DLSCH_t *new_eNB_dlsch(unsigned char Kmimo,unsigned char Mdlharq,uint32_
 
        }*/
 
-    for (i=0; i<10; i++)
-      dlsch->harq_ids[i] = Mdlharq;
+    for (i=0; i<20; i++)
+      dlsch->harq_ids[i/10][i%10] = Mdlharq;
 
     for (i=0; i<Mdlharq; i++) {
       dlsch->harq_processes[i] = (LTE_DL_eNB_HARQ_t *)malloc16(sizeof(LTE_DL_eNB_HARQ_t));
@@ -227,11 +227,16 @@ void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch)
   if (dlsch) {
     Mdlharq = dlsch->Mdlharq;
     dlsch->rnti = 0;
+#ifdef PHY_TX_THREAD
+    for (i=0; i<10; i++)
+      dlsch->active[i] = 0;
+#else
     dlsch->active = 0;
+#endif
     dlsch->harq_mask = 0;
 
-    for (i=0; i<10; i++)
-      dlsch->harq_ids[i] = Mdlharq;
+    for (i=0; i<20; i++)
+      dlsch->harq_ids[i/10][i%10] = Mdlharq;
 
     for (i=0; i<Mdlharq; i++) {
       if (dlsch->harq_processes[i]) {
@@ -413,7 +418,11 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB,
   unsigned int crc=1;
   unsigned short iind;
 
-  unsigned char harq_pid = dlsch->harq_ids[subframe];
+  unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
+  if(harq_pid >= dlsch->Mdlharq) {
+    LOG_E(PHY,"dlsch_encoding_2threads illegal harq_pid %d\n", harq_pid);
+    return(-1);
+  }
   unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
   unsigned int A;
   unsigned char mod_order;
@@ -629,7 +638,7 @@ int dlsch_encoding_all(PHY_VARS_eNB *eNB,
 {
 	int encoding_return = 0;
 	unsigned int L,C,B;
-	B = dlsch->harq_processes[dlsch->harq_ids[subframe]]->B;
+	B = dlsch->harq_processes[dlsch->harq_ids[frame%2][subframe]]->B;
 	if(B<=6144)
 	{
 		L=0;
@@ -732,7 +741,11 @@ int dlsch_encoding(PHY_VARS_eNB *eNB,
   unsigned short iind;
 
   LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
-  unsigned char harq_pid = dlsch->harq_ids[subframe];
+  unsigned char harq_pid = dlsch->harq_ids[frame%2][subframe];
+  if(harq_pid >= dlsch->Mdlharq) {
+    LOG_E(PHY,"dlsch_encoding illegal harq_pid %d\n", harq_pid);
+    return(-1);
+  }
   unsigned short nb_rb = dlsch->harq_processes[harq_pid]->nb_rb;
   unsigned int A;
   unsigned char mod_order;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
index a2f8f08073827072f130f0424bc019a3e7e4c97c..b2de2e00674029b6fbfb8f64df2bd1c32bf68808 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c
@@ -2077,6 +2077,7 @@ inline int check_skip_dc(int rb,LTE_DL_FRAME_PARMS *frame_parms) {
 int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
                      int32_t **txdataF,
                      int16_t amp,
+                     int frame,
                      uint32_t subframe_offset,
                      uint8_t num_pdcch_symbols,
                      LTE_eNB_DLSCH_t *dlsch0,
@@ -2149,7 +2150,11 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
 
   if ((dlsch0 != NULL) && (dlsch1 != NULL)){
 
-    harq_pid = dlsch0->harq_ids[subframe_offset];
+    harq_pid = dlsch0->harq_ids[frame%2][subframe_offset];
+    if(harq_pid >= dlsch0->Mdlharq) {
+      LOG_E(PHY,"illegal harq_pid %d\n", harq_pid);
+      return(-1);
+    }
     dlsch0_harq = dlsch0->harq_processes[harq_pid];
     mimo_mode = dlsch0_harq->mimo_mode;
     mod_order0 = dlsch0_harq->Qm;
@@ -2166,7 +2171,11 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
 
   }else if ((dlsch0 != NULL) && (dlsch1 == NULL)){
 
-    harq_pid = dlsch0->harq_ids[subframe_offset];
+    harq_pid = dlsch0->harq_ids[frame%2][subframe_offset];
+    if(harq_pid >= dlsch0->Mdlharq) {
+      LOG_E(PHY,"illegal harq_pid %d\n", harq_pid);
+      return(-1);
+    }
     dlsch0_harq = dlsch0->harq_processes[harq_pid];
     mimo_mode = dlsch0_harq->mimo_mode;
     mod_order0 = dlsch0_harq->Qm;
@@ -2183,7 +2192,11 @@ int dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
 
   }else if ((dlsch0 == NULL) && (dlsch1 != NULL)){
 
-    harq_pid = dlsch1->harq_ids[subframe_offset];
+    harq_pid = dlsch1->harq_ids[frame%2][subframe_offset];
+    if(harq_pid >= dlsch1->Mdlharq) {
+      LOG_E(PHY,"illegal harq_pid %d\n", harq_pid);
+      return(-1);
+    }
     dlsch1_harq = dlsch1->harq_processes[harq_pid];
     mimo_mode = dlsch1_harq->mimo_mode;
     mod_order0 = dlsch1_harq->Qm;
diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
index c1f80c40a4c1816525e9f51921f34866734f13d4..f582021fca3ce930c6bd5f5ee5f9591923f1a982 100644
--- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
+++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c
@@ -34,47 +34,20 @@
 
 #include "PHY/defs_eNB.h"
 #include "PHY/defs_UE.h"
+#include "PHY/LTE_REFSIG/lte_refsig.h"
 #include "PHY/CODING/coding_extern.h"
 #include "PHY/CODING/lte_interleaver_inline.h"
 #include "transport_eNB.h"
 #include "PHY/phy_extern.h"
 #include "UTIL/LOG/vcd_signal_dumper.h"
 
-static inline unsigned int lte_gold_scram(unsigned int *x1, unsigned int *x2, unsigned char reset) __attribute__((always_inline));
-static inline unsigned int lte_gold_scram(unsigned int *x1, unsigned int *x2, unsigned char reset)
-{
-  int n;
-
-  if (reset) {
-    *x1 = 1+ (1<<31);
-    *x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
-
-    // skip first 50 double words (1600 bits)
-    //      printf("n=0 : x1 %x, x2 %x\n",x1,x2);
-    for (n=1; n<50; n++) {
-      *x1 = (*x1>>1) ^ (*x1>>4);
-      *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
-      *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
-      *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
-    }
-  }
-
-  *x1 = (*x1>>1) ^ (*x1>>4);
-  *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
-  *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
-  *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
-  return(*x1^*x2);
-  //  printf("n=%d : c %x\n",n,x1^x2);
-
-}
-
 void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
                       int mbsfn_flag,
                       LTE_eNB_DLSCH_t *dlsch,
-		      int harq_pid,
+                      int harq_pid,
                       int G,
                       uint8_t q,
-		      uint16_t frame,
+                      uint16_t frame,
                       uint8_t Ns)
 {
 
@@ -92,13 +65,27 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
   uint8_t Nacc=4;
   uint16_t j0,j,idelta;
   uint16_t i  = (Ns>>1) + (10*frame);
+#ifdef PHY_TX_THREAD
+  uint16_t i0 = dlsch->harq_processes[harq_pid]->i0;
+#else
   uint16_t i0 = dlsch->i0;
+#endif
 
+#ifdef PHY_TX_THREAD
+  if (dlsch->harq_processes[harq_pid]->sib1_br_flag==1)                              Nacc=1;
+#else
   if (dlsch->sib1_br_flag==1)                              Nacc=1;
+#endif
   else if (dlsch->rnti == 0xFFFF || dlsch->rnti == 0xFFFE) Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
+#ifdef PHY_TX_THREAD
+  // Note: above SC-RNTI will also have to be added when/if implemented
+  else if (dlsch->harq_processes[harq_pid]->CEmode == CEmodeA)                       Nacc=1;
+  else if (dlsch->harq_processes[harq_pid]->CEmode == CEmodeB)                       Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
+#else
   // Note: above SC-RNTI will also have to be added when/if implemented
   else if (dlsch->CEmode == CEmodeA)                       Nacc=1;
   else if (dlsch->CEmode == CEmodeB)                       Nacc = (frame_parms->frame_type == TDD) ? 10 : 4;
+#endif
 
   if (frame_parms->frame_type == FDD || Nacc == 1) idelta = 0;
   else                                             idelta = Nacc-2;
@@ -111,7 +98,11 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
   // x1 is set in lte_gold_generic
   if (mbsfn_flag == 0) {
 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+#ifdef PHY_TX_THREAD
+    if (dlsch->harq_processes[harq_pid]->i0 != 0xFFFF) {
+#else
     if (dlsch->i0 != 0xFFFF) {
+#endif
       // rule for BL/CE UEs from Section 6.3.1 in 36.211
       x2=  (dlsch->rnti<<14) + (q<<13) + ((((j0+j)*Nacc)%10)<<9) + frame_parms->Nid_cell;
       if ((frame&1023) < 200) LOG_D(PHY,"Scrambling init for (i0 %d, i %d, j0 %d, j %d, Nacc %d) => x2 %d\n",i0,i,j0,j,Nacc,x2);
@@ -130,7 +121,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
   printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2);
 #endif
 #endif
-  s = lte_gold_scram(&x1, &x2, 1);
+  s = lte_gold_generic(&x1, &x2, 1);
 
   for (n=0; n<(1+(G>>5)); n++) {
 
@@ -179,7 +170,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms,
 
     
     
-    s = lte_gold_scram(&x1, &x2, 0);
+    s = lte_gold_generic(&x1, &x2, 0);
     e += 32;
   }
 
@@ -225,7 +216,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
 #ifdef DEBUG_SCRAMBLING
     printf("unscrambling: rnti %x, q %d, Ns %d, Nid_cell %d G %d, x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell,G,x2);
 #endif
-  s = lte_gold_scram(&x1, &x2, 1);
+  s = lte_gold_generic(&x1, &x2, 1);
 
   for (i=0; i<(1+(G>>5)); i++) {
     for (j=0; j<32; j++,k++) {
@@ -238,7 +229,7 @@ void dlsch_unscrambling(LTE_DL_FRAME_PARMS *frame_parms,
 #endif
     }
 
-    s = lte_gold_scram(&x1, &x2, 0);
+    s = lte_gold_generic(&x1, &x2, 0);
   }
 }
 
diff --git a/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
new file mode 100644
index 0000000000000000000000000000000000000000..b249052cbf26c477276f251a7c502cd0b3b4c0cb
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/lte_gold_generic.c
@@ -0,0 +1,75 @@
+/*
+ * 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.1  (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 "PHY/types.h"
+
+/**
+   \brief Gold Sequence Generation defined in 3x.211
+   \param x1 x1 shift register
+   \param x2 x2 shift register / cinit if reset is set
+   \param reset Reset flag / reinitialize the generator
+   \return c 32 bits of gold output
+*/
+extern inline  uint32_t lte_gold_generic(uint32_t *x1, uint32_t *x2, uint8_t reset)
+{
+  int32_t n;
+
+  // 3GPP 3x.211
+  // Nc = 1600
+  // c(n)     = [x1(n+Nc) + x2(n+Nc)]mod2
+  // x1(n+31) = [x1(n+3)                     + x1(n)]mod2
+  // x2(n+31) = [x2(n+3) + x2(n+2) + x2(n+1) + x2(n)]mod2
+  if (reset)
+  {
+      // Init value for x1: x1(0) = 1, x1(n) = 0, n=1,2,...,30
+      // x1(31) = [x1(3) + x1(0)]mod2 = 1
+      *x1 = 1 + (1<<31);
+      // Init value for x2: cinit = sum_{i=0}^30 x2*2^i
+      // x2(31) = [x2(3)    + x2(2)    + x2(1)    + x2(0)]mod2
+      //        =  (*x2>>3) ^ (*x2>>2) + (*x2>>1) + *x2
+      *x2 = *x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
+
+      // x1 and x2 contain bits n = 0,1,...,31
+
+      // Nc = 1600 bits are skipped at the beginning
+      // i.e., 1600 / 32 = 50 32bit words
+
+      for (n = 1; n < 50; n++)
+      {
+          // Compute x1(0),...,x1(27)
+          *x1 = (*x1>>1) ^ (*x1>>4);
+          // Compute x1(28),..,x1(31) and xor
+          *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
+          // Compute x2(0),...,x2(27)
+          *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
+          // Compute x2(28),..,x2(31) and xor
+          *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
+      }
+  }
+
+  *x1 = (*x1>>1) ^ (*x1>>4);
+  *x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
+  *x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
+  *x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
+
+  // c(n) = [x1(n+Nc) + x2(n+Nc)]mod2
+  return(*x1^*x2);
+}
diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c
index 2f39346be2027e4fc1d9460ec6cb508026b9f666..ec9c9f2477fd8297ed6128a9a9fbda18e1451f0d 100644
--- a/openair1/PHY/LTE_TRANSPORT/prach_common.c
+++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c
@@ -570,7 +570,7 @@ int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t su
   uint8_t prach_ConfigIndex  = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
   int prach_mask             = is_prach_subframe0(frame_parms,prach_ConfigIndex,frame,subframe);
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   int i;
 
   for (i=0;i<4;i++) {
diff --git a/openair1/PHY/LTE_TRANSPORT/pucch.c b/openair1/PHY/LTE_TRANSPORT/pucch.c
index e7aa11d30ad4b6b2fa069b6a2dd3f254979a734f..fa86c650643f9c83c677e70a3880813ec2889098 100644
--- a/openair1/PHY/LTE_TRANSPORT/pucch.c
+++ b/openair1/PHY/LTE_TRANSPORT/pucch.c
@@ -795,25 +795,11 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
       for (j=0;j<NUMBER_OF_UE_MAX;j++) {
 	eNB->pucch1_stats_cnt[j][i]=0;
 	eNB->pucch1ab_stats_cnt[j][i]=0;
-      }
-    }
-#if defined(USRP_REC_PLAY)
-    // It's probably bad to do this statically only once.
-    // Looks like the above is incomplete.
-    // Such reset needs to be done once a UE PHY structure is being used/re-used
-    // Don't know if this is ever possible in current architecture
-    for (i=0;i<10240;i++) {
-      for (j=0;j<NUMBER_OF_UE_MAX;j++) {
-	eNB->pucch1_stats[j][i]=0;
+#if defined(USRP_REC_PLAY) // not 100% sure
 	eNB->pucch1_stats_thres[j][i]=0;
+#endif	
       }
     }
-    for (i=0;i<20480;i++) {
-      for (j=0;j<NUMBER_OF_UE_MAX;j++) {
-	eNB->pucch1ab_stats[j][i]=0;
-      }
-    }
-#endif    
     first_call=0;
   }
 
@@ -1236,6 +1222,7 @@ uint32_t rx_pucch(PHY_VARS_eNB *eNB,
 #if defined(USRP_REC_PLAY)
     // It looks like the value is a bit messy when RF is replayed.
     // For instance i assume to skip pucch1_thres from the test below.
+    // Not 100% sure
     if (sigma2_dB<(dB_fixed(stat_max)))  {//
 #else
     if (sigma2_dB<(dB_fixed(stat_max)-pucch1_thres))  {//
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h
index 167e2b111a566a7929e1f76cc3003a41623ea756..130c9737749fbae5025ba3bf1f0fd50b18027637 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_common.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h
@@ -105,7 +105,7 @@ typedef enum {
 
 
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 typedef enum {
   CEmodeA = 0,
   CEmodeB = 1
@@ -138,7 +138,7 @@ typedef enum {
   HARQ_SR_CQI  
 } UCI_type_t;
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 typedef enum {
   NOCE,
   CEMODEA,
@@ -183,7 +183,7 @@ typedef struct {
   PRACH_TDD_PREAMBLE_MAP_elem map[6];
 } PRACH_TDD_PREAMBLE_MAP;
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 
 typedef struct {
   uint16_t slss_id;
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
index 3013dfb2183ece44d3f17afae72f0804b7652d2b..d1dd595d3599ad248f0776f5834dc8cb6670a6d8 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h
@@ -125,6 +125,15 @@ typedef struct {
   uint8_t first_layer;
   /// codeword this transport block is mapped to
   uint8_t codeword;
+#ifdef PHY_TX_THREAD
+#ifdef Rel14
+  /// indicator that this DLSCH corresponds to SIB1-BR, needed for c_init for scrambling
+  uint8_t sib1_br_flag;
+  /// initial absolute subframe (see 36.211 Section 6.3.1), needed for c_init for scrambling
+  uint16_t i0;
+  CEmode_t CEmode;
+#endif
+#endif
 } LTE_DL_eNB_HARQ_t;
 
 
@@ -138,7 +147,11 @@ typedef struct {
   /// Allocated RNTI (0 means DLSCH_t is not currently used)
   uint16_t rnti;
   /// Active flag for baseband transmitter processing
+#ifdef PHY_TX_THREAD
+  uint8_t active[10];
+#else
   uint8_t active;
+#endif
   /// HARQ process mask, indicates which processes are currently active
   uint16_t harq_mask;
   /// Indicator of TX activation per subframe.  Used during PUCCH detection for ACK/NAK.
@@ -146,7 +159,7 @@ typedef struct {
   /// First CCE of last PDSCH scheduling per subframe.  Again used during PUCCH detection for ACK/NAK.
   uint8_t nCCE[10];
   /// Process ID's per subframe.  Used to associate received ACKs on PUSCH/PUCCH to DLSCH harq process ids
-  uint8_t harq_ids[10];
+  uint8_t harq_ids[2][10];
   /// Window size (in outgoing transport blocks) for fine-grain rate adaptation
   uint8_t ra_window_size;
   /// First-round error threshold for fine-grain rate adaptation
@@ -169,6 +182,7 @@ typedef struct {
   int16_t sqrt_rho_a;
   /// amplitude of PDSCH (compared to RS) in symbols containing pilots
   int16_t sqrt_rho_b;
+#ifndef PHY_TX_THREAD
 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// indicator that this DLSCH corresponds to SIB1-BR, needed for c_init for scrambling
   uint8_t sib1_br_flag;
@@ -176,6 +190,7 @@ typedef struct {
   uint16_t i0;
   CEmode_t CEmode;
 #endif
+#endif
 } LTE_eNB_DLSCH_t;
 
 
diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
index 5547c308e9c320d1ea2c003b927f2f9e1776d3e0..37ac335d02c632238539ede9af847e61b101eafe 100644
--- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h
+++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h
@@ -241,6 +241,7 @@ int32_t allocate_REs_in_RB(PHY_VARS_eNB* phy_vars_eNB,
 int32_t dlsch_modulation(PHY_VARS_eNB* phy_vars_eNB,
                          int32_t **txdataF,
                          int16_t amp,
+                         int frame,
                          uint32_t sub_frame_offset,
                          uint8_t num_pdcch_symbols,
                          LTE_eNB_DLSCH_t *dlsch0,
@@ -418,7 +419,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d
 void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
 	      nfapi_hi_dci0_dci_pdu *pdu);
 
-void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe);
+void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe);
 
 int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB,
 				       unsigned char *rar_pdu,
@@ -577,7 +578,7 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru,
 	      uint16_t *max_preamble_energy, 
 	      uint16_t *max_preamble_delay, 
 	      uint16_t Nf, uint8_t tdd_mapindex
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 	      ,
               uint8_t br_flag
 #endif
@@ -611,11 +612,11 @@ void conv_eMTC_rballoc(uint16_t resource_block_coding,
 		       uint32_t N_RB_DL,
 		       uint32_t *rb_alloc);
 
-int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
+int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
 
-int8_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
+int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type);
 
-int8_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type);
+int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type);
 
 /**@}*/
 #endif
diff --git a/openair1/PHY/LTE_TRANSPORT/uci_tools.c b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
index 539d5476ab8a92ff67b9ec8e36f1a685e2551fd1..88c652133b783bb627f708985c08c0d4004ca707 100644
--- a/openair1/PHY/LTE_TRANSPORT/uci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/uci_tools.c
@@ -37,10 +37,9 @@
 //#define DEBUG_UCI 1
 
 
-int8_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type) {
-  uint8_t i;
-  int8_t first_free_index=-1;
-
+int16_t find_uci(uint16_t rnti, int frame, int subframe, PHY_VARS_eNB *eNB,find_type_t type) {
+  uint16_t i;
+  int16_t first_free_index=-1;
   AssertFatal(eNB!=NULL,"eNB is null\n");
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
     if ((eNB->uci_vars[i].active >0) &&
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 50f469011f0237923c090dc48c0c59d8492d0cf7..2083d1630984fe45d323542954c365b9e6915a9f 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -915,8 +915,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
         nb_rb);
 	
   //#endif
-
-  if (ulsch_harq->round == 0) {
+  //if (ulsch_harq->round == 0) { // delete for RB shortage pattern
     // This is a new packet, so compute quantities regarding segmentation
     ulsch_harq->B = A+24;
     lte_segmentation(NULL,
@@ -929,8 +928,7 @@ unsigned int  ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
                      &ulsch_harq->Kminus,
                      &ulsch_harq->F);
     //  CLEAR LLR's HERE for first packet in process
-  }
-
+  //}
   //  printf("after segmentation c[%d] = %p\n",0,ulsch_harq->c[0]);
 
   sumKr = 0;
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
index 0ffe3d735b23f86748fac00508501f9d24c07c65..6bad4de05bbdfc149fd2a172b5c892edeb5bb6a8 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c
@@ -1024,20 +1024,6 @@ void ulsch_channel_compensation(int32_t **rxdataF_ext,
 #endif
 }
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
                          LTE_DL_FRAME_PARMS *frame_parms,
                          int32_t *avg,
@@ -1047,24 +1033,23 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
   int16_t rb;
   uint8_t aarx;
 #if defined(__x86_64__) || defined(__i386__)
-  __m128i avg128U;
   __m128i *ul_ch128;
+  __m128 avg128U;
 #elif defined(__arm__)
-  int16x4_t *ul_ch128;
   int32x4_t avg128U;
+  int16x4_t *ul_ch128;
 #endif
-
   for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
     //clear average level
 #if defined(__x86_64__) || defined(__i386__)
-    avg128U = _mm_setzero_si128();
+    avg128U = _mm_setzero_ps();
     ul_ch128=(__m128i *)drs_ch_estimates_ext[aarx];
 
     for (rb=0; rb<nb_rb; rb++) {
 
-      avg128U = _mm_add_epi32(avg128U,_mm_madd_epi16(ul_ch128[0],ul_ch128[0]));
-      avg128U = _mm_add_epi32(avg128U,_mm_madd_epi16(ul_ch128[1],ul_ch128[1]));
-      avg128U = _mm_add_epi32(avg128U,_mm_madd_epi16(ul_ch128[2],ul_ch128[2]));
+      avg128U = _mm_add_ps(avg128U,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch128[0],ul_ch128[0])));
+      avg128U = _mm_add_ps(avg128U,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch128[1],ul_ch128[1])));
+      avg128U = _mm_add_ps(avg128U,_mm_cvtepi32_ps(_mm_madd_epi16(ul_ch128[2],ul_ch128[2])));
 
       ul_ch128+=3;
 
@@ -1091,10 +1076,10 @@ void ulsch_channel_level(int32_t **drs_ch_estimates_ext,
 #endif
 
     DevAssert( nb_rb );
-    avg[aarx] = (((int*)&avg128U)[0] +
-                 ((int*)&avg128U)[1] +
-                 ((int*)&avg128U)[2] +
-                 ((int*)&avg128U)[3])/(nb_rb*12);
+    avg[aarx] = (int)((((float*)&avg128U)[0] +
+                       ((float*)&avg128U)[1] +
+                       ((float*)&avg128U)[2] +
+                       ((float*)&avg128U)[3])/(float)(nb_rb*12));
 
   }
 
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
index 665d5cead04d59a18aaebce0701066b9f1861600..0bb20dfdc4f39acb3b54409fc87ceaa6eab75520 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
+++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
@@ -1185,7 +1185,7 @@ int rx_pdsch(PHY_VARS_UE *ue,
 #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));
+    LOG_D(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
diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
index 9b3a95a14a9f0814e8fc0ea81b78dda0427ca868..ade621faa2a3fb3b386e4df3e8a1782549f56219 100644
--- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
+++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h
@@ -1677,9 +1677,5 @@ uint8_t get_prach_prb_offset(LTE_DL_FRAME_PARMS *frame_parms,
 			     uint8_t n_ra_prboffset,
 			     uint8_t tdd_mapindex, uint16_t Nf);
 
-
-
-
-
 /**@}*/
 #endif
diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h
index c253488a200b687ea107541f2991fd7d12cafd3d..cca2e90252ca93004a5fff108b9f69138eb14627 100644
--- a/openair1/PHY/defs_common.h
+++ b/openair1/PHY/defs_common.h
@@ -72,13 +72,11 @@
 
 #include <pthread.h>
 
-#include "targets/ARCH/COMMON/common_lib.h"
 #include "targets/COMMON/openairinterface5g_limits.h"
 
 #include "types.h"
 #include "nfapi_interface.h"
 //#include "defs.h"
-#include "openair2/COMMON/platform_types.h"
 
 #define RX_NB_TH_MAX 2
 #define RX_NB_TH 2
@@ -159,7 +157,7 @@ typedef struct {
   PRACH_CONFIG_INFO prach_ConfigInfo;
 } PRACH_CONFIG_COMMON;
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 
 /// PRACH-eMTC-Config from 36.331 RRC spec
 typedef struct {
@@ -192,7 +190,7 @@ typedef struct {
   /// prach_Config_enabled=1 means enabled. \vr{[0..1]}
   uint8_t prach_Config_enabled;
   /// PRACH Configuration Information
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   PRACH_eMTC_CONFIG_INFO prach_ConfigInfo;
 #endif  
 } PRACH_eMTC_CONFIG_COMMON;
@@ -644,7 +642,7 @@ typedef struct {
   uint8_t nb_antenna_ports_eNB;
   /// PRACH_CONFIG
   PRACH_CONFIG_COMMON prach_config_common;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// PRACH_eMTC_CONFIG
   PRACH_eMTC_CONFIG_COMMON prach_emtc_config_common;
 #endif
@@ -678,7 +676,8 @@ typedef struct {
   uint16_t phich_reg[MAX_NUM_PHICH_GROUPS][3];
 
   struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[MAX_MBSFN_AREA];
-
+  /// for fair RR scheduler
+  uint32_t ue_multiple_max;
 } LTE_DL_FRAME_PARMS;
 
 typedef enum {
diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h
index 828169030735f1781fda77f7d72f35e17badf325..df3c1e449770221d919851dcd63080b8fbcdf43b 100644
--- a/openair1/PHY/defs_eNB.h
+++ b/openair1/PHY/defs_eNB.h
@@ -229,6 +229,34 @@ typedef struct RU_proc_t_s {
   int                  num_slaves;
   /// array of pointers to slaves
   struct RU_proc_t_s           **slave_proc;
+#ifdef PHY_TX_THREAD
+  /// pthread structure for PRACH thread
+  pthread_t pthread_phy_tx;
+  pthread_mutex_t mutex_phy_tx;
+  pthread_cond_t cond_phy_tx;
+  /// \internal This variable is protected by \ref mutex_phy_tx.
+  int instance_cnt_phy_tx;
+  /// frame to act upon for transmission
+  int frame_phy_tx;
+  /// subframe to act upon for transmission
+  int subframe_phy_tx;
+  /// timestamp to send to "slave rru"
+  openair0_timestamp timestamp_phy_tx;
+  /// pthread structure for RF TX thread
+  pthread_t pthread_rf_tx;
+  pthread_mutex_t mutex_rf_tx;
+  pthread_cond_t cond_rf_tx;
+  /// \internal This variable is protected by \ref mutex_rf_tx.
+  int instance_cnt_rf_tx;
+#endif
+#if defined(PRE_SCD_THREAD)
+  pthread_t pthread_pre_scd;
+  /// condition variable for time processing thread
+  pthread_cond_t cond_pre_scd;
+  /// mutex for time thread
+  pthread_mutex_t mutex_pre_scd;
+  int instance_pre_scd;
+#endif
   /// pipeline ready state
   int ru_rx_ready;
   int ru_tx_ready;
@@ -331,7 +359,7 @@ typedef struct RU_t_s{
   int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru);
   /// function pointer to wakeup routine in lte-enb.
   void (*wakeup_prach_eNB)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// function pointer to wakeup routine in lte-enb.
   void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe);
 #endif
@@ -456,7 +484,7 @@ typedef struct RRU_config_s {
   int prach_FreqOffset[MAX_BANDS_PER_RRU];
   /// prach_ConfigIndex for IF4p5
   int prach_ConfigIndex[MAX_BANDS_PER_RRU];
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   int emtc_prach_CElevel_enable[MAX_BANDS_PER_RRU][4];
   /// emtc_prach_FreqOffset for IF4p5 per CE Level
   int emtc_prach_FreqOffset[MAX_BANDS_PER_RRU][4];
@@ -591,7 +619,7 @@ typedef struct {
   int32_t **prach_ifft[4];
 
   /// repetition number
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// indicator of first frame in a group of PRACH repetitions
   int first_frame[4];
   /// current repetition for each CE level
@@ -678,7 +706,7 @@ typedef struct eNB_proc_t_s {
   int subframe_rx;
   /// subframe to act upon for PRACH
   int subframe_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// subframe to act upon for reception of prach BL/CE UEs
   int subframe_prach_br;
 #endif
@@ -688,7 +716,7 @@ typedef struct eNB_proc_t_s {
   int frame_tx;
   /// frame to act upon for PRACH
   int frame_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// frame to act upon for PRACH BL/CE UEs
   int frame_prach_br;
 #endif
@@ -698,7 +726,7 @@ typedef struct eNB_proc_t_s {
   int instance_cnt_te;
   /// \internal This variable is protected by \ref mutex_prach.
   int instance_cnt_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// \internal This variable is protected by \ref mutex_prach for BL/CE UEs.
   int instance_cnt_prach_br;
 #endif
@@ -720,7 +748,7 @@ typedef struct eNB_proc_t_s {
   pthread_attr_t attr_single;
   /// pthread attributes for prach processing thread
   pthread_attr_t attr_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// pthread attributes for prach processing thread BL/CE UEs
   pthread_attr_t attr_prach_br;
 #endif
@@ -734,7 +762,7 @@ typedef struct eNB_proc_t_s {
   struct sched_param sched_param_single;
   /// scheduling parameters for prach thread
   struct sched_param sched_param_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// scheduling parameters for prach thread
   struct sched_param sched_param_prach_br;
 #endif
@@ -746,7 +774,7 @@ typedef struct eNB_proc_t_s {
   pthread_t pthread_te;
   /// pthread structure for PRACH thread
   pthread_t pthread_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// pthread structure for PRACH thread BL/CE UEs
   pthread_t pthread_prach_br;
 #endif
@@ -756,7 +784,7 @@ typedef struct eNB_proc_t_s {
   pthread_cond_t cond_te;
   /// condition variable for PRACH processing thread;
   pthread_cond_t cond_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// condition variable for PRACH processing thread BL/CE UEs;
   pthread_cond_t cond_prach_br;
 #endif
@@ -768,7 +796,7 @@ typedef struct eNB_proc_t_s {
   pthread_mutex_t mutex_te;
   /// mutex for PRACH thread
   pthread_mutex_t mutex_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// mutex for PRACH thread for BL/CE UEs
   pthread_mutex_t mutex_prach_br;
 #endif
@@ -784,7 +812,7 @@ typedef struct eNB_proc_t_s {
   int RU_mask;
   /// mask for RUs serving eNB (PRACH)
   int RU_mask_prach;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// mask for RUs serving eNB (PRACH)
   int RU_mask_prach_br;
 #endif
diff --git a/openair1/PHY/impl_defs_lte.h b/openair1/PHY/impl_defs_lte.h
index 8ffe1fabf40533f151ade91c194e6b906a2301b4..d649dce100482c0fc70012c6b4cc64f51e8e8487 100644
--- a/openair1/PHY/impl_defs_lte.h
+++ b/openair1/PHY/impl_defs_lte.h
@@ -33,11 +33,6 @@
 #ifndef __PHY_IMPLEMENTATION_DEFS_LTE_H__
 #define __PHY_IMPLEMENTATION_DEFS_LTE_H__
 
-
-
-
-
-
 typedef struct {
   /// \brief Holds the transmit data in the frequency domain.
   /// - first index: rx antenna [0..nb_antennas_rx[
@@ -73,9 +68,4 @@ typedef struct {
   int32_t **tdd_calib_coeffs;
 } RU_COMMON;
 
-
-
-
-
-
 #endif
diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c
index 5687fd1fc3e7aad6d255f7772daadec6d57b72cc..8840d065ecef45ec85e575d2dd5cd1b20c564b50 100644
--- a/openair1/SCHED/fapi_l1.c
+++ b/openair1/SCHED/fapi_l1.c
@@ -157,31 +157,35 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
   int harq_pid;
 
   UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
-  AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
-  AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
+  if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){
+    LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rel8->rnti,UE_id);
+    return;
+  }
+  //AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
+  //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];
 
 #if (RRC_VERSION >= MAKE_VERSION(13, 0, 0))
-  if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[subframe] = 0;
+  if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[frame%2][subframe] = 0;
 #endif
 
-  harq_pid        = dlsch0->harq_ids[subframe];
+  harq_pid        = dlsch0->harq_ids[frame%2][subframe];
   AssertFatal((harq_pid>=0) && (harq_pid<8),"harq_pid %d not in 0...7 frame:%d subframe:%d subframe(TX):%d rnti:%x UE_id:%d dlsch0[harq_ids:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d]\n",
       harq_pid,
       frame,subframe,
       proc->subframe_tx,rel8->rnti,UE_id,
-      dlsch0->harq_ids[0],
-      dlsch0->harq_ids[1],
-      dlsch0->harq_ids[2],
-      dlsch0->harq_ids[3],
-      dlsch0->harq_ids[4],
-      dlsch0->harq_ids[5],
-      dlsch0->harq_ids[6],
-      dlsch0->harq_ids[7],
-      dlsch0->harq_ids[8],
-      dlsch0->harq_ids[9]
+      dlsch0->harq_ids[frame%2][0],
+      dlsch0->harq_ids[frame%2][1],
+      dlsch0->harq_ids[frame%2][2],
+      dlsch0->harq_ids[frame%2][3],
+      dlsch0->harq_ids[frame%2][4],
+      dlsch0->harq_ids[frame%2][5],
+      dlsch0->harq_ids[frame%2][6],
+      dlsch0->harq_ids[frame%2][7],
+      dlsch0->harq_ids[frame%2][8],
+      dlsch0->harq_ids[frame%2][9]
       );
   dlsch0_harq     = dlsch0->harq_processes[harq_pid];
   dlsch1_harq     = dlsch1->harq_processes[harq_pid];
@@ -190,11 +194,19 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
   // compute DL power control parameters
   eNB->pdsch_config_dedicated[UE_id].p_a = rel8->pa;
 
+#ifdef PHY_TX_THREAD
+  if (dlsch0->active[proc->subframe_tx]){
+# else
   if (dlsch0->active){
+#endif
     computeRhoA_eNB(rel8->pa, dlsch0,dlsch0_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
     computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch0,dlsch0_harq->dl_power_off);
   }
+#ifdef PHY_TX_THREAD
+  if (dlsch1->active[proc->subframe_tx]){
+#else
   if (dlsch1->active){
+#endif
     computeRhoA_eNB(rel8->pa, dlsch1,dlsch1_harq->dl_power_off, eNB->frame_parms.nb_antenna_ports_eNB);
     computeRhoB_eNB(rel8->pa,eNB->frame_parms.pdsch_config_common.p_b,eNB->frame_parms.nb_antenna_ports_eNB,dlsch1,dlsch1_harq->dl_power_off);
   }
@@ -202,10 +214,17 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
   dlsch0_harq->pdsch_start = eNB->pdcch_vars[subframe & 1].num_pdcch_symbols;
 
   if (dlsch0_harq->round==0) {  //get pointer to SDU if this a new SDU
-    AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n",
-                frame,subframe,
-                proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid,
-                dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start);
+    if(sdu == NULL) {
+      LOG_E(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n",
+            frame,subframe,
+            proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid,
+            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start);
+      return;
+    }
+    //AssertFatal(sdu!=NULL,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d : sdu is null for pdu_index %d dlsch0_harq[round:%d SFN/SF:%d%d pdu:%p mcs:%d ndi:%d pdschstart:%d]\n",
+    //            frame,subframe,
+    //            proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid,
+    //            dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index,dlsch0_harq->round,dlsch0_harq->frame,dlsch0_harq->subframe,dlsch0_harq->pdu,dlsch0_harq->mcs,dlsch0_harq->ndi,dlsch0_harq->pdsch_start);
     if (rel8->rnti != 0xFFFF) LOG_D(PHY,"NFAPI: SFN/SF:%04d%d proc:TX:[frame %d, subframe %d]: programming dlsch for round 0, rnti %x, UE_id %d, harq_pid %d\n",
                                     frame,subframe,proc->frame_tx,proc->subframe_tx,rel8->rnti,UE_id,harq_pid);
     if (codeword_index == 0) dlsch0_harq->pdu                    = sdu;
@@ -218,7 +237,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
   }
 
 #if (RRC_VERSION >= MAKE_VERSION(13, 0, 0))
+#ifdef PHY_TX_THREAD
+  dlsch0_harq->sib1_br_flag=0;
+#else
   dlsch0->sib1_br_flag=0;
+#endif
 
   if ((rel13->pdsch_payload_type <2) && (rel13->ue_type>0)) { // this is a BR/CE UE and SIB1-BR/SI-BR
     dlsch0->rnti             = 0xFFFF;
@@ -226,7 +249,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
     dlsch0->Mdlharq          = 4;
     dlsch0->Nsoft            = 25344;
 
+#ifdef PHY_TX_THREAD
+    if (rel13->pdsch_payload_type == 0) dlsch0_harq->sib1_br_flag=1;
+#else
     if (rel13->pdsch_payload_type == 0) dlsch0->sib1_br_flag=1;
+#endif
 
     // configure PDSCH
     switch (eNB->frame_parms.N_RB_DL) {
@@ -253,7 +280,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
       dlsch0_harq->rb_alloc[3]      = localRIV2alloc_LUT100_3[rel8->resource_block_coding];
     }
 
+#ifdef PHY_TX_THREAD
+    dlsch0->active[proc->subframe_tx]= 1;
+#else
     dlsch0->active                  = 1;
+#endif
 
     dlsch0_harq->nb_rb              = 6;
     dlsch0_harq->vrb_type           = LOCALIZED;
@@ -268,12 +299,21 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr
     dlsch0_harq->codeword           = 0;
     dlsch0_harq->pdsch_start        = rel10->pdsch_start;
   }
+#ifdef PHY_TX_THREAD
+  dlsch0_harq->i0          = rel13->initial_transmission_sf_io;
+#else
   dlsch0->i0               = rel13->initial_transmission_sf_io;
 #endif
 
+#endif
+
 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", 
+#ifdef PHY_TX_THREAD
+      dlsch0_harq->i0,
+#else
       dlsch0->i0, 
+#endif
       dlsch0_harq->pdsch_start, dlsch0_harq->nb_rb, dlsch0_harq->vrb_type, dlsch0_harq->rvidx, dlsch0_harq->Nl, dlsch0_harq->mimo_mode, dlsch0_harq->dl_power_off, dlsch0_harq->round, dlsch0_harq->status, dlsch0_harq->TBS, dlsch0_harq->Qm, dlsch0_harq->codeword, dlsch0_harq->rb_alloc[0],
       rel8->length
       );
@@ -306,6 +346,10 @@ void handle_ulsch_harq_pdu(
   ulsch_harq->subframe                   = subframe;
   ulsch_harq->O_ACK                      = harq_information->harq_information_rel10.harq_size;
   ulsch->beta_offset_harqack_times8      = to_beta_offset_harqack[harq_information->harq_information_rel10.delta_offset_harq];
+  if (eNB->frame_parms.frame_type == TDD) {
+    if (harq_information->harq_information_rel10.ack_nack_mode==0) //bundling
+        ulsch->bundling = 1;
+   }
 }
 
 uint16_t to_beta_offset_ri[16]={9,13,16,20,25,32,40,50,64,80,101,127,160,0,0,0};
@@ -530,8 +574,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
                          uint16_t frame,uint8_t subframe,uint8_t srs_present)
 {
   nfapi_ul_config_ulsch_pdu_rel8_t *rel8 = &ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8;
-
-  int8_t UE_id;
+  int16_t UE_id;
 
   // check if we have received a dci for this ue and ulsch descriptor is configured
 
@@ -540,14 +583,14 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
                 "No existing UE ULSCH for rnti %x\n",rel8->rnti);
     LOG_D(PHY,"Applying UL config for UE %d, rnti %x for frame %d, subframe %d, modulation %d, rvidx %d\n", UE_id,rel8->rnti,frame,subframe,rel8->modulation_type,rel8->redundancy_version);
 
-    fill_ulsch(eNB,&ul_config_pdu->ulsch_pdu,frame,subframe);
+    fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_pdu,frame,subframe);
 
   }
   else if (ul_config_pdu->pdu_type == NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE) {
     AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
                 "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_harq_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
 
-    fill_ulsch(eNB,&ul_config_pdu->ulsch_harq_pdu.ulsch_pdu,frame,subframe);
+    fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_harq_pdu.ulsch_pdu,frame,subframe);
     handle_ulsch_harq_pdu(eNB, UE_id, ul_config_pdu,
         &ul_config_pdu->ulsch_harq_pdu.harq_information, frame, subframe);
 
@@ -556,7 +599,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
     AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
                                     eNB,SEARCH_EXIST_OR_FREE))>=0,
                 "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
-    fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu,frame,subframe);
+    fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_cqi_ri_pdu.ulsch_pdu,frame,subframe);
     handle_ulsch_cqi_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe);
 
   }
@@ -564,7 +607,7 @@ void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,
     AssertFatal((UE_id = find_ulsch(ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti,
                                     eNB,SEARCH_EXIST_OR_FREE))>=0,
                 "No available UE ULSCH for rnti %x\n",ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu.ulsch_pdu_rel8.rnti);
-    fill_ulsch(eNB,&ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu,frame,subframe);
+    fill_ulsch(eNB,UE_id,&ul_config_pdu->ulsch_cqi_harq_ri_pdu.ulsch_pdu,frame,subframe);
     handle_ulsch_cqi_harq_ri_pdu(eNB,UE_id,ul_config_pdu,frame,subframe);
     handle_ulsch_harq_pdu(eNB, UE_id, ul_config_pdu,
         &ul_config_pdu->ulsch_cqi_harq_ri_pdu.harq_information, frame, subframe);
@@ -656,13 +699,19 @@ void schedule_response(Sched_Rsp_t *Sched_INFO)
   eNB->pdcch_vars[subframe&1].num_dci           = 0;
   eNB->phich_vars[subframe&1].num_hi            = 0;
 
-  LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d hi_dci0:SFN/SF:%04d%d:pdus:%d ul_cfg:SFN/SF:%04d%d:pdus:%d num_pdcch_symbols:%d\n",
-        frame,subframe,
-        NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu,
-        NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus,
-        NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),number_hi_dci0_pdu,
-        NFAPI_SFNSF2SFN(UL_req->sfn_sf),NFAPI_SFNSF2SF(UL_req->sfn_sf),number_ul_pdu, 
-        eNB->pdcch_vars[subframe&1].num_pdcch_symbols);
+  LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SF:%04d%d DL_req:SFN/SF:%04d%d:dl_pdu:%d tx_req:SFN/SF:%04d%d:pdus:%d\n",
+       frame,subframe,
+       NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),number_dl_pdu,
+       NFAPI_SFNSF2SFN(TX_req->sfn_sf),NFAPI_SFNSF2SF(TX_req->sfn_sf),TX_req->tx_request_body.number_of_pdus
+       );
+  LOG_D(PHY,"NFAPI: hi_dci0:SFN/SF:%04d%d:pdus:%d\n",
+        NFAPI_SFNSF2SFN(HI_DCI0_req->sfn_sf),NFAPI_SFNSF2SF(HI_DCI0_req->sfn_sf),number_hi_dci0_pdu
+       );
+  if(UL_req!=NULL)
+    LOG_D(PHY,"NFAPI: ul_cfg:SFN/SF:%04d%d:pdus:%d num_pdcch_symbols:%d\n",
+          NFAPI_SFNSF2SFN(UL_req->sfn_sf),NFAPI_SFNSF2SF(UL_req->sfn_sf),number_ul_pdu,
+          eNB->pdcch_vars[subframe&1].num_pdcch_symbols);
+
 
   int do_oai =0;
   int dont_send =0;
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 81679f199c64b506de424bfb20bcf03ababa2deb..26a518e8ef5474ae8b194696fab446c2641af1d0 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -336,6 +336,29 @@ unsigned char ul_ACK_subframe2_dl_subframe(LTE_DL_FRAME_PARMS *frame_parms,unsig
   return(0);
 }
 
+int ul_ACK_subframe2_dl_frame(LTE_DL_FRAME_PARMS *frame_parms,int frame, unsigned char subframe,unsigned char subframe_tx)
+{
+
+  if (frame_parms->frame_type == FDD) {
+    return (((subframe_tx > subframe ) ? frame-1 : frame)+1024)%1024;
+  } else {
+    switch (frame_parms->tdd_config) {
+    case 1:
+      return(((subframe_tx > subframe ) ? frame-1 : frame)+1024)%1024;
+      break;
+    case 3:
+        //TODO
+      break;
+    case 4:
+        //TODO
+      break;
+    }
+  }
+
+  return(0);
+}
+
+
 unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe)
 {
 
@@ -343,6 +366,23 @@ unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char s
     return(1);
   } else {
     switch (frame_parms->tdd_config) {
+    case 1:
+        return 1; // don't ACK special subframe for now
+      if (subframe == 2) {  // ACK subframes 5 and 6
+        return(2);
+      } else if (subframe == 3) { // ACK subframe 9
+        return(1);  // To be updated
+      } else if (subframe == 7) { // ACK subframes 0 and 1
+        return(2);  // To be updated
+      } else if (subframe == 8) { // ACK subframe 4
+        return(1);  // To be updated
+      } else {
+        LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n",
+              subframe,frame_parms->tdd_config);
+        return(0);
+      }
+
+      break;
     case 3:
       if (subframe == 2) {  // ACK subframes 5 and 6
         return(2); // should be 3
@@ -381,23 +421,6 @@ unsigned char ul_ACK_subframe2_M(LTE_DL_FRAME_PARMS *frame_parms,unsigned char s
               }
 
               break;
-
-    case 1:
-      if (subframe == 2) {  // ACK subframes 5 and 6
-        return(2);
-      } else if (subframe == 3) { // ACK subframe 9
-        return(1);  // To be updated
-      } else if (subframe == 7) { // ACK subframes 0 and 1
-        return(2);  // To be updated
-      } else if (subframe == 8) { // ACK subframe 4
-        return(1);  // To be updated
-      } else {
-        LOG_E(PHY,"phy_procedures_lte_common.c/subframe2_dl_harq_pid: illegal subframe %d for tdd_config %d\n",
-              subframe,frame_parms->tdd_config);
-        return(0);
-      }
-
-      break;
     }
   }
 
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index 7fbc6a1745bd6f4ec46d10b8f332765f302e3665..69cd78c0adaf2550ce8230e71bbfe28fee4afb46 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -55,7 +55,7 @@ extern uint8_t nfapi_mode;
 
 
 
-int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint8_t UE_id,uint8_t harq_pid, uint8_t bw_factor)
+int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor)
 {
 
   uint32_t Nre,sumKr,MPR_x100,Kr,r;
@@ -195,10 +195,20 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
 
   // generate Cell-Specific Reference Signals for both slots
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
+
+   if(subframe_select(fp,subframe) == SF_S)
+       generate_pilots_slot(eNB,
+                    txdataF,
+                    AMP,
+                    subframe<<1,1);
+   else
   generate_pilots_slot(eNB,
 		       txdataF,
 		       AMP,
 		       subframe<<1,0);
+
+ // check that 2nd slot is for DL
+
   // check that 2nd slot is for DL
   if (subframe_select(fp,subframe) == SF_DL)
     generate_pilots_slot(eNB,
@@ -435,15 +445,19 @@ void pdsch_procedures(PHY_VARS_eNB *eNB,
     dlsch_modulation(eNB,
 		   eNB->common_vars.txdataF,
 		   AMP,
+		   frame,
 		   subframe,
 		   dlsch_harq->pdsch_start,
 		   dlsch,
 		   dlsch1);
   
-    stop_meas(&eNB->dlsch_modulation_stats);
+  stop_meas(&eNB->dlsch_modulation_stats);
   }
-
+#ifdef PHY_TX_THREAD
+  dlsch->active[subframe] = 0;
+#else
   dlsch->active = 0;
+#endif
   dlsch_harq->round++;
 
   LOG_D(PHY,"Generating DLSCH/PDSCH dlsch_harq[round:%d]\n",dlsch_harq->round);
@@ -460,7 +474,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
   int subframe=proc->subframe_tx;
   uint32_t i,aa;
   uint8_t harq_pid;
-  int8_t UE_id=0;
+  int16_t UE_id=0;
   uint8_t num_pdcch_symbols=0;
   uint8_t num_dci=0;
   uint8_t ul_subframe;
@@ -586,10 +600,14 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
       if ((dlsch0)&&
 	  (dlsch0->rnti>0)&&
+#ifdef PHY_TX_THREAD
+	  (dlsch0->active[subframe] == 1)) {
+#else
 	  (dlsch0->active == 1)) {
+#endif
 
 	// get harq_pid
-	harq_pid = dlsch0->harq_ids[subframe];
+	harq_pid = dlsch0->harq_ids[frame%2][subframe];
 	AssertFatal(harq_pid>=0,"harq_pid is negative\n");
 
         if (harq_pid>=8)
@@ -614,8 +632,12 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
 
 
       else if ((dlsch0)&&
-          (dlsch0->rnti>0)&&
-          (dlsch0->active == 0)) {
+	       (dlsch0->rnti>0)&&
+#ifdef PHY_TX_THREAD
+	       (dlsch0->active[subframe] == 0)) {
+#else
+           (dlsch0->active == 0)) {
+#endif
 
         // clear subframe TX flag since UE is not scheduled for PDSCH in this subframe (so that we don't look for PUCCH later)
         dlsch0->subframe_tx[subframe]=0;
@@ -686,7 +708,7 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u
   pdu->rx_ue_information.tl.tag                       = NFAPI_RX_UE_INFORMATION_TAG;
   pdu->rx_ue_information.rnti                         = rnti;
 
-  int SNRtimes10 = dB_fixed_times10(stat) - 200;//(10*eNB->measurements.n0_power_dB[0]);
+  int SNRtimes10 = dB_fixed_times10(stat) - 300;//(10*eNB->measurements.n0_power_dB[0]);
 
 
   pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
@@ -749,7 +771,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
         LOG_E(PHY,"Unknown number for N_RB_UL %d\n",fp->N_RB_UL);
         break;
       }
-
+      SR_payload = 0;
       switch (uci->type) {
       case SR:
       case HARQ_SR:
@@ -764,20 +786,21 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 			      frame,
 			      subframe,
 			      PUCCH1_THRES);
-	LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (SR n1pucch is %d)\n",
+	LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking SR is %d (uci.type %d SR n1pucch is %d)\n",
 	      eNB->Mod_id,
 	      uci->rnti,
 	      frame,
 	      subframe,
 	      SR_payload,
+              uci->type,
 	      uci->n_pucch_1_0_sr[0]);
 	if (uci->type == SR) {
 	  if (SR_payload == 1) {
 	    fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
-        continue;
+	    break;
 	  }
 	  else {
-        continue;
+	    break;
 	  }
 	}
       case HARQ:
@@ -832,8 +855,34 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 
 	}
 	else { // frame_type == TDD
-
-
+#if 1
+	      metric[0] = rx_pucch(eNB,
+	                   uci->pucch_fmt,
+	                   i,
+	                   uci->n_pucch_1[0][0],
+	                   0, //n2_pucch
+	                   uci->srs_active, // shortened format
+	                   pucch_b0b1[0],
+	                   frame,
+	                   subframe,
+	                   PUCCH1a_THRES);
+	      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,metric_SR);
+
+	      if (uci->type==HARQ_SR && metric[0] <= metric_SR) {
+	          SR_payload = 1;
+	          metric[0] = rx_pucch(eNB,
+	                     pucch_format1b,
+	                     i,
+	                     uci->n_pucch_1_0_sr[0],
+	                     0, //n2_pucch
+	                     uci->srs_active, // shortened format
+	                     pucch_b0b1[0],
+	                     frame,
+	                     subframe,
+	                     PUCCH1a_THRES);
+	      }
+#else
 	  // if SR was detected, use the n1_pucch from SR
 	  if (SR_payload==1) {
 #ifdef DEBUG_PHY_PROC
@@ -880,22 +929,25 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	    
 
 	  }
-
-	  
+#ifdef DEBUG_PHY_PROC
+ 	      LOG_D(PHY,"RNTI %x type %d SR_payload %d  Frame %d Subframe %d  pucch_b0b1[0][0] %d pucch_b0b1[0][1] %d pucch_b0b1[1][0] %d pucch_b0b1[1][1] %d  \n",
+	              uci->rnti,uci->type,SR_payload,frame,subframe,pucch_b0b1[0][0],pucch_b0b1[0][1],pucch_b0b1[1][0],pucch_b0b1[1][1]);
+#endif
+#endif
 	  if (SR_payload == 1) { // this implements Table 7.3.1 from 36.213
 	    if (pucch_b0b1[0][0] == 4) { // there isn't a likely transmission
 	      harq_ack[0] = 4; // DTX
 	    }
-	    else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] == 1) { // 1/4/7 ACKs
+	    else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] == 1) { // 1/4/7 ACKs
 	      harq_ack[0] = 1;
 	    }
-	    else if (pucch_b0b1[1][0] == 1 && pucch_b0b1[1][1] != 1) { // 2/5/8 ACKs
+	    else if (pucch_b0b1[0][0] == 1 && pucch_b0b1[0][1] != 1) { // 2/5/8 ACKs
 	      harq_ack[0] = 2;
 	    }
-	    else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] == 1) { // 3/6/9 ACKs
+	    else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] == 1) { // 3/6/9 ACKs
 	      harq_ack[0] = 3;
 	    }
-	    else if (pucch_b0b1[1][0] != 1 && pucch_b0b1[1][1] != 1) { // 0 ACKs, or at least one DL assignment missed
+	    else if (pucch_b0b1[0][0] != 1 && pucch_b0b1[0][1] != 1) { // 0 ACKs, or at least one DL assignment missed
 	      harq_ack[0] = 0;
 	    }
         uci->stat = metric[0];
@@ -1211,8 +1263,7 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
   const int subframe = proc->subframe_rx;
   const int frame    = proc->frame_rx;
   
-  if (fp->frame_type == FDD) harq_pid = ((10*frame) + subframe)&7;
-  else                       harq_pid = subframe%10;
+  harq_pid = subframe2harq_pid(&eNB->frame_parms,frame,subframe);
 
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
     ulsch = eNB->ulsch[i];
@@ -1283,8 +1334,8 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
             ulsch->rnti,
             dB_fixed(eNB->pusch_vars[i]->ulsch_power[0]),
             dB_fixed(eNB->pusch_vars[i]->ulsch_power[1]),
-            20,//eNB->measurements.n0_power_dB[0],
-            20,//eNB->measurements.n0_power_dB[1],
+            30,//eNB->measurements.n0_power_dB[0],
+            30,//eNB->measurements.n0_power_dB[1],
             ulsch_harq->o_ACK[0],
             ulsch_harq->o_ACK[1],
             ret,
@@ -1304,6 +1355,13 @@ void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	fill_ulsch_cqi_indication(eNB,frame,subframe,
 				  ulsch_harq,
 				  ulsch->rnti);
+	        RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe));
+      }else{
+          if(RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag & (1 << subframe) ){
+              RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_flag &= (~(1 << subframe));
+              RC.mac[eNB->Mod_id]->UE_list.UE_sched_ctrl[i].cqi_req_timer=30;
+              LOG_D(PHY,"Frame %d,Subframe %d, We're supposed to get a cqi here. Set cqi_req_timer to 30.\n",frame,subframe);
+          }
       }
       
       if (ret == (1+MAX_TURBO_ITERATIONS)) {
@@ -1516,7 +1574,7 @@ void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe)
   pdu->rx_indication_rel8.timing_advance = timing_advance_update;
 
   // 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]);
+  int SNRtimes10 = dB_fixed_times10(eNB->pusch_vars[UE_id]->ulsch_power[0]) - 300;//(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;
@@ -1538,7 +1596,7 @@ static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,ui
   LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
   int harq_pid;
-  int subframe_tx;
+  int subframe_tx,frame_tx;
   int M,m;
 
   AssertFatal(UE_id!=-1,"no existing dlsch context\n");
@@ -1548,7 +1606,9 @@ static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,ui
 
   if (eNB->frame_parms.frame_type == FDD) {  
     subframe_tx = (subframe+6)%10;
-    harq_pid = dlsch0->harq_ids[subframe_tx];
+    frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame,subframe,subframe_tx);
+    harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx]; // or just use 0 for fdd?
+
     AssertFatal((harq_pid>=0) && (harq_pid<10),"harq_pid %d not in 0...9\n",harq_pid);
     dlsch0_harq     = dlsch0->harq_processes[harq_pid];
     dlsch1_harq     = dlsch1->harq_processes[harq_pid];
@@ -1573,9 +1633,10 @@ static void do_release_harq(PHY_VARS_eNB *eNB,int UE_id,int tb,uint16_t frame,ui
       subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms,
 						 subframe,
 						 m);
+      frame_tx = ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame,subframe,subframe_tx);
       if (((1<<m)&mask) > 0) {
-	harq_pid = dlsch0->harq_ids[subframe_tx];
-	if ((harq_pid>=0) && (harq_pid<10)) {
+          harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx];
+	if ((harq_pid>=0) && (harq_pid<dlsch0->Mdlharq)) {
 	  dlsch0_harq     = dlsch0->harq_processes[harq_pid];
 	  dlsch1_harq     = dlsch1->harq_processes[harq_pid];
 	  AssertFatal(dlsch0_harq!=NULL,"dlsch0_harq is null\n");
@@ -1608,7 +1669,7 @@ int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
   LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
   LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
   int harq_pid;
-  int subframe_tx;
+  int subframe_tx,frame_tx;
   int m;
 
   M=ul_ACK_subframe2_M(&eNB->frame_parms,
@@ -1618,7 +1679,10 @@ int getM(PHY_VARS_eNB *eNB,int frame,int subframe) {
     subframe_tx = ul_ACK_subframe2_dl_subframe(&eNB->frame_parms,
 					       subframe,
 					       m);
-    harq_pid = dlsch0->harq_ids[subframe_tx];
+    frame_tx =  ul_ACK_subframe2_dl_frame(&eNB->frame_parms,frame,
+                                            subframe,subframe_tx);
+    harq_pid = dlsch0->harq_ids[frame_tx%2][subframe_tx];
+
     if (harq_pid>=0 && harq_pid<10) {
       dlsch0_harq     = dlsch0->harq_processes[harq_pid];
       dlsch1_harq     = dlsch1->harq_processes[harq_pid];
@@ -1667,15 +1731,11 @@ 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)
 {
   int UE_id = find_dlsch(rnti,eNB,SEARCH_EXIST);
-  //AssertFatal(UE_id>=0,"UE_id doesn't exist\n");
-
-  if (UE_id < 0)
-  {
-    LOG_E(PHY,"%s(eNB, ulsch_harq, rnti:%04x, frame:%d, subframe:%d, bundling:%d) harq_pdus:%d - Could not find rnti - abort fill of ulsch harq ind\n", __FUNCTION__, rnti, frame, subframe, bundling,eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs);
+  if( (UE_id<0) || (UE_id>=NUMBER_OF_UE_MAX) ){
+    LOG_E(PHY,"illegal UE_id found!!! rnti %04x UE_id %d\n",rnti,UE_id);
     return;
   }
-
-  LOG_D(PHY,"%s(eNB, ulsch_harq, rnti:%04x, frame:%d, subframe:%d, bundling:%d) harq_pdus:%d O_ACK:%d\n", __FUNCTION__, rnti, frame, subframe, bundling,eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,ulsch_harq->O_ACK);
+  //AssertFatal(UE_id>=0,"UE_id doesn't exist\n");
 
   pthread_mutex_lock(&eNB->UL_INFO_mutex);
   nfapi_harq_indication_pdu_t *pdu =   &eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list[eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs];
@@ -1707,12 +1767,16 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
 
 #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]));
+      {
+        int subframe_tx = (subframe+6)%10;
+        int frame_tx = subframe_tx >= 6 ? (frame+1023)%1024 : frame;
+        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[frame_tx%2][subframe_tx]));
+        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[frame_tx%2][subframe_tx]));
+      }
 #endif
     }
   }
@@ -1727,7 +1791,7 @@ void fill_ulsch_harq_indication(PHY_VARS_eNB *eNB,LTE_UL_eNB_HARQ_t *ulsch_harq,
     for (i=0;i<ulsch_harq->O_ACK;i++) {
       AssertFatal(ulsch_harq->o_ACK[i] == 0 || ulsch_harq->o_ACK[i] == 1, "harq_ack[%d] is %d, should be 1,2 or 4\n",i,ulsch_harq->o_ACK[i]);
 
-      pdu->harq_indication_tdd_rel13.harq_data[0].multiplex.value_0 = 2-ulsch_harq->o_ACK[i];
+      pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 2-ulsch_harq->o_ACK[i];
       // release DLSCH if needed
       /* TODO: review this code, it's most certainly wrong.
        * We have to release the proper HARQ in case of ACK or NACK if max retransmission reached.
@@ -1783,7 +1847,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 
   // estimate UL_CQI for MAC (from antenna port 0 only)
   pdu->ul_cqi_information.tl.tag = NFAPI_UL_CQI_INFORMATION_TAG;
-  int SNRtimes10 = dB_fixed_times10(uci->stat) - 200;//(10*eNB->measurements.n0_power_dB[0]);
+  int SNRtimes10 = dB_fixed_times10(uci->stat) - 300;//(10*eNB->measurements.n0_power_dB[0]);
 
   if (SNRtimes10 < -100) LOG_I(PHY,"uci->stat %d \n",uci->stat);
 
@@ -1805,12 +1869,16 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 
 
 #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]));
+      {
+        int subframe_tx = (subframe+6)%10;
+        int frame_tx = subframe_tx >= 6 ? (frame+1023)%1024 : frame;
+        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[frame_tx%2][subframe_tx]));
+        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[frame_tx%2][subframe_tx]));
+      }
 #endif
     }
     else if (uci->pucch_fmt == pucch_format1b) {
@@ -1834,7 +1902,7 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
 
     pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
     pdu->harq_indication_tdd_rel13.mode = tdd_mapping_mode;  
-
+    LOG_D(PHY,"%s(eNB, uci_harq format %d, rnti:%04x, frame:%d, subframe:%d, tdd_mapping_mode:%d) harq_ack[0]:%d harq_ack[1]:%d\n", __FUNCTION__, uci->pucch_fmt,uci->rnti, frame, subframe, tdd_mapping_mode,harq_ack[0],harq_ack[1]);
     switch (tdd_mapping_mode) {
     case 0: // bundling
 
@@ -1896,32 +1964,44 @@ void fill_uci_harq_indication(PHY_VARS_eNB *eNB,
     case 2: // special bundling (SR collision)
       pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG;
       pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1;
+      pdu->harq_indication_tdd_rel13.mode = 0;
       int tdd_config5_sf2scheds=0;
       if (eNB->frame_parms.tdd_config==5) tdd_config5_sf2scheds = getM(eNB,frame,subframe);
  
       switch (harq_ack[0]) {
       case 0:
+      case 4:
+          pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0;
         /* TODO: release_harq here? this whole code looks suspicious */
 	break;
       case 1: // check if M=1,4,7
 	if (uci->num_pucch_resources == 1 || uci->num_pucch_resources == 4 ||
 	    tdd_config5_sf2scheds == 1 || tdd_config5_sf2scheds == 4 || tdd_config5_sf2scheds == 7) {
+	    pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
 	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
 	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
+	}else{
+          pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0;
 	}
 	break;
       case 2: // check if M=2,5,8
 	if (uci->num_pucch_resources == 2 || tdd_config5_sf2scheds == 2 || 
 	    tdd_config5_sf2scheds == 5 || tdd_config5_sf2scheds == 8) {
+	    pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
 	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
 	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
+	}else{
+          pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0;
 	}
 	break;
       case 3: // check if M=3,6,9
 	if (uci->num_pucch_resources == 3 || tdd_config5_sf2scheds == 3 || 
 	    tdd_config5_sf2scheds == 6 || tdd_config5_sf2scheds == 9) {
+	    pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1;
 	  release_harq(eNB,UE_id,0,frame,subframe,0xffff, 1);
 	  release_harq(eNB,UE_id,1,frame,subframe,0xffff, 1);
+	}else{
+          pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 0;
 	}
 	break;
       }
diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c
index d5a78c7f98e05be2c8a72687643f9ba1c3e92313..5f65f81fbea2aef7e58495ddcd74fcec1c9ccacf 100644
--- a/openair1/SCHED/ru_procedures.c
+++ b/openair1/SCHED/ru_procedures.c
@@ -111,7 +111,7 @@ void feptx0(RU_t *ru,int slot) {
     }
 */
     // TDD: turn on tx switch N_TA_offset before by setting buffer in these samples to 0    
-    if ((slot == 0) &&
+/*    if ((slot == 0) &&
         (fp->frame_type == TDD) && 
         ((fp->tdd_config==0) ||
          (fp->tdd_config==1) ||
@@ -128,7 +128,7 @@ void feptx0(RU_t *ru,int slot) {
 	
 	ru->common.txdata[aa][tx_offset] = 0x00000000;
       }
-    }
+    }*/
   }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPTX_OFDM+slot , 0);
 }
diff --git a/openair1/SCHED/sched_common.h b/openair1/SCHED/sched_common.h
index 30de6dbb4a3c201761b7158bdc863f4407590b81..fdf365af1c72587f4506fa906ab860e56bd7c8ba 100644
--- a/openair1/SCHED/sched_common.h
+++ b/openair1/SCHED/sched_common.h
@@ -322,9 +322,7 @@ LTE_DL_FRAME_PARMS *get_lte_frame_parms(module_id_t Mod_id, uint8_t CC_id);
 MU_MIMO_mode* get_mu_mimo_mode (module_id_t Mod_id, uint8_t CC_id, rnti_t rnti);
 
 int16_t get_hundred_times_delta_IF(PHY_VARS_UE *phy_vars_ue,uint8_t eNB_id,uint8_t harq_pid);
-
-int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid, uint8_t bw_factor);
-
+int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor);
 int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid);
 
 int16_t get_target_pusch_rx_power(module_id_t module_idP, uint8_t CC_id);
diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h
index e03b7f6b62be7579cdefd02a17b69db3e2809c95..cf6c5815f203bf1ac410bd292e2ca26ae0178d6c 100644
--- a/openair1/SCHED/sched_eNB.h
+++ b/openair1/SCHED/sched_eNB.h
@@ -127,7 +127,7 @@ void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc);
   @param phy_vars_eNB Pointer to eNB variables on which to act
   @param br_flag indicator for eMTC PRACH
 */
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 void prach_procedures(PHY_VARS_eNB *eNB,
 		      int br_flag);
 #else
@@ -208,7 +208,7 @@ LTE_eNB_UE_stats* get_UE_stats(uint8_t Mod_id, uint8_t CC_id,uint16_t rnti);
 lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subframe);
 
 
-int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid, uint8_t bw_factor);
+int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *phy_vars_eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor);
 
 int16_t get_hundred_times_delta_IF_mac(module_id_t module_idP, uint8_t CC_id, rnti_t rnti, uint8_t harq_pid);
 
diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c
index da788d343ca04e33720b2d9add754a1d0f6238f7..215b93bd463072c34daaa30bec605ed9c1d8e37b 100644
--- a/openair1/SCHED_UE/phy_procedures_lte_ue.c
+++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c
@@ -204,9 +204,14 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
 unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb)
 {
 
-  int gain_dB = power_dBm - power_max_dBm;
+  int gain_dB;
   double gain_lin;
 
+  if (power_dBm<=power_max_dBm)
+    gain_dB = power_dBm - power_max_dBm;
+  else
+    gain_dB = 0;
+
   gain_lin = pow(10,.1*gain_dB);
   AssertFatal((nb_rb >0) && (nb_rb <= N_RB_UL),"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL);
   return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb)));
@@ -252,7 +257,7 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s
   write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
 }
 
-void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
+void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
 {
 
   // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
@@ -352,7 +357,7 @@ void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t ti
 
 }
 
-void process_timing_advance(uint8_t Mod_id,uint8_t CC_id,int16_t timing_advance)
+void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance)
 {
 
   //  uint32_t frame = PHY_vars_UE_g[Mod_id]->frame;
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
index 90ba1ec8044e81b6491e98a82e26a14c3909ad73..20682a57be8e87cd48019a8f5bc5ad399a3a0822 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
@@ -3426,6 +3426,7 @@ int main(int argc, char **argv)
               re_allocated = dlsch_modulation(eNB,
                                               eNB->common_vars.txdataF[eNB_id],
                                               AMP,
+                                              frame,
                                               subframe,
                                               num_pdcch_symbols,
                                               ((TB0_active == 1)? eNB->dlsch[k][0]: NULL),
diff --git a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
index 3c4b3d0cd308cf8ea52667ff25f8ade505607f88..e1385e68f1fd064de1fc9b90e972730354868db0 100644
--- a/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
+++ b/openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
@@ -2679,6 +2679,7 @@ PMI_FEEDBACK:
               re_allocated = dlsch_modulation(eNB,
 					      eNB->common_vars.txdataF[eNB_id],
                                               AMP,
+                                              frame,
                                               subframe,
                                               num_pdcch_symbols,
                                               eNB->dlsch[k][0],
diff --git a/openair1/SIMULATION/LTE_PHY/dummy_functions.c b/openair1/SIMULATION/LTE_PHY/dummy_functions.c
index ac96d53b0f5d2f6baa8bc91c849813c15b621eb9..586193484dd968d8564ad82c9f710c6a252fc246 100644
--- a/openair1/SIMULATION/LTE_PHY/dummy_functions.c
+++ b/openair1/SIMULATION/LTE_PHY/dummy_functions.c
@@ -60,7 +60,7 @@ void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 		     uint8_t * sdu, uint16_t sdu_len, uint8_t eNB_index,
 		     uint8_t sync_area){}
 
-int ue_query_mch(uint8_t Mod_id, uint8_t CC_id, uint32_t frame,
+int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
 		 sub_frame_t subframe, uint8_t eNB_index,
 		 uint8_t * sync_area, uint8_t * mcch_active){ return(0);}
 
diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h
index fb229bf951b58d757ab0c9f2253a110dc1974baf..d902de15d9f2b51bbeb2db9e028dfa5324f239b8 100644
--- a/openair2/COMMON/mac_rrc_primitives.h
+++ b/openair2/COMMON/mac_rrc_primitives.h
@@ -365,7 +365,7 @@ typedef struct {
 #endif
                            );
   unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, const unsigned int,char*
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                   ,uint32_t
                                   ,uint32_t
 #endif
@@ -373,7 +373,7 @@ typedef struct {
   void (*mac_rlc_data_ind)(module_id_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* );
   mac_rlc_status_resp_t (*mac_rlc_status_ind)     (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, sub_frame_t subframeP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP,
       logical_chan_id_t channel_idP, tb_size_t tb_sizeP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
       ,uint32_t sourceL2Id
       ,uint32_t destinationL2Id
 #endif
diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h
index bb8fa7bb1c2ed9f5a3224f3906e3544fcd4dd760..3f736e5b3cf5406c1b22d930142320aa393282dc 100644
--- a/openair2/COMMON/platform_types.h
+++ b/openair2/COMMON/platform_types.h
@@ -68,7 +68,7 @@ typedef int32_t               sdu_size_t;
 typedef uint32_t              frame_t;
 typedef int32_t               sframe_t;
 typedef uint32_t              sub_frame_t;
-typedef uint8_t               module_id_t;
+typedef uint16_t               module_id_t;
 typedef uint8_t               slice_id_t;
 typedef uint8_t               eNB_index_t;
 typedef uint16_t              ue_id_t;
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 5625c9fab501ddf03384b7bc84460e1611ebe73d..7ef9a960f92fbbc687f554932abd664a652a16a0 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -123,9 +123,9 @@ typedef struct RrcConfigurationReq_s {
   long                    pucch_delta_shift[MAX_NUM_CCs];
   long                    pucch_nRB_CQI[MAX_NUM_CCs];
   long                    pucch_nCS_AN[MAX_NUM_CCs];
-#if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
+//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
   long                    pucch_n1_AN[MAX_NUM_CCs];
-#endif
+//#endif
   long                    pdsch_referenceSignalPower[MAX_NUM_CCs];
   long                    pdsch_p_b[MAX_NUM_CCs];
   long                    pusch_n_SB[MAX_NUM_CCs];
@@ -174,6 +174,7 @@ typedef struct RrcConfigurationReq_s {
   long                    ue_TimersAndConstants_n310[MAX_NUM_CCs];
   long                    ue_TimersAndConstants_n311[MAX_NUM_CCs];
   long                    ue_TransmissionMode[MAX_NUM_CCs];
+  long                    ue_multiple_max[MAX_NUM_CCs];
 
   //TTN - for D2D
   //SIB18
@@ -219,13 +220,10 @@ typedef struct RrcConfigurationReq_s {
   char*                          discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs];
   long                           discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs];
   long                           discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs];
-
-
-
-
-
 } RrcConfigurationReq;
+
 #define MAX_NUM_NBIOT_CELEVELS    3
+
 typedef struct NbIoTRrcConfigurationReq_s {
   uint32_t            cell_identity;
 
diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h
index 4e732fe942bee9528bf6bde32e60e4b2cd2cbba6..ef7d5987852bfaa90c3c17d72f3445e2879e6e53 100644
--- a/openair2/ENB_APP/MACRLC_paramdef.h
+++ b/openair2/ENB_APP/MACRLC_paramdef.h
@@ -53,7 +53,10 @@
 #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_SCHED_MODE                    "scheduler_mode"
+#define CONFIG_STRING_MACRLC_PHY_TEST_MODE                 "phy_test_mode"
+#define CONFIG_MACRLC_PUSCH10xSNR                          "puSch10xSnr"
+#define CONFIG_MACRLC_PUCCH10xSNR                          "puCch10xSnr"
 
 /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/
 /*                                            MacRLC  configuration parameters                                                                           */
@@ -77,6 +80,10 @@
 {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_SCHED_MODE,                        NULL,     0,          strptr:NULL,         defstrval:"default",       TYPE_STRING,   0},        \
+{CONFIG_STRING_MACRLC_PHY_TEST_MODE,                     NULL,     0,          uptr:NULL,           defintval:1,               TYPE_UINT,     0},        \
+{CONFIG_MACRLC_PUSCH10xSNR,  		                 NULL,     0,          iptr:NULL,           defintval:200,             TYPE_INT,      0},        \
+{CONFIG_MACRLC_PUCCH10xSNR,  		                 NULL,     0,          iptr:NULL,           defintval:200,             TYPE_INT,      0},        \
 }
 #define MACRLC_CC_IDX                                          0
 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX                      1
@@ -95,4 +102,8 @@
 #define MACRLC_REMOTE_S_PORTC_IDX                              14
 #define MACRLC_LOCAL_S_PORTD_IDX                               15
 #define MACRLC_REMOTE_S_PORTD_IDX                              16
+#define MACRLC_SCHED_MODE_IDX                                  17
+#define MACRLC_PHY_TEST_IDX                                    18
+#define MACRLC_PUSCH10xSNR_IDX                                 19
+#define MACRLC_PUCCH10xSNR_IDX                                 20
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c
index d1b1b750261a1c2f5f92921d35525649b50f4d36..3b65dfafdbafa734c709bef2e263f0641b733010 100644
--- a/openair2/ENB_APP/enb_config.c
+++ b/openair2/ENB_APP/enb_config.c
@@ -102,6 +102,7 @@ void RCconfig_flexran()
     ue_TimersAndConstants_n310, ue_TimersAndConstants_n311,
     ue_TransmissionMode;
 
+    int32_t     ue_multiple_max               = 0;
 
     e_SL_CP_Len_r12                rxPool_sc_CP_Len;
     e_SL_PeriodComm_r12            rxPool_sc_Period;
@@ -387,6 +388,8 @@ void RCconfig_macrlc() {
     RC.nb_mac_CC = (int*)malloc(RC.nb_macrlc_inst*sizeof(int));
 
     for (j=0;j<RC.nb_macrlc_inst;j++) {
+      RC.mac[j]->puSch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCH10xSNR_IDX ].iptr);
+      RC.mac[j]->puCch10xSnr = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCH10xSNR_IDX ].iptr);
       RC.nb_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr);
       //RC.mac[j]->phy_test = *(MacRLC_ParamList.paramarray[j][MACRLC_PHY_TEST_IDX].iptr);
       //printf("PHY_TEST = %d,%d\n", RC.mac[j]->phy_test, j);
@@ -427,7 +430,17 @@ void RCconfig_macrlc() {
         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: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr));
-      }	
+      }
+      if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "default") == 0){
+      	global_scheduler_mode=SCHED_MODE_DEFAULT;
+      	printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
+      }else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "fairRR") == 0){
+      	global_scheduler_mode=SCHED_MODE_FAIR_RR;
+      	printf("sched mode = fairRR %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
+      }else{
+      	global_scheduler_mode=SCHED_MODE_DEFAULT;
+      	printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr));
+      }
     }// j=0..num_inst
   } else {// MacRLC_ParamList.numelt > 0
 	  AssertFatal (0,
@@ -521,6 +534,8 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
   int32_t     ue_TimersAndConstants_n311    = 0;
   int32_t     ue_TransmissionMode           = 0;
 
+  int32_t     ue_multiple_max               = 0;
+
   //TTN - for D2D
   //SIB18
   const char*       rxPool_sc_CP_Len                                        = NULL;
@@ -567,7 +582,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
   libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size        = 0;
   libconfig_int     discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0;
 
-
   int32_t     srb1_timer_poll_retransmit    = 0;
   int32_t     srb1_timer_reordering         = 0;
   int32_t     srb1_timer_status_prohibit    = 0;
@@ -918,13 +932,11 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 			     RC.config_file_name, i, prach_zero_correlation);
 	      
 	      RRC_CONFIGURATION_REQ (msg_p).prach_freq_offset[j] = prach_freq_offset;
-	      
 	      if ((prach_freq_offset <0) || (prach_freq_offset > 94))
 		AssertFatal (0,
 			     "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for prach_freq_offset choice: 0..94!\n",
 			     RC.config_file_name, i, prach_freq_offset);
 	      
-	      
 	      RRC_CONFIGURATION_REQ (msg_p).pucch_delta_shift[j] = pucch_delta_shift-1;
 	      
 	      if ((pucch_delta_shift <1) || (pucch_delta_shift > 3))
@@ -946,7 +958,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 			       "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n",
 			       RC.config_file_name, i, pucch_nCS_AN);
 
-#if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
+//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
 		RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[j] = pucch_n1_AN;
 
 		if ((pucch_n1_AN <0) || (pucch_n1_AN > 2047))
@@ -954,7 +966,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 			       "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_n1_AN choice: 0..2047!\n",
 			       RC.config_file_name, i, pucch_n1_AN);
 
-#endif
+//#endif
 		RRC_CONFIGURATION_REQ (msg_p).pdsch_referenceSignalPower[j] = pdsch_referenceSignalPower;
 
 		if ((pdsch_referenceSignalPower <-60) || (pdsch_referenceSignalPower > 50))
@@ -1580,6 +1592,34 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) {
 		  break;
 		}
 
+        RRC_CONFIGURATION_REQ (msg_p).ue_multiple_max[j] = ue_multiple_max;
+
+        switch (N_RB_DL) {
+        case 25:
+          if ((ue_multiple_max < 1) || (ue_multiple_max > 4))
+            AssertFatal (0,
+                     "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..4!\n",
+                     RC.config_file_name, i, ue_multiple_max);
+          break;
+        case 50:
+          if ((ue_multiple_max < 1) || (ue_multiple_max > 8))
+            AssertFatal (0,
+                     "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..8!\n",
+                     RC.config_file_name, i, ue_multiple_max);
+          break;
+        case 100:
+          if ((ue_multiple_max < 1) || (ue_multiple_max > 16))
+            AssertFatal (0,
+                     "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for ue_multiple_max choice: 1..16!\n",
+                     RC.config_file_name, i, ue_multiple_max);
+          break;
+        default:
+          AssertFatal (0,
+                   "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 25,50,100 !\n",
+                   RC.config_file_name, i, N_RB_DL);
+          break;
+        }
+
 		//TTN - for D2D
 		//SIB18
 		if (strcmp(rxPool_sc_CP_Len,"normal")==0) {
diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h
index 9d057b86197a28e513276bc031e819787c0060c6..23b4c2a8376e90349ce8a7f03fbc36dd85dcfb0a 100755
--- a/openair2/ENB_APP/enb_paramdef.h
+++ b/openair2/ENB_APP/enb_paramdef.h
@@ -304,6 +304,7 @@ typedef enum {
 #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_UE_MULTIPLE_MAX                               "ue_multiple_max"
 
 //TTN - for D2D
 //SIB18
@@ -490,7 +491,7 @@ typedef enum {
 {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_PUCCH_N1_AN,                                  NULL,   0,           iptr:&pucch_n1_AN,                              defintval:0,               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},  \
@@ -538,6 +539,7 @@ typedef enum {
 {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},  \
+{ENB_CONFIG_STRING_UE_MULTIPLE_MAX,                              NULL,   0,           iptr:&ue_multiple_max,                          defintval:4,               TYPE_UINT,       0},  \
 {ENB_CONFIG_STRING_RXPOOL_SC_CP_LEN,                             NULL,   0,   strptr:(char **)&rxPool_sc_CP_Len,          defstrval:"normal",  TYPE_STRING,  0}, \
 {ENB_CONFIG_STRING_RXPOOL_SC_PRIOD,                              NULL,   0,   strptr:(char **)&rxPool_sc_Period,          defstrval:"sf40",  TYPE_STRING,  0}, \
 {ENB_CONFIG_STRING_RXPOOL_DATA_CP_LEN,                           NULL,   0,   strptr:(char **)&rxPool_data_CP_Len,          defstrval:"normal",  TYPE_STRING,  0}, \
@@ -826,9 +828,9 @@ typedef enum {
 #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_SCHED_MODE                    "scheduler_mode"
 #define CONFIG_STRING_MACRLC_PHY_TEST_MODE                 "phy_test_mode"
 
-
 #define MACRLC_CC_IDX                                          0
 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX                      1
 #define MACRLC_LOCAL_N_IF_NAME_IDX                             2
@@ -846,5 +848,6 @@ typedef enum {
 #define MACRLC_REMOTE_S_PORTC_IDX                              14
 #define MACRLC_LOCAL_S_PORTD_IDX                               15
 #define MACRLC_REMOTE_S_PORTD_IDX                              16
-#define MACRLC_PHY_TEST_IDX                                    17
+#define MACRLC_SCHED_MODE_IDX                                  17
+#define MACRLC_PHY_TEST_IDX                                    18
 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/
diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c
index 2e5bccd93514671481c537884190448238a19a13..e39d676061f5e38a47078ee38001c785790811be 100644
--- a/openair2/ENB_APP/flexran_agent_ran_api.c
+++ b/openair2/ENB_APP/flexran_agent_ran_api.c
@@ -141,7 +141,7 @@ rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logi
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                     ,0, 0
 #endif
                                                     );
@@ -154,7 +154,7 @@ rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, lo
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                     ,0, 0
 #endif
                                                     );
@@ -167,7 +167,7 @@ frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t chann
   frame_t frame = flexran_get_current_frame(mod_id);
   sub_frame_t subframe = flexran_get_current_subframe(mod_id);
   mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                     ,0, 0
 #endif
                                                     );
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index 78e4ca04ab240f9e65b6671b337f082deb1fb5fd..929c0fad245fac3222ba55991aeaf7e4c3f0513d 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -218,7 +218,7 @@ void config_mib(int                 Mod_idP,
   cfg->rf_config.dl_channel_bandwidth.value        = to_prb(dl_BandwidthP);
   cfg->rf_config.dl_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_DL_CHANNEL_BANDWIDTH_TAG;
   cfg->num_tlv++;
-  LOG_E(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP);
+  LOG_D(PHY,"%s() dl_BandwidthP:%d\n", __FUNCTION__, dl_BandwidthP);
 
   cfg->rf_config.ul_channel_bandwidth.value        = to_prb(dl_BandwidthP);
   cfg->rf_config.ul_channel_bandwidth.tl.tag = NFAPI_RF_CONFIG_UL_CHANNEL_BANDWIDTH_TAG;
@@ -727,7 +727,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
 
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_IN);
 
-  LOG_E(MAC, "RC.mac:%p mib:%p\n", RC.mac, mib);
+  LOG_D(MAC, "RC.mac:%p mib:%p\n", RC.mac, mib);
 
   if (mib != NULL) {
     if (RC.mac == NULL)
@@ -962,8 +962,8 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
   }
   
 #endif
-    
-    LOG_E(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req);
+
+    LOG_D(MAC, "%s() %s:%d RC.mac[Mod_idP]->if_inst->PHY_config_req:%p\n", __FUNCTION__, __FILE__, __LINE__, RC.mac[Mod_idP]->if_inst->PHY_config_req);
 
     // if in nFAPI mode 
     if (
@@ -987,6 +987,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP,
       
       VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
     }
-    
+    RC.mac[Mod_idP]->scheduler_mode = global_scheduler_mode;
+
     return(0);			   
 }
diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c
index 0b27955dad61a096ffebeaf9b87e0b8fd556ba93..c837304d9cd81a851bbe1291d1ecaeafa102473b 100644
--- a/openair2/LAYER2/MAC/config_ue.c
+++ b/openair2/LAYER2/MAC/config_ue.c
@@ -138,7 +138,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
 #ifdef CBA
 		      , uint8_t num_active_cba_groups, uint16_t cba_rnti
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   ,config_action_t  config_action
   ,const uint32_t * const sourceL2Id
   ,const uint32_t * const destinationL2Id
@@ -590,7 +590,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
     (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
   //for D2D
-  #if defined(Rel10) || defined(Rel14)
+  #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
     switch (config_action) {
     case CONFIG_ACTION_ADD:
        if (sourceL2Id){
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index fd086c4adba680f002b274ef8f7eba983247accf..c222aff64bf6ed2194075983e57d00d08826c978 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -51,6 +51,9 @@
 #include "flexran_agent_extern.h"
 #include "flexran_agent_mac.h"
 
+/* for fair round robin SCHED */
+#include "eNB_scheduler_fairRR.h"
+
 #if defined(ENABLE_ITTI)
 #include "intertask_interface.h"
 #endif
@@ -359,8 +362,9 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
   // check uplink failure
   if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 0) &&
       (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0)) {
-    LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
-	  UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
+    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 1)
+      LOG_I(MAC, "UE %d rnti %x: UL Failure timer %d \n", UE_id, rnti,
+            UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
     if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent == 0) {
       UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 1;
 
@@ -385,23 +389,24 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
       DL_req[CC_id].dl_config_request_body.number_dci++;
       DL_req[CC_id].dl_config_request_body.number_pdu++;
       DL_req[CC_id].dl_config_request_body.tl.tag                      = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
-      LOG_I(MAC,
+      LOG_D(MAC,
 	    "UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d), resource_block_coding %d \n",
 	    UE_id, rnti,
 	    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer,
 	    dl_config_pdu->dci_dl_pdu.
 	    dci_dl_pdu_rel8.resource_block_coding);
     } else {		// ra_pdcch_sent==1
-      LOG_I(MAC,
+      LOG_D(MAC,
 	    "UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",
 	    UE_id, rnti,
 	    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
-      if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0;	// resend every 4 frames
+      if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 80) == 0) UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent = 0;	// resend every 8 frames
     }
 
     UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
     // check threshold
-    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
+    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 4000) {
+      // note: probably ul_failure_timer should be less than UE radio link failure time(see T310/N310/N311)
       // inform RRC of failure and clear timer
       LOG_I(MAC,
 	    "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
@@ -436,7 +441,7 @@ clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP,
 {
   nfapi_dl_config_request_t      *DL_req = &eNB->DL_req[0];
   nfapi_ul_config_request_t      *UL_req = &eNB->UL_req[0];
-  nfapi_hi_dci0_request_t   *HI_DCI0_req = &eNB->HI_DCI0_req[0];
+  nfapi_hi_dci0_request_t   *HI_DCI0_req = &eNB->HI_DCI0_req[CC_idP][subframeP];
   nfapi_tx_request_t             *TX_req = &eNB->TX_req[0];
 
   eNB->pdu_index[CC_idP] = 0;
@@ -449,8 +454,8 @@ clear_nfapi_information(eNB_MAC_INST * eNB, int CC_idP,
     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<<4);
-    HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci                    = 0;
+    HI_DCI0_req->hi_dci0_request_body.sfnsf                                   = subframeP + (frameP<<4);
+    HI_DCI0_req->hi_dci0_request_body.number_of_dci                           = 0;
 
 
     UL_req[CC_idP].ul_config_request_body.number_of_pdus                      = 0;
@@ -532,7 +537,6 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
   // refresh UE list based on UEs dropped by PHY in previous subframe
   for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
     if (UE_list->active[i]) {
-
       rnti = UE_RNTI(module_idP, i);
       CC_id = UE_PCCID(module_idP, i);
       
@@ -570,14 +574,21 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
 	if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer >=
 	   RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres) {
 	  RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer = 0;
-	  for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_ENB; ue_id_l++) {
-	    if (reestablish_rnti_map[ue_id_l][0] == rnti) {
-	      // clear currentC-RNTI from map
-	      reestablish_rnti_map[ue_id_l][0] = 0;
-	      reestablish_rnti_map[ue_id_l][1] = 0;
-	      break;
+          //clear reestablish_rnti_map
+          if(RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer_thres >20){
+	    for (int ue_id_l = 0; ue_id_l < MAX_MOBILES_PER_ENB; ue_id_l++) {
+	      if (reestablish_rnti_map[ue_id_l][0] == rnti) {
+	        // clear currentC-RNTI from map
+	        reestablish_rnti_map[ue_id_l][0] = 0;
+	        reestablish_rnti_map[ue_id_l][1] = 0;
+	        break;
+	      }
 	    }
-	  }
+
+            PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rnti, 0, 0,module_idP);
+            rrc_rlc_remove_ue(&ctxt);
+            pdcp_remove_UE(&ctxt);
+          }
 	  // Note: This should not be done in the MAC!
 	  for (int ii=0; ii<MAX_MOBILES_PER_ENB; ii++) {
 	    LTE_eNB_ULSCH_t *ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii];
@@ -617,13 +628,15 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
       }
     }
   }
+
+#if (!defined(PRE_SCD_THREAD))
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES,
 				 NOT_A_RNTI, frameP, subframeP,
 				 module_idP);
   pdcp_run(&ctxt);
 
-
   rrc_rx_tx(&ctxt, CC_id);
+#endif
 
 #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
 
@@ -637,6 +650,22 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
 
 #endif
 
+  static int debug_flag=0;
+  void (*schedule_ulsch_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe);
+  void (*schedule_ue_spec_p)(module_id_t module_idP, frame_t frameP, sub_frame_t subframe, int *mbsfn_flag);
+  if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_DEFAULT){
+    schedule_ulsch_p = schedule_ulsch;
+    schedule_ue_spec_p = schedule_dlsch;
+  }else if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
+    memset(dlsch_ue_select, 0, sizeof(dlsch_ue_select));
+    schedule_ulsch_p = schedule_ulsch_fairRR;
+    schedule_ue_spec_p = schedule_ue_spec_fairRR;
+  }
+  if(debug_flag==0){
+    LOG_E(MAC,"SCHED_MODE=%d\n",RC.mac[module_idP]->scheduler_mode);
+    debug_flag=1;
+  }
+
   // This schedules MIB
 
   if ((subframeP == 0) && (frameP & 3) == 0)
@@ -653,13 +682,13 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
     // This schedules SRS in subframeP
     schedule_SRS(module_idP, frameP, subframeP);
     // This schedules ULSCH in subframeP (dci0)
-    schedule_ulsch(module_idP, frameP, subframeP);
+    schedule_ulsch_p(module_idP, frameP, subframeP);
     // This schedules UCI_SR in subframeP
     schedule_SR(module_idP, frameP, subframeP);
     // This schedules UCI_CSI in subframeP
     schedule_CSI(module_idP, frameP, subframeP);
     // This schedules DLSCH in subframeP
-    schedule_dlsch(module_idP, frameP, subframeP, mbsfn_status);
+    schedule_ue_spec_p(module_idP, frameP, subframeP, mbsfn_status);
   }
   else{
     schedule_ulsch_phy_test(module_idP,frameP,subframeP);
@@ -670,8 +699,10 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
     flexran_agent_send_update_stats(module_idP);
   
   // 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);
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+    if(cc[CC_id].tdd_Config == NULL || !(is_UL_sf(&cc[CC_id],subframeP)))
+      allocate_CCEs(module_idP, CC_id, frameP, subframeP, 2);
+  }
 
   stop_meas(&RC.mac[module_idP]->eNB_scheduler);
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
index 6a528a9930af00239341bb305093c53f8415760f..654f69ba91eb83175a96c6b1b0855223575b7e45 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
@@ -106,10 +106,10 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP,
     nfapi_ul_config_request_t *ul_req;
     nfapi_ul_config_request_body_t *ul_req_body;
     nfapi_ul_config_request_pdu_t *ul_config_pdu;
-    nfapi_hi_dci0_request_t        *hi_dci0_req = &mac->HI_DCI0_req[CC_id];
-    nfapi_hi_dci0_request_body_t   *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
+    nfapi_hi_dci0_request_t        *hi_dci0_req;
+    nfapi_hi_dci0_request_body_t   *hi_dci0_req_body;
     nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
-
+    uint8_t sf_ahead_dl;
     uint8_t rvseq[4] = { 0, 2, 3, 1 };
 
 
@@ -211,6 +211,9 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP,
         LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round);
 
 	if (ra->msg3_round != 0) {	// program HI too
+	    sf_ahead_dl = ul_subframe2_k_phich(cc, subframeP);
+	    hi_dci0_req = &mac->HI_DCI0_req[CC_id][(subframeP+sf_ahead_dl)%10];
+	    hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
 	    hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
 	    memset((void *) hi_dci0_pdu, 0,
 		   sizeof(nfapi_hi_dci0_request_pdu_t));
@@ -225,7 +228,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP,
             hi_dci0_req_body->sfnsf                                 = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0);
             hi_dci0_req_body->tl.tag                                = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
 
-            hi_dci0_req->sfn_sf                                     = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 4);
+            hi_dci0_req->sfn_sf                                     = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl);
             hi_dci0_req->header.message_id                          = NFAPI_HI_DCI0_REQUEST;
 
             if (nfapi_mode) {
@@ -283,7 +286,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
 
     LOG_D(MAC,"absSF:%d absSF_Msg2:%d ra->rach_resource_type:%d\n",absSF,absSF_Msg2,ra->rach_resource_type);
 
-    if (absSF > absSF_Msg2)
+    if (absSF < absSF_Msg2)
 	return;			// we're not ready yet, need to be to start ==  
 
     if (cc[CC_idP].radioResourceConfigCommon_BR) {
@@ -486,6 +489,9 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
 		TX_req->segments[0].segment_length = 7;
 		TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
 		mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
+		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
+    		  set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
+		}
 	    }
 	}
 
@@ -587,6 +593,9 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
 		TX_req->segments[0].segment_data =
 		    cc[CC_idP].RAR_pdu.payload;
 		mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
+		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
+    		  set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
+		}
 	    }			// PDCCH CCE allocation is feasible
 	}			// Msg2 frame/subframe condition
     }				// else BL/CE
@@ -693,17 +702,17 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
 
     // set HARQ process round to 0 for this UE
 
-    if (cc->tdd_Config)
-	ra->harq_pid = ((frameP * 10) + subframeP) % 10;
-    else
-	ra->harq_pid = ((frameP * 10) + subframeP) & 7;
+    ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
 
    /* // Get RRCConnectionSetup for Piggyback
     rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1,	// 1 transport block
 				      &cc[CC_idP].CCCH_pdu.payload[0], 0);	// not used in this case
-
-    AssertFatal(rrc_sdu_length > 0,
-		"[MAC][eNB Scheduler] CCCH not allocated\n");
+    if(rrc_sdu_length <= 0) {
+      LOG_D(MAC,"[MAC][eNB Scheduler] CCCH not allocated (%d)\n",rrc_sdu_length);
+      return;
+    }
+    //AssertFatal(rrc_sdu_length > 0,
+		//"[MAC][eNB Scheduler] CCCH not allocated\n");
 
 
     LOG_D(MAC,
@@ -987,6 +996,9 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
 			  module_idP, CC_idP, frameP, UE_RNTI(module_idP,UE_id),
 			  rrc_sdu_length);
 		}
+		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
+        	  set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
+		}
 	    }			// Msg4 frame/subframe
 	}			// msg4_mpdcch_repetition_count
     }				// rach_resource_type > 0 
@@ -1086,10 +1098,8 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
 		      "Frame %d, Subframe %d: Preparing for Msg4 retransmission currently %d.%d\n",
 		      frameP, subframeP, ra->Msg4_frame,
 		      ra->Msg4_subframe);
-		if (ra->Msg4_subframe > 1)
-		    ra->Msg4_frame++;
-		ra->Msg4_frame &= 1023;
-		ra->Msg4_subframe = (ra->Msg4_subframe + 8) % 10;
+		get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe);
+
 		LOG_D(MAC,
 		      "Frame %d, Subframe %d: Msg4 retransmission in %d.%d\n",
 		      frameP, subframeP, ra->Msg4_frame,
@@ -1097,9 +1107,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
 		lcid = 0;
 
 		// put HARQ process round to 0
-		if (cc->tdd_Config) ra->harq_pid = ((frameP * 10) + subframeP) % 10;
-		else
-		  ra->harq_pid = ((frameP * 10) + subframeP) & 7;
+		ra->harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
 		UE_list->UE_sched_ctrl[UE_id].round[CC_idP][ra->harq_pid] = 0;
 
 		if ((ra->msg4_TBsize - rrc_sdu_length - msg4_header) <= 2) {
@@ -1194,7 +1202,9 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP,
 							      UE_id),
 			  rrc_sdu_length);
 		}
-
+		if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
+        	  set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
+		}
 	    }			// CCE Allocation feasible
 	}			// msg4 frame/subframe
     }				// else rach_resource_type
@@ -1339,6 +1349,9 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
 					    (cc->p_eNB == 1) ? 1 : 2,	// transmission mode
 					    1,	// num_bf_prb_per_subband
 					    1);	// num_bf_vector
+		    if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
+	       	      set_dl_ue_select_msg4(CC_idP, 4, UE_id, ra->rnti);
+		    }
 		} else
 		    LOG_D(MAC,
 			  "msg4 retransmission for rnti %x (round %d) fsf %d/%d CCE allocation failed!\n",
@@ -1355,10 +1368,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
 				      dci_dl_pdu_rel8.cce_idx);
 
 		// prepare frame for retransmission
-		if (ra->Msg4_subframe > 1)
-		    ra->Msg4_frame++;
-		ra->Msg4_frame &= 1023;
-		ra->Msg4_subframe = (ra->Msg4_subframe + 8) % 10;
+		get_retransmission_timing(mac->common_channels[CC_idP].tdd_Config,&ra->Msg4_frame,&ra->Msg4_subframe);
 
 		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",
@@ -1376,6 +1386,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP,
 	UE_id = find_UE_id(module_idP, ra->rnti);
 	DevAssert(UE_id != -1);
 	mac->UE_list.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE;
+        cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti);
     }
 }
 
@@ -1406,7 +1417,7 @@ schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
 
 	    if (ra->state == MSG2)
 		generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
-	    else if (ra->state == MSG4)
+	    else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP )
 		generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
 	    else if (ra->state == WAITMSG4ACK)
 		check_Msg4_retransmission(module_idP, CC_id, frameP,
@@ -1442,6 +1453,8 @@ initiate_ra_proc(module_id_t module_idP,
 
     struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
     PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
+  
+    static uint8_t failure_cnt = 0;
 
     if (cc->radioResourceConfigCommon_BR
 	&& cc->radioResourceConfigCommon_BR->ext4) {
@@ -1494,11 +1507,22 @@ initiate_ra_proc(module_id_t module_idP,
 	    ra[i].msg4_mpdcch_repetition_cnt = 0;
 #endif
 
-            // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes
-            if (nfapi_mode)
-              offset = 7;
-            else
-              offset = 5;
+
+            //TODO Fill in other TDD config. What about nfapi_mode?
+            if(cc->tdd_Config!=NULL){
+              switch(cc->tdd_Config->subframeAssignment){
+                default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
+                case 1 :
+                  offset = 6;
+                  break;
+              }
+            }else{//FDD
+                // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes
+                if (nfapi_mode)
+                  offset = 7;
+                else
+                  offset = 5;
+            }
 
             add_subframe(&msg2_frame, &msg2_subframe, offset);
 
@@ -1545,6 +1569,7 @@ initiate_ra_proc(module_id_t module_idP,
 	    }
 	    ra[i].RA_rnti = ra_rnti;
 	    ra[i].preamble_index = preamble_index;
+	    failure_cnt = 0;
 	    LOG_D(MAC,
 		  "[eNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state %d\n",
 		  module_idP, CC_id, frameP, ra[i].Msg2_frame,
@@ -1557,6 +1582,13 @@ initiate_ra_proc(module_id_t module_idP,
     LOG_E(MAC,
 	  "[eNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",
 	  module_idP, CC_id, frameP, preamble_index);
+  
+    failure_cnt++;
+    if(failure_cnt > 20) {
+      LOG_E(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP);
+      clear_ra_proc(module_idP, CC_id, frameP);
+    }
+  
 }
 
 void
@@ -1579,6 +1611,22 @@ cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP,
 	  ra[i].RRC_timer = 20;
 	  ra[i].rnti = 0;
 	  ra[i].msg3_round = 0;
+    LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Canceled RA procedure for UE rnti %x\n", module_idP, CC_id, frameP, rnti);
 	}
     }
 }
+
+void clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP)
+{
+  unsigned char i;
+  RA_t *ra = (RA_t *) & RC.mac[module_idP]->common_channels[CC_id].ra[0];
+
+  for (i = 0; i < NB_RA_PROC_MAX; i++) {
+    LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra[i].rnti);
+    ra[i].state = IDLE;
+    ra[i].timing_offset = 0;
+    ra[i].RRC_timer = 20;
+    ra[i].rnti = 0;
+    ra[i].msg3_round = 0;
+  }
+}
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 0c44946d732f43b0224bc569cb3e693ef12d0af7..93ecdc3d4f711e79b6e9c0108a00a9a84f468d3a 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -368,21 +368,23 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP,
 
     case 1:
       switch (subframeP) {
+      case 0:
       case 1:
 	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI;
 	break;
 
       case 4:
-	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
-	break;
+        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
+        break;
 
+      case 5:
       case 6:
-	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
-	break;
+        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
+        break;
 
       case 9:
-	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
-	break;
+        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
+        break;
       }
 
     case 2:
@@ -632,8 +634,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
       break;
     case 6:
     case 7:
-      if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4)
-	  && (tdd_sfa != 5))
+      if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5))
 	return;
       break;
     case 8:
@@ -642,8 +643,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	return;
       break;
     case 9:
-      if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4)
-	  && (tdd_sfa != 6))
+      if (tdd_sfa == 0)
 	return;
       break;
 
@@ -772,8 +772,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
       nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
 
-      if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10;
-      else            	  harq_pid = ((frameP * 10) + subframeP) & 7;
+      harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
 
       round = ue_sched_ctl->round[CC_id][harq_pid];
 
@@ -832,7 +831,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	  if (cc[CC_id].tdd_Config != NULL) {
 	    UE_list->UE_template[CC_id][UE_id].DAI++;
 	    update_ul_dci(module_idP, CC_id, rnti,
-			  UE_list->UE_template[CC_id][UE_id].DAI);
+			  UE_list->UE_template[CC_id][UE_id].DAI, subframeP);
 	    LOG_D(MAC,
 		  "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
 		  CC_id, subframeP, UE_id,
@@ -1005,7 +1004,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
 	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
                                           TBS - ta_len - header_length_total - sdu_length_total - 3
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                     ,0, 0
 #endif
                           );
@@ -1020,11 +1019,62 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	    sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
                                               TBS, //not used
 					      (char *)&dlsch_buffer[0]
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                           ,0, 0
 #endif
                           );
 
+            pthread_mutex_lock(&rrc_release_freelist);
+            if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){
+              uint16_t release_total = 0;
+              for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
+                if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){
+                  release_total++;
+                }else{
+                  continue;
+                }
+
+                if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1){
+                  if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){
+                    for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
+                      if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){
+                        rrc_release_info.RRC_release_ctrl[release_num].flag = 3;
+                        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num);
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2){
+                  if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){
+                    for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
+                      if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){
+                        rrc_release_info.RRC_release_ctrl[release_num].flag = 4;
+                        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num);
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(release_total >= rrc_release_info.num_UEs)
+                  break;
+              }
+            }
+            pthread_mutex_unlock(&rrc_release_freelist);
+
+            RA_t *ra = &eNB->common_channels[CC_id].ra[0];
+            for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) {
+              if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)){
+                for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
+                  if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]){
+                    ra[ra_ii].crnti_harq_pid = harq_pid;
+                    ra[ra_ii].state = MSGCRNTI_ACK;
+                    break;
+                  }
+                }
+              }
+            }
+
 	    T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
 	      T_INT(CC_id), T_INT(rnti), T_INT(frameP),
 	      T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH),
@@ -1063,7 +1113,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
 	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
                                           TBS - ta_len - header_length_total - sdu_length_total - 3
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                     ,0, 0
 #endif
                                          );
@@ -1079,7 +1129,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	    sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
                                                       TBS, //not used
 						      (char *)&dlsch_buffer[sdu_length_total]
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                           ,0, 0
 #endif
 	    );
@@ -1134,7 +1184,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 					    MBMS_FLAG_NO,
 					    lcid,
 					    TBS - ta_len - header_length_total - sdu_length_total - 3
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                     ,0, 0
 #endif
                                            );
@@ -1152,7 +1202,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid,
                                                        TBS, //not used
 						       (char *)&dlsch_buffer[sdu_length_total]
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                           ,0, 0
 #endif
 	      );
@@ -1368,18 +1418,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	  if (cc[CC_id].tdd_Config != NULL) {	// TDD
 	    UE_list->UE_template[CC_id][UE_id].DAI++;
 	    update_ul_dci(module_idP, CC_id, rnti,
-			  UE_list->UE_template[CC_id][UE_id].
-			  DAI);
+			  UE_list->UE_template[CC_id][UE_id].DAI,
+                          subframeP);
 	  }
 
 	  // do PUCCH power control
 	  // this is the normalized RX power
 	  eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
 
-	  /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */
-	  normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id];
-	  target_rx_power = 208;
-
+	  /* unit is not dBm, it's special from nfapi */
+	  // converting to dBm: ToDo: Noise power hard coded to 30
+	  normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30;
+	  target_rx_power= eNB->puCch10xSnr/10 + 30;
 	  // 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;
@@ -1583,8 +1633,7 @@ fill_DLSCH_dci(module_id_t module_idP,
 	// clear scheduling flag
 	eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING;
 	rnti = UE_RNTI(module_idP, UE_id);
-	if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10;
-	else          	    harq_pid = ((frameP * 10) + subframeP) & 7;
+        harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
 	nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
 
 	/// Synchronizing rballoc with rballoc_sub
@@ -1663,12 +1712,12 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
 //------------------------------------------------------------------------------
 void
 update_ul_dci(module_id_t module_idP,
-	      uint8_t CC_idP, rnti_t rntiP, uint8_t daiP)
+	      uint8_t CC_idP, rnti_t rntiP, uint8_t daiP, sub_frame_t subframe)
 //------------------------------------------------------------------------------
 {
 
   nfapi_hi_dci0_request_t *HI_DCI0_req =
-    &RC.mac[module_idP]->HI_DCI0_req[CC_idP];
+    &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe];
   nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
     &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0];
   COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP];
@@ -1677,7 +1726,7 @@ update_ul_dci(module_id_t module_idP,
 
   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 <HI_DCI0_req->hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_hi;
 	 i++) {
 
       if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) &&
@@ -1816,7 +1865,7 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
 	LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id,i, pcch_sdu_length);
 #ifdef FORMAT1C
 	//NO SIB
-	if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
+	if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
 	    (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
 	  switch (n_rb_dl) {
 #if 0
@@ -1935,7 +1984,7 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
 	}
 #else
 	//NO SIB
-	if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
+	if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
 	    (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
 	  switch (n_rb_dl) {
 	  case 25:
@@ -2027,6 +2076,10 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
 	  LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP);
 	  dl_req->number_dci++;
 	  dl_req->number_pdu++;
+          dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+          eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
+          eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
+
 	  dl_config_pdu                                                                  = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
 	  memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
 	  dl_config_pdu->pdu_type                                                        = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE;
@@ -2067,6 +2120,7 @@ void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
 	  TX_req->num_segments                                                           = 1;
 	  TX_req->segments[0].segment_length                                             = pcch_sdu_length;
 	  TX_req->segments[0].segment_data                                               = cc[CC_id].PCCH_pdu.payload;
+          eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG;
 	  eNB->TX_req[CC_id].tx_request_body.number_of_pdus++;
 	} else {
 	  LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP);
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
new file mode 100644
index 0000000000000000000000000000000000000000..a7f5afd51d294a819914527d6bbc958b1afe03fc
--- /dev/null
+++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
@@ -0,0 +1,3078 @@
+/*
+ * 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.1  (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 eNB_scheduler_fairRR.h
+ * \brief eNB scheduler fair round robin
+ * \author Masayuki Harada
+ * \date 2018
+ * \email masayuki.harada@jp.fujitsu.com
+ * \version 1.0
+ * @ingroup _mac
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+
+#include "assertions.h"
+
+#include "PHY/phy_extern.h"
+
+#include "LAYER2/MAC/mac_proto.h"
+#include "LAYER2/MAC/mac_extern.h"
+#include "LAYER2/MAC/eNB_scheduler_fairRR.h"
+#include "UTIL/LOG/log.h"
+#include "UTIL/LOG/vcd_signal_dumper.h"
+#include "UTIL/OPT/opt.h"
+#include "OCG.h"
+#include "OCG_extern.h"
+#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
+#include "rlc.h"
+
+#include "T.h"
+
+extern uint8_t nfapi_mode;
+#ifdef PHY_TX_THREAD
+extern volatile int16_t phy_tx_txdataF_end;
+extern int oai_exit;
+#endif
+/* internal vars */
+DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs];
+int last_dlsch_ue_id[MAX_NUM_CCs] = {-1};
+int last_ulsch_ue_id[MAX_NUM_CCs] = {-1};
+
+#if defined(PRE_SCD_THREAD)
+uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+uint8_t dlsch_ue_select_tbl_in_use;
+uint8_t new_dlsch_ue_select_tbl_in_use;
+boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
+eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+#endif
+
+#define DEBUG_eNB_SCHEDULER 1
+#define DEBUG_HEADER_PARSING 1
+//#define DEBUG_PACKET_TRACE 1
+
+void set_dl_ue_select_msg2(int CC_idP, uint16_t nb_rb, int UE_id, rnti_t rnti) {
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].ue_priority = SCH_DL_MSG2;
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].nb_rb = nb_rb;
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].UE_id = UE_id;
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].rnti = rnti;
+  dlsch_ue_select[CC_idP].ue_num++;
+}
+void set_dl_ue_select_msg4(int CC_idP, uint16_t nb_rb, int UE_id, rnti_t rnti) {
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].ue_priority = SCH_DL_MSG4;
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].nb_rb = nb_rb;
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].UE_id = UE_id;
+  dlsch_ue_select[CC_idP].list[dlsch_ue_select[CC_idP].ue_num].rnti = rnti;
+  dlsch_ue_select[CC_idP].ue_num++;
+}
+#if defined(PRE_SCD_THREAD)
+inline uint16_t search_rbs_required(uint16_t mcs, uint16_t TBS,uint16_t NB_RB, uint16_t step_size){
+  uint16_t nb_rb,i_TBS,tmp_TBS;
+  i_TBS=get_I_TBS(mcs);
+  for(nb_rb=step_size;nb_rb<NB_RB;nb_rb+=step_size){
+    tmp_TBS = TBStable[i_TBS][nb_rb-1]>>3;
+    if(TBS<tmp_TBS)return(nb_rb);
+  }
+  return NB_RB;
+}
+void pre_scd_nb_rbs_required(    module_id_t     module_idP,
+                                 frame_t         frameP,
+                                 sub_frame_t     subframeP,
+                                 int             min_rb_unit[MAX_NUM_CCs],
+                                 uint16_t        nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX])
+{
+    int                          CC_id=0,UE_id, lc_id, N_RB_DL;
+    UE_TEMPLATE                  UE_template;
+    eNB_UE_STATS                 *eNB_UE_stats;
+    rnti_t                       rnti;
+    mac_rlc_status_resp_t        rlc_status;
+    uint16_t                     step_size=2;
+    
+    N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth);
+    if(N_RB_DL==50) step_size=3;
+    if(N_RB_DL==100) step_size=4;
+    memset(nb_rbs_required, 0, sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
+    UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
+
+    for (UE_id = 0; UE_id <NUMBER_OF_UE_MAX; UE_id++) {
+        if (pre_scd_activeUE[UE_id] != TRUE)
+            continue;
+
+        // store dlsch buffer
+
+        // clear logical channel interface variables
+        UE_template.dl_buffer_total = 0;
+
+        rnti = UE_RNTI(module_idP, UE_id);
+
+        for (lc_id = DCCH; lc_id <= DTCH; lc_id++) {
+            rlc_status =
+                    mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP,
+                            ENB_FLAG_YES, MBMS_FLAG_NO, lc_id, 0
+#ifdef Rel14
+                            ,0, 0
+#endif
+                    );
+            UE_template.dl_buffer_total += rlc_status.bytes_in_buffer; //storing the total dlsch buffer
+        }
+         // end of store dlsch buffer
+
+        // assgin rbs required
+        // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
+        //update CQI information across component carriers
+        eNB_UE_stats = &pre_scd_eNB_UE_stats[CC_id][UE_id];
+
+        eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]];
+
+
+        if (UE_template.dl_buffer_total > 0) {
+          nb_rbs_required[CC_id][UE_id] = search_rbs_required(eNB_UE_stats->dlsch_mcs1, UE_template.dl_buffer_total, N_RB_DL, step_size);
+        }
+    }
+}
+#endif
+
+int cc_id_end(uint8_t *cc_id_flag )
+{
+  int end_flag = 1;
+  for (int CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
+    if (cc_id_flag[CC_id]==0) {
+      end_flag = 0;
+      break;
+    }
+  }
+  return end_flag;
+}
+
+void dlsch_scheduler_pre_ue_select_fairRR(
+    module_id_t     module_idP,
+    frame_t         frameP,
+    sub_frame_t     subframeP,
+    int*            mbsfn_flag,
+    uint16_t        nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
+    DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs])
+{
+  eNB_MAC_INST                   *eNB      = RC.mac[module_idP];
+  COMMON_channels_t              *cc       = eNB->common_channels;
+  UE_list_t                      *UE_list  = &eNB->UE_list;
+  UE_sched_ctrl                  *ue_sched_ctl;
+  uint8_t                        CC_id;
+  int                            UE_id;
+  unsigned char                  round             = 0;
+  unsigned char                  harq_pid          = 0;
+  rnti_t                         rnti;
+  uint16_t                       i;
+  unsigned char                  aggregation;
+  int                            format_flag;
+  nfapi_dl_config_request_body_t *DL_req;
+  nfapi_dl_config_request_pdu_t  *dl_config_pdu;
+  uint16_t                       dlsch_ue_max_num[MAX_NUM_CCs] = {0};
+  uint16_t                       saved_dlsch_dci[MAX_NUM_CCs] = {0};
+  uint8_t                        end_flag[MAX_NUM_CCs] = {0};
+
+  // Initialization
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+    dlsch_ue_max_num[CC_id] = (uint16_t)RC.rrc[module_idP]->configuration.ue_multiple_max[CC_id];
+
+    // save origin DL PDU number
+    DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+    saved_dlsch_dci[CC_id] = DL_req->number_pdu;
+  }
+
+  // Insert DLSCH(retransmission) UE into selected UE list
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+    if (mbsfn_flag[CC_id]>0) {
+      continue;
+    }
+
+    DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+    for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) {
+      if (UE_list->active[UE_id] == FALSE) {
+        continue;
+      }
+
+      rnti = UE_RNTI(module_idP, UE_id);
+      if (rnti == NOT_A_RNTI) {
+        continue;
+      }
+
+      if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED){
+        continue;
+      }
+
+      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+#if 0
+      if (ue_sched_ctl->ul_out_of_sync == 1) {
+        continue;
+      }
+#endif
+      harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP ,subframeP);
+
+      round = ue_sched_ctl->round[CC_id][harq_pid];
+      if (round != 8) {  // retransmission
+        if(UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] == 0){
+          continue;
+        }
+        switch (get_tmode(module_idP, CC_id, UE_id)) {
+          case 1:
+          case 2:
+          case 7:
+            aggregation = get_aggregation(get_bw_index(module_idP, CC_id),
+                  ue_sched_ctl->dl_cqi[CC_id],
+                  format1);
+            break;
+          case 3:
+            aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
+                  ue_sched_ctl->dl_cqi[CC_id],
+                  format2A);
+            break;
+          default:
+            LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
+            aggregation = 2;
+            break;
+        }
+        format_flag = 1;
+        if (!CCE_allocation_infeasible(module_idP,
+                                      CC_id,
+                                      format_flag,
+                                      subframeP,
+                                      aggregation,
+                                      rnti)) {
+          dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
+          dl_config_pdu->pdu_type                                     = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+          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++;
+
+          nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+          // Insert DLSCH(retransmission) UE into selected UE list
+          dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id;
+          dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_RETRANS;
+          dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti;
+          dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id];
+          dlsch_ue_select[CC_id].ue_num++;
+          if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) {
+            end_flag[CC_id] = 1;
+            break;
+          }
+        } else {
+          if (cc[CC_id].tdd_Config != NULL) { //TDD
+            set_ue_dai (subframeP,
+                         UE_id,
+                         CC_id,
+            cc[CC_id].tdd_Config->subframeAssignment,
+                         UE_list);
+            // update UL DAI after DLSCH scheduling
+            set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
+          }
+
+          add_ue_dlsch_info(module_idP,
+                            CC_id,
+                            UE_id,
+                            subframeP,
+                            S_DL_NONE);
+          end_flag[CC_id] = 1;
+          break;
+        }
+      }
+    }
+  }
+  if(cc_id_end(end_flag) == 1){
+    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+      DL_req->number_pdu = saved_dlsch_dci[CC_id];
+    }
+    return;
+  }
+
+  // Insert DLSCH(first transmission) UE into selected UE list (UE_id > last_dlsch_ue_id[CC_id])
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      if (mbsfn_flag[CC_id]>0) {
+        continue;
+      }
+
+      DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+      for (UE_id = (last_dlsch_ue_id[CC_id]+1); UE_id <NUMBER_OF_UE_MAX; UE_id++) {
+        if(end_flag[CC_id] == 1){
+          break;
+        }
+
+        if (UE_list->active[UE_id] == FALSE) {
+          continue;
+        }
+
+        rnti = UE_RNTI(module_idP,UE_id);
+        if (rnti == NOT_A_RNTI)
+          continue;
+
+        if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED){
+          continue;
+        }
+
+        ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+#if 0
+        if (ue_sched_ctl->ul_out_of_sync == 1) {
+          continue;
+        }
+#endif
+       for(i = 0;i<dlsch_ue_select[CC_id].ue_num;i++){
+          if(dlsch_ue_select[CC_id].list[i].UE_id == UE_id){
+           break;
+          }
+        }
+        if(i < dlsch_ue_select[CC_id].ue_num)
+          continue;
+
+        harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP ,subframeP);
+
+        round = ue_sched_ctl->round[CC_id][harq_pid];
+        if (round == 8) {
+            if (nb_rbs_required[CC_id][UE_id] == 0) {
+              continue;
+            }
+            switch (get_tmode(module_idP, CC_id, UE_id)) {
+              case 1:
+              case 2:
+              case 7:
+                aggregation = get_aggregation(get_bw_index(module_idP, CC_id),
+                      ue_sched_ctl->dl_cqi[CC_id],
+                      format1);
+                break;
+              case 3:
+                aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
+                      ue_sched_ctl->dl_cqi[CC_id],
+                      format2A);
+                break;
+              default:
+                LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
+                aggregation = 2;
+                break;
+            }
+            format_flag = 1;
+            if (!CCE_allocation_infeasible(module_idP,
+                                           CC_id,
+                                           format_flag,
+                                           subframeP,
+                                           aggregation,
+                                           rnti)) {
+              dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
+              dl_config_pdu->pdu_type                                     = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+              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++;
+
+              // Insert DLSCH(first transmission) UE into selected selected UE list
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_FIRST;
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id];
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id;
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti;
+              dlsch_ue_select[CC_id].ue_num++;
+
+          if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) {
+                  end_flag[CC_id] = 1;
+                  break;
+              }
+          }else {
+            if (cc[CC_id].tdd_Config != NULL) { //TDD
+              set_ue_dai (subframeP,
+                           UE_id,
+                           CC_id,
+              cc[CC_id].tdd_Config->subframeAssignment,
+                           UE_list);
+              // update UL DAI after DLSCH scheduling
+              set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
+            }
+           add_ue_dlsch_info(module_idP,
+                            CC_id,
+                            UE_id,
+                            subframeP,
+                            S_DL_NONE);
+            end_flag[CC_id] = 1;
+            break;
+          }
+      }
+    }
+  }
+  if(cc_id_end(end_flag) == 1){
+    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+      DL_req->number_pdu = saved_dlsch_dci[CC_id];
+    }
+    return;
+  }
+
+  // Insert DLSCH(first transmission) UE into selected UE list (UE_id <= last_dlsch_ue_id[CC_id])
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      if (mbsfn_flag[CC_id]>0) {
+        continue;
+      }
+
+      DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+      for (UE_id = 0; UE_id <= last_dlsch_ue_id[CC_id]; UE_id++) {
+        if(end_flag[CC_id] == 1){
+          break;
+        }
+
+        if (UE_list->active[UE_id] == FALSE) {
+          continue;
+        }
+
+        rnti = UE_RNTI(module_idP,UE_id);
+        if (rnti == NOT_A_RNTI)
+          continue;
+
+        if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED){
+          continue;
+        }
+
+        ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+#if 0
+        if (ue_sched_ctl->ul_out_of_sync == 1) {
+          continue;
+        }
+#endif
+        for(i = 0;i<dlsch_ue_select[CC_id].ue_num;i++){
+          if(dlsch_ue_select[CC_id].list[i].UE_id == UE_id){
+           break;
+          }
+        }
+        if(i < dlsch_ue_select[CC_id].ue_num)
+          continue;
+
+        harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP ,subframeP);
+
+        round = ue_sched_ctl->round[CC_id][harq_pid];
+        if (round == 8) {
+            if (nb_rbs_required[CC_id][UE_id] == 0) {
+                continue;
+             }
+            switch (get_tmode(module_idP, CC_id, UE_id)) {
+              case 1:
+              case 2:
+              case 7:
+                aggregation = get_aggregation(get_bw_index(module_idP, CC_id),
+                      ue_sched_ctl->dl_cqi[CC_id],
+                      format1);
+                break;
+              case 3:
+                aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
+                      ue_sched_ctl->dl_cqi[CC_id],
+                      format2A);
+                break;
+              default:
+                LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
+                aggregation = 2;
+                break;
+            }
+            format_flag = 1;
+            if (!CCE_allocation_infeasible(module_idP,
+                                           CC_id,
+                                           format_flag,
+                                           subframeP,
+                                           aggregation,
+                                           rnti)) {
+              dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
+              dl_config_pdu->pdu_type                                     = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+              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++;
+
+              // Insert DLSCH(first transmission) UE into selected selected UE list
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_FIRST;
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id];
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id;
+              dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti;
+              dlsch_ue_select[CC_id].ue_num++;
+
+              if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) {
+                end_flag[CC_id] = 1;
+                break;
+              }
+            } else {
+              if (cc[CC_id].tdd_Config != NULL) { //TDD
+                set_ue_dai (subframeP,
+                            UE_id,
+                            CC_id,
+                            cc[CC_id].tdd_Config->subframeAssignment,
+                            UE_list);
+              // update UL DAI after DLSCH scheduling
+                set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
+              }
+          add_ue_dlsch_info(module_idP,
+                            CC_id,
+                            UE_id,
+                            subframeP,
+                            S_DL_NONE);
+              end_flag[CC_id] = 1;
+              break;
+            }
+      }
+    }
+  }
+
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+    DL_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+    DL_req->number_pdu = saved_dlsch_dci[CC_id];
+  }
+  return;
+}
+
+
+
+// This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done
+void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
+                                    frame_t       frameP,
+                                    sub_frame_t   subframeP,
+                                    int           N_RBG[MAX_NUM_CCs],
+                                    int           *mbsfn_flag)
+{
+
+  unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,Round=0;
+  uint16_t                temp_total_rbs_count;
+  unsigned char           temp_total_ue_count;
+  unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX];
+  int                     UE_id, i; 
+  uint16_t                j;
+  uint16_t                nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+  uint16_t                nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+//  uint16_t                nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+  uint16_t                average_rbs_per_user[MAX_NUM_CCs] = {0};
+  rnti_t             rnti;
+  int                min_rb_unit[MAX_NUM_CCs];
+//  uint16_t r1=0;
+  uint8_t CC_id;
+  UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list;
+
+  int N_RB_DL;
+  int transmission_mode = 0;
+  UE_sched_ctrl *ue_sched_ctl;
+  //  int rrc_status           = RRC_IDLE;
+  COMMON_channels_t *cc;
+
+#ifdef TM5
+    int harq_pid1 = 0;
+    int round1 = 0, round2 = 0;
+    int UE_id2;
+    uint16_t i1, i2, i3;
+    rnti_t rnti1, rnti2;
+    LTE_eNB_UE_stats *eNB_UE_stats1 = NULL;
+    LTE_eNB_UE_stats *eNB_UE_stats2 = NULL;
+    UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2;
+#endif
+
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+
+	if (mbsfn_flag[CC_id] > 0)	// If this CC is allocated for MBSFN skip it here
+	    continue;
+
+
+
+	min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
+
+	for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+	    if (UE_list->active[i] != TRUE)
+		continue;
+
+	    UE_id = i;
+	    // Initialize scheduling information for all active UEs
+
+
+
+	    dlsch_scheduler_pre_processor_reset(Mod_id,
+						UE_id,
+						CC_id,
+						frameP,
+						subframeP,
+						N_RBG[CC_id],
+						nb_rbs_required,
+						rballoc_sub,
+						MIMO_mode_indicator);
+
+	}
+    }
+
+#if (!defined(PRE_SCD_THREAD))
+    // Store the DLSCH buffer for each logical channel
+    store_dlsch_buffer(Mod_id, frameP, subframeP);
+
+
+
+    // Calculate the number of RBs required by each UE on the basis of logical channel's buffer
+    assign_rbs_required(Mod_id, frameP, subframeP, nb_rbs_required,
+			min_rb_unit);
+#else
+    memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use] , sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
+#endif
+
+  dlsch_scheduler_pre_ue_select_fairRR(Mod_id,frameP,subframeP, mbsfn_flag,nb_rbs_required,dlsch_ue_select);
+
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+    average_rbs_per_user[CC_id] = 0;
+    cc = &RC.mac[Mod_id]->common_channels[CC_id];
+    // Get total available RBS count and total UE count
+    N_RB_DL = to_prb(cc->mib->message.dl_Bandwidth);
+    temp_total_rbs_count = RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs;
+    temp_total_ue_count = dlsch_ue_select[CC_id].ue_num;
+
+    for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
+      if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){
+          temp_total_ue_count--;
+          continue;
+      }
+      if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){
+          temp_total_ue_count--;
+          continue;
+      }
+      UE_id = dlsch_ue_select[CC_id].list[i].UE_id;
+      nb_rbs_required[CC_id][UE_id] = dlsch_ue_select[CC_id].list[i].nb_rb;
+
+      average_rbs_per_user[CC_id] = (uint16_t)round((double)temp_total_rbs_count/(double)temp_total_ue_count);
+      if( average_rbs_per_user[CC_id] < min_rb_unit[CC_id] ){
+        temp_total_ue_count--;
+        dlsch_ue_select[CC_id].ue_num--;
+        i--;
+        continue;
+      }
+
+      rnti = dlsch_ue_select[CC_id].list[i].rnti;
+
+      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+      harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
+      Round    = ue_sched_ctl->round[CC_id][harq_pid];
+
+      //if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round > 0) {
+      if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || Round != 8) {  // FIXME
+        nb_rbs_required_remaining[CC_id][UE_id] = dlsch_ue_select[CC_id].list[i].nb_rb;
+      } else {
+        nb_rbs_required_remaining[CC_id][UE_id] = cmin(average_rbs_per_user[CC_id], dlsch_ue_select[CC_id].list[i].nb_rb);
+      }
+
+      transmission_mode = get_tmode(Mod_id,CC_id,UE_id);
+
+      LOG_T(MAC,"calling dlsch_scheduler_pre_processor_allocate .. \n ");
+      dlsch_scheduler_pre_processor_allocate (Mod_id,
+                                              UE_id,
+                                              CC_id,
+                                              N_RBG[CC_id],
+                                              transmission_mode,
+                                              min_rb_unit[CC_id],
+                                              N_RB_DL,
+                                              nb_rbs_required,
+                                              nb_rbs_required_remaining,
+                                              rballoc_sub,
+                                              MIMO_mode_indicator);
+      temp_total_rbs_count -= ue_sched_ctl->pre_nb_available_rbs[CC_id];
+      temp_total_ue_count--;
+
+      if (ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) {
+        dlsch_ue_select[CC_id].ue_num = i;
+        break;
+      }
+
+      if (temp_total_rbs_count == 0) {
+        dlsch_ue_select[CC_id].ue_num = i+1;
+        break;
+      }
+      LOG_D(MAC,"DLSCH UE Select: frame %d subframe %d pre_nb_available_rbs %d(i %d UE_id %d nb_rbs_required %d nb_rbs_required_remaining %d average_rbs_per_user %d (temp_total rbs_count %d ue_num %d) available_prbs %d)\n",
+          frameP,subframeP,ue_sched_ctl->pre_nb_available_rbs[CC_id],i,UE_id,nb_rbs_required[CC_id][UE_id],nb_rbs_required_remaining[CC_id][UE_id],
+          average_rbs_per_user[CC_id],temp_total_rbs_count,temp_total_ue_count,RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs);
+#ifdef TM5
+      // TODO: data channel TM5: to be re-visited
+#endif
+    }
+  }
+
+#ifdef TM5
+
+    // This has to be revisited!!!!
+    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+	i1 = 0;
+	i2 = 0;
+	i3 = 0;
+
+	for (j = 0; j < N_RBG[CC_id]; j++) {
+	    if (MIMO_mode_indicator[CC_id][j] == 2) {
+		i1 = i1 + 1;
+	    } else if (MIMO_mode_indicator[CC_id][j] == 1) {
+		i2 = i2 + 1;
+	    } else if (MIMO_mode_indicator[CC_id][j] == 0) {
+		i3 = i3 + 1;
+	    }
+	}
+
+	if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) {
+	    PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions =
+		PHY_vars_eNB_g[Mod_id][CC_id]->
+		check_for_SUMIMO_transmissions + 1;
+	}
+
+	if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) {
+	    PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions =
+		PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions +
+		1;
+	}
+
+        if((i1 < N_RBG[CC_id]) && (i3 > 0)) {
+		PHY_vars_eNB_g[Mod_id][CC_id]->
+		check_for_MUMIMO_transmissions + 1;
+	}
+
+	PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions =
+	    PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions +
+	    1;
+
+    }
+
+#endif
+
+  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+      for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
+        if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){
+            continue;
+        }
+        if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){
+            continue;
+        }
+        UE_id = dlsch_ue_select[CC_id].list[i].UE_id;
+        ue_sched_ctl = &RC.mac[Mod_id]->UE_list.UE_sched_ctrl[UE_id];
+	    //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id];
+
+	    if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) {
+		LOG_D(MAC,
+		      "******************DL Scheduling Information for UE%d ************************\n",
+		      UE_id);
+		LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id,
+		      ue_sched_ctl->dl_pow_off[CC_id]);
+		LOG_D(MAC,
+		      "***********RB Alloc for every subband for UE%d ***********\n",
+		      UE_id);
+
+		for (j = 0; j < N_RBG[CC_id]; j++) {
+		    //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i];
+		    LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n",
+			  UE_id, j,
+			  ue_sched_ctl->rballoc_sub_UE[CC_id][j]);
+		}
+
+		//PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id];
+		LOG_D(MAC, "Total RBs allocated for UE%d = %d\n", UE_id,
+		      ue_sched_ctl->pre_nb_available_rbs[CC_id]);
+	    }
+	}
+    }
+}
+
+
+//------------------------------------------------------------------------------
+void
+schedule_ue_spec_fairRR(module_id_t module_idP,
+		 frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag)
+//------------------------------------------------------------------------------
+{
+
+
+    uint8_t CC_id;
+    int UE_id;
+    unsigned char aggregation;
+    mac_rlc_status_resp_t rlc_status;
+    unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0;
+    unsigned char header_len_dtch = 0, header_len_dtch_tmp =
+	0, header_len_dtch_last = 0;
+    unsigned char ta_len = 0;
+    unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0;
+    uint16_t nb_rb, nb_rb_temp, nb_available_rb;
+    uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding =
+	0, post_padding = 0;
+    unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
+    unsigned char round = 0;
+    unsigned char harq_pid = 0;
+    eNB_UE_STATS *eNB_UE_stats = NULL;
+    uint16_t sdu_length_total = 0;
+
+    eNB_MAC_INST *eNB = RC.mac[module_idP];
+    COMMON_channels_t *cc = eNB->common_channels;
+    UE_list_t *UE_list = &eNB->UE_list;
+    int continue_flag = 0;
+    int32_t normalized_rx_power, target_rx_power;
+    int32_t tpc = 1;
+    static int32_t tpc_accumulated = 0;
+    UE_sched_ctrl *ue_sched_ctl;
+    int mcs;
+    int i;
+    int min_rb_unit[MAX_NUM_CCs];
+    int N_RB_DL[MAX_NUM_CCs];
+    int total_nb_available_rb[MAX_NUM_CCs];
+    int N_RBG[MAX_NUM_CCs];
+    nfapi_dl_config_request_body_t *dl_req;
+    nfapi_dl_config_request_pdu_t *dl_config_pdu;
+    int tdd_sfa;
+    int ta_update;
+
+#if 0
+    if (UE_list->head == -1) {
+	return;
+    }
+#endif
+
+    start_meas(&eNB->schedule_dlsch);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
+	(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
+
+
+    // for TDD: check that we have to act here, otherwise return
+    if (cc[0].tdd_Config) {
+	tdd_sfa = cc[0].tdd_Config->subframeAssignment;
+	switch (subframeP) {
+	case 0:
+	    // always continue
+	    break;
+	case 1:
+	    return;
+	    break;
+	case 2:
+	    return;
+	    break;
+	case 3:
+	    if ((tdd_sfa != 2) && (tdd_sfa != 5))
+		return;
+	    break;
+	case 4:
+	    if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4)
+		&& (tdd_sfa != 5))
+		return;
+	    break;
+	case 5:
+	    break;
+	case 6:
+	case 7:
+	    if ((tdd_sfa != 3)&& (tdd_sfa != 4) && (tdd_sfa != 5))
+		return;
+	    break;
+	case 8:
+	    if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4)
+		&& (tdd_sfa != 5))
+		return;
+	    break;
+	case 9:
+	    if (tdd_sfa == 0)
+		return;
+	    break;
+
+	  }
+    }
+
+    //weight = get_ue_weight(module_idP,UE_id);
+    aggregation = 2;
+    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+	N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth);
+	min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
+	// get number of PRBs less those used by common channels
+	total_nb_available_rb[CC_id] = N_RB_DL[CC_id];
+	for (i = 0; i < N_RB_DL[CC_id]; i++)
+	    if (cc[CC_id].vrb_map[i] != 0)
+		total_nb_available_rb[CC_id]--;
+
+	N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth);
+
+	// store the global enb stats:
+	eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs;
+	eNB->eNB_stats[CC_id].available_prbs =
+	    total_nb_available_rb[CC_id];
+	eNB->eNB_stats[CC_id].total_available_prbs +=
+	    total_nb_available_rb[CC_id];
+	eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0;
+	eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0;
+    }
+
+  /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band)
+
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN);
+  start_meas(&eNB->schedule_dlsch_preprocessor);
+  dlsch_scheduler_pre_processor_fairRR(module_idP,
+                                frameP,
+                                subframeP,
+                                N_RBG,
+                                mbsfn_flag);
+  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);
+
+    dl_req        = &eNB->DL_req[CC_id].dl_config_request_body;
+
+    if (mbsfn_flag[CC_id]>0)
+      continue;
+
+    for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) {
+      if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){
+        continue;
+      }
+      if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){
+        continue;
+      }
+      UE_id = dlsch_ue_select[CC_id].list[i].UE_id;
+      rnti = UE_RNTI(module_idP,UE_id);
+      if (rnti==NOT_A_RNTI) {
+        LOG_E(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs);
+        continue;
+      }
+
+      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
+      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+
+      switch(get_tmode(module_idP,CC_id,UE_id)){
+      case 1:
+      case 2:
+      case 7:
+        aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
+                                      ue_sched_ctl->dl_cqi[CC_id],
+                                      format1);
+        break;
+      case 3:
+        aggregation = get_aggregation(get_bw_index(module_idP,CC_id),
+                                      ue_sched_ctl->dl_cqi[CC_id],
+                                      format2A);
+        break;
+      default:
+        LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
+        aggregation = 2;
+        break;
+      }
+
+      if (cc[CC_id].tdd_Config != NULL) { //TDD
+        set_ue_dai (subframeP,
+                    UE_id,
+                    CC_id,
+  		    cc[CC_id].tdd_Config->subframeAssignment,
+                    UE_list);
+        // update UL DAI after DLSCH scheduling
+        set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
+      }
+#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];
+
+	    harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
+
+	    round = ue_sched_ctl->round[CC_id][harq_pid];
+
+	    UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti;
+	    UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status =
+		mac_eNB_get_rrc_status(module_idP, rnti);
+	    UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid;
+	    UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
+
+
+	    if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status <
+		RRC_CONNECTED)
+		continue;
+
+	    sdu_length_total = 0;
+	    num_sdus = 0;
+
+	    /*
+	       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);
+	     */
+            if (nfapi_mode) {
+              eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
+            }
+            else {
+              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;
+
+	    // initializing the rb allocation indicator for each UE
+	    for (j = 0; j < N_RBG[CC_id]; j++) {
+		UE_list->
+		    UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]
+		    = 0;
+	    }
+
+	    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, ue_sched_ctl->dl_cqi[CC_id],
+		  eNB_UE_stats->dlsch_mcs1,
+		  UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);
+
+
+
+	    /* process retransmission  */
+
+	    if (round != 8) {
+
+		// get freq_allocation
+		nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+		TBS =
+		    get_TBS_DL(UE_list->
+			       UE_template[CC_id][UE_id].oldmcs1[harq_pid],
+			       nb_rb);
+
+		if (nb_rb <= nb_available_rb) {
+		    if (cc[CC_id].tdd_Config != NULL) {
+			UE_list->UE_template[CC_id][UE_id].DAI++;
+			update_ul_dci(module_idP, CC_id, rnti,
+				      UE_list->UE_template[CC_id][UE_id].
+				      DAI,subframeP);
+			LOG_D(MAC,
+			      "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
+			      CC_id, subframeP, UE_id,
+			      UE_list->UE_template[CC_id][UE_id].DAI);
+		    }
+
+		    if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
+			for (j = 0; j < N_RBG[CC_id]; j++) {	// for indicating the rballoc for each sub-band
+			    UE_list->UE_template[CC_id][UE_id].
+				rballoc_subband[harq_pid][j] =
+				ue_sched_ctl->rballoc_sub_UE[CC_id][j];
+			}
+		    } else {
+			nb_rb_temp = nb_rb;
+			j = 0;
+
+			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) &&
+				    ((N_RB_DL[CC_id] == 25) ||
+				     (N_RB_DL[CC_id] == 50))) {
+				    nb_rb_temp =
+					nb_rb_temp - min_rb_unit[CC_id] +
+					1;
+				} else {
+				    nb_rb_temp =
+					nb_rb_temp - min_rb_unit[CC_id];
+				}
+			    }
+
+			    j = j + 1;
+			}
+		    }
+
+		    nb_available_rb -= nb_rb;
+		    /*
+		       eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
+		       eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
+
+		       for(j=0; j<N_RBG[CC_id]; j++) {
+		       eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
+		       }
+		     */
+
+		    switch (get_tmode(module_idP, CC_id, UE_id)) {
+		    case 1:
+		    case 2:
+		    case 7:
+		    default:
+                      LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti);
+
+			dl_config_pdu =
+			    &dl_req->dl_config_pdu_list[dl_req->
+							number_pdu];
+			memset((void *) dl_config_pdu, 0,
+			       sizeof(nfapi_dl_config_request_pdu_t));
+			dl_config_pdu->pdu_type =
+			    NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
+			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),
+					    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
+
+			dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
+			    harq_process = harq_pid;
+			dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1;	// dont adjust power when retransmitting
+			dl_config_pdu->dci_dl_pdu.
+			    dci_dl_pdu_rel8.new_data_indicator_1 =
+			    UE_list->UE_template[CC_id][UE_id].
+			    oldNDI[harq_pid];
+			dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 =
+			    UE_list->UE_template[CC_id][UE_id].
+			    oldmcs1[harq_pid];
+			dl_config_pdu->dci_dl_pdu.
+			    dci_dl_pdu_rel8.redundancy_version_1 =
+			    round & 3;
+
+			if (cc[CC_id].tdd_Config != NULL) {	//TDD
+			    dl_config_pdu->dci_dl_pdu.
+				dci_dl_pdu_rel8.downlink_assignment_index =
+				(UE_list->UE_template[CC_id][UE_id].DAI -
+				 1) & 3;
+			    LOG_D(MAC,
+				  "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
+				  module_idP, CC_id, harq_pid, round,
+				  (UE_list->UE_template[CC_id][UE_id].DAI -
+				   1),
+				  UE_list->
+				  UE_template[CC_id][UE_id].oldmcs1
+				  [harq_pid]);
+			} else {
+			    LOG_D(MAC,
+				  "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
+				  module_idP, CC_id, harq_pid, round,
+				  UE_list->
+				  UE_template[CC_id][UE_id].oldmcs1
+				  [harq_pid]);
+
+			}
+			if (!CCE_allocation_infeasible
+			    (module_idP, CC_id, 1, subframeP,
+			     dl_config_pdu->dci_dl_pdu.
+			     dci_dl_pdu_rel8.aggregation_level, rnti)) {
+			    dl_req->number_dci++;
+			    dl_req->number_pdu++;
+                            dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+
+                            eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
+                            eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
+
+			    fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1
+						    /* retransmission, no pdu_index */
+						    , rnti, 0,	// type 0 allocation from 7.1.6 in 36.213
+						    0,	// virtual_resource_block_assignment_flag, unused here
+						    0,	// resource_block_coding, to be filled in later
+						    getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3,	// redundancy version
+						    1,	// transport blocks
+						    0,	// transport block to codeword swap flag
+						    cc[CC_id].p_eNB == 1 ? 0 : 1,	// transmission_scheme
+						    1,	// number of layers
+						    1,	// number of subbands
+						    //                      uint8_t codebook_index,
+						    4,	// UE category capacity
+						    UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0,	// delta_power_offset for TM5
+						    0,	// ngap
+						    0,	// nprb
+						    cc[CC_id].p_eNB == 1 ? 1 : 2,	// transmission mode
+						    0,	//number of PRBs treated as one subband, not used here
+						    0	// number of beamforming vectors, not used here
+				);
+
+			    LOG_D(MAC,
+				  "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",
+				  eNB->pdu_index[CC_id], round);
+
+			    program_dlsch_acknak(module_idP, CC_id, UE_id,
+						 frameP, subframeP,
+						 dl_config_pdu->
+						 dci_dl_pdu.dci_dl_pdu_rel8.
+						 cce_idx);
+			    // No TX request for retransmission (check if null request for FAPI)
+			} else {
+			    LOG_W(MAC,
+				  "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n",
+				  frameP, subframeP, UE_id, rnti);
+			}
+		    }
+
+
+		    add_ue_dlsch_info(module_idP,
+				      CC_id, UE_id, subframeP,
+				      S_DL_SCHEDULED);
+
+		    //eNB_UE_stats->dlsch_trials[round]++;
+		    UE_list->eNB_UE_stats[CC_id][UE_id].
+			num_retransmission += 1;
+		    UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx =
+			nb_rb;
+		    UE_list->eNB_UE_stats[CC_id][UE_id].
+			total_rbs_used_retx += nb_rb;
+		    UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 =
+			eNB_UE_stats->dlsch_mcs1;
+		    UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 =
+			eNB_UE_stats->dlsch_mcs1;
+		} else {
+		    LOG_D(MAC,
+			  "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
+			  module_idP, frameP, CC_id, UE_id);
+		}
+	    } else {		/* This is a potentially new SDU opportunity */
+
+		rlc_status.bytes_in_buffer = 0;
+		// Now check RLC information to compute number of required RBs
+		// get maximum TBS size for RLC request
+		TBS =
+		    get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb);
+		// check first for RLC data on DCCH
+		// add the length for  all the control elements (timing adv, drx, etc) : header + payload
+
+		if (ue_sched_ctl->ta_timer == 0) {
+		    ta_update = ue_sched_ctl->ta_update;
+		    /* if we send TA then set timer to not send it for a while */
+		    if (ta_update != 31)
+			ue_sched_ctl->ta_timer = 20;
+		    /* reset ta_update */
+		    ue_sched_ctl->ta_update = 31;
+		} else {
+		    ta_update = 31;
+		}
+
+		ta_len = (ta_update != 31) ? 2 : 0;
+
+		header_len_dcch = 2;	// 2 bytes DCCH SDU subheader
+
+		if (TBS - ta_len - header_len_dcch > 0) {
+		    rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch)
+#ifdef Rel14
+                                                    ,0, 0
+#endif
+                                                   );	// transport block set size
+
+		    sdu_lengths[0] = 0;
+
+		    if (rlc_status.bytes_in_buffer > 0) {	// There is DCCH to transmit
+			LOG_D(MAC,
+			      "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
+			      module_idP, frameP, subframeP, CC_id,
+			      TBS - header_len_dcch);
+			sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS,	//not used
+							  (char *)
+							  &dlsch_buffer
+							  [0]
+#ifdef Rel14
+                                                          ,0, 0
+#endif
+                                                         );
+            pthread_mutex_lock(&rrc_release_freelist);
+            if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){
+              uint16_t release_total = 0;
+              for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
+                if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){
+                  release_total++;
+                }else{
+                  continue;
+                }
+
+                if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1){
+                  if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){
+                    for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
+                      if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){
+                        rrc_release_info.RRC_release_ctrl[release_num].flag = 3;
+                        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num);
+                        break;
+                       }
+                     }
+                  }
+                }
+                if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2){
+                  if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){
+                    for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
+                      if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){
+                          rrc_release_info.RRC_release_ctrl[release_num].flag = 4;
+                          LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num);
+                          break;
+                      }
+                    }
+                  }
+                }
+                if(release_total >= rrc_release_info.num_UEs)
+                  break;
+              }
+            }
+            pthread_mutex_unlock(&rrc_release_freelist);
+
+            RA_t *ra = &eNB->common_channels[CC_id].ra[0];
+            for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) {
+              if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)){
+                for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
+                  if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]){
+                    ra[ra_ii].crnti_harq_pid = harq_pid;
+                    ra[ra_ii].state = MSGCRNTI_ACK;
+                    break;
+                  }
+                }
+              }
+            }
+			T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
+			  T_INT(CC_id), T_INT(rnti), T_INT(frameP),
+			  T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH),
+			  T_INT(sdu_lengths[0]));
+                       LOG_D(MAC,
+                             "[eNB %d][DCCH] CC_id %d frame %d subframe %d UE_id %d/%x Got %d bytes bytes_in_buffer %d from release_num %d\n",
+                             module_idP, CC_id, frameP, subframeP, UE_id, rnti, sdu_lengths[0],rlc_status.bytes_in_buffer,rrc_release_info.num_UEs);
+ 
+			sdu_length_total = sdu_lengths[0];
+			sdu_lcids[0] = DCCH;
+			UE_list->eNB_UE_stats[CC_id][UE_id].
+			    num_pdu_tx[DCCH] += 1;
+			UE_list->
+			    eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]
+			    += sdu_lengths[0];
+			num_sdus = 1;
+#ifdef DEBUG_eNB_SCHEDULER
+			LOG_T(MAC,
+			      "[eNB %d][DCCH] CC_id %d Got %d bytes :",
+			      module_idP, CC_id, sdu_lengths[0]);
+
+			for (j = 0; j < sdu_lengths[0]; j++) {
+			    LOG_T(MAC, "%x ", dlsch_buffer[j]);
+			}
+
+			LOG_T(MAC, "\n");
+#endif
+		    } else {
+			header_len_dcch = 0;
+			sdu_length_total = 0;
+		    }
+		}
+		// check for DCCH1 and update header information (assume 2 byte sub-header)
+		if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) {
+		    rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total)
+#ifdef Rel14
+                                                    ,0, 0
+#endif
+                                                   );	// transport block set size less allocations for timing advance and
+		    // DCCH SDU
+		    sdu_lengths[num_sdus] = 0;
+
+		    if (rlc_status.bytes_in_buffer > 0) {
+			LOG_D(MAC,
+			      "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
+			      module_idP, frameP, CC_id,
+			      TBS - header_len_dcch - sdu_length_total);
+			sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS,	//not used
+								  (char *)
+								  &dlsch_buffer
+								  [sdu_length_total]
+#ifdef Rel14
+                                                                  ,0, 0
+#endif
+                                                                 );
+
+			T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
+			  T_INT(CC_id), T_INT(rnti), T_INT(frameP),
+			  T_INT(subframeP), T_INT(harq_pid),
+			  T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus]));
+
+			sdu_lcids[num_sdus] = DCCH1;
+			sdu_length_total += sdu_lengths[num_sdus];
+			header_len_dcch += 2;
+			UE_list->eNB_UE_stats[CC_id][UE_id].
+			    num_pdu_tx[DCCH1] += 1;
+			UE_list->
+			    eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]
+			    += sdu_lengths[num_sdus];
+			num_sdus++;
+#ifdef DEBUG_eNB_SCHEDULER
+			LOG_T(MAC,
+			      "[eNB %d][DCCH1] CC_id %d Got %d bytes :",
+			      module_idP, CC_id, sdu_lengths[num_sdus]);
+
+			for (j = 0; j < sdu_lengths[num_sdus]; j++) {
+			    LOG_T(MAC, "%x ", dlsch_buffer[j]);
+			}
+
+			LOG_T(MAC, "\n");
+#endif
+
+		    }
+		}
+		// assume the max dtch header size, and adjust it later
+		header_len_dtch = 0;
+		header_len_dtch_last = 0;	// the header length of the last mac sdu
+		// lcid has to be sorted before the actual allocation (similar struct as ue_list).
+	    /* TODO limited lcid for performance */
+        for (lcid = DTCH; lcid >= DTCH; lcid--) {
+		    // TBD: check if the lcid is active
+
+		    header_len_dtch += 3;
+		    header_len_dtch_last = 3;
+		    LOG_D(MAC,
+			  "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
+			  module_idP, frameP, lcid, TBS,
+			  TBS - ta_len - header_len_dcch -
+			  sdu_length_total - header_len_dtch);
+
+		    if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) {	// NN: > 2 ? 
+			rlc_status = mac_rlc_status_ind(module_idP,
+							rnti,
+							module_idP,
+							frameP,
+							subframeP,
+							ENB_FLAG_YES,
+							MBMS_FLAG_NO,
+							lcid,
+							TBS - ta_len -
+							header_len_dcch -
+							sdu_length_total -
+							header_len_dtch
+#ifdef Rel14
+                                                        ,0, 0
+#endif
+                                                       );
+
+
+			if (rlc_status.bytes_in_buffer > 0) {
+
+			    LOG_D(MAC,
+				  "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
+				  module_idP, frameP,
+				  TBS - header_len_dcch -
+				  sdu_length_total - header_len_dtch, lcid,
+				  header_len_dtch);
+			    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS,	//not used
+								     (char
+								      *)
+								     &dlsch_buffer
+								     [sdu_length_total]
+#ifdef Rel14
+                                                                     ,0, 0
+#endif
+                                                                    );
+			    T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
+			      T_INT(CC_id), T_INT(rnti), T_INT(frameP),
+			      T_INT(subframeP), T_INT(harq_pid),
+			      T_INT(lcid), T_INT(sdu_lengths[num_sdus]));
+
+			    LOG_D(MAC,
+				  "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
+				  module_idP, sdu_lengths[num_sdus], lcid);
+			    sdu_lcids[num_sdus] = lcid;
+			    sdu_length_total += sdu_lengths[num_sdus];
+			    UE_list->
+				eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]
+				+= 1;
+			    UE_list->
+				eNB_UE_stats[CC_id][UE_id].num_bytes_tx
+				[lcid] += sdu_lengths[num_sdus];
+			    if (sdu_lengths[num_sdus] < 128) {
+				header_len_dtch--;
+				header_len_dtch_last--;
+			    }
+			    num_sdus++;
+                            UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+			}	// no data for this LCID
+			else {
+			    header_len_dtch -= 3;
+			}
+		    }		// no TBS left
+		    else {
+			header_len_dtch -= 3;
+			break;
+		    }
+		}
+		if (header_len_dtch == 0)
+		    header_len_dtch_last = 0;
+		// there is at least one SDU 
+		// if (num_sdus > 0 ){
+		if ((sdu_length_total + header_len_dcch +
+		     header_len_dtch) > 0) {
+
+		    // Now compute number of required RBs for total sdu length
+		    // Assume RAH format 2
+		    // adjust  header lengths
+		    header_len_dcch_tmp = header_len_dcch;
+		    header_len_dtch_tmp = header_len_dtch;
+		    if (header_len_dtch == 0) {
+			header_len_dcch = (header_len_dcch > 0) ? 1 : 0;	//header_len_dcch;  // remove length field
+		    } else {
+			header_len_dtch_last -= 1;	// now use it to find how many bytes has to be removed for the last MAC SDU 
+			header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch;	// remove length field for the last SDU
+		    }
+
+		    mcs = eNB_UE_stats->dlsch_mcs1;
+            nb_rb = min_rb_unit[CC_id];
+		    TBS = get_TBS_DL(mcs, nb_rb);
+
+		    while (TBS <
+			   (sdu_length_total + header_len_dcch +
+			    header_len_dtch + ta_len)) {
+			nb_rb += min_rb_unit[CC_id];	//
+
+			if (nb_rb > nb_available_rb) {	// if we've gone beyond the maximum number of RBs
+			    // (can happen if N_RB_DL is odd)
+			    TBS =
+				get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
+					   nb_available_rb);
+			    nb_rb = nb_available_rb;
+			    break;
+			}
+
+			TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb);
+		    }
+
+		    if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
+			for (j = 0; j < N_RBG[CC_id]; j++) {	// for indicating the rballoc for each sub-band
+			    UE_list->UE_template[CC_id][UE_id].
+				rballoc_subband[harq_pid][j] =
+				ue_sched_ctl->rballoc_sub_UE[CC_id][j];
+			}
+		    } else {
+			nb_rb_temp = nb_rb;
+			j = 0;
+
+			while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
+			    if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] ==
+				1) {
+				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) &&
+				    ((N_RB_DL[CC_id] == 25) ||
+				     (N_RB_DL[CC_id] == 50))) {
+				    nb_rb_temp =
+					nb_rb_temp - min_rb_unit[CC_id] +
+					1;
+				} else {
+				    nb_rb_temp =
+					nb_rb_temp - min_rb_unit[CC_id];
+				}
+			    }
+
+			    j = j + 1;
+			}
+		    }
+
+		    // decrease mcs until TBS falls below required length
+		    while ((TBS >
+			    (sdu_length_total + header_len_dcch +
+			     header_len_dtch + ta_len)) && (mcs > 0)) {
+			mcs--;
+			TBS = get_TBS_DL(mcs, nb_rb);
+		    }
+
+		    // if we have decreased too much or we don't have enough RBs, increase MCS
+		    while ((TBS <
+			    (sdu_length_total + header_len_dcch +
+			     header_len_dtch + ta_len))
+			   && (((ue_sched_ctl->dl_pow_off[CC_id] > 0)
+				&& (mcs < 28))
+			       || ((ue_sched_ctl->dl_pow_off[CC_id] == 0)
+				   && (mcs <= 15)))) {
+			mcs++;
+			TBS = get_TBS_DL(mcs, nb_rb);
+		    }
+
+		    LOG_D(MAC,
+			  "dlsch_mcs before and after the rate matching = (%d, %d)\n",
+			  eNB_UE_stats->dlsch_mcs1, mcs);
+
+#ifdef DEBUG_eNB_SCHEDULER
+		    LOG_D(MAC,
+			  "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
+			  module_idP, CC_id, mcs, TBS, nb_rb);
+		    // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
+		    //  TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
+#endif
+
+		    if ((TBS - header_len_dcch - header_len_dtch -
+			 sdu_length_total - ta_len) <= 2) {
+			padding =
+			    (TBS - header_len_dcch - header_len_dtch -
+			     sdu_length_total - ta_len);
+			post_padding = 0;
+		    } else {
+			padding = 0;
+
+			// adjust the header len
+			if (header_len_dtch == 0) {
+			    header_len_dcch = header_len_dcch_tmp;
+			} else {	//if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
+			    header_len_dtch = header_len_dtch_tmp;
+			}
+
+			post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len;	// 1 is for the postpadding header
+		    }
+
+#ifdef PHY_TX_THREAD
+  struct timespec time_req, time_rem;
+  time_req.tv_sec = 0;
+  time_req.tv_nsec = 10000;
+		    while((!oai_exit)&&(phy_tx_txdataF_end == 0)){
+		      nanosleep(&time_req,&time_rem);
+		        continue;
+		    }
+#endif
+
+		    offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus,	//num_sdus
+						   sdu_lengths,	//
+						   sdu_lcids, 255,	// no drx
+						   ta_update,	// timing advance
+						   NULL,	// contention res id
+						   padding, post_padding);
+
+		    //#ifdef DEBUG_eNB_SCHEDULER
+		    if (ta_update != 31) {
+			LOG_D(MAC,
+			      "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n",
+			      module_idP, frameP, UE_id, CC_id,
+			      sdu_length_total, num_sdus, sdu_lengths[0],
+			      sdu_lcids[0], offset, ta_update, padding,
+			      post_padding, mcs, TBS, nb_rb,
+			      header_len_dcch, header_len_dtch);
+		    }
+		    //#endif
+#ifdef DEBUG_eNB_SCHEDULER
+		    LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n");
+
+		    for (i = 0; i < 16; i++) {
+			LOG_T(MAC, "%x.", dlsch_buffer[i]);
+		    }
+
+		    LOG_T(MAC, "\n");
+#endif
+
+          // cycle through SDUs and place in dlsch_buffer
+          memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total);
+          // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
+
+          // fill remainder of DLSCH with random data
+          for (j=0; j<(TBS-sdu_length_total-offset); j++) {
+            UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff);
+          }
+
+          if (opt_enabled == 1) {
+            trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
+                      TBS, module_idP, 3, UE_RNTI(module_idP,UE_id),
+                      eNB->frame, eNB->subframe,0,0);
+            LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d  rnti %x  with size %d\n",
+                  module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS);
+          }
+
+          T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP),
+            T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
+
+	  UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb;
+
+          add_ue_dlsch_info(module_idP,
+                            CC_id,
+                            UE_id,
+                            subframeP,
+                            S_DL_SCHEDULED);
+          // store stats
+          eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total;
+          eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1;
+
+          UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb;
+          UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb;
+          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
+          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=mcs;
+          UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS;
+
+          UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS- sdu_length_total;
+          UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total;
+          UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS;
+          UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus+=1;
+
+          if (cc[CC_id].tdd_Config != NULL) { // TDD
+            UE_list->UE_template[CC_id][UE_id].DAI++;
+            update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI,subframeP);
+          }
+
+	  // do PUCCH power control
+          // this is the normalized RX power
+	  eNB_UE_stats =  &UE_list->eNB_UE_stats[CC_id][UE_id];
+
+          /* TODO: fix how we deal with power, unit is not dBm, it's special from nfapi */
+	  normalized_rx_power = ue_sched_ctl->pucch1_snr[CC_id];
+	  target_rx_power = 208;
+	    
+          // 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 (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;
+	      
+	      if (normalized_rx_power>(target_rx_power+4)) {
+		tpc = 0; //-1
+		tpc_accumulated--;
+	      } else if (normalized_rx_power<(target_rx_power-4)) {
+		tpc = 2; //+1
+		tpc_accumulated++;
+	      } else {
+		tpc = 1; //0
+	      }
+	      	      
+	      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);
+
+	    } // Po_PUCCH has been updated 
+	    else {
+	      tpc = 1; //0
+	    } // time to do TPC update 
+	  else {
+	    tpc = 1; //0
+	  }
+
+	  dl_config_pdu                                                         = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
+	  memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
+	  dl_config_pdu->pdu_type                                               = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; 
+	  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.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),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
+	  
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                = harq_pid;
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                         = tpc; // dont adjust power when retransmitting
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1        = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
+	  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;
+	  //deactivate second codeword
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2                       = 0;
+	  dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2        = 1;
+	  if (cc[CC_id].tdd_Config != NULL) { //TDD
+	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
+	    LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n",
+		  module_idP,CC_id,harq_pid,
+		  (UE_list->UE_template[CC_id][UE_id].DAI-1),
+		  mcs);
+	  } else {
+	    LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n",
+		  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)) {
+
+
+	    ue_sched_ctl->round[CC_id][harq_pid] = 0;
+	    dl_req->number_dci++;
+	    dl_req->number_pdu++;
+	    dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
+	    
+	    eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
+	    eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
+	    // Toggle NDI for next time
+	    LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",
+		  CC_id, frameP,subframeP,UE_id,
+		  rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]);
+	    
+	    UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
+	    UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
+	    UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
+	    AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n");
+	    AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
+	    
+	    fill_nfapi_dlsch_config(eNB,dl_req,
+				    TBS,
+				    eNB->pdu_index[CC_id],
+				    rnti,
+				    0, // type 0 allocation from 7.1.6 in 36.213
+				    0, // virtual_resource_block_assignment_flag, unused here
+				    0, // resource_block_coding, to be filled in later
+				    getQm(mcs),
+				    0, // redundancy version
+				    1, // transport blocks
+				    0, // transport block to codeword swap flag
+				    cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme
+				    1, // number of layers
+				    1, // number of subbands
+				    //			     uint8_t codebook_index,
+				    4, // UE category capacity
+				    UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 
+				    0, // delta_power_offset for TM5
+				    0, // ngap
+				    0, // nprb
+				    cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode
+				    0, //number of PRBs treated as one subband, not used here
+				    0 // number of beamforming vectors, not used here
+				    );  
+	    eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
+							  (frameP*10)+subframeP,
+							  TBS,
+							  eNB->pdu_index[CC_id],
+							  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]);
+
+	    eNB->pdu_index[CC_id]++;
+	    program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
+        last_dlsch_ue_id[CC_id] = UE_id;
+	  }
+	  else {
+	    LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n",
+		  frameP,subframeP,UE_id,rnti);
+	  }
+        } else {  // There is no data from RLC or MAC header, so don't schedule
+
+        }
+      }
+
+      if (cc[CC_id].tdd_Config != NULL){ // TDD
+        set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
+      }
+
+    } // UE_id loop
+  }  // CC_id loop
+
+
+  fill_DLSCH_dci_fairRR(module_idP,frameP,subframeP,mbsfn_flag);
+  stop_meas(&eNB->schedule_dlsch);
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT);
+
+
+}
+
+//------------------------------------------------------------------------------
+void
+fill_DLSCH_dci_fairRR(
+	       module_id_t module_idP,
+	       frame_t frameP,
+	       sub_frame_t subframeP,
+	       int* mbsfn_flagP)
+//------------------------------------------------------------------------------
+{
+
+  // loop over all allocated UEs and compute frequency allocations for PDSCH
+  int   UE_id = -1;
+  uint8_t            /* first_rb, */ nb_rb=3;
+  rnti_t        rnti;
+  //unsigned char *vrb_map;
+  uint8_t            rballoc_sub[25];
+  //uint8_t number_of_subbands=13;
+
+  //unsigned char round;
+  unsigned char     harq_pid;
+  int               i;
+  int               CC_id;
+  eNB_MAC_INST      *eNB  =RC.mac[module_idP];
+  UE_list_t         *UE_list = &eNB->UE_list;
+  int               N_RBG;
+  int               N_RB_DL;
+  COMMON_channels_t *cc;
+  int               j;
+  start_meas(&eNB->fill_DLSCH_dci);
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,VCD_FUNCTION_IN);
+
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    LOG_D(MAC,"Doing fill DCI for CC_id %d\n",CC_id);
+
+    if (mbsfn_flagP[CC_id]>0)
+      continue;
+
+    cc              = &eNB->common_channels[CC_id];
+    N_RBG           = to_rbg(cc->mib->message.dl_Bandwidth);
+    N_RB_DL         = to_prb(cc->mib->message.dl_Bandwidth);
+
+    // UE specific DCIs
+    for (j = 0; j < dlsch_ue_select[CC_id].ue_num; j++) {
+      if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG2){
+        continue;
+      }
+      if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG4){
+        continue;
+      }
+      UE_id = dlsch_ue_select[CC_id].list[j].UE_id;
+      LOG_T(MAC,"CC_id %d, UE_id: %d => status %d\n",CC_id,UE_id,eNB_dlsch_info[module_idP][CC_id][UE_id].status);
+
+      if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) {
+
+        // clear scheduling flag
+        eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING;
+        rnti = UE_RNTI(module_idP,UE_id);
+        harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
+        nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
+
+
+	
+        /// Synchronizing rballoc with rballoc_sub
+        for(i=0; i<N_RBG; i++) {
+          rballoc_sub[i] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][i];
+        }
+
+	nfapi_dl_config_request_t      *DL_req         = &RC.mac[module_idP]->DL_req[0];
+	nfapi_dl_config_request_pdu_t* dl_config_pdu;
+
+	for (i=0;i<DL_req[CC_id].dl_config_request_body.number_pdu;i++) {
+	  dl_config_pdu                    = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i];
+	  if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)&&
+	      (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) &&
+          (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) {
+	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding    = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub);
+	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0;
+	  }
+	  else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)&&
+		       (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) &&
+               (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type==0)) {
+	    dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding    = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub);
+	  }
+         }
+	}
+      }
+    }
+
+    stop_meas(&eNB->fill_DLSCH_dci);
+    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
+	(VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT);
+}
+
+
+
+void ulsch_scheduler_pre_ue_select_fairRR(
+    module_id_t       module_idP,
+    frame_t           frameP,
+    sub_frame_t       subframeP,
+    sub_frame_t       sched_subframeP,
+    ULSCH_UE_SELECT   ulsch_ue_select[MAX_NUM_CCs])
+{
+  eNB_MAC_INST *eNB=RC.mac[module_idP];
+  COMMON_channels_t *cc;
+  int CC_id,UE_id;
+  int ret;
+  uint16_t i;
+  uint8_t ue_first_num[MAX_NUM_CCs];
+  uint8_t first_ue_total[MAX_NUM_CCs][20];
+  uint8_t first_ue_id[MAX_NUM_CCs][20];
+  uint8_t ul_inactivity_num[MAX_NUM_CCs];
+  uint8_t ul_inactivity_id[MAX_NUM_CCs][20];
+//  LTE_DL_FRAME_PARMS *frame_parms;
+  uint8_t ulsch_ue_max_num[MAX_NUM_CCs];
+  uint16_t saved_ulsch_dci[MAX_NUM_CCs];
+  rnti_t rnti;
+  UE_sched_ctrl *UE_sched_ctl = NULL;
+  uint8_t cc_id_flag[MAX_NUM_CCs];
+  uint8_t harq_pid = 0,round = 0;
+  UE_list_t *UE_list= &eNB->UE_list;
+
+
+  uint8_t                        aggregation = 2;
+  int                            format_flag;
+  nfapi_hi_dci0_request_body_t   *HI_DCI0_req;
+  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
+
+
+  for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) {
+      //save ulsch dci number
+      saved_ulsch_dci[CC_id] = eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci;
+      // maximum multiplicity number
+      ulsch_ue_max_num[CC_id] =RC.rrc[module_idP]->configuration.ue_multiple_max[CC_id];
+
+      cc_id_flag[CC_id] = 0;
+      ue_first_num[CC_id] = 0;
+      ul_inactivity_num[CC_id] = 0;
+
+  }
+  // UE round >0
+  for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) {
+      if (UE_list->active[UE_id] == FALSE)
+          continue;
+
+      rnti = UE_RNTI(module_idP,UE_id);
+      if (rnti ==NOT_A_RNTI)
+        continue;
+
+      CC_id = UE_PCCID(module_idP,UE_id);
+      if (UE_list->UE_template[CC_id][UE_id].configured == FALSE)
+        continue;
+
+      if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
+        continue;
+
+      // UL DCI
+      HI_DCI0_req   = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
+      if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
+        cc_id_flag[CC_id] = 1;
+        HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id];
+        ret = cc_id_end(cc_id_flag);
+        if ( ret == 0 ) {
+            continue;
+        }
+        if ( ret == 1 ) {
+            return;
+        }
+      }
+
+      cc = &eNB->common_channels[CC_id];
+      //harq_pid
+      harq_pid = subframe2harqpid(cc,(frameP+(sched_subframeP<subframeP ? 1 : 0)),sched_subframeP);
+      //round
+      round = UE_list->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid];
+
+      if ( round > 0 ) {
+          hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
+          format_flag = 2;
+          if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
+              cc_id_flag[CC_id] = 1;
+              continue;
+          } else {
+              hi_dci0_pdu->pdu_type                               = NFAPI_HI_DCI0_DCI_PDU_TYPE;
+              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++;
+
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_RETRANS;
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = eNB->UE_list.UE_template[CC_id][UE_id].first_rb_ul[harq_pid];
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = eNB->UE_list.UE_template[CC_id][UE_id].nb_rb_ul[harq_pid];
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id;
+              ulsch_ue_select[CC_id].ue_num++;
+              continue;
+          }
+      }
+      //
+      int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes;
+      if (bytes_to_schedule < 0) bytes_to_schedule = 0;
+
+      if ( UE_id > last_ulsch_ue_id[CC_id] && ((ulsch_ue_select[CC_id].ue_num+ue_first_num[CC_id]) < ulsch_ue_max_num[CC_id]) ) {
+        if ( bytes_to_schedule > 0 ) {
+          first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id;
+          first_ue_total[CC_id][ue_first_num[CC_id]] = bytes_to_schedule;
+          ue_first_num[CC_id]++;
+          continue;
+        }
+        if ( UE_list->UE_template[CC_id][UE_id].ul_SR > 0 ) {
+          first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id;
+          first_ue_total[CC_id] [ue_first_num[CC_id]] = 0;
+          ue_first_num[CC_id]++;
+          continue;
+        }
+        UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+        if ( ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0))  ||
+            ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) {
+          first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id;
+          first_ue_total[CC_id] [ue_first_num[CC_id]] = 0;
+          ue_first_num[CC_id]++;
+          continue;
+        }
+        /*if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id] ) < ulsch_ue_max_num[CC_id] ) {
+            UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+            uint8_t ul_period = 0;
+            if (cc->tdd_Config) {
+              ul_period = 50;
+            } else {
+              ul_period = 20;
+            }
+            if ( ((UE_sched_ctl->ul_inactivity_timer>ul_period)&&(UE_sched_ctl->ul_scheduled==0))  ||
+              ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) {
+            ul_inactivity_id[CC_id][ul_inactivity_num[CC_id]]= UE_id;
+            ul_inactivity_num[CC_id] ++;
+            continue;
+          }
+        }*/
+      }
+
+  }
+
+  for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) {
+    HI_DCI0_req   = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
+    for ( int temp = 0; temp < ue_first_num[CC_id]; temp++ ) {
+      if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
+        cc_id_flag[CC_id] = 1;
+        HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id];
+        break;
+      }
+
+      hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
+      format_flag = 2;
+      rnti = UE_RNTI(module_idP,first_ue_id[CC_id][temp]);
+      if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
+    	  cc_id_flag[CC_id] = 1;
+          break;
+      } else {
+          hi_dci0_pdu->pdu_type                               = NFAPI_HI_DCI0_DCI_PDU_TYPE;
+          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++;
+
+          ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_FIRST;
+          ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = first_ue_total[CC_id][temp];
+          ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = first_ue_id[CC_id][temp];
+          ulsch_ue_select[CC_id].ue_num++;
+      }
+    }
+  }
+
+  for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) {
+    if (UE_list->active[UE_id] == FALSE)
+        continue;
+
+    rnti = UE_RNTI(module_idP,UE_id);
+    if (rnti ==NOT_A_RNTI)
+        continue;
+
+    CC_id = UE_PCCID(module_idP,UE_id);
+
+    if (UE_id > last_ulsch_ue_id[CC_id])
+        continue;
+
+    if (UE_list->UE_template[CC_id][UE_id].configured == FALSE)
+        continue;
+
+    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
+        continue;
+
+    if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
+        cc_id_flag[CC_id] = 1;
+        HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id];
+        ret = cc_id_end(cc_id_flag);
+        if ( ret == 0 ) {
+            continue;
+        }
+        if ( ret == 1 ) {
+            return;
+        }
+    }
+
+    for(i = 0;i<ulsch_ue_select[CC_id].ue_num;i++){
+      if(ulsch_ue_select[CC_id].list[i].UE_id == UE_id){
+       break;
+      }
+    }
+    if(i < ulsch_ue_select[CC_id].ue_num)
+      continue;
+
+    HI_DCI0_req   = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
+    //SR BSR
+        UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+
+    int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes;
+    if (bytes_to_schedule < 0) bytes_to_schedule = 0;
+
+    if ( (bytes_to_schedule > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) ||
+          ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0))  ||
+          ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) ){
+        hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
+        format_flag = 2;
+        if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
+            cc_id_flag[CC_id] = 1;
+            continue;
+        } else {
+              hi_dci0_pdu->pdu_type                               = NFAPI_HI_DCI0_DCI_PDU_TYPE;
+              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++;
+
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_FIRST;
+              if(bytes_to_schedule > 0)
+                  ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = bytes_to_schedule;
+              else if(UE_list->UE_template[CC_id][UE_id].ul_SR > 0)
+                  ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0;
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id;
+              ulsch_ue_select[CC_id].ue_num++;
+              continue;
+          }
+    }
+    //inactivity UE
+/*    if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id]) < ulsch_ue_max_num[CC_id] ) {
+        UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
+        uint8_t ul_period = 0;
+        if (cc->tdd_Config) {
+          ul_period = 50;
+        } else {
+          ul_period = 20;
+        }
+        if ( ((UE_sched_ctl->ul_inactivity_timer>ul_period)&&(UE_sched_ctl->ul_scheduled==0))  ||
+            ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) {
+          ul_inactivity_id[CC_id][ul_inactivity_num[CC_id]]= UE_id;
+          ul_inactivity_num[CC_id]++;
+          continue;
+        }
+    }*/
+  }
+
+  for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) {
+    HI_DCI0_req   = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
+    for ( int temp = 0; temp < ul_inactivity_num[CC_id]; temp++ ) {
+      if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) {
+        HI_DCI0_req   = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
+        cc_id_flag[CC_id] = 1;
+        break;
+      }
+
+      hi_dci0_pdu   = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi];
+      format_flag = 2;
+      rnti = UE_RNTI(module_idP,ul_inactivity_id[CC_id][temp]);
+      if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) {
+          cc_id_flag[CC_id] = 1;
+          continue;
+      } else {
+          hi_dci0_pdu->pdu_type                               = NFAPI_HI_DCI0_DCI_PDU_TYPE;
+          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++;
+
+          ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_INACTIVE;
+          ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0;
+          ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = ul_inactivity_id[CC_id][temp];
+          ulsch_ue_select[CC_id].ue_num++;
+      }
+    }
+    HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id];
+  }
+  return;
+}
+
+uint8_t find_rb_table_index(uint8_t average_rbs)
+{
+  int i;
+  for ( i = 0; i < 34; i++ ) {
+    if ( rb_table[i] > average_rbs ) {
+      return (i-1);
+    }
+  }
+  return i;
+}
+
+void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
+                                   frame_t frameP,
+                                   sub_frame_t subframeP,
+                                   sub_frame_t sched_subframeP,
+                                   ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs])
+{
+  int                CC_id,ulsch_ue_num;
+  eNB_MAC_INST       *eNB = RC.mac[module_idP];
+  UE_list_t          *UE_list= &eNB->UE_list;
+  UE_TEMPLATE        *UE_template = NULL;
+  LTE_DL_FRAME_PARMS *frame_parms = NULL;
+  uint8_t            ue_num_temp;
+  uint8_t            total_rbs=0;
+  uint8_t            average_rbs;
+  uint16_t           first_rb[MAX_NUM_CCs];
+  uint8_t            mcs;
+  uint8_t            rb_table_index;
+  uint8_t            num_pucch_rb;
+  uint32_t           tbs;
+  int16_t            tx_power;
+  int                UE_id;
+  rnti_t             rnti;
+  COMMON_channels_t *cc;
+  LOG_D(MAC,"In ulsch_preprocessor: ulsch ue select\n");
+  //ue select
+  ulsch_scheduler_pre_ue_select_fairRR(module_idP,frameP,subframeP,sched_subframeP,ulsch_ue_select);
+
+  // MCS and RB assgin
+  for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) {
+    cc = &RC.mac[module_idP]->common_channels[CC_id];
+    frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms);
+    if (cc->tdd_Config) { //TDD
+      if (frame_parms->N_RB_UL == 25) {
+          num_pucch_rb = 1;
+      } else if (frame_parms->N_RB_UL == 50) {
+          num_pucch_rb = 2;
+      } else {
+          num_pucch_rb = 3;
+      }
+    } else {//FDD
+      if (frame_parms->N_RB_UL == 25) {
+          num_pucch_rb = 1;
+      } else {
+          num_pucch_rb = 2;
+      }
+    }
+
+    first_rb[CC_id] = num_pucch_rb;
+    ue_num_temp       = ulsch_ue_select[CC_id].ue_num;
+    for ( ulsch_ue_num = 0; ulsch_ue_num < ulsch_ue_select[CC_id].ue_num; ulsch_ue_num++ ) {
+
+      UE_id = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id;
+
+      if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_MSG3) {
+        first_rb[CC_id] ++;
+        ue_num_temp--;
+        continue;
+      }
+
+      if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_PRACH) {
+        first_rb[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb+ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+        ue_num_temp--;
+        continue;
+      }
+
+      rnti = UE_RNTI(CC_id,UE_id);
+
+      if (first_rb[CC_id] >= frame_parms->N_RB_UL-num_pucch_rb ) {
+         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);
+         break;
+      }
+      total_rbs = frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id];
+
+      average_rbs = (int)round((double)total_rbs/(double)ue_num_temp);
+      if ( average_rbs < 3 ) {
+        ue_num_temp--;
+        ulsch_ue_num--;
+        ulsch_ue_select[CC_id].ue_num--;
+        continue;
+      }
+      if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_RETRANS ) {
+        if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb <= average_rbs ) {
+            // assigne RBS(nb_rb)
+            ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id];
+            first_rb[CC_id] = first_rb[CC_id] + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+        }
+        if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb > average_rbs ) {
+          if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb <= total_rbs ) {
+              // assigne RBS(average_rbs)
+              ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id];
+              first_rb[CC_id] = first_rb[CC_id] + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+          } else {
+              // assigne RBS(remain rbs)
+              ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id];
+              rb_table_index = 2;
+              while(rb_table[rb_table_index] <= total_rbs){
+                rb_table_index++;
+              }
+              ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb = rb_table[rb_table_index-1];
+              first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index-1];
+          }
+        }
+      }else{
+        UE_template = &UE_list->UE_template[CC_id][UE_id];
+        if ( UE_list->UE_sched_ctrl[UE_id].phr_received == 1 ) {
+          mcs = 20;
+        } else {
+          mcs = 10;
+        }
+        if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority  == SCH_UL_FIRST ) {
+          int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes;
+          if (bytes_to_schedule < 0) bytes_to_schedule = 0;
+
+          if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0 ) {
+            rb_table_index = 2;
+            tbs = get_TBS_UL(mcs,rb_table[rb_table_index]);
+            tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0);
+
+            while ( (((UE_template->phr_info - tx_power) < 0 ) || (tbs > bytes_to_schedule)) && (mcs > 3) ) {
+              mcs--;
+              tbs = get_TBS_UL(mcs,rb_table[rb_table_index]);
+              tx_power= estimate_ue_tx_power(tbs*8,rb_table[rb_table_index],0,frame_parms->Ncp,0);
+            }
+
+            while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) &&
+                   ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) {
+              rb_table_index++;
+              tbs = get_TBS_UL(mcs,rb_table[rb_table_index])<<3;
+              tx_power= estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0);
+            }
+
+            if ( rb_table[rb_table_index]<3 ) {
+              rb_table_index=2;
+            }
+            if ( rb_table[rb_table_index] <= average_rbs ) {
+              // assigne RBS( nb_rb)
+              first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index];
+              UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = rb_table[rb_table_index];
+              UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index;
+              UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs;
+            }
+            if ( rb_table[rb_table_index] > average_rbs ) {
+              // assigne RBS(average_rbs)
+              rb_table_index = find_rb_table_index(average_rbs);
+              if (rb_table_index>=34){
+                  LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: average RBs %d > 100\n",
+                         module_idP,frameP,subframeP,UE_id,rnti,CC_id,average_rbs);
+                  break;
+              }
+              first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index];
+              UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = rb_table[rb_table_index];
+              UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index;
+              UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs;
+            }
+          }else {
+            // assigne RBS( 3 RBs)
+            first_rb[CC_id] = first_rb[CC_id] + 3;
+            UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3;
+            UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
+            UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
+          }
+        }else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority  == SCH_UL_INACTIVE ) {
+          // assigne RBS( 3 RBs)
+          first_rb[CC_id] = first_rb[CC_id] + 3;
+          UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3;
+          UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2;
+          UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10;
+        }
+      }
+      ue_num_temp--;
+    }
+  }
+}
+
+
+void
+schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP,
+	       sub_frame_t subframeP)
+{
+  uint16_t i;
+  int CC_id;
+  eNB_MAC_INST *mac = RC.mac[module_idP];
+  COMMON_channels_t *cc;
+  int sched_frame=frameP;
+
+  start_meas(&mac->schedule_ulsch);
+
+  int sched_subframe = (subframeP+4)%10;
+
+  cc = &mac->common_channels[0];
+  int tdd_sfa;
+  // for TDD: check subframes where we have to act and return if nothing should be done now
+  if (cc->tdd_Config) {
+    tdd_sfa = cc->tdd_Config->subframeAssignment;
+    switch (subframeP) {
+    case 0:
+      if ((tdd_sfa == 0)||
+          (tdd_sfa == 3)) sched_subframe = 4;
+      else if (tdd_sfa==6) sched_subframe = 7;
+      else return;
+      break;
+    case 1:
+      if ((tdd_sfa==0)||
+          (tdd_sfa==1)) sched_subframe = 7;
+      else if (tdd_sfa==6) sched_subframe = 8;
+      else return;
+      break;
+    case 2: // Don't schedule UL in subframe 2 for TDD
+      return;
+    case 3:
+      if (tdd_sfa==2) sched_subframe = 7;
+      else return;
+      break;
+    case 4:
+      if (tdd_sfa==1) sched_subframe = 8;
+      else return;
+      break;
+    case 5:
+      if (tdd_sfa==0)      sched_subframe = 9;
+      else if (tdd_sfa==6) sched_subframe = 2;
+      else return;
+      break;
+    case 6:
+      if (tdd_sfa==0 || tdd_sfa==1)      sched_subframe = 2;
+      else if (tdd_sfa==6) sched_subframe = 3;
+      else return;
+      break;
+    case 7:
+      return;
+    case 8:
+      if ((tdd_sfa>=2) && (tdd_sfa<=5)) sched_subframe=2;
+      else return;
+      break;
+    case 9:
+      if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3;
+      else if (tdd_sfa==6) sched_subframe=4;
+      else return;
+      break;
+    }
+  }
+  if (sched_subframe < subframeP) sched_frame++;
+  ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs];
+  memset(ulsch_ue_select, 0, sizeof(ulsch_ue_select));
+
+  LTE_DL_FRAME_PARMS *frame_parms ;
+
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    cc = &mac->common_channels[CC_id];
+    frame_parms= &RC.eNB[module_idP][CC_id]->frame_parms;
+    // output of scheduling, the UE numbers in RBs, where it is in the code???
+    // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3
+    // Msg3 is using 1 PRB so we need to increase first_rb accordingly
+    // not sure about the break (can there be more than 1 active RA procedure?)
+    for (i=0; i<NB_RA_PROC_MAX; i++) {
+      if ((cc->ra[i].state == WAITMSG3) &&(cc->ra[i].Msg3_subframe == sched_subframe)) {  
+        ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_MSG3;
+        if (cc->tdd_Config == NULL) {
+            if(frame_parms->N_RB_UL == 25){
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1;
+            }else{
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 2;
+            }
+        } else {
+            switch(frame_parms->N_RB_UL){
+            case 25:
+            default:
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1;
+              break;
+            case 50:
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 2;
+              break;
+            case 100:
+              ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 3;
+              break;
+            }
+        }
+        ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = 1;
+        ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = -1;
+        ulsch_ue_select[CC_id].ue_num++;
+        break;
+      }
+    }
+
+    //PRACH
+    if (is_prach_subframe(frame_parms,sched_frame,sched_subframe)==1) {
+      ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_PRACH;
+      ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = get_prach_prb_offset(
+    		                                                                 frame_parms,
+    		                                                                 frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
+    		                                                                 frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
+    		                                                                 0,//tdd_mapindex
+    		                                                                 frameP); //Nf
+      ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = 6;
+      ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = -1;
+      ulsch_ue_select[CC_id].ue_num++;
+    }
+  }
+
+  schedule_ulsch_rnti_fairRR(module_idP, frameP, subframeP, sched_subframe,ulsch_ue_select);
+  stop_meas(&mac->schedule_ulsch);
+}
+
+void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
+                         frame_t       frameP,
+                         sub_frame_t   subframeP,
+                         unsigned char sched_subframeP,
+                         ULSCH_UE_SELECT  ulsch_ue_select[MAX_NUM_CCs])
+{
+  int16_t           UE_id;
+  uint8_t           aggregation    = 2;
+  uint16_t          first_rb[MAX_NUM_CCs];
+  uint8_t           ULSCH_first_end;
+  rnti_t            rnti           = -1;
+  uint8_t           round          = 0;
+  uint8_t           harq_pid       = 0;
+  uint8_t           status         = 0;
+    uint8_t           rb_table_index = -1;
+  uint32_t          cqi_req,cshift,ndi,tpc;
+  int32_t           normalized_rx_power;
+  int32_t           target_rx_power=-90;
+  static int32_t    tpc_accumulated=0;
+  int               CC_id,ulsch_ue_num;
+  int               N_RB_UL;
+  eNB_MAC_INST      *eNB = RC.mac[module_idP];
+  COMMON_channels_t *cc;
+  UE_list_t         *UE_list=&eNB->UE_list;
+  UE_TEMPLATE       *UE_template;
+  UE_sched_ctrl     *UE_sched_ctrl;
+  int               sched_frame=frameP;
+  int               rvidx_tab[4] = {0,2,3,1};
+  uint16_t          ul_req_index;
+  uint8_t           dlsch_flag;
+  if (sched_subframeP < subframeP) sched_frame++;
+
+  nfapi_hi_dci0_request_body_t   *hi_dci0_req;
+  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
+
+  nfapi_ul_config_request_body_t *ul_req_tmp;
+  nfapi_ul_config_ulsch_harq_information *ulsch_harq_information;
+  LOG_D(MAC,"entering ulsch preprocesor\n");
+  ulsch_scheduler_pre_processor_fairRR(module_idP,
+                                frameP,
+                                subframeP,
+                                sched_subframeP,
+                                ulsch_ue_select);
+
+  LOG_D(MAC,"exiting ulsch preprocesor\n");
+
+
+
+  // loop over all active UEs
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+      hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
+      eNB->HI_DCI0_req[CC_id][subframeP].sfn_sf = (frameP<<4)+subframeP;
+      ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body;
+      nfapi_ul_config_request_t *ul_req  = &eNB->UL_req_tmp[CC_id][sched_subframeP];
+
+    ULSCH_first_end = 0;
+    cc  = &eNB->common_channels[CC_id];
+    // This is the actual CC_id in the list
+    N_RB_UL      = to_prb(cc->mib->message.dl_Bandwidth);
+    //leave out first RB for PUCCH
+    if (cc->tdd_Config == NULL) {
+        if(N_RB_UL == 25){
+          first_rb[CC_id] = 1;
+        }else{
+          first_rb[CC_id] = 2;
+        }
+    }else {
+        switch(N_RB_UL){
+        case 25:
+        default:
+            first_rb[CC_id] = 1;
+          break;
+        case 50:
+            first_rb[CC_id] = 2;
+          break;
+        case 100:
+            first_rb[CC_id] = 3;
+          break;
+        }
+    }
+    for ( ulsch_ue_num = 0; ulsch_ue_num < ulsch_ue_select[CC_id].ue_num; ulsch_ue_num++ ) {
+      UE_id = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id;
+      /* be sure that there are some free RBs */
+      if (cc->tdd_Config == NULL){
+          if(N_RB_UL == 25){
+            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);
+              break;
+            }
+          }else{
+              if (first_rb[CC_id] >= N_RB_UL-2) {
+                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);
+                break;
+              }
+          }
+      } else {
+          if(N_RB_UL == 25){
+            if (first_rb[CC_id] >= N_RB_UL-1) {
+              LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n",
+                       module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb);
+              break;
+            }
+          }else if(N_RB_UL == 50){
+              if (first_rb[CC_id] >= N_RB_UL-2) {
+                LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n",
+                         module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb);
+                break;
+              }
+          }else if(N_RB_UL == 100){
+              if (first_rb[CC_id] >= N_RB_UL-3) {
+                LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n",
+                       module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb);
+                break;
+              }
+          }
+      }
+      //MSG3
+      if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_MSG3) {
+        first_rb[CC_id] ++;
+        continue;
+      }
+      //PRACH
+      if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_PRACH) {
+        first_rb[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb+ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+        continue;
+      }
+
+      UE_template   = &UE_list->UE_template[CC_id][UE_id];
+      UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
+      harq_pid      = subframe2harqpid(cc,sched_frame,sched_subframeP);
+      rnti = UE_RNTI(CC_id,UE_id);
+      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);
+
+      int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes;
+      if (bytes_to_schedule < 0) bytes_to_schedule = 0;
+
+      RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = bytes_to_schedule;
+      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]);
+
+      status = mac_eNB_get_rrc_status(module_idP,rnti);
+      if (status < RRC_CONNECTED)
+        cqi_req = 0;
+      else if (UE_sched_ctrl->cqi_req_timer>30) {
+        cqi_req = 1;
+        UE_sched_ctrl->cqi_req_timer=0;
+        UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP;
+      }
+      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 = UE_sched_ctrl->pusch_snr[CC_id];
+      target_rx_power = 178;
+
+      // 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_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe;
+      if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case
+          ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around
+        {
+          UE_template->pusch_tpc_tx_frame=frameP;
+          UE_template->pusch_tpc_tx_subframe=subframeP;
+          if (normalized_rx_power>(target_rx_power+4)) {
+            tpc = 0; //-1
+            tpc_accumulated--;
+          } else if (normalized_rx_power<(target_rx_power-4)) {
+            tpc = 2; //+1
+            tpc_accumulated++;
+          } else {
+            tpc = 1; //0
+          }
+        } else {
+          tpc = 1; //0
+        }
+        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,
+              tpc_accumulated,normalized_rx_power,target_rx_power);
+        }
+          // new transmission
+          if ((ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST) ||
+              (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE)) {
+              LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x (SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
+                    module_idP,harq_pid,frameP,subframeP,UE_id,rnti,UE_template->ul_SR,
+                    UE_sched_ctrl->ul_inactivity_timer,
+                    UE_sched_ctrl->ul_failure_timer,
+                    UE_sched_ctrl->cqi_req_timer);
+
+            ndi = 1-UE_template->oldNDI_UL[harq_pid];
+            UE_template->oldNDI_UL[harq_pid]=ndi;
+            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;
+            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 {
+              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=UE_template->mcs_UL[harq_pid];
+
+            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=UE_template->TBS_UL[harq_pid];
+
+            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(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_D(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,UE_template->mcs_UL[harq_pid],
+                    first_rb[CC_id],rb_table[rb_table_index],
+                    rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid);
+
+            // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
+            //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];
+
+            UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
+            if (UE_id == UE_list->head)
+              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,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);*/
+            // Cyclic shift for DM RS
+            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[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_DCI_PDU_TYPE;
+            hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_dci_pdu);
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format                        = NFAPI_UL_DCI_FORMAT_0;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level                 = aggregation;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti                              = rnti;
+            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                             = 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;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc                               = tpc;
+            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];
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid                          = harq_pid;
+
+            hi_dci0_req->number_of_dci++;
+            hi_dci0_req->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4)
+            hi_dci0_req->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
+            nfapi_hi_dci0_request_t        *nfapi_hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP];
+            nfapi_hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday!
+            nfapi_hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
+
+            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);
+
+            ul_req_index = 0;
+            dlsch_flag = 0;
+            for(ul_req_index = 0;ul_req_index < ul_req_tmp->number_of_pdus;ul_req_index++){
+                if((ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) &&
+                   (ul_req_tmp->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)){
+                   dlsch_flag = 1;
+                   LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index);
+                   break;
+                }
+            }
+            // Add UL_config PDUs
+            fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_index],
+                                                 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
+            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_index],
+                                                   UE_template->rach_resource_type>2 ? 2 : 1,
+                                                   1, //total_number_of_repetitions
+                                                   1, //repetition_number
+                                                   (frameP*10)+subframeP);
+            }
+#endif
+            if(dlsch_flag == 1){
+                if(cqi_req == 1){
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
+                    ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;    // last symbol not punctured
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
+
+                }else{
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
+                    ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
+                    ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
+                }
+                fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP);
+            }else{
+                ul_req_tmp->number_of_pdus++;
+            }
+            eNB->ul_handle++;
+            ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
+            ul_req_tmp->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
+            uint16_t ul_sched_frame = sched_frame;
+            uint16_t ul_sched_subframeP = sched_subframeP;
+            add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2);
+            ul_req->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP;
+
+            add_ue_ulsch_info(module_idP,
+                              CC_id,
+                              UE_id,
+                              subframeP,
+                              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];
+            if(ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST) {
+              UE_template->scheduled_ul_bytes += get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]);
+              UE_template->ul_SR = 0;
+#if 0
+              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,get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]));
+                if(ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0){
+                    if (UE_template->ul_total_buffer > get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]))
+                      UE_template->ul_total_buffer -= get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]);
+                    else
+                      UE_template->ul_total_buffer = 0;
+                    LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);
+                } else {
+                    UE_template->ul_SR = 0;
+                }
+              LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);
+#endif
+            }
+            if((ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE) && (ULSCH_first_end == 0)) {
+                ULSCH_first_end = 1;
+                last_ulsch_ue_id[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num-1].UE_id;
+            }
+            if((ulsch_ue_num == ulsch_ue_select[CC_id].ue_num-1) && (ULSCH_first_end == 0)) {
+                ULSCH_first_end = 1;
+                last_ulsch_ue_id[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id;
+            }
+          }
+          else if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_RETRANS) { // 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(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
+              T_INT(round));
+
+            round = UE_sched_ctrl->round_UL[CC_id][harq_pid];
+            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;
+            uint8_t mcs_rv = 0;
+            if(rvidx_tab[round&3]==1){
+               mcs_rv = 29;
+            }else if(rvidx_tab[round&3]==2){
+               mcs_rv = 30;
+            }else if(rvidx_tab[round&3]==3){
+               mcs_rv = 31;
+            }
+            UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb);
+            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid];
+
+
+            if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
+              LOG_D(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_rv,first_rb[CC_id],rb_table[rb_table_index],rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid);
+
+            // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
+            //store for possible retransmission
+            UE_template->nb_rb_ul[harq_pid]    = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+            UE_template->first_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb;
+
+            UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
+            // Cyclic shift for DM RS
+            cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
+
+            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_DCI_PDU_TYPE;
+            hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_dci_pdu);
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format                        = NFAPI_UL_DCI_FORMAT_0;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level                 = aggregation;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti                              = rnti;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power                = 6000;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start              = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block          = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1                             = mcs_rv;
+            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             = UE_template->oldNDI_UL[harq_pid];
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc                               = tpc;
+            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];
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid                          = harq_pid;
+
+            hi_dci0_req->number_of_dci++;
+            // 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);
+            ul_req_index = 0;
+            dlsch_flag = 0;
+            for(ul_req_index = 0;ul_req_index < ul_req_tmp->number_of_pdus;ul_req_index++){
+                if((ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) &&
+                   (ul_req_tmp->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)){
+                   dlsch_flag = 1;
+                   LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(phich)\n",frameP,subframeP,rnti,ul_req_index);
+                   break;
+                }
+            }
+            fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_index],
+                                                 cqi_req,
+                                                 cc,
+                                                 UE_template->physicalConfigDedicated,
+                                                 get_tmode(module_idP,CC_id,UE_id),
+                                                 eNB->ul_handle,
+                                                 rnti,
+                                                 ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb, // resource_block_start
+                                                 ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb, // 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_index],
+                                                   UE_template->rach_resource_type>2 ? 2 : 1,
+                                                   1, //total_number_of_repetitions
+                                                   1, //repetition_number
+                                                   (frameP*10)+subframeP);
+            }
+#endif
+              if(dlsch_flag == 1){
+                  if(cqi_req == 1){
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
+                      ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;    // last symbol not punctured
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+
+                  }else{
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
+                      ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
+                      ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+                  }
+                  fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP);
+              }else{
+                ul_req_tmp->number_of_pdus++;
+              }
+              eNB->ul_handle++;
+            ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
+            ul_req_tmp->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
+            ul_req->sfn_sf = sched_frame<<4|sched_subframeP;
+
+              LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0(round >0)\n", module_idP,CC_id,frameP,subframeP,UE_id);
+
+              // increment first rb for next UE allocation
+              first_rb[CC_id]+=ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb;
+          }
+    } // loop over UE_id
+  } // loop of CC_id
+}
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c901186098c24b1a861dd208c97f8212c638ef0
--- /dev/null
+++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.h
@@ -0,0 +1,131 @@
+/*
+ * 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.1  (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 eNB_scheduler_fairRR.h
+ * \brief eNB scheduler fair round robin header
+ * \author Masayuki Harada
+ * \date 2018
+ * \email masayuki.harada@jp.fujitsu.com
+ * \version 1.0
+ * @ingroup _mac
+ */
+
+
+#ifndef __LAYER2_MAC_ENB_SCHEDULER_FAIRRR_H__
+#define __LAYER2_MAC_ENB_SCHEDULER_FAIRRR_H__
+
+/* define */
+enum SCH_UE_PRIORITY {
+  SCH_PRIORITY_NONE,
+  SCH_DL_SI,
+  SCH_DL_PAGING,
+  SCH_DL_MSG2,
+  SCH_DL_MSG4,
+  SCH_UL_PRACH,
+  SCH_UL_MSG3,
+  SCH_DL_RETRANS,
+  SCH_UL_RETRANS,
+  SCH_DL_FIRST,
+  SCH_UL_FIRST,
+  SCH_UL_INACTIVE
+};
+
+typedef struct {
+  int UE_id;
+  enum SCH_UE_PRIORITY ue_priority;
+  rnti_t rnti;
+  uint16_t nb_rb;
+} DLSCH_UE_INFO;
+
+typedef struct {
+  uint16_t    ue_num;
+  DLSCH_UE_INFO list[20];
+} DLSCH_UE_SELECT;
+
+typedef struct {
+  int     UE_id;
+  enum SCH_UE_PRIORITY ue_priority;
+  uint8_t start_rb;
+  uint8_t nb_rb;
+  uint16_t ul_total_buffer;
+} ULSCH_UE_INFO;
+
+typedef struct {
+  uint8_t ue_num;
+  ULSCH_UE_INFO list[20];
+} ULSCH_UE_SELECT;
+
+/* proto */
+void set_dl_ue_select_msg2(int CC_idP, uint16_t nb_rb, int UE_id, rnti_t rnti);
+void set_dl_ue_select_msg4(int CC_idP, uint16_t nb_rb, int UE_id, rnti_t rnti);
+
+void dlsch_scheduler_pre_ue_select_fairRR(
+    module_id_t     module_idP,
+    frame_t         frameP,
+    sub_frame_t     subframeP,
+    int*            mbsfn_flag,
+    uint16_t        nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX],
+    DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs]);
+
+void dlsch_scheduler_pre_processor_fairRR (module_id_t   Mod_id,
+                                    frame_t       frameP,
+                                    sub_frame_t   subframeP,
+                                    int           N_RBG[MAX_NUM_CCs],
+                                    int           *mbsfn_flag);
+
+void fill_DLSCH_dci_fairRR(
+	       module_id_t module_idP,
+	       frame_t frameP,
+	       sub_frame_t subframeP,
+	       int* mbsfn_flagP);
+
+void schedule_ue_spec_fairRR(module_id_t module_idP,
+		 frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag);
+
+void ulsch_scheduler_pre_ue_select_fairRR(
+    module_id_t       module_idP,
+    frame_t           frameP,
+    sub_frame_t       subframeP,
+    sub_frame_t       sched_subframeP,
+    ULSCH_UE_SELECT   ulsch_ue_select[MAX_NUM_CCs]);
+
+void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP,
+                                   frame_t frameP,
+                                   sub_frame_t subframeP,
+                                   sub_frame_t sched_subframeP,
+                                   ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]);
+
+void schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP,
+	       sub_frame_t subframeP);
+
+void schedule_ulsch_rnti_fairRR(module_id_t   module_idP,
+                         frame_t       frameP,
+                         sub_frame_t   subframeP,
+                         unsigned char sched_subframeP,
+                         ULSCH_UE_SELECT  ulsch_ue_select[MAX_NUM_CCs]);
+
+
+/* extern */
+extern DLSCH_UE_SELECT dlsch_ue_select[MAX_NUM_CCs];
+extern int last_dlsch_ue_id[MAX_NUM_CCs];
+extern int last_ulsch_ue_id[MAX_NUM_CCs];
+
+#endif
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
index bcaa30e3c1f5e30919f3717263dda5ba97006eb6..80ee6376ae9bff085de8663ec06ff87b0b04c815 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c
@@ -633,7 +633,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 			       MTCH,
 			       TBS - header_len_mcch - header_len_msi -
 			       sdu_length_total - header_len_mtch
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                     ,0, 0
 #endif
                                     );
@@ -652,7 +652,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 	    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0,	//not used
 						     (char *)
 						     &mch_buffer[sdu_length_total]
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                 ,0,
                                  0
 #endif
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
index b1bb4a41308c98522a9c1d499d3f9ea1c81a9d98..bf6fd8db6a1a24768a018d8a224c9d216c133f94 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c
@@ -213,7 +213,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
   
   if (sched_subframe<subframeP) sched_frame++;
 
-  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
+  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body;
   nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
 
   //nfapi_ul_config_request_pdu_t  *ul_config_pdu = &ul_req->ul_config_pdu_list[0];;
@@ -221,7 +221,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
 
 
   eNB->UL_req[CC_id].sfn_sf   = (sched_frame<<4) + sched_subframe;
-  eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
+  eNB->HI_DCI0_req[CC_id][subframeP].sfn_sf = (frameP<<4)+subframeP;
   
   for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
     //rnti = UE_RNTI(module_idP,UE_id);
@@ -281,7 +281,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
 	  // 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]; 	
+	  hi_dci0_pdu                                                         = &hi_dci0_req->hi_dci0_pdu_list[eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci+eNB->HI_DCI0_req[CC_id][subframeP].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; 
 	  hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_dci_pdu);
@@ -300,7 +300,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
 	  hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index               = UE_template->DAI_ul[sched_subframe];
 
 	    
-	  eNB->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_dci++;
+	  eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci++;
 	    
 	    
 	  // Add UL_config PDUs
@@ -325,7 +325,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s
 						 0, // n_srs
 						 get_TBS_UL(mcs,nb_rb)
 						 );
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 	  if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation
 	    fill_nfapi_ulsch_config_request_emtc(&ul_req->ul_config_pdu_list[ul_req->number_of_pdus],
 						   UE_template->rach_resource_type>2 ? 2 : 1,
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index fbb125cf726d7643fd719fc0fac3207a902d341a..1ac70037235e8a8df48ca7dd3c088d1c295d2285 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -55,6 +55,7 @@
 
 #define ENABLE_MAC_PAYLOAD_DEBUG
 #define DEBUG_eNB_SCHEDULER 1
+extern uint16_t frame_cnt;
 
 #include "common/ran_context.h"
 
@@ -555,11 +556,61 @@ int is_UL_sf(COMMON_channels_t * ccP, sub_frame_t subframeP)
   }
 }
 
+int is_S_sf(COMMON_channels_t * ccP, sub_frame_t subframeP)
+{
+    // if FDD return dummy value
+    if (ccP->tdd_Config == NULL)
+    return (0);
+
+    switch (subframeP) {
+    case 1:
+        return (1);
+        break;
+
+    case 6:
+        if(ccP->tdd_Config->subframeAssignment == 0 || ccP->tdd_Config->subframeAssignment == 1
+                || ccP->tdd_Config->subframeAssignment == 2 || ccP->tdd_Config->subframeAssignment == 6)
+        return (1);
+        break;
+
+    default:
+        return (0);
+        break;
+    }
+    return 0;
+}
+
+uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe){
+
+    if(cc->tdd_Config){//TODO fill other tdd config
+        switch(cc->tdd_Config->subframeAssignment){
+        case 0:
+            break;
+        case 1:
+            if(ul_subframe == 2 || ul_subframe == 7)
+                return 4;
+            else if(ul_subframe == 3 || ul_subframe == 8)
+                return 6;
+            else return 255;
+            break;
+        case 2:
+            break;
+        case 3:
+            break;
+        case 4:
+            break;
+        case 5:
+            break;
+        }
+    }
+    return 4; //idk  sf_ahead?
+}
+
 uint16_t get_pucch1_absSF(COMMON_channels_t * cc, uint16_t dlsch_absSF)
 {
   uint16_t sf, f, nextf;
 
-  if (cc->tdd_Config == NULL) {	//FDD n+4
+  if (cc->tdd_Config == NULL) { //FDD n+4
     return ((dlsch_absSF + 4) % 10240);
   } else {
     sf = dlsch_absSF % 10;
@@ -568,72 +619,93 @@ uint16_t get_pucch1_absSF(COMMON_channels_t * cc, uint16_t dlsch_absSF)
 
     switch (cc->tdd_Config->subframeAssignment) {
     case 0:
-      AssertFatal(1 == 0, "SFA 0 to be filled in now, :-)\n");
+      if ((sf == 0) || (sf == 5))
+        return ((10 * f) + sf + 4)% 10240;  // ACK/NAK in SF 4,9 same frame
+      else if (sf == 6)
+        return ((10 * nextf) + 2)% 10240;  // ACK/NAK in SF 2 next frame
+      else if (sf == 1)
+        return ((10 * f) + 7)% 10240;  // ACK/NAK in SF 7 same frame
+      else
+        AssertFatal(1 == 0,
+                   "Impossible dlsch subframe %d for TDD configuration 0\n",
+                   sf);
+
       break;
     case 1:
       if ((sf == 5) || (sf == 6))
-	return ((10 * nextf) + 2);	// ACK/NAK in SF 2 next frame
+        return ((10 * nextf) + 2)% 10240;        // ACK/NAK in SF 2 next frame
       else if (sf == 9)
-	return ((10 * nextf) + 3);	// ACK/NAK in SF 3 next frame
+        return ((10 * nextf) + 3)% 10240;        // ACK/NAK in SF 3 next frame
       else if ((sf == 0) || (sf == 1))
-	return ((10 * f) + 2);	// ACK/NAK in SF 7 same frame
+        return ((10 * f) + 7)% 10240;        // ACK/NAK in SF 7 same frame
+      else if (sf == 4)
+        return ((10 * f) + 8)% 10240;  // ACK/NAK in SF 8 same frame
       else
-	AssertFatal(1 == 0,
-		    "Impossible dlsch subframe %d for TDD configuration 3\n",
-		    sf);
+        AssertFatal(1 == 0,
+                    "Impossible dlsch subframe %d for TDD configuration 1\n",
+                    sf);
       break;
     case 2:
       if ((sf == 4) || (sf == 5) || (sf == 6) || (sf == 8))
-	return ((10 * nextf) + 2);	// ACK/NAK in SF 2 next frame
+        return ((10 * nextf) + 2)% 10240;        // ACK/NAK in SF 2 next frame
       else if (sf == 9)
-	return ((10 * nextf) + 7);	// ACK/NAK in SF 7 next frame
+        return ((10 * nextf) + 7)% 10240;        // ACK/NAK in SF 7 next frame
       else if ((sf == 0) || (sf == 1) || (sf == 3))
-	return ((10 * f) + 7);	// ACK/NAK in SF 7 same frame
+        return ((10 * f) + 7)% 10240;        // ACK/NAK in SF 7 same frame
       else
-	AssertFatal(1 == 0,
-		    "Impossible dlsch subframe %d for TDD configuration 3\n",
-		    sf);
+        AssertFatal(1 == 0,
+                    "Impossible dlsch subframe %d for TDD configuration 2\n",
+                    sf);
       break;
     case 3:
       if ((sf == 5) || (sf == 6) || (sf == 7) || (sf == 8)
-	  || (sf == 9))
-	return ((10 * nextf) + (sf >> 1));	// ACK/NAK in 2,3,4 resp. next frame
+          || (sf == 9))
+        return ((10 * nextf) + ((sf-1) >> 1))% 10240;   // ACK/NAK in 2,3,4 resp. next frame
       else if (sf == 1)
-	return ((10 * nextf) + 2);	// ACK/NAK in 2 next frame
+        return ((10 * nextf) + 2)% 10240;         // ACK/NAK in 2 next frame
       else if (sf == 0)
-	return ((10 * f) + 4);	// ACK/NAK in 4 same frame
+        return ((10 * f) + 4)% 10240;        // ACK/NAK in 4 same frame
       else
-	AssertFatal(1 == 0,
-		    "Impossible dlsch subframe %d for TDD configuration 3\n",
-		    sf);
+        AssertFatal(1 == 0,
+                    "Impossible dlsch subframe %d for TDD configuration 3\n",
+                    sf);
       break;
     case 4:
       if ((sf == 6) || (sf == 7) || (sf == 8) || (sf == 9))
-	return (((10 * nextf) + 3) % 10240);	// ACK/NAK in SF 3 next frame
+        return (((10 * nextf) + 3) % 10240);        // ACK/NAK in SF 3 next frame
       else if ((sf == 0) || (sf == 1) || (sf == 4) || (sf == 5))
-	return (((10 * nextf) + 2) % 10240);	// ACK/NAK in SF 2 next frame
+        return (((10 * nextf) + 2) % 10240);        // ACK/NAK in SF 2 next frame
       else
-	AssertFatal(1 == 0,
-		    "Impossible dlsch subframe %d for TDD configuration 4\n",
-		    sf);
+        AssertFatal(1 == 0,
+                    "Impossible dlsch subframe %d for TDD configuration 4\n",
+                    sf);
       break;
     case 5:
       if ((sf == 0) || (sf == 1) || (sf == 3) || (sf == 4)
-	  || (sf == 5) || (sf == 6) || (sf == 7) || (sf == 8))
-	return (((10 * nextf) + 2) % 10240);	// ACK/NAK in SF 3 next frame
+          || (sf == 5) || (sf == 6) || (sf == 7) || (sf == 8))
+        return (((10 * nextf) + 2) % 10240);        // ACK/NAK in SF 3 next frame
       else if (sf == 9)
-	return (((10 * (1 + nextf)) + 2) % 10240);	// ACK/NAK in SF 2 next frame
+        return (((10 * (1 + nextf)) + 2) % 10240);        // ACK/NAK in SF 2 next frame
       else
-	AssertFatal(1 == 0,
-		    "Impossible dlsch subframe %d for TDD configuration 5\n",
-		    sf);
+        AssertFatal(1 == 0,
+                    "Impossible dlsch subframe %d for TDD configuration 5\n",
+                    sf);
       break;
     case 6:
-      AssertFatal(1 == 0, "SFA 6 To be filled in now, :-)\n");
+      if ((sf == 5) || (sf == 6))
+        return ((10 * f) + sf + 7)% 10240;  // ACK/NAK in SF 2,3 next frame
+      else if (sf == 9)
+        return ((10 * nextf) + 4)% 10240;  // ACK/NAK in SF 4 next frame
+      else if ((sf == 1) || (sf == 0))
+        return ((10 * f) + sf + 7)% 10240;  // ACK/NAK in SF 7 same frame
+      else
+        AssertFatal(1 == 0,
+                "Impossible dlsch subframe %d for TDD configuration 6\n",
+                sf);
       break;
     default:
       AssertFatal(1 == 0, "Illegal TDD subframe Assigment %d\n",
-		  (int) cc->tdd_Config->subframeAssignment);
+                  (int) cc->tdd_Config->subframeAssignment);
       break;
     }
   }
@@ -1156,7 +1228,7 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP,
     }
   }
 
-  if (ulsch_harq_information) fill_nfapi_ulsch_harq_information(module_idP, CC_idP, rnti, ulsch_harq_information);
+  if (ulsch_harq_information) fill_nfapi_ulsch_harq_information(module_idP, CC_idP, rnti, ulsch_harq_information, subframeP);
 
   if (harq_information) fill_nfapi_harq_information(module_idP, CC_idP,
 						    rnti,
@@ -1164,9 +1236,9 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP,
 						    harq_information, cce_idx);
 }
 
-uint8_t get_V_UL_DAI(module_id_t module_idP, int CC_idP, uint16_t rntiP)
+uint8_t get_V_UL_DAI(module_id_t module_idP, int CC_idP, uint16_t rntiP,sub_frame_t subframeP)
 {
-  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_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body;
   nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu  = &HI_DCI0_req->hi_dci0_pdu_list[0];
 
   for (int i = 0; i < HI_DCI0_req->number_of_dci; i++) {
@@ -1181,7 +1253,8 @@ void
 fill_nfapi_ulsch_harq_information(module_id_t                            module_idP,
 				  int                                    CC_idP,
 				  uint16_t                               rntiP,
-				  nfapi_ul_config_ulsch_harq_information *harq_information)
+				  nfapi_ul_config_ulsch_harq_information *harq_information,
+				  sub_frame_t                            subframeP)
 {
   eNB_MAC_INST *eNB     = RC.mac[module_idP];
   COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
@@ -1232,7 +1305,7 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
       harq_information->harq_information_rel10.harq_size = 1;
     else {
       if (harq_information->harq_information_rel10.ack_nack_mode == 1)
-	harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP);
+	harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP, subframeP);
       else
         harq_information->harq_information_rel10.harq_size = 1;
     }
@@ -1242,7 +1315,7 @@ fill_nfapi_ulsch_harq_information(module_id_t                            module_
       harq_information->harq_information_rel10.harq_size = 2;
     } else {
       if (harq_information->harq_information_rel10.ack_nack_mode == 1)
-	harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP);
+	harq_information->harq_information_rel10.harq_size = get_V_UL_DAI(module_idP, CC_idP, rntiP, subframeP);
       else
 	harq_information->harq_information_rel10.harq_size = 2;
     }
@@ -1284,19 +1357,23 @@ fill_nfapi_harq_information(module_id_t                      module_idP,
   case 6:
   case 7:
     if (cc->tdd_Config != NULL) {
-      AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL,
-		  "pucch_ConfigDedicated is null for TDD!\n");
-      if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL)
+//      AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL,
+//		  "pucch_ConfigDedicated is null for TDD!\n");
+      if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL
+          && UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL
+          && (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL)
 	  && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing))
-	{
-	  harq_information->harq_information_rel10_tdd.harq_size             = 2;	// 2-bit ACK/NAK
-	  harq_information->harq_information_rel10_tdd.ack_nack_mode         = 1;	// multiplexing
-	} else {
-	harq_information->harq_information_rel10_tdd.harq_size               = 1;	// 1-bit ACK/NAK
-	harq_information->harq_information_rel10_tdd.ack_nack_mode           = 0;	// bundling
+      {
+        harq_information->harq_information_rel10_tdd.harq_size             = 2;        // 2-bit ACK/NAK
+        harq_information->harq_information_rel10_tdd.ack_nack_mode         = 1;        // multiplexing
+      } else {
+        harq_information->harq_information_rel10_tdd.harq_size             = 1;        // 1-bit ACK/NAK
+        harq_information->harq_information_rel10_tdd.ack_nack_mode         = 0;        // bundling
       }
       harq_information->harq_information_rel10_tdd.tl.tag                    = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG;
-      harq_information->harq_information_rel10_tdd.n_pucch_1_0               = cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP;
+      LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[module_idP][CC_idP]->frame_parms;
+      harq_information->harq_information_rel10_tdd.n_pucch_1_0               = get_Np(frame_parms->N_RB_DL,cce_idxP,0) +
+                                                                               cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + cce_idxP;
       harq_information->harq_information_rel10_tdd.number_of_pucch_resources = 1;
     } else {
       harq_information->harq_information_rel9_fdd.tl.tag                     = NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG;
@@ -1374,7 +1451,7 @@ void
 fill_nfapi_dlsch_config(eNB_MAC_INST * eNB,
 			nfapi_dl_config_request_body_t * dl_req,
 			uint16_t length,
-			uint16_t pdu_index,
+			int16_t pdu_index,
 			uint16_t rnti,
 			uint8_t resource_allocation_type,
 			uint8_t
@@ -1434,7 +1511,7 @@ 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, 
+		  int16_t                 pdu_index, 
 		  uint8_t                 *pdu)
 {
   nfapi_tx_request_pdu_t *TX_req = &tx_req_body->tx_pdu_list[tx_req_body->number_of_pdus];
@@ -1485,7 +1562,8 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd
   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;
+  else if(mcs < 29)  ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 6;
+  else               ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 0;
   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;
@@ -1967,17 +2045,30 @@ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP)
   eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
   
   // check if this has an RA process active
-  RA_t *ra;
-  for (i = 0; i < NB_RA_PROC_MAX; i++) {
-    ra = (RA_t *) & RC.mac[mod_idP]->common_channels[pCC_id].ra[i];
-    if (ra->rnti == rntiP) {
-      ra->state = IDLE;
-      ra->timing_offset = 0;
-      ra->RRC_timer = 20;
-      ra->rnti = 0;
-      //break;
+  if(find_RA_id(mod_idP, pCC_id, rntiP) != -1) {
+    cancel_ra_proc(mod_idP, pCC_id, 0, rntiP);
+  }
+
+  pthread_mutex_lock(&rrc_release_freelist);
+  if(rrc_release_info.num_UEs > 0){
+    uint16_t release_total = 0;
+    for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
+      if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){
+        release_total++;
+      }else{
+        continue;
+      }
+      if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rntiP){
+        rrc_release_info.RRC_release_ctrl[release_num].flag = 0;
+        rrc_release_info.num_UEs--;
+        release_total--;
+      }
+      if(release_total >= rrc_release_info.num_UEs){
+        break;
+      }
     }
   }
+  pthread_mutex_unlock(&rrc_release_freelist);
   
   return 0;
 }
@@ -2766,13 +2857,13 @@ get_nCCE_max(COMMON_channels_t * cc, int num_pdcch_symbols, int subframe)
 
 // Allocate the CCEs
 int
-allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
+allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, int test_onlyP)
 {
   int *CCE_table = RC.mac[module_idP]->CCE_table[CC_idP];
   nfapi_dl_config_request_body_t *DL_req =
     &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body;
   nfapi_hi_dci0_request_body_t *HI_DCI0_req =
-    &RC.mac[module_idP]->HI_DCI0_req[CC_idP].hi_dci0_request_body;
+    &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframeP].hi_dci0_request_body;
   nfapi_dl_config_request_pdu_t *dl_config_pdu =
     &DL_req->dl_config_pdu_list[0];
   nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
@@ -2783,6 +2874,17 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
   int fCCE;
   int i, j, idci;
   int nCCE = 0;
+  int max_symbol;
+
+  eNB_MAC_INST *eNB = RC.mac[module_idP];
+  COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
+  int ackNAK_absSF = get_pucch1_absSF(cc, (frameP*10+subframeP));
+  if (cc->tdd_Config!=NULL && is_S_sf(cc,subframeP) > 0)
+    max_symbol = 2;
+  else
+    max_symbol = 3;
+
+  nfapi_ul_config_request_body_t *ul_req = &eNB->UL_req_tmp[CC_idP][ackNAK_absSF % 10].ul_config_request_body;
 
   LOG_D(MAC,
 	"Allocate CCEs subframe %d, test %d : (DL PDU %d, DL DCI %d, UL %d)\n",
@@ -2811,7 +2913,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
       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)
+	if (DL_req->number_pdcch_ofdm_symbols == max_symbol)
 	  goto failed;
 	LOG_D(MAC,
 	      "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n",
@@ -2833,7 +2935,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
 			     dci_dl_pdu.dci_dl_pdu_rel8.rnti,
 			     subframeP);
       if (fCCE == -1) {
-	if (DL_req->number_pdcch_ofdm_symbols == 3) {
+	if (DL_req->number_pdcch_ofdm_symbols == max_symbol) {
 	  LOG_D(MAC,
 		"subframe %d: Dropping Allocation for RNTI %x\n",
 		subframeP,
@@ -2876,7 +2978,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
       // the allocation is feasible, rnti rule passes
       nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level;
       LOG_D(MAC, "Allocating at nCCE %d\n", fCCE);
-      if (test_onlyP == 0) {
+      if ((test_onlyP%2) == 0) {
 	dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE;
 	LOG_D(MAC,
 	      "Allocate COMMON DCI CCEs subframe %d, test %d => L %d fCCE %d\n",
@@ -2904,7 +3006,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
 	    nCCE, nCCE_max, DL_req->number_pdcch_ofdm_symbols);
 
       if (nCCE + (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level) > nCCE_max) {
-	if (DL_req->number_pdcch_ofdm_symbols == 3)
+	if (DL_req->number_pdcch_ofdm_symbols == max_symbol)
 	  goto failed;
 	LOG_D(MAC,
 	      "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n",
@@ -2925,7 +3027,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
 			     hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.
 			     rnti, subframeP);
       if (fCCE == -1) {
-	if (DL_req->number_pdcch_ofdm_symbols == 3) {
+	if (DL_req->number_pdcch_ofdm_symbols == max_symbol) {
 	  LOG_D(MAC,
 		"subframe %d: Dropping Allocation for RNTI %x\n",
 		subframeP,
@@ -2965,7 +3067,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
       // the allocation is feasible, rnti rule passes
       nCCE += hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.aggregation_level;
       LOG_D(MAC, "Allocating at nCCE %d\n", fCCE);
-      if (test_onlyP == 0) {
+      if ((test_onlyP%2) == 0) {
 	hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.cce_index = fCCE;
 	LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n",
 	      subframeP, test_onlyP);
@@ -2989,7 +3091,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
 	    DL_req->number_pdcch_ofdm_symbols);
 
       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)
+	if (DL_req->number_pdcch_ofdm_symbols == max_symbol)
 	  goto failed;
 	LOG_D(MAC,
 	      "Can't fit DCI allocations with %d PDCCH symbols, increasing by 1\n",
@@ -3007,7 +3109,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
 			     dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti,
 			     subframeP);
       if (fCCE == -1) {
-	if (DL_req->number_pdcch_ofdm_symbols == 3) {
+	if (DL_req->number_pdcch_ofdm_symbols == max_symbol) {
 	  LOG_I(MAC,
 		"subframe %d: Dropping Allocation for RNTI %x\n",
 		subframeP,
@@ -3015,7 +3117,7 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
 		rnti);
 	  for (j = 0; j <= i; j++) {
 	    if (dl_config_pdu[j].pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)
-	      LOG_I(MAC,
+	      LOG_D(MAC,
 		    "DCI %d/%d (%d,%d) : rnti %x dci format %d, aggreg %d nCCE %d / %d (num_pdcch_symbols %d)\n",
 		    j,
 		    DL_req->number_dci + HI_DCI0_req->number_of_dci,
@@ -3047,11 +3149,25 @@ allocate_CCEs(int module_idP, int CC_idP, int subframeP, int test_onlyP)
       // the allocation is feasible, rnti rule passes
       nCCE += dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level;
       LOG_D(MAC, "Allocating at nCCE %d\n", fCCE);
-      if (test_onlyP == 0) {
+      if ((test_onlyP%2) == 0) {
 	dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.cce_idx = fCCE;
 	LOG_D(MAC, "Allocate CCEs subframe %d, test %d\n",
 	      subframeP, test_onlyP);
       }
+      if ((test_onlyP/2) == 1) {
+       for(int ack_int = 0;ack_int < ul_req->number_of_pdus; ack_int++){
+        if(((ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) ||
+          (ul_req->ul_config_pdu_list[ack_int].pdu_type == NFAPI_UL_CONFIG_UCI_SR_HARQ_PDU_TYPE)) &&
+          (ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.ue_information.ue_information_rel8.rnti == dl_config_pdu[i].dci_dl_pdu.dci_dl_pdu_rel8.rnti)){
+          if (cc->tdd_Config==NULL)
+           ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel9_fdd.n_pucch_1_0 =
+            cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE;
+          else
+           ul_req->ul_config_pdu_list[ack_int].uci_harq_pdu.harq_information.harq_information_rel10_tdd.n_pucch_1_0 =
+            cc->radioResourceConfigCommon->pucch_ConfigCommon.n1PUCCH_AN + fCCE + get_Np(to_prb(cc->mib->message.dl_Bandwidth),fCCE,0) ;
+        }
+       }
+      }
       idci++;
     }
   }				// for i = 0 ... num_DL_DCIs
@@ -3134,7 +3250,7 @@ CCE_allocation_infeasible(int module_idP,
 {
   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_body_t *HI_DCI0_req    = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe].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;
@@ -3158,7 +3274,7 @@ CCE_allocation_infeasible(int module_idP,
 	    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);
+      ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0);
       if (ret == -1) res = TRUE;
       DL_req->number_pdu--;
     }
@@ -3173,7 +3289,7 @@ CCE_allocation_infeasible(int module_idP,
       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);
+      ret = allocate_CCEs(module_idP, CC_idP, 0, subframe, 0);
       if (ret == -1) res = TRUE;
       HI_DCI0_req->number_of_dci--;
     }
@@ -3181,6 +3297,78 @@ CCE_allocation_infeasible(int module_idP,
 
   return res;
 }
+void get_retransmission_timing(TDD_Config_t *tdd_Config, frame_t *frameP,
+    sub_frame_t *subframeP)
+{
+
+    if (tdd_Config == NULL)
+    {
+        if (*subframeP > 1)
+            *frameP = (*frameP + 1) % 1024;
+        *subframeP = (*subframeP + 8) % 10;
+    }
+    else
+    {
+        switch (tdd_Config->subframeAssignment)//TODO fill in other TDD configs
+        {
+        default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
+        case 1:
+            if (*subframeP == 0 || *subframeP == 5)
+            {
+                *subframeP  += 19;
+                *frameP = (*frameP + *subframeP/10) % 1024;
+                *subframeP %= 10;
+            }
+            else if (*subframeP == 4 || *subframeP == 9)
+            {
+                *subframeP  += 16;
+                *frameP = (*frameP + *subframeP/10) % 1024;
+                *subframeP %= 10;
+            }
+            else
+            {
+                AssertFatal(2 == 1,
+                        "Illegal dl subframe %d for tdd config %d\n", *subframeP,
+                        tdd_Config->subframeAssignment);
+            }
+            break;
+        }
+    }
+}
+
+uint8_t get_dl_subframe_count(int tdd_config_sfa, sub_frame_t subframeP){
+
+    uint8_t tdd1[10] = {1,-1,-1,-1,2,3,-1,-1,-1,4}; // special subframes 1,6 are excluded
+
+    switch(tdd_config_sfa){// TODO fill in other tdd configs
+    case 1 :
+        return tdd1[subframeP];
+        break;
+    }
+    return -1;
+}
+
+uint8_t frame_subframe2_dl_harq_pid(TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP){
+    int harq_pid;
+    if(tdd_Config){
+
+        switch(tdd_Config->subframeAssignment){ //TODO fill in other tdd config
+        case 1:
+            harq_pid = (((frame_cnt*1024 + abs_frameP) * 4) - 1 + get_dl_subframe_count(tdd_Config->subframeAssignment,subframeP))%7;//4 dl subframe in a frame
+            if(harq_pid < 0)
+              harq_pid += 7;
+            LOG_D(MAC,"[frame_subframe2_dl_harq_pid] (%d,%d) calculate harq_pid ((( %d * 1024 + %d) *4) - 1 + %d)%7 = %d \n",
+                    (abs_frameP+1024)%1024,subframeP,frame_cnt,abs_frameP,
+                    get_dl_subframe_count(tdd_Config->subframeAssignment,subframeP),harq_pid);
+            return harq_pid;
+            break;
+        }
+    }else{
+        return ((abs_frameP*10)+subframeP)&7;
+    }
+    return -1;
+}
+
 
 void
 extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
@@ -3198,8 +3386,12 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
   int pCCid = UE_list->pCC_id[UE_id];
   int spatial_bundling = 0;
   int tmode[5];
-  int i, j;
+  int i, j, m;
   uint8_t *pdu;
+  LTE_DL_FRAME_PARMS    *fp;
+  sub_frame_t subframe_tx;
+  int frame_tx;
+  uint8_t harq_pid;
 
 #if (RRC_VERSION >= MAKE_VERSION(13, 0, 0))
   if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL &&
@@ -3211,7 +3403,7 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	      && (format == 1))))
     spatial_bundling = 1;
 #endif
-
+  fp=&(RC.eNB[mod_idP][CC_idP]->frame_parms);
   for (i = 0; i < numCC; i++)
     tmode[i] = get_tmode(mod_idP, i, UE_id);
 
@@ -3222,10 +3414,53 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
     num_ack_nak = harq_indication_tdd->number_of_ack_nack;
 
     switch (harq_indication_tdd->mode) {
-    case 0:		// Format 1a/b
-      AssertFatal(numCC == 1,
-		  "numCC %d > 1, should not be using Format1a/b\n",
-		  numCC);
+    case 0:		// Format 1a/b bundling
+      AssertFatal(numCC == 1, "numCC %d > 1, should not be using Format1a/b\n", numCC);
+      int M = ul_ACK_subframe2_M(fp,subframeP);
+      for(m=0;m<M;m++){
+       subframe_tx = ul_ACK_subframe2_dl_subframe(fp,subframeP,m);
+       if(frameP==1023&&subframeP>5)
+        frame_tx=-1;
+       else
+        frame_tx = subframeP < 4 ? frameP -1 : frameP;
+       harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame_tx,subframe_tx);
+        RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0];
+
+       if(num_ack_nak==1){
+         if(harq_indication_tdd->harq_data[0].bundling.value_0==1){ //ack
+           sched_ctl->round[CC_idP][harq_pid] = 8; // release HARQ process
+           sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
+           LOG_D(MAC,"frame %d subframe %d Acking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]);
+         }else{ //nack
+         if( sched_ctl->round[CC_idP][harq_pid]<8)
+           sched_ctl->round[CC_idP][harq_pid]++;
+       LOG_D(MAC,"frame %d subframe %d Nacking (%d,%d) harq_pid %d round %d\n",frameP,subframeP,frame_tx,subframe_tx,harq_pid,sched_ctl->round[CC_idP][harq_pid]);
+      if(sched_ctl->round[CC_idP][harq_pid] == 8){
+       for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) {
+        if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){
+         //Msg NACK num to MAC ,remove UE
+         // add UE info to freeList
+         LOG_I(RRC, "put UE %x into freeList\n", rnti);
+         put_UE_in_freelist(mod_idP, rnti, 1);
+        }
+       }
+      }
+         }
+        }
+        for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) {
+        if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) && (ra[ra_i].crnti_harq_pid == harq_pid)) {
+         LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",harq_indication_tdd->harq_data[0].bundling.value_0,rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP);
+         if(num_ack_nak == 1 && harq_indication_tdd->harq_data[0].bundling.value_0 == 1) {
+          cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti);
+         }else{
+          if(sched_ctl->round[CC_idP][harq_pid] == 7){
+           cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti);
+          }
+         }
+         break;
+        }
+       }
+      }
       break;
     case 1:		// Channel Selection
       break;
@@ -3241,7 +3476,7 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
     num_ack_nak         = harq_indication_fdd->number_of_ack_nack;
     pdu                 = &harq_indication_fdd->harq_tb_n[0];
 
-    uint8_t harq_pid = ((10 * frameP) + subframeP + 10236) & 7;
+    harq_pid = ((10 * frameP) + subframeP + 10236) & 7;
 
     LOG_D(MAC,"frame %d subframe %d harq_pid %d mode %d tmode[0] %d num_ack_nak %d round %d\n",frameP,subframeP,harq_pid,harq_indication_fdd->mode,tmode[0],num_ack_nak,sched_ctl->round[CC_idP][harq_pid]);
 
@@ -3265,6 +3500,22 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	LOG_D(MAC, "Received %d for harq_pid %d\n", pdu[0],
 	      harq_pid);
 
+    RA_t *ra = &RC.mac[mod_idP]->common_channels[CC_idP].ra[0];
+    for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) {
+     if ((ra[ra_i].rnti == rnti) && (ra[ra_i].state == MSGCRNTI_ACK) &&
+       (ra[ra_i].crnti_harq_pid == harq_pid)) {
+      LOG_D(MAC,"CRNTI Reconfiguration: ACK %d rnti %x round %d frame %d subframe %d \n",pdu[0],rnti,sched_ctl->round[CC_idP][harq_pid],frameP,subframeP);
+      if(pdu[0] == 1){
+       cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti);
+      }else{
+       if(sched_ctl->round[CC_idP][harq_pid] == 7){
+        cancel_ra_proc(mod_idP, CC_idP, frameP, ra[ra_i].rnti);
+       }
+      }
+      break;
+     }
+    }
+
 	if (pdu[0] == 1) {	// ACK
 	  sched_ctl->round[CC_idP][harq_pid] = 8;	// release HARQ process
 	  sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
@@ -3274,6 +3525,16 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id,
 	    sched_ctl->round[CC_idP][harq_pid] = 8;	// release HARQ process
 	    sched_ctl->tbcnt[CC_idP][harq_pid] = 0;
           }
+          if (sched_ctl->round[CC_idP][harq_pid] == 8){
+           for (uint8_t ra_i = 0; ra_i < NB_RA_PROC_MAX; ra_i++) {
+            if((ra[ra_i].rnti == rnti) && (ra[ra_i].state == WAITMSG4ACK)){
+             //Msg NACK num to MAC ,remove UE
+             // add UE info to freeList
+             LOG_I(RRC, "put UE %x into freeList\n", rnti);
+             put_UE_in_freelist(mod_idP, rnti, 1);
+            }
+           }
+          }
         }
       } else {
 	// one or two ACK/NAK bits
@@ -4011,6 +4272,7 @@ cqi_indication(module_id_t mod_idP, int CC_idP, frame_t frameP,
       extract_pusch_csi(mod_idP, CC_idP, UE_id, frameP, subframeP,
 			pdu, rel9->length);
 
+      LOG_D(MAC,"Frame %d Subframe %d update CQI:%d\n",frameP,subframeP,sched_ctl->dl_cqi[CC_idP]);
     }
 
     // timing advance
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 3884615b89783114a07210742cd11ad6b71cab80..e58972c5e77214b644ea691ec0017cc119b7765d 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -107,6 +107,7 @@ char *ul_scheduler_type[MAX_NUM_SLICES] = {"schedule_ulsch_rnti",
 					   "schedule_ulsch_rnti",
 					   "schedule_ulsch_rnti"
 };
+extern mui_t    rrc_eNB_mui;
 
 /* Slice Function Pointer */
 slice_scheduler_ul slice_sched_ul[MAX_NUM_SLICES] = {0};
@@ -196,6 +197,10 @@ rx_sdu(const module_id_t enb_mod_idP,
 	    UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
 	    ul_cqi);
 
+      if(ul_cqi>200){ // too high energy pattern
+        UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi;
+      }
+
       //      AssertFatal(1==0,"ulsch in error\n");
       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));
@@ -207,6 +212,9 @@ rx_sdu(const module_id_t enb_mod_idP,
         UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid];
         if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0)
           UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0;
+
+        if (find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1)
+          cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
       } else
 	UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
 
@@ -216,7 +224,9 @@ rx_sdu(const module_id_t enb_mod_idP,
       LOG_D(MAC,
 	"Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n",
 	current_rnti, harq_pid, first_rb);
-      nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_idP];
+      nfapi_hi_dci0_request_t *hi_dci0_req;
+      uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP] , subframeP);
+      hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10];
       nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
       nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
         &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
@@ -230,7 +240,7 @@ rx_sdu(const module_id_t enb_mod_idP,
       hi_dci0_req_body->number_of_hi++;
       hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0);
       hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
-      hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4);
+      hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl);
       hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
 
       return;
@@ -260,7 +270,7 @@ rx_sdu(const module_id_t enb_mod_idP,
 	    (int) mac->common_channels[CC_idP].
 	    radioResourceConfigCommon->rach_ConfigCommon.
 	    maxHARQ_Msg3Tx);
-      if (ra[RA_id].msg3_round == mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
+      if (ra[RA_id].msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
 	cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
       }
 
@@ -268,8 +278,9 @@ rx_sdu(const module_id_t enb_mod_idP,
 	first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
 	ra[RA_id].msg3_round++;
 	// prepare handling of retransmission
-	ra[RA_id].Msg3_frame    = (ra[RA_id].Msg3_frame + ((ra[RA_id].Msg3_subframe > 1) ? 1 : 0)) % 1024;
-	ra[RA_id].Msg3_subframe = (ra[RA_id].Msg3_subframe + 8) % 10;
+        get_Msg3allocret(&mac->common_channels[CC_idP],
+                 ra[RA_id].Msg3_subframe, ra[RA_id].Msg3_frame,
+                 &ra[RA_id].Msg3_frame, &ra[RA_id].Msg3_subframe);
 	add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP);
       }
 
@@ -285,6 +296,12 @@ rx_sdu(const module_id_t enb_mod_idP,
   }
   payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP);
 
+  if(payload_ptr == NULL){
+   LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n",
+         enb_mod_idP, harq_pid, CC_idP,current_rnti, UE_id);
+   return;
+  }
+
   T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP),
     T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
     T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
@@ -332,8 +349,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 	      enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i,
 	      num_ce, old_rnti, old_UE_id);
 	/* receiving CRNTI means that the current rnti has to go away */
-	cancel_ra_proc(enb_mod_idP, CC_idP, frameP,
-		       current_rnti);
+	//cancel_ra_proc(enb_mod_idP, CC_idP, frameP,
+	//	       current_rnti);
 	if (old_UE_id != -1) {
 	  /* TODO: if the UE did random access (followed by a MAC uplink with
 	   * CRNTI) because none of its scheduling request was granted, then
@@ -346,16 +363,45 @@ rx_sdu(const module_id_t enb_mod_idP,
 	   * We have to take care of this. As the code is, nothing is done and
 	   * the UE state in the eNB is wrong.
 	   */
-	  UE_id = old_UE_id;
-	  UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
-	  UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
-	  if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
-	    UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
-	    mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP,
-				   subframeP, old_rnti);
-	  }
-	  current_rnti = old_rnti;
-	}
+          for (ii = 0; ii < NB_RA_PROC_MAX; ii++) {
+            ra = &mac->common_channels[CC_idP].ra[ii];
+            if ((ra->rnti == current_rnti) && (ra->state != IDLE)) {
+              mac_rrc_data_ind(enb_mod_idP,
+                               CC_idP,
+                               frameP, subframeP,
+                               old_rnti,
+                               DCCH,
+                               (uint8_t *) payload_ptr,
+                               rx_lengths[i],
+                               0);
+              // prepare transmission of Msg4(RRCConnectionReconfiguration)
+              ra->state = MSGCRNTI;
+              LOG_I(MAC,
+                    "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) RRCConnectionReconfiguration(Msg4)\n",
+                    enb_mod_idP, frameP, subframeP, CC_idP, old_rnti, old_UE_id);
+
+              UE_id = old_UE_id;
+              current_rnti = old_rnti;
+              ra->rnti = old_rnti;
+              ra->crnti_rrc_mui = rrc_eNB_mui-1;
+              ra->crnti_harq_pid = -1;
+              //clear timer
+              UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
+              UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
+              UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0;
+              if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
+                UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
+                mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP,
+                                       subframeP, old_rnti);
+              }
+              UE_list->UE_template[CC_idP][UE_id].ul_SR = 1;
+              UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1;
+              break;
+            }
+          }
+        } else {
+          cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti);
+        }
 	crnti_rx = 1;
 	payload_ptr += 2;
 	break;
@@ -550,8 +596,9 @@ rx_sdu(const module_id_t enb_mod_idP,
 				    ra[ii].rach_resource_type
 #endif
 				    )) == -1) {
-	      AssertFatal(1 == 0,
-			  "[MAC][eNB] Max user count reached\n");
+              LOG_E(MAC,"[MAC][eNB] Max user count reached\n");
+              cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti);
+              break;
 	      // kill RA procedure
 	    } else
 	      LOG_D(MAC,
@@ -584,10 +631,22 @@ rx_sdu(const module_id_t enb_mod_idP,
 
 
 
-	  // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
-	  ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0);
-	  ra->Msg4_subframe = (subframeP + 4) % 10;
+          if(mac->common_channels[CC_idP].tdd_Config!=NULL){
+            switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment){
+            case 1:
+              ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0);
+              ra->Msg4_subframe = (subframeP + 7) % 10;
+              break;
+            default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
+             // TODO need to be complete for other tdd configs.
+            }
+          }else{
+            // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
+            ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0);
+            ra->Msg4_subframe = (subframeP + 4) % 10;
+          }
 
+          UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
 	}		// if process is active
       }			// loop on RA processes
 
@@ -714,7 +773,10 @@ rx_sdu(const module_id_t enb_mod_idP,
   LOG_D(MAC,
 	"Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",
 	current_rnti, harq_pid, first_rb);
-  nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_idP];
+  nfapi_hi_dci0_request_t *hi_dci0_req;
+  uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP] , subframeP);
+  hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10];
+
   nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
   nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu =
     &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
@@ -728,7 +790,7 @@ rx_sdu(const module_id_t enb_mod_idP,
   hi_dci0_req_body->number_of_hi++;
   hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0);
   hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
-  hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4);
+  hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl);
   hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
 
   /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */
@@ -848,7 +910,8 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header,
 	  ce_len++;
 	} else {
 	  LOG_E(MAC, "unknown CE %d \n", lcid);
-	  AssertFatal(1 == 0, "unknown CE");
+	  //AssertFatal(1 == 0, "unknown CE");
+          return NULL;
 	}
       }
     }
@@ -895,6 +958,7 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
 
   start_meas(&mac->schedule_ulsch);
 
+  int sched_frame=frameP;
   int sched_subframe = (subframeP + 4) % 10;
 
   cc = &mac->common_channels[0];
@@ -904,8 +968,10 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
     tdd_sfa = cc->tdd_Config->subframeAssignment;
     switch (subframeP) {
     case 0:
-      if ((tdd_sfa == 0) || (tdd_sfa == 3) || (tdd_sfa == 6))
+      if ((tdd_sfa == 0) || (tdd_sfa == 3))
 	sched_subframe = 4;
+      else if (tdd_sfa == 6)
+	sched_subframe = 7;
       else
 	return;
       break;
@@ -914,6 +980,8 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
 	sched_subframe = 7;
       else if (tdd_sfa == 6)
 	sched_subframe = 8;
+      else
+        return;
       break;
     default:
       return;
@@ -936,12 +1004,12 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
       if (tdd_sfa == 0)
 	sched_subframe = 9;
       else if (tdd_sfa == 6)
-	sched_subframe = 3;
+	sched_subframe = 2;
       else
 	return;
       break;
     case 6:
-      if (tdd_sfa == 1)
+      if (tdd_sfa == 0 || tdd_sfa == 1)
 	sched_subframe = 2;
       else if (tdd_sfa == 6)
 	sched_subframe = 3;
@@ -951,21 +1019,23 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP,
     case 7:
       return;
     case 8:
-      if ((tdd_sfa >= 2) || (tdd_sfa <= 5))
-	sched_subframe = 2;
+      if ((tdd_sfa >= 2) && (tdd_sfa <= 5))
+        sched_subframe = 2;
       else
-	return;
+        return;
       break;
     case 9:
       if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4))
-	sched_subframe = 3;
+        sched_subframe = 3;
       else if (tdd_sfa == 6)
-	sched_subframe = 4;
+        sched_subframe = 4;
       else
-	return;
+        return;
       break;
     }
   }
+  if (sched_subframe < subframeP) sched_frame++;
+
   for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
 
 
@@ -1112,8 +1182,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
   uint8_t status = 0;
   uint8_t rb_table_index = -1;
   uint32_t cqi_req, cshift, ndi, tpc;
-  int32_t normalized_rx_power;
-  int32_t target_rx_power = -90;
+  int32_t normalized_rx_power, target_rx_power;
   static int32_t tpc_accumulated = 0;
   int n;
   int CC_id = 0;
@@ -1126,19 +1195,21 @@ schedule_ulsch_rnti(module_id_t module_idP,
   UE_sched_ctrl *UE_sched_ctrl;
   int sched_frame = frameP;
   int rvidx_tab[4] = { 0, 2, 3, 1 };
+  uint16_t          ul_req_index;
+  uint8_t           dlsch_flag;
 
   if (sched_subframeP < subframeP)
       sched_frame++;
 
-  nfapi_hi_dci0_request_t        *hi_dci0_req = &mac->HI_DCI0_req[CC_id];
+  nfapi_hi_dci0_request_t        *hi_dci0_req = &mac->HI_DCI0_req[CC_id][subframeP];
   nfapi_hi_dci0_request_body_t   *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
   nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
 
   nfapi_ul_config_request_t *ul_req_tmp            = &mac->UL_req_tmp[CC_id][sched_subframeP];
   nfapi_ul_config_request_body_t *ul_req_tmp_body  = &ul_req_tmp->ul_config_request_body;
-
+  nfapi_ul_config_ulsch_harq_information *ulsch_harq_information;
   //LOG_D(MAC, "entering ulsch preprocesor\n");
-  ulsch_scheduler_pre_processor(module_idP, slice_id, frameP, subframeP, first_rb);
+  ulsch_scheduler_pre_processor(module_idP, slice_id, frameP, subframeP, sched_subframeP, first_rb);
 
   //LOG_D(MAC, "exiting ulsch preprocesor\n");
 
@@ -1268,6 +1339,7 @@ schedule_ulsch_rnti(module_id_t module_idP,
 	      cqi_req = 0;
 	    } else {
 	      cqi_req = 1;
+              UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP;
 	    }
 	    UE_sched_ctrl->cqi_req_timer = 0;
 	  } else
@@ -1277,9 +1349,10 @@ schedule_ulsch_rnti(module_id_t module_idP,
 	  //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 = UE_sched_ctrl->pusch_snr[CC_id];
-	  target_rx_power = 178;
-
+	  //is not in dBm, unit from nfapi, converting to dBm: ToDo: Noise power hard coded to 30
+	  normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30;
+	  target_rx_power= mac->puSch10xSnr/10 + 30;
+	  //printf("\n mac->puSch10xSnr = %d,  normalized_rx_power = %d, target_rx_power = %d \n",mac->puSch10xSnr,normalized_rx_power,target_rx_power);
 	  // 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_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe;
@@ -1404,9 +1477,10 @@ schedule_ulsch_rnti(module_id_t module_idP,
 	    hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
 	    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];
+            hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid;
 
 	    hi_dci0_req_body->number_of_dci++;
-	    hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 4);
+	    hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4);
 	    hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
 
 	    hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday!
@@ -1418,8 +1492,18 @@ schedule_ulsch_rnti(module_id_t module_idP,
 		  harq_pid, frameP, subframeP, UE_id, rnti,
 		  sched_frame, sched_subframeP);
 
+            ul_req_index = 0;
+            dlsch_flag = 0;
+            for(ul_req_index = 0;ul_req_index < ul_req_tmp_body->number_of_pdus;ul_req_index++){
+              if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE){
+                dlsch_flag = 1;
+                LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index);
+                break;
+              }
+            }
+
 	    // Add UL_config PDUs
-	    fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb[CC_id],	// resource_block_start
+	    fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->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
@@ -1437,22 +1521,41 @@ schedule_ulsch_rnti(module_id_t module_idP,
 						  [rb_table_index]));
 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 	    if (UE_template->rach_resource_type > 0) {	// This is a BL/CE UE allocation
-	      fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1,	//total_number_of_repetitions
+	      fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1,	//total_number_of_repetitions
 						   1,	//repetition_number
 						   (frameP *
 						    10) +
 						   subframeP);
 	    }
 #endif
+            if(dlsch_flag == 1){
+              if(cqi_req == 1){
+                 ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
+                 ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
+                 ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                 ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;    // last symbol not punctured
+                 ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
+
+              }else{
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
+                ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
+              }
+              fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP);
+            }else{
+              ul_req_tmp_body->number_of_pdus++;
+            }
+
 	    ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST;
-	    ul_req_tmp_body->number_of_pdus++;
 	    ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
 	    mac->ul_handle++;
 
 	    uint16_t ul_sched_frame = sched_frame;
 	    uint16_t ul_sched_subframeP = sched_subframeP;
 
-	    add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2);
+	    //add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2);
 	    ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP;
 
 	    add_ue_ulsch_info(module_idP,
@@ -1505,7 +1608,16 @@ schedule_ulsch_rnti(module_id_t module_idP,
 		  "[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_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid],	// resource_block_start
+            ul_req_index = 0;
+            dlsch_flag = 0;
+            for(ul_req_index = 0;ul_req_index < ul_req_tmp_body->number_of_pdus;ul_req_index++){
+              if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE){
+                dlsch_flag = 1;
+                LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index);
+                break;
+              }
+            }
+	    fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->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
@@ -1520,14 +1632,33 @@ schedule_ulsch_rnti(module_id_t module_idP,
 						 TBS_UL[harq_pid]);
 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 	    if (UE_template->rach_resource_type > 0) {	// This is a BL/CE UE allocation
-	      fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_tmp_body->number_of_pdus], UE_template->rach_resource_type > 2 ? 2 : 1, 1,	//total_number_of_repetitions
+	      fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1,	//total_number_of_repetitions
 						   1,	//repetition_number
 						   (frameP *
 						    10) +
 						   subframeP);
 	    }
 #endif
-	    ul_req_tmp_body->number_of_pdus++;
+            if(dlsch_flag == 1){
+              if(cqi_req == 1){
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
+                ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;    // last symbol not punctured
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid];
+
+              }else{
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
+                ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
+                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid];
+              }
+              fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP);
+            }else{
+              ul_req_tmp_body->number_of_pdus++;
+            }
+
 	    mac->ul_handle++;
 
 	    ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h
index fac596f406710f5928d9ad36311bbe13da0ae503..333dfb3b880a96a1ac2c207317232f0a5eea3137 100644
--- a/openair2/LAYER2/MAC/mac.h
+++ b/openair2/LAYER2/MAC/mac.h
@@ -87,7 +87,7 @@
 #define PCCH_PAYLOAD_SIZE_MAX 128
 #define RAR_PAYLOAD_SIZE_MAX 128
 
-#define SCH_PAYLOAD_SIZE_MAX 4096
+#define SCH_PAYLOAD_SIZE_MAX 8192
 #define DCH_PAYLOAD_SIZE_MAX 4096
 /// Logical channel ids from 36-311 (Note BCCH is not specified in 36-311, uses the same as first DRB)
 
@@ -130,7 +130,7 @@
 /*!\brief Maximum number od control elemenets */
 #define MAX_NUM_CE 5
 /*!\brief Maximum number of random access process */
-#if defined(USRP_REC_PLAY)
+#if 0 // #if defined(USRP_REC_PLAY)
 #define NB_RA_PROC_MAX 1
 #else
 #define NB_RA_PROC_MAX 4
@@ -511,7 +511,9 @@ typedef enum {
     MSG2,
     WAITMSG3,
     MSG4,
-    WAITMSG4ACK
+    WAITMSG4ACK,
+    MSGCRNTI,
+    MSGCRNTI_ACK
 } RA_state;
 
 /*!\brief  UE ULSCH scheduling states*/
@@ -541,6 +543,12 @@ typedef enum {
     CBA_RS			/// random allocation
 } CBA_POLICY;
 
+/*!\brief  scheduler mode */
+typedef enum {
+    SCHED_MODE_DEFAULT = 0,			/// default cheduler
+    SCHED_MODE_FAIR_RR			/// fair raund robin
+} SCHEDULER_MODES;
+
 
 /*! \brief temporary struct for ULSCH sched */
 typedef struct {
@@ -984,7 +992,9 @@ typedef struct {
     uint8_t aperiodic_wideband_cqi1[NFAPI_CC_MAX];
     uint8_t aperiodic_wideband_pmi1[NFAPI_CC_MAX];
     uint8_t dl_cqi[NFAPI_CC_MAX];
-    int32_t       uplane_inactivity_timer;
+    int32_t uplane_inactivity_timer;
+    uint8_t crnti_reconfigurationcomplete_flag;
+    uint8_t cqi_req_flag;
 } UE_sched_ctrl;
 /*! \brief eNB template for the Random access information */
 typedef struct {
@@ -1043,6 +1053,8 @@ typedef struct {
     uint8_t msg2_narrowband;
     uint8_t msg34_narrowband;
 #endif
+    int32_t  crnti_rrc_mui;
+    int8_t   crnti_harq_pid;
 } RA_t;
 
 
@@ -1092,6 +1104,22 @@ typedef struct {
 
 } UE_list_t;
 
+/*! \brief deleting control information*/
+typedef struct {
+    ///rnti of UE
+    rnti_t rnti;
+    ///remove UE context flag
+    boolean_t removeContextFlg;
+} UE_free_ctrl;
+/*! \brief REMOVE UE list used by eNB to order UEs/CC for deleting*/
+typedef struct {
+    /// deleting control info
+    UE_free_ctrl UE_free_ctrl[NUMBER_OF_UE_MAX+1];
+    int num_UEs;
+    int head_freelist; ///the head position of the delete list
+    int tail_freelist; ///the tail position of the delete list
+} UE_free_list_t;
+
 /*! \brief eNB common channels */
 typedef struct {
     int physCellId;
@@ -1180,7 +1208,7 @@ typedef struct eNB_MAC_INST_s {
   /// Common cell resources
   COMMON_channels_t common_channels[NFAPI_CC_MAX];
   /// current PDU index (BCH,MCH,DLSCH)
-  uint16_t pdu_index[NFAPI_CC_MAX];
+  int16_t pdu_index[NFAPI_CC_MAX];
   
   /// NFAPI Config Request Structure
   nfapi_config_request_t config[NFAPI_CC_MAX];
@@ -1201,9 +1229,9 @@ typedef struct eNB_MAC_INST_s {
   nfapi_ul_config_request_t UL_req_tmp[NFAPI_CC_MAX][10];
   /// Preallocated HI_DCI0 pdu list
   nfapi_hi_dci0_request_pdu_t
-  hi_dci0_pdu_list[NFAPI_CC_MAX][MAX_NUM_HI_DCI0_PDU];
+  hi_dci0_pdu_list[NFAPI_CC_MAX][10][MAX_NUM_HI_DCI0_PDU];
   /// NFAPI HI/DCI0 Config Request Structure
-  nfapi_hi_dci0_request_t HI_DCI0_req[NFAPI_CC_MAX];
+  nfapi_hi_dci0_request_t HI_DCI0_req[NFAPI_CC_MAX][10];
   /// Prealocated TX pdu list
   nfapi_tx_request_pdu_t
   tx_request_pdu[NFAPI_CC_MAX][MAX_NUM_TX_REQUEST_PDU];
@@ -1242,6 +1270,13 @@ typedef struct eNB_MAC_INST_s {
   time_stats_t rx_ulsch_sdu;	// include rlc_data_ind
   /// processing time of eNB PCH scheduler
   time_stats_t schedule_pch;
+
+  UE_free_list_t UE_free_list;
+  /// for scheduling selection
+  SCHEDULER_MODES scheduler_mode;
+
+  int32_t puSch10xSnr;
+  int32_t puCch10xSnr;
 } eNB_MAC_INST;
 
 /*
@@ -1400,12 +1435,12 @@ typedef struct {
     RAR_PDU RAR_pdu;
     /// Incoming DLSCH pdu for PHY
     DLSCH_PDU DLSCH_pdu[MAX_MOBILES_PER_ENB][2];
-#ifdef Rel14
-  int sltx_active;
-  SLSCH_t slsch;
-  SLDCH_t sldch;
-  ULSCH_PDU slsch_pdu;
-  int slsch_lcid;
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+    int sltx_active;
+    SLSCH_t slsch;
+    SLDCH_t sldch;
+    ULSCH_PDU slsch_pdu;
+    int slsch_lcid;
 #endif
     /// number of attempt for rach
     uint8_t RA_attempt_number;
@@ -1513,6 +1548,23 @@ typedef struct {
     uint8_t n_adj_cells;
 } neigh_cell_id_t;
 
+typedef struct {
+  volatile uint8_t flag;
+  rnti_t rnti;
+  mui_t  rrc_eNB_mui;
+}RRC_release_ctrl;
+ 
+typedef struct {
+    uint16_t num_UEs;
+    RRC_release_ctrl RRC_release_ctrl[NUMBER_OF_UE_MAX];
+} RRC_release_list_t;
+
+typedef  struct {
+  uint8_t                      rrc_mui_num;
+  mui_t                        rrc_mui[128];
+}mac_rlc_am_muilist_t;
+
 #include "mac_proto.h"
+
 /*@}*/
 #endif /*__LAYER2_MAC_DEFS_H__ */
diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h
index 4ac7cf4d58e79ca0363cd9d813232135b551b9f1..ca72882471f11122633b5dc76af58740f73ce757 100644
--- a/openair2/LAYER2/MAC/mac_extern.h
+++ b/openair2/LAYER2/MAC/mac_extern.h
@@ -76,4 +76,14 @@ extern uint32_t RRC_CONNECTION_FLAG;
 extern uint8_t rb_table[34];
 
 
+#if defined(PRE_SCD_THREAD)
+extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+extern uint8_t dlsch_ue_select_tbl_in_use;
+extern uint8_t new_dlsch_ue_select_tbl_in_use;
+extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
+extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+#endif
+
+extern mac_rlc_am_muilist_t rlc_am_mui;
+extern SCHEDULER_MODES global_scheduler_mode;
 #endif //DEF_H
diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h
index d648f9def75b2e80756e921cdefaea90d84d7fd8..069cd63829379286a3fcf20560ef77d6b856d670 100644
--- a/openair2/LAYER2/MAC/mac_proto.h
+++ b/openair2/LAYER2/MAC/mac_proto.h
@@ -135,8 +135,7 @@ void schedule_ulsch_rnti(module_id_t module_idP, slice_id_t slice_idP, frame_t f
 @param subframe Index of subframe
 @param mbsfn_flag Indicates that this subframe is for MCH/MCCH
 */
-void fill_DLSCH_dci(module_id_t module_idP, frame_t frameP,
-		    sub_frame_t subframe, int *mbsfn_flag);
+void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP,sub_frame_t subframe,int *mbsfn_flag);
 
 /** \brief UE specific DLSCH scheduling. Retrieves next ue to be schduled from round-robin scheduler and gets the appropriate harq_pid for the subframe from PHY. If the process is active and requires a retransmission, it schedules the retransmission with the same PRB count and MCS as the first transmission. Otherwise it consults RLC for DCCH/DTCH SDUs (status with maximum number of available PRBS), builds the MAC header (timing advance sent by default) and copies
 @param Mod_id Instance ID of eNB
@@ -314,6 +313,9 @@ void cancel_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP,
 @param Msg3_frame    frame where scheduling takes place
 @param Msg3_subframe subframe where scheduling takes place
 */
+
+void clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
+
 void set_msg3_subframe(module_id_t Mod_id,
 		       int CC_id,
 		       int frame,
@@ -427,7 +429,7 @@ int get_nCCE_offset(int *CCE_table,
 		    const unsigned short rnti,
 		    const unsigned char subframe);
 
-int allocate_CCEs(int module_idP, int CC_idP, int subframe, int test_only);
+int allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, int test_only);
 
 boolean_t CCE_allocation_infeasible(int module_idP,
 				    int CC_idP,
@@ -543,7 +545,7 @@ void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
 @param[out] sync_area return the sync area
 @param[out] mcch_active flag indicating whether this MCCH is active in this SF
 */
-int ue_query_mch(uint8_t Mod_id, uint8_t CC_id, uint32_t frame,
+int ue_query_mch(module_id_t Mod_id, uint8_t CC_id, uint32_t frame,
 		 sub_frame_t subframe, uint8_t eNB_index,
 		 uint8_t * sync_area, uint8_t * mcch_active);
 
@@ -683,9 +685,17 @@ int UE_num_active_CC(UE_list_t * listP, int ue_idP);
 int UE_PCCID(module_id_t mod_idP, int ue_idP);
 rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP);
 
+uint8_t find_rb_table_index(uint8_t average_rbs);
+
+void set_ul_DAI(int module_idP,
+                int UE_idP,
+                int CC_idP,
+                int frameP,
+                int subframeP);
 
 void ulsch_scheduler_pre_processor(module_id_t module_idP, slice_id_t slice_id, int frameP,
 				   sub_frame_t subframeP,
+                                   unsigned char sched_subframeP,
 				   uint16_t * first_rb);
 void store_ulsch_buffer(module_id_t module_idP, int frameP,
 			sub_frame_t subframeP);
@@ -694,6 +704,7 @@ void assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP,
 			   sub_frame_t subframeP, uint16_t * first_rb);
 void adjust_bsr_info(int buffer_occupancy, uint16_t TBS,
 		     UE_TEMPLATE * UE_template);
+
 int phy_stats_exist(module_id_t Mod_id, int rnti);
 void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t subframeP);
 
@@ -860,7 +871,7 @@ uint32_t allocate_prbs_sub(int nb_rb, int N_RB_DL, int N_RBG,
 			   uint8_t * rballoc);
 
 void update_ul_dci(module_id_t module_idP, uint8_t CC_id, rnti_t rnti,
-		   uint8_t dai);
+		   uint8_t dai, sub_frame_t subframe);
 
 int get_bw_index(module_id_t module_id, uint8_t CC_id);
 
@@ -1018,10 +1029,10 @@ int rrc_mac_config_req_ue(module_id_t module_idP,
 			  ,
 			  uint8_t num_active_cba_groups, uint16_t cba_rnti
 #endif
-#if defined(Rel14)
-           ,config_action_t config_action
-           ,const uint32_t * const sourceL2Id
-           ,const uint32_t * const destinationL2Id
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
+			  ,config_action_t config_action
+			  ,const uint32_t * const sourceL2Id
+			  ,const uint32_t * const destinationL2Id
 #endif
 			  );
 
@@ -1091,7 +1102,7 @@ void extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id,
 
 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);
+			   int16_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,
@@ -1131,7 +1142,7 @@ void program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP,
 
 void fill_nfapi_dlsch_config(eNB_MAC_INST * eNB,
 			     nfapi_dl_config_request_body_t * dl_req,
-			     uint16_t length, uint16_t pdu_index,
+			     uint16_t length, int16_t pdu_index,
 			     uint16_t rnti,
 			     uint8_t resource_allocation_type,
 			     uint8_t
@@ -1165,7 +1176,8 @@ void fill_nfapi_ulsch_harq_information(module_id_t module_idP,
 				       int CC_idP,
 				       uint16_t rntiP,
 				       nfapi_ul_config_ulsch_harq_information
-				       * harq_information);
+				       * harq_information,
+				       sub_frame_t subframeP);
 
 uint16_t fill_nfapi_uci_acknak(module_id_t module_idP,
 			       int CC_idP,
@@ -1214,6 +1226,13 @@ uint32_t from_earfcn(int eutra_bandP, uint32_t dl_earfcn);
 int32_t get_uldl_offset(int eutra_bandP);
 int l2_init_ue(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active,
 	       uint8_t HO_active);
+#if defined(PRE_SCD_THREAD)
+void pre_scd_nb_rbs_required(    module_id_t     module_idP,
+                                 frame_t         frameP,
+                                 sub_frame_t     subframeP,
+                                 int             min_rb_unit[MAX_NUM_CCs],
+                                 uint16_t        nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]);
+#endif
 
 /*Slice related functions */
 uint16_t flexran_nb_rbs_allowed_slice(float rb_percentage, int total_rbs);
diff --git a/openair2/LAYER2/MAC/mac_vars.h b/openair2/LAYER2/MAC/mac_vars.h
index 5b00387de6e6144bd51891b39cf432b650a03925..76842afd38358bed4baeb0ff3b72d0c68cf728db 100644
--- a/openair2/LAYER2/MAC/mac_vars.h
+++ b/openair2/LAYER2/MAC/mac_vars.h
@@ -142,4 +142,6 @@ DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
 
 DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
 
+mac_rlc_am_muilist_t rlc_am_mui;
+SCHEDULER_MODES global_scheduler_mode;
 #endif
diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c
index 062ead2a206d1e6db672afc02d60785e3b628abd..d32da8ac7259fad0c17cfb06c266669059a71e76 100644
--- a/openair2/LAYER2/MAC/main.c
+++ b/openair2/LAYER2/MAC/main.c
@@ -58,23 +58,27 @@ void mac_top_init_eNB(void)
 	  RC.nb_macrlc_inst);
 
     if (RC.nb_macrlc_inst > 0) {
-	RC.mac =
-	    (eNB_MAC_INST **) malloc16(RC.nb_macrlc_inst *
-				       sizeof(eNB_MAC_INST *));
+      if (RC.mac == NULL){
+		RC.mac =
+			(eNB_MAC_INST **) malloc16(RC.nb_macrlc_inst *
+						   sizeof(eNB_MAC_INST *));
+        }
 	AssertFatal(RC.mac != NULL,
 		    "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",
 		    RC.nb_macrlc_inst * sizeof(eNB_MAC_INST *),
 		    RC.nb_macrlc_inst, sizeof(eNB_MAC_INST));
 	for (i = 0; i < RC.nb_macrlc_inst; i++) {
-	    RC.mac[i] = (eNB_MAC_INST *) malloc16(sizeof(eNB_MAC_INST));
-	    AssertFatal(RC.mac != NULL,
-			"can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",
-			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));
+            if (RC.mac[i] == NULL) {
+                RC.mac[i] = (eNB_MAC_INST *) malloc16(sizeof(eNB_MAC_INST));
+                AssertFatal(RC.mac[i] != NULL,
+                            "can't ALLOCATE %zu Bytes for %d eNB_MAC_INST with size %zu \n",
+                            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 = i;
 	    for (j = 0; j < MAX_NUM_CCs; j++) {
 		RC.mac[i]->DL_req[j].dl_config_request_body.
@@ -85,9 +89,10 @@ void mac_top_init_eNB(void)
 		    RC.mac[i]->UL_req_tmp[j][k].
 			ul_config_request_body.ul_config_pdu_list =
 			RC.mac[i]->ul_config_pdu_list_tmp[j][k];
-		RC.mac[i]->HI_DCI0_req[j].
-		    hi_dci0_request_body.hi_dci0_pdu_list =
-		    RC.mac[i]->hi_dci0_pdu_list[j];
+		for(int sf=0;sf<10;sf++){
+		    RC.mac[i]->HI_DCI0_req[j][sf].hi_dci0_request_body.hi_dci0_pdu_list =RC.mac[i]->hi_dci0_pdu_list[j][sf];
+		}
+
 		RC.mac[i]->TX_req[j].tx_request_body.tx_pdu_list =
 		    RC.mac[i]->tx_request_pdu[j];
 		RC.mac[i]->ul_handle = 0;
diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c
index e9b3befc1c10b827b98ecfcb6ac8dcb6a60efdec..76c87e798bcb62c908801bb4955ad520cb27e5ee 100644
--- a/openair2/LAYER2/MAC/pre_processor.c
+++ b/openair2/LAYER2/MAC/pre_processor.c
@@ -129,12 +129,12 @@ store_dlsch_buffer(module_id_t Mod_id, slice_id_t slice_id, frame_t frameP,
 
 	rnti = UE_RNTI(Mod_id, UE_id);
 
-	for (i = 0; i < MAX_NUM_LCID; i++) {	// loop over all the logical channels
+        for (i = 0; i < MAX_NUM_LCID; i++) {    // loop over all the logical channels
 
 	    rlc_status =
 		mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP,
 				   ENB_FLAG_YES, MBMS_FLAG_NO, i, 0
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                    ,0, 0
 #endif
                    );
@@ -318,10 +318,8 @@ maxround(module_id_t Mod_id, uint16_t rnti, int frame,
 	cc = &RC.mac[Mod_id]->common_channels[CC_id];
 
 	UE_id = find_UE_id(Mod_id, rnti);
-	if (cc->tdd_Config)
-	    harq_pid = ((frame * 10) + subframe) % 10;
-	else
-	    harq_pid = ((frame * 10) + subframe) & 7;
+
+	harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frame ,subframe);
 
 	round = UE_list->UE_sched_ctrl[UE_id].round[CC_id][harq_pid];
 	if (round > round_max) {
@@ -501,8 +499,10 @@ void sort_UEs(module_id_t Mod_idP, slice_id_t slice_id, int frameP, sub_frame_t
 			continue;
 		if ((rnti = UE_RNTI(Mod_idP, i)) == NOT_A_RNTI)
 			continue;
+#if 0
 		if (UE_list->UE_sched_ctrl[i].ul_out_of_sync == 1)
 			continue;
+#endif
 		if (!ue_slice_membership(i, slice_id))
 			continue;
 
@@ -638,8 +638,10 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
 
     if (rnti == NOT_A_RNTI)
       continue;
+#if 0
     if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
       continue;
+#endif
     if (!ue_slice_membership(UE_id, slice_id))
       continue;
 
@@ -719,8 +721,10 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
 
     if (rnti == NOT_A_RNTI)
       continue;
+#if 0
     if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
       continue;
+#endif
     if (!ue_slice_membership(UE_id, slice_id))
       continue;
 
@@ -728,11 +732,7 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
       CC_id = UE_list->ordered_CCids[ii][UE_id];
       ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
       cc = &RC.mac[Mod_id]->common_channels[CC_id];
-      // TODO Can we use subframe2harqpid() here?
-      if (cc->tdd_Config)
-        harq_pid = ((frameP * 10) + subframeP) % 10;
-      else
-        harq_pid = ((frameP * 10) + subframeP) & 7;
+      harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
       round = ue_sched_ctl->round[CC_id][harq_pid];
 
       // control channel or retransmission
@@ -797,8 +797,10 @@ void dlsch_scheduler_pre_processor_accounting(module_id_t Mod_id,
           // LOG_D(MAC,"UE %d rnti 0x\n", UE_id, rnti );
           if (rnti == NOT_A_RNTI)
             continue;
+#if 0
           if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1)
             continue;
+#endif
           if (!ue_slice_membership(UE_id, slice_id))
             continue;
 
@@ -1401,11 +1403,12 @@ dlsch_scheduler_pre_processor_allocate(module_id_t Mod_id,
 
 /// ULSCH PRE_PROCESSOR
 
-
-void
-ulsch_scheduler_pre_processor(module_id_t module_idP,
-			      slice_id_t slice_id, int frameP,
-			      sub_frame_t subframeP, uint16_t * first_rb)
+void ulsch_scheduler_pre_processor(module_id_t module_idP,
+                                   slice_id_t slice_id,
+                                   int frameP,
+                                   sub_frame_t subframeP,
+                                   unsigned char sched_subframeP,
+                                   uint16_t *first_rb)
 {
 
     int16_t i;
@@ -1530,7 +1533,7 @@ ulsch_scheduler_pre_processor(module_id_t module_idP,
         CC_id = UE_list->ordered_ULCCids[n][UE_id];
         UE_template = &UE_list->UE_template[CC_id][UE_id];
         harq_pid = subframe2harqpid(&RC.mac[module_idP]->common_channels[CC_id],
-                                    frameP, subframeP);
+                                    frameP, sched_subframeP);
 
         //      mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,openair_harq_UL);
 
@@ -1617,7 +1620,6 @@ ulsch_scheduler_pre_processor(module_id_t module_idP,
 #endif
 }
 
-
 void
 assign_max_mcs_min_rb(module_id_t module_idP, int slice_id, int frameP,
 		      sub_frame_t subframeP, uint16_t * first_rb)
diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c
index 5a66645e3d81e9d5b2ae324372d111193af5eab3..94362d499af6eec3a7f419c72b09b0d0b4f22fd0 100644
--- a/openair2/LAYER2/MAC/ra_procedures.c
+++ b/openair2/LAYER2/MAC/ra_procedures.c
@@ -410,7 +410,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
 				       UE_mac_inst[module_idP].crnti,
 				       eNB_indexP, frameP, subframeP,
 				       ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,0, 0
 #endif
                );
@@ -431,7 +431,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id,
 
 		sdu_lengths[0] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6,	//not used
 						  (char *) &ulsch_buff[0]
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 						  ,0,
 						  0
 #endif
diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c
index d97ab6580e4ff8163307d94faec8cdcfee546f04..9e5824fdd38eecadf44da1b77a58a361e1ac2179 100644
--- a/openair2/LAYER2/MAC/rar_tools.c
+++ b/openair2/LAYER2/MAC/rar_tools.c
@@ -71,7 +71,16 @@ fill_rar(const module_id_t module_idP,
     ra->timing_offset /= 16;	//T_A = N_TA/16, where N_TA should be on a 30.72Msps
     rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4));	// 7 MSBs of timing advance + divide by 4
     rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0;	// 4 LSBs of timing advance + divide by 4
-    ra->msg3_first_rb = 6;
+    COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
+    if(N_RB_UL == 25){
+      ra->msg3_first_rb = 1;
+    }else{
+      if (cc->tdd_Config && N_RB_UL == 100) {
+        ra->msg3_first_rb = 3;
+      } else {
+        ra->msg3_first_rb = 2;
+      }
+    }
     ra->msg3_nb_rb = 1;
     uint16_t rballoc = mac_computeRIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb);	// first PRB only for UL Grant
     rar[1] |= (rballoc >> 7) & 7;	// Hopping = 0 (bit 3), 3 MSBs of rballoc
@@ -80,6 +89,7 @@ fill_rar(const module_id_t module_idP,
     ra->msg3_TPC = 3;
     ra->msg3_ULdelay = 0;
     ra->msg3_cqireq = 0;
+    ra->msg3_round = 0;
     rar[2] |= ((ra->msg3_mcs & 0x8) >> 3);	// mcs 10
     rar[3] =
 	(((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) |
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index 948f6c08d0032c6a105a2d6850aa01431e390db2..4948562e0ff38cd3386ee56ede6395c61f81ef27 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -1853,7 +1853,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP,
 							 lcid,
 							 buflen_remain,
 							 (char *)&ulsch_buff[sdu_length_total]
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 							 ,0,
                               0
 #endif
@@ -2840,7 +2840,7 @@ update_bsr(module_id_t module_idP, frame_t frameP,
 		    rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO,
 		                                    lcid,
 		                                    0xFFFF //TBS is not used in RLC at this step, set a special value for debug
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                           ,0, 0
 #endif
                                           );
@@ -3291,7 +3291,7 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_
                ue->slsch_lcid,
                req,
                (char*)(ue->slsch_pdu.payload + sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG))
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,ue->sourceL2Id,
                ue->destinationL2Id
 #endif
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index c77f33e308d4d7b03b3b19df4ea6177ccd170909..ccee62df97fd7fc7e49ebcec0dc936826c111a23 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -83,7 +83,7 @@ boolean_t pdcp_data_req(
   const sdu_size_t     sdu_buffer_sizeP,
   unsigned char *const sdu_buffer_pP,
   const pdcp_transmission_mode_t modeP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     ,const uint32_t * const sourceL2Id
     ,const uint32_t * const destinationL2Id
 #endif
@@ -170,7 +170,7 @@ boolean_t pdcp_data_req(
                                 sdu_buffer_sizeP);
 #endif
       rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                 ,NULL, NULL
 #endif
                                 );
@@ -360,7 +360,7 @@ boolean_t pdcp_data_req(
     LOG_F(PDCP,"\n");
 #endif
     rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                              ,sourceL2Id
                              ,destinationL2Id
 #endif
@@ -982,7 +982,7 @@ pdcp_run (
                                 RRC_DCCH_DATA_REQ (msg_p).sdu_size,
                                 RRC_DCCH_DATA_REQ (msg_p).sdu_p,
                                 RRC_DCCH_DATA_REQ (msg_p).mode
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                 , NULL, NULL
 #endif
                                 );
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
index 6fd0621644423cd7d054f133339bfd1398bb1175..7e26ceda5255c38b1ab264d6ab94c2c7f899e830 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
@@ -260,7 +260,7 @@ public_pdcp(boolean_t pdcp_data_req(
               const sdu_size_t sdu_buffer_size,
               unsigned char* const sdu_buffer,
               const pdcp_transmission_mode_t mode
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
               ,const uint32_t * const sourceL2Id
               ,const uint32_t * const destinationL2Id
 #endif
@@ -437,7 +437,7 @@ typedef struct pdcp_data_req_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   traffic_type;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   uint32_t sourceL2Id;
   uint32_t destinationL2Id;
 #endif
@@ -448,7 +448,7 @@ typedef struct pdcp_data_ind_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   dummy_traffic_type;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   uint32_t sourceL2Id;
   uint32_t destinationL2Id;
 #endif
@@ -462,7 +462,7 @@ struct pdcp_netlink_element_s {
 };
 
 //TTN for D2D (PC5S)
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 #define PDCP_SOCKET_PORT_NO 9999 //temporary value
 #define PC5_SIGNALLING_PAYLOAD_SIZE   100  //should be updated with a correct value
 int pdcp_pc5_sockfd;
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c
index abec97ddfd4c0c8a6aea1cede86a7dc19c170837..0ef6893d084a4c366fba14276dd5655fd46d40c6 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_control_primitive.c
@@ -45,6 +45,7 @@ configure_pdcp_req (struct pdcp_entity *pdcpP, void *rlcP, uint8_t rlc_sap_typeP
   mem_block      *mb;
 
   mb = get_free_mem_block (sizeof (struct cpdcp_primitive), __func__);
+  if(mb==NULL) return;
   ((struct cpdcp_primitive *) mb->data)->type = CPDCP_CONFIG_REQ;
   ((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_sap = rlcP;
   ((struct cpdcp_primitive *) mb->data)->primitive.config_req.rlc_type_sap = rlc_sap_typeP;
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index be3d4fd4344bdfe32c17871a3e4e5fb9fb04ae27..5b89e8cddeb12dc9358dabbc4a630dd926243df2 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -202,7 +202,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const  ctxt_pP)
       cont = 0;
 
 //TTN - for D2D (PC5S)
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
       sidelink_pc5s_element *sl_pc5s_msg_recv = NULL;
       char send_buf[BUFSIZE];
       int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
@@ -452,7 +452,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
       pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED,
                     RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf,
                     PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                     , NULL, NULL
 #endif
                    );
@@ -488,7 +488,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
    pdcp_t*                        pdcp_p    = NULL;
 
 //TTN for D2D (PC5S)
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
    int prose_addr_len;
    char send_buf[BUFSIZE], receive_buf[BUFSIZE];
    // Panos: Remove the following definitions due to warnings of unused variables.
@@ -568,7 +568,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                data_p->pdcp_read_header.data_size,
                data_p->data,
                pdcp_mode
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,NULL, NULL
 #endif
                );
@@ -596,7 +596,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                      data_p->pdcp_read_header.data_size,
                      data_p->data,
                      PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                      ,NULL, NULL
 #endif
                      );
@@ -613,7 +613,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                data_p->pdcp_read_header.data_size,
                data_p->data,
                PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,NULL, NULL
 #endif
                );
@@ -633,7 +633,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
 
 
 //TTN for D2D (PC5S)
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
    prose_addr_len = sizeof(prose_pdcp_addr);
    // receive a message from ProSe App
    memset(receive_buf, 0, BUFSIZE);
@@ -775,7 +775,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                         pc5s_header->data_size,
                         (unsigned char *)receive_buf,
                         PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                         ,&pc5s_header->sourceL2Id
                         ,&pc5s_header->destinationL2Id
 #endif
@@ -833,7 +833,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                      pc5s_header->data_size,
                      (unsigned char *)receive_buf,
                      PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                      ,&pc5s_header->sourceL2Id
                      ,&pc5s_header->destinationL2Id
 #endif
@@ -980,7 +980,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                               pdcp_read_header_g.data_size,
                               (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                               PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                               ,NULL, NULL
 #endif
                               );
@@ -1017,7 +1017,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                                  pdcp_read_header_g.data_size,
                                  (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                                  PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                 ,NULL, NULL
 #endif
                                 );
@@ -1083,7 +1083,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                               pdcp_read_header_g.data_size,
                               (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                               PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                               ,&pdcp_read_header_g.sourceL2Id
                               ,&pdcp_read_header_g.destinationL2Id
 #endif
@@ -1141,7 +1141,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
                            pdcp_read_header_g.data_size,
                            (unsigned char *)NLMSG_DATA(nas_nlh_rx),
                            PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                            ,&pdcp_read_header_g.sourceL2Id
                            ,&pdcp_read_header_g.destinationL2Id
 #endif
@@ -1189,7 +1189,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const  ctxt_pP)
 }
 
 //TTN for D2D (PC5S)
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 
 void
 pdcp_pc5_socket_init() {
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h
index a939543432674fabc3568ce499ec32095656c675..291ec5e2a728a8f2cb421f0acb52cd3096b9ba84 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h
@@ -53,7 +53,7 @@ extern int  reception_from_rohc_bs(void);
 extern BOOL     pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t * sduP, uint8_t is_data_plane);
 extern BOOL     pdcp_data_req (module_id_t module_id, uint32_t frame, uint8_t eNB_flag, rb_id_t rab_id, uint32_t muiP, uint32_t confirmP, sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer,
                                uint8_t is_data_pdu
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                ,const uint32_t * const sourceL2Id
                                ,const uint32_t * const destinationL2Id
 #endif
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
index 0e9452cf210f3582e2362832080b19dfa1aa1721..7af03529645a1415d76c934919020bc8800ac4c1 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c
@@ -509,6 +509,7 @@ rlc_am_rx (
 
   default:
     LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" TX UNKNOWN PROTOCOL STATE 0x%02X\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP, rlc), rlc->protocol_state);
+    list_free (&data_indP.data);
   }
 }
 
@@ -551,7 +552,9 @@ rlc_am_mac_status_indication (
 
   rlc->last_absolute_subframe_status_indication = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP);
 
-  rlc->nb_bytes_requested_by_mac = tb_sizeP;
+  if (tb_sizeP > 0) {
+    rlc->nb_bytes_requested_by_mac = tb_sizeP;
+  }
 
   status_resp.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes(ctxt_pP, rlc);
 
@@ -585,7 +588,6 @@ rlc_am_mac_status_indication (
 
     sdu_size            = ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_size;
     sdu_remaining_size  = ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_remaining_size;
-
     status_resp.head_sdu_remaining_size_to_send = sdu_remaining_size;
 
     if (sdu_size == sdu_remaining_size)  {
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c
index 996dd96f353f17bf4e11d0f810eef14ce0472930..3159eccc0cdbc960232a656d4dd889847dc7fd9d 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c
@@ -42,8 +42,17 @@ void rlc_am_free_in_sdu(
 {
   if (index_in_bufferP <= RLC_AM_SDU_CONTROL_BUFFER_SIZE) {
 	/* BugFix:  SDU shall have been already freed during initial PDU segmentation or concatenation !! */
+//Assertion(eNB)_PRAN_DesignDocument_annex No.761
+    if(rlcP->input_sdus[index_in_bufferP].mem_block != NULL)
+    {
+      LOG_E(RLC, "RLC AM Tx SDU Conf: Data Part is not empty index=%d LcId=%d\n",
+             index_in_bufferP,rlcP->channel_id);
+      return;
+    }
+/*
 	  AssertFatal(rlcP->input_sdus[index_in_bufferP].mem_block == NULL, "RLC AM Tx SDU Conf: Data Part is not empty index=%d LcId=%d\n",
 				index_in_bufferP,rlcP->channel_id);
+*/
 	/*
     if (rlcP->input_sdus[index_in_bufferP].mem_block != NULL) {
       free_mem_block(rlcP->input_sdus[index_in_bufferP].mem_block, __func__);
@@ -121,8 +130,13 @@ rlc_am_pdu_sdu_data_cnf(
 
       for (pdu_sdu_index = 0; pdu_sdu_index < rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].nb_sdus; pdu_sdu_index++) {
         sdu_index = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].sdus_index[pdu_sdu_index];
-        assert(sdu_index >= 0);
-        assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE);
+        //assert(sdu_index >= 0);
+        //assert(sdu_index < RLC_AM_SDU_CONTROL_BUFFER_SIZE);
+        if(sdu_index < 0 || sdu_index >= RLC_AM_SDU_CONTROL_BUFFER_SIZE) {
+          LOG_E(RLC, "sdu_index error. sdu_index %d, pdu_sdu_index %d\n", sdu_index, pdu_sdu_index);
+          continue;
+        }
+        
         rlc_pP->input_sdus[sdu_index].nb_pdus_ack += 1;
 
         if ((rlc_pP->input_sdus[sdu_index].nb_pdus_ack == rlc_pP->input_sdus[sdu_index].nb_pdus) &&
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c
index 83b0dfd46b86b583eedf242c09fe8671818610ce..8b5776dfe7ebd89aaff51385f6442e65e86432d2 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c
@@ -57,7 +57,12 @@ rlc_am_reassembly (
   if (rlc_pP->output_sdu_in_construction == NULL) {
     rlc_pP->output_sdu_in_construction = get_free_mem_block (RLC_SDU_MAX_SIZE, __func__);
     rlc_pP->output_sdu_size_to_write = 0;
-    assert(rlc_pP->output_sdu_in_construction != NULL);
+    //assert(rlc_pP->output_sdu_in_construction != NULL);
+    if(rlc_pP->output_sdu_in_construction == NULL) {
+      LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PAYLOAD] output_sdu_in_construction is NULL\n",
+            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
+      return;
+    }
   }
 
   if (rlc_pP->output_sdu_in_construction != NULL) {
@@ -198,10 +203,16 @@ rlc_am_send_sdu (
             PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
       //msg("[RLC_AM][MOD %d] Freeing mem_block ...\n", rlc_pP->module_id);
       //free_mem_block (rlc_pP->output_sdu_in_construction, __func__);
+//Assertion(eNB)_PRAN_DesignDocument_annex No.764
+     LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" SEND SDU REQUESTED %d bytes\n",
+             PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
+             rlc_pP->output_sdu_size_to_write);
+/*
       AssertFatal(3==4,
                   PROTOCOL_RLC_AM_CTXT_FMT" SEND SDU REQUESTED %d bytes",
                   PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
                   rlc_pP->output_sdu_size_to_write);
+*/
     }
 
     rlc_pP->output_sdu_size_to_write = 0;
@@ -270,7 +281,9 @@ rlc_am_reassemble_pdu(
       break;
 
     default:
-      assert(0 != 0);
+//Assertion(eNB)_PRAN_DesignDocument_annex No.1428
+      LOG_E(RLC, "RLC_E_FIXED_PART_DATA_FIELD_FOLLOW error pdu_info->fi[%d]\n", pdu_info->fi);
+//      assert(0 != 0);
     }
   } else {
     switch (pdu_info->fi) {
@@ -386,7 +399,9 @@ rlc_am_reassemble_pdu(
       break;
 
     default:
-      assert(1 != 1);
+//Assertion(eNB)_PRAN_DesignDocument_annex No.1429
+      LOG_E(RLC, "not RLC_E_FIXED_PART_DATA_FIELD_FOLLOW error pdu_info->fi[%d]\n", pdu_info->fi);
+//      assert(1 != 1);
     }
   }
 
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
index be4b43d1a075db6c89e0dc0dd8b2539fbaae2ba6..83dec8653a65cb9ec08da12ae966c383e28d9854 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c
@@ -47,9 +47,15 @@ rlc_am_get_data_pdu_infos(
     pdu_info_pP->d_c = header_pP->b1 >> 7;
     pdu_info_pP->num_li = 0;
 
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.766
+  if(pdu_info_pP->d_c == 0)
+  {
+     LOG_E(RLC, "RLC AM Rx PDU Data D/C Header Error LcId=%d\n", rlc_pP->channel_id);
+     return -2;
+  }
+/*
     AssertFatal (pdu_info_pP->d_c != 0, "RLC AM Rx PDU Data D/C Header Error LcId=%d\n", rlc_pP->channel_id);
-
+*/
     pdu_info_pP->rf  = (header_pP->b1 >> 6) & 0x01;
     pdu_info_pP->p   = (header_pP->b1 >> 5) & 0x01;
     pdu_info_pP->fi  = (header_pP->b1 >> 3) & 0x03;
@@ -264,9 +270,17 @@ rlc_am_receive_routing (
         rlc_pP->stat_rx_control_pdu += 1;
         rlc_am_receive_process_control_pdu (ctxt_pP, rlc_pP, tb_p, &first_byte_p, &tb_size_in_bytes);
         // Test if remaining bytes not processed (up to know, highest probability is bug in MAC)
+//Assertion(eNB)_PRAN_DesignDocument_annex No.767
+  if(tb_size_in_bytes != 0)
+  {
+     LOG_E(RLC, "Remaining %d bytes following a control PDU\n",
+             tb_size_in_bytes);
+  }
+/*
         AssertFatal( tb_size_in_bytes == 0,
                      "Remaining %d bytes following a control PDU",
                      tb_size_in_bytes);
+*/
       }
 
       LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RX ROUTING] VR(R)=%03d VR(MR)=%03d\n",
@@ -396,14 +410,20 @@ rlc_am_receive_process_data_pdu (
         }
 
         if (pdu_info_p->sn == rlc_pP->vr_r) {
+mem_block_t*       cursor_p                    = rlc_pP->receiver_buffer.head;
+rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data);
+if( (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received) == (pdu_cursor_mgnt_p->all_segments_received)){
           if (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received) {
             rlc_am_rx_update_vr_r(ctxt_pP, rlc_pP, tb_pP);
             rlc_pP->vr_mr = (rlc_pP->vr_r + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK;
           }
-
           reassemble = rlc_am_rx_check_vr_reassemble(ctxt_pP, rlc_pP);
           //TODO : optimization : check whether a reassembly is needed by looking at LI, FI, SO, etc...
-
+}else{
+  LOG_E(RLC, "BAD all_segments_received!!! discard buffer!!!\n");
+  /* Discard received block if out of window, duplicate or header error */
+  free_mem_block (tb_pP, __func__);
+}
         }
 
         //FNA: fix check VrX out of receiving window
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 42e84986238fd9d669e06061222a6492eb74a674..827bf1b627d8c5eacbd16c22d6862a025bd7a063 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
@@ -60,10 +60,14 @@ boolean_t rlc_am_nack_pdu (
   sdu_size_t pdu_data_to_retx = 0;
 
   if (mb_p != NULL) {
-    assert(so_startP <= so_endP);
-
+    //assert(so_startP <= so_endP);
+    if(so_startP > so_endP) {
+      LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU, so_startP %d, so_endP %d\n",
+            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_startP, so_endP);
+      status = FALSE;
+    }
     // Handle full PDU NACK first
-    if ((so_startP == 0) && (so_endP == 0x7FFF)) {
+    else if ((so_startP == 0) && (so_endP == 0x7FFF)) {
     	if ((prev_nack_snP != snP) && (tx_data_pdu_buffer_p->flags.ack == 0) && (tx_data_pdu_buffer_p->flags.max_retransmit == 0)) {
     		pdu_data_to_retx = tx_data_pdu_buffer_p->payload_size;
             /* Increment VtReTxNext if this is the first NACK or if some segments have already been transmitted */
@@ -82,12 +86,17 @@ boolean_t rlc_am_nack_pdu (
                   snP,
                   so_stopP);
         #endif
-            assert(tx_data_pdu_buffer_p->nack_so_start < tx_data_pdu_buffer_p->payload_size);
+            //assert(tx_data_pdu_buffer_p->nack_so_start < tx_data_pdu_buffer_p->payload_size);
+    	      if(tx_data_pdu_buffer_p->nack_so_start >= tx_data_pdu_buffer_p->payload_size){
+              LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU, nack_so_start %d, payload_size %d\n",
+                    PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),tx_data_pdu_buffer_p->nack_so_start, tx_data_pdu_buffer_p->payload_size);
+    	        status = FALSE;
+    	      }
     	}
     	else {
     		status = FALSE;
     	}
-      }
+    }
     else if (tx_data_pdu_buffer_p->flags.max_retransmit == 0) {
     	// Handle Segment offset
 		if (so_endP == 0x7FFF) {
@@ -225,9 +234,18 @@ void rlc_am_ack_pdu (
     }
 
     if (tx_data_pdu_buffer->retx_payload_size) {
+//Assertion(eNB)_PRAN_DesignDocument_annex No.768
+      if(tx_data_pdu_buffer->flags.ack != 0)
+      {
+        LOG_E(RLC, "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);
+         return;
+      }
+/*
     	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;
@@ -256,15 +274,23 @@ mem_block_t* rlc_am_retransmit_get_copy (
   const rlc_sn_t snP)
 {
   mem_block_t* mb_original_p = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block;
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.784
+  if(mb_original_p == NULL)
+  {
+     LOG_E(RLC,"RLC AM PDU Copy Error: Empty block sn=%d vtA=%d vtS=%d LcId=%d !\n",
+           snP,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+     return NULL;
+  }
+/*
   AssertFatal (mb_original_p != NULL, "RLC AM PDU Copy Error: Empty block sn=%d vtA=%d vtS=%d LcId=%d !\n",
 		  snP,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
-
+*/
   rlc_am_tx_data_pdu_management_t *pdu_mngt = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE];
 
   /* We need to allocate a new buffer and copy to it because header content may change for Polling bit */
   int size             = pdu_mngt->header_and_payload_size + sizeof(struct mac_tb_req);
   mem_block_t* mb_copy = get_free_mem_block(size, __func__);
+  if(mb_copy == NULL) return NULL;
   memcpy(mb_copy->data, mb_original_p->data, size);
 
   rlc_am_pdu_sn_10_t *pdu_p                         = (rlc_am_pdu_sn_10_t*) (&mb_copy->data[sizeof(struct mac_tb_req)]);
@@ -295,20 +321,43 @@ mem_block_t* rlc_am_retransmit_get_am_segment(
 	uint8_t li_bit_offset = 4; /* toggle between 0 and 4 */
 	uint8_t li_jump_offset = 1; /* toggle between 1 and 2 */
 
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.774
+    if(mb_original_p == NULL)
+    {
+      LOG_E(RLC,"RLC AM PDU Segment Error: Empty block sn=%d vtA=%d vtS=%d LcId=%d !\n",
+            sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+      return NULL;
+    }
+/*
 	AssertFatal (mb_original_p != NULL, "RLC AM PDU Segment Error: Empty block sn=%d vtA=%d vtS=%d LcId=%d !\n",
 			sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
-
-
+*/
+//Assertion(eNB)_PRAN_DesignDocument_annex No.775
+  if(pdu_mngt->payload != mb_original_p->data + sizeof(struct mac_tb_req) + pdu_mngt->header_and_payload_size - pdu_mngt->payload_size)
+  {
+     LOG_E(RLC,"RLC AM PDU Segment Error: Inconsistent data pointers p1=%p p2=%p sn = %d total size = %d data size = %d LcId=%d !\n",
+           pdu_mngt->payload,mb_original_p->data + sizeof(struct mac_tb_req),pdu_mngt->header_and_payload_size,pdu_mngt->payload_size,sn,rlc_pP->channel_id);
+     return NULL;
+  }
+/*
 	AssertFatal (pdu_mngt->payload == mb_original_p->data + sizeof(struct mac_tb_req) + pdu_mngt->header_and_payload_size - pdu_mngt->payload_size,
 			"RLC AM PDU Segment Error: Inconsistent data pointers p1=%p p2=%p sn = %d total size = %d data size = %d LcId=%d !\n",
 			pdu_mngt->payload,mb_original_p->data + sizeof(struct mac_tb_req),pdu_mngt->header_and_payload_size,pdu_mngt->payload_size,sn,rlc_pP->channel_id);
-
+*/
 	/* Init ReTx Hole list if not configured, ie the whole PDU has to be retransmitted */
 	if (pdu_mngt->num_holes == 0)
 	{
+//Assertion(eNB)_PRAN_DesignDocument_annex No.776
+  if(pdu_mngt->retx_payload_size != pdu_mngt->payload_size)
+  {
+     LOG_E(RLC,"RLC AM PDU ReTx Segment: Expecting full PDU size ReTxSize=%d DataSize=%d sn=%d vtA=%d vtS=%d LcId=%d !\n",
+            pdu_mngt->retx_payload_size,pdu_mngt->payload_size,sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+     return NULL;
+  }
+/*
 		AssertFatal (pdu_mngt->retx_payload_size == pdu_mngt->payload_size,"RLC AM PDU ReTx Segment: Expecting full PDU size ReTxSize=%d DataSize=%d sn=%d vtA=%d vtS=%d LcId=%d !\n",
 				pdu_mngt->retx_payload_size,pdu_mngt->payload_size,sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+*/
 		pdu_mngt->retx_hole_index = 0;
 		pdu_mngt->hole_so_start[0] = 0;
 		pdu_mngt->hole_so_stop[0] = pdu_mngt->payload_size - 1;
@@ -318,11 +367,18 @@ mem_block_t* rlc_am_retransmit_get_am_segment(
 	/* Init SO Start and SO Stop */
 	retx_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index];
 	retx_so_stop = pdu_mngt->hole_so_stop[pdu_mngt->retx_hole_index];
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.777
+  if((retx_so_start > retx_so_stop) || (retx_so_stop - retx_so_start + 1 > pdu_mngt->payload_size))
+  {
+     LOG_E(RLC,"RLC AM Tx PDU Segment Data SO Error: retx_so_start=%d retx_so_stop=%d OriginalPDUDataLength=%d sn=%d LcId=%d!\n",
+           retx_so_start,retx_so_stop,pdu_mngt->payload_size,sn,rlc_pP->channel_id);
+     return NULL;
+  }
+/*
 	AssertFatal ((retx_so_start <= retx_so_stop) && (retx_so_stop - retx_so_start + 1 <= pdu_mngt->payload_size),
 			"RLC AM Tx PDU Segment Data SO Error: retx_so_start=%d retx_so_stop=%d OriginalPDUDataLength=%d sn=%d LcId=%d!\n",
 			retx_so_start,retx_so_stop,pdu_mngt->payload_size,sn,rlc_pP->channel_id);
-
+*/
 	/* Init FI to the same value as original PDU */
 	fi_start = (!(RLC_AM_PDU_GET_FI_START(*(pdu_mngt->first_byte))));
 	fi_end = (!(RLC_AM_PDU_GET_FI_END(*(pdu_mngt->first_byte))));
@@ -339,6 +395,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment(
 		*payload_sizeP = retx_so_stop - retx_so_start + 1;
 
 		mem_pdu_segment_p = get_free_mem_block((*payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + sizeof(struct mac_tb_req)), __func__);
+		if(mem_pdu_segment_p == NULL) return NULL;
 		pdu_segment_header_p        = (uint8_t *)&mem_pdu_segment_p->data[sizeof(struct mac_tb_req)];
 		((struct mac_tb_req*)(mem_pdu_segment_p->data))->data_ptr = pdu_segment_header_p;
 		((struct mac_tb_req*)(mem_pdu_segment_p->data))->tb_size = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE + *payload_sizeP;
@@ -408,8 +465,17 @@ mem_block_t* rlc_am_retransmit_get_am_segment(
 			/* Set FI Start if retx_so_start = cumulated data size */
 			fi_start = TRUE;
 			/* there must be at least one SDU more */
+//Assertion(eNB)_PRAN_DesignDocument_annex No.778
+            if(sdu_index >= pdu_mngt->nb_sdus)
+            {
+               LOG_E(RLC,"RLC AM Tx PDU Segment Error: sdu_index=%d nb_sdus=%d sn=%d LcId=%d !\n",
+                    sdu_index,pdu_mngt->nb_sdus,sn,rlc_pP->channel_id);
+               return NULL;
+            }
+/*
 			AssertFatal (sdu_index < pdu_mngt->nb_sdus, "RLC AM Tx PDU Segment Error: sdu_index=%d nb_sdus=%d sn=%d LcId=%d !\n",
 					sdu_index,pdu_mngt->nb_sdus,sn,rlc_pP->channel_id);
+*/
 			if (sdu_index < pdu_mngt->nb_sdus - 1)
 			{
 				temp_read = ((*pdu_original_header_p) << 8) | (*(pdu_original_header_p + 1));
@@ -487,17 +553,33 @@ mem_block_t* rlc_am_retransmit_get_am_segment(
 
 			/* Set number of LIs in the segment */
 			num_LIs_pdu_segment = sdu_segment_index - 1;
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.779
+            if(num_LIs_pdu_segment >  pdu_mngt->nb_sdus - 1)
+            {
+              LOG_E(RLC, "RLC AM Tx PDU Segment Data Error: nbLISegment=%d nbLIPDU=%d sn=%d LcId=%d !\n",
+                   num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id);
+              return NULL;
+            }
+/*
 			AssertFatal (num_LIs_pdu_segment <=  pdu_mngt->nb_sdus - 1, "RLC AM Tx PDU Segment Data Error: nbLISegment=%d nbLIPDU=%d sn=%d LcId=%d !\n",
 					num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id);
-
+*/
 			/* Bound to available TBS taking into account min PDU segment header*/
 			sdu_segment_index = 0;
 			while ((sdu_segment_index < num_LIs_pdu_segment + 1) && (rlc_pP->nb_bytes_requested_by_mac > *payload_sizeP + RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index)))
 			{
+//Assertion(eNB)_PRAN_DesignDocument_annex No.780
+            if(sdus_segment_size[sdu_segment_index] <= 0)
+            {
+              LOG_E(RLC, "RLC AM Tx PDU Segment Data Error: EMpty LI index=%d numLISegment=%d numLIPDU=%d PDULength=%d SOStart=%d SOStop=%d sn=%d LcId=%d !\n",
+                   sdu_segment_index,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,pdu_mngt->payload_size,retx_so_start,retx_so_stop,sn,rlc_pP->channel_id);
+              sdu_segment_index++;
+              continue;
+            }
+/*
 				AssertFatal (sdus_segment_size[sdu_segment_index] > 0, "RLC AM Tx PDU Segment Data Error: EMpty LI index=%d numLISegment=%d numLIPDU=%d PDULength=%d SOStart=%d SOStop=%d sn=%d LcId=%d !\n",
 						sdu_segment_index,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,pdu_mngt->payload_size,retx_so_start,retx_so_stop,sn,rlc_pP->channel_id);
-
+*/
 				/* Add next sdu_segment_index to data part */
 				if (RLC_AM_PDU_SEGMENT_HEADER_SIZE(sdu_segment_index) + (*payload_sizeP) + sdus_segment_size[sdu_segment_index] <= rlc_pP->nb_bytes_requested_by_mac)
 				{
@@ -519,11 +601,18 @@ mem_block_t* rlc_am_retransmit_get_am_segment(
 
 		/* update retx_so_stop */
 		retx_so_stop = retx_so_start + (*payload_sizeP) - 1;
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.781
+        if((retx_so_stop > pdu_mngt->payload_size - 1) || (retx_so_stop - retx_so_start + 1 >= pdu_mngt->payload_size))
+        {
+           LOG_E(RLC,"RLC AM Tx PDU Segment Data Error: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d numLISegment=%d numLIPDU=%d sn=%d LcId=%d !\n",
+                retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id);
+           return NULL;
+         }
+/*
 		AssertFatal ((retx_so_stop <= pdu_mngt->payload_size - 1) && (retx_so_stop - retx_so_start + 1 < pdu_mngt->payload_size),
 				"RLC AM Tx PDU Segment Data Error: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d numLISegment=%d numLIPDU=%d sn=%d LcId=%d !\n",
 				retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id);
-
+*/
 		/* init FI End to FALSE if retx_so_stop is not end of PDU */
 		if (retx_so_stop != pdu_mngt->payload_size - 1)
 		{
@@ -541,16 +630,33 @@ mem_block_t* rlc_am_retransmit_get_am_segment(
 				fi_end = TRUE;
 			}
 		}
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.782
+         if(data_size != *payload_sizeP)
+         {
+            LOG_E(RLC,"RLC AM Tx PDU Segment Data Error: SduSum=%d Data=%d sn=%d LcId=%d !\n",
+                  data_size,*payload_sizeP,sn,rlc_pP->channel_id);
+            return NULL;
+         }
+/*
 		AssertFatal (data_size == *payload_sizeP, "RLC AM Tx PDU Segment Data Error: SduSum=%d Data=%d sn=%d LcId=%d !\n",
 				data_size,*payload_sizeP,sn,rlc_pP->channel_id);
-
+*/
 
 
 		/* Allocation */
+//Assertion(eNB)_PRAN_DesignDocument_annex No.783
+       if(header_segment_length + *payload_sizeP > pdu_mngt->header_and_payload_size + 2)
+        {
+           LOG_E(RLC, "RLC AM PDU Segment Error: Hdr=%d Data=%d Original Hdr+Data =%d sn=%d LcId=%d !\n",
+                 header_segment_length,*payload_sizeP,pdu_mngt->header_and_payload_size,sn,rlc_pP->channel_id);
+           return NULL;
+        }
+/*
 		AssertFatal (header_segment_length + *payload_sizeP <= pdu_mngt->header_and_payload_size + 2, "RLC AM PDU Segment Error: Hdr=%d Data=%d Original Hdr+Data =%d sn=%d LcId=%d !\n",
 				header_segment_length,*payload_sizeP,pdu_mngt->header_and_payload_size,sn,rlc_pP->channel_id);
+*/
 		mem_pdu_segment_p = get_free_mem_block((*payload_sizeP + header_segment_length + sizeof(struct mac_tb_req)), __func__);
+		if(mem_pdu_segment_p == NULL) return NULL;
 		pdu_segment_header_p        = (uint8_t *)&mem_pdu_segment_p->data[sizeof(struct mac_tb_req)];
 		((struct mac_tb_req*)(mem_pdu_segment_p->data))->data_ptr = pdu_segment_header_p;
 		((struct mac_tb_req*)(mem_pdu_segment_p->data))->tb_size = header_segment_length + *payload_sizeP;
@@ -718,6 +824,7 @@ mem_block_t* rlc_am_retransmit_get_subsegment(
 
   if (mb_original_p != NULL) {
     mem_block_t*           mb_sub_segment_p  = get_free_mem_block(*sizeP + sizeof(struct mac_tb_req), __func__);
+    if(mb_sub_segment_p == NULL) return NULL;
     rlc_am_pdu_sn_10_t*    pdu_original_p    = (rlc_am_pdu_sn_10_t*) (&mb_original_p->data[sizeof(struct mac_tb_req)]);
     rlc_am_pdu_sn_10_t*    pdu_sub_segment_p = (rlc_am_pdu_sn_10_t*) (&mb_sub_segment_p->data[sizeof(struct mac_tb_req)]);
     rlc_am_pdu_info_t      pdu_info;
@@ -1170,7 +1277,11 @@ void rlc_am_tx_buffer_display (
         LOG_D(RLC, "SO:%04d->%04d)\t", tx_data_pdu_buffer_p->nack_so_start, tx_data_pdu_buffer_p->nack_so_stop);
       } else {
         for (i=0; i<tx_data_pdu_buffer_p->num_holes; i++) {
-          assert(i < RLC_AM_MAX_HOLES_REPORT_PER_PDU);
+          //assert(i < RLC_AM_MAX_HOLES_REPORT_PER_PDU);
+          if(i >= RLC_AM_MAX_HOLES_REPORT_PER_PDU) {
+            LOG_E(RLC, "num_holes error. %d %d %d\n", tx_data_pdu_buffer_p->num_holes, i, RLC_AM_MAX_HOLES_REPORT_PER_PDU);
+            break;
+          }
           LOG_D(RLC, "SO:%04d->%04d)\t", tx_data_pdu_buffer_p->hole_so_start[i], tx_data_pdu_buffer_p->hole_so_stop[i]);
         }
       }
@@ -1193,22 +1304,50 @@ mem_block_t * rlc_am_get_pdu_to_retransmit(
 	  rlc_sn_t             sn_end      = rlc_pP->vt_s;
 	  mem_block_t*         pdu_p        = NULL;
 	  rlc_am_tx_data_pdu_management_t* tx_data_pdu_management;
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.769
+      if((rlc_pP->retrans_num_pdus <= 0) || (rlc_pP->vt_a ==  rlc_pP->vt_s))
+      {
+         LOG_E(RLC, "RLC AM ReTx start process Error: NbPDUtoRetx=%d vtA=%d vtS=%d  LcId=%d !\n",
+                rlc_pP->retrans_num_pdus,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+         return NULL;
+      }
+/*
 	  AssertFatal ((rlc_pP->retrans_num_pdus > 0) && (rlc_pP->vt_a !=  rlc_pP->vt_s), "RLC AM ReTx start process Error: NbPDUtoRetx=%d vtA=%d vtS=%d  LcId=%d !\n",
 			  rlc_pP->retrans_num_pdus,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
-
+*/
 	  do
 	  {
 		  tx_data_pdu_management = &rlc_pP->tx_data_pdu_buffer[sn % RLC_AM_WINDOW_SIZE];
 		  if ((tx_data_pdu_management->flags.retransmit) && (tx_data_pdu_management->flags.max_retransmit == 0))
 		  {
+//Assertion(eNB)_PRAN_DesignDocument_annex No.770
+            if(tx_data_pdu_management->sn != sn)
+            {
+               LOG_E(RLC, "RLC AM ReTx PDU Error: SN Error pdu_sn=%d sn=%d vtA=%d vtS=%d LcId=%d !\n",
+                     tx_data_pdu_management->sn,sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+            }
+//Assertion(eNB)_PRAN_DesignDocument_annex No.771
+            else if(tx_data_pdu_management->flags.transmitted != 1)
+            {
+               LOG_E(RLC, "RLC AM ReTx PDU Error: State Error sn=%d vtA=%d vtS=%d LcId=%d !\n",
+                     sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+            }
+//Assertion(eNB)_PRAN_DesignDocument_annex No.772
+            else if(tx_data_pdu_management->retx_payload_size <= 0)
+            {
+               LOG_E(RLC, "RLC AM ReTx PDU Error: No Data to Retx sn=%d vtA=%d vtS=%d LcId=%d !\n",
+                     sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
+            }
+            else
+            {
+/*
 			  AssertFatal (tx_data_pdu_management->sn == sn, "RLC AM ReTx PDU Error: SN Error pdu_sn=%d sn=%d vtA=%d vtS=%d LcId=%d !\n",
 					  tx_data_pdu_management->sn,sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
 			  AssertFatal (tx_data_pdu_management->flags.transmitted == 1, "RLC AM ReTx PDU Error: State Error sn=%d vtA=%d vtS=%d LcId=%d !\n",
 			  					  sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
 			  AssertFatal (tx_data_pdu_management->retx_payload_size > 0, "RLC AM ReTx PDU Error: No Data to Retx sn=%d vtA=%d vtS=%d LcId=%d !\n",
 					  sn,rlc_pP->vt_a,rlc_pP->vt_s,rlc_pP->channel_id);
-
+*/
 			  /* Either the whole RLC PDU is to be transmitted and there is enough MAC TBS or there is minimum TBS size for transmitting 1 AM PDU segment */
 			  if ((tx_data_pdu_management->retx_payload_size == tx_data_pdu_management->payload_size) && (rlc_pP->nb_bytes_requested_by_mac >= tx_data_pdu_management->header_and_payload_size))
 			  {
@@ -1256,9 +1395,18 @@ mem_block_t * rlc_am_get_pdu_to_retransmit(
 
 					  if (pdu_p != NULL)
 					  {
+//Assertion(eNB)_PRAN_DesignDocument_annex No.773
+                        if((tx_data_pdu_management->retx_payload_size < pdu_data_size)|| (rlc_pP->retrans_num_bytes_to_retransmit < pdu_data_size))
+                        {
+                           LOG_E(RLC, "RLC AM ReTx PDU Segment Error: DataSize=%d PDUReTxsize=%d TotalReTxsize=%d sn=%d LcId=%d !\n",
+                                pdu_data_size,tx_data_pdu_management->retx_payload_size,rlc_pP->retrans_num_bytes_to_retransmit,sn,rlc_pP->channel_id);
+                         }
+                         else
+                         {
+/*
 						  AssertFatal ((tx_data_pdu_management->retx_payload_size >= pdu_data_size) && (rlc_pP->retrans_num_bytes_to_retransmit >= pdu_data_size), "RLC AM ReTx PDU Segment Error: DataSize=%d PDUReTxsize=%d TotalReTxsize=%d sn=%d LcId=%d !\n",
 								  pdu_data_size,tx_data_pdu_management->retx_payload_size,rlc_pP->retrans_num_bytes_to_retransmit,sn,rlc_pP->channel_id);
-
+*/
 						  tx_data_pdu_management->retx_payload_size -= pdu_data_size;
 						  rlc_pP->retrans_num_bytes_to_retransmit -= pdu_data_size;
 						  if (tx_data_pdu_management->retx_payload_size == 0)
@@ -1276,6 +1424,7 @@ mem_block_t * rlc_am_get_pdu_to_retransmit(
 				          rlc_pP->stat_tx_retransmit_bytes           += pdu_data_size;
 				          rlc_pP->stat_tx_retransmit_bytes_by_status += pdu_data_size;
 
+                          }//Assertion(eNB)_PRAN_DesignDocument_annex No.773
 					  }
 				  }
 				  else
@@ -1300,8 +1449,8 @@ mem_block_t * rlc_am_get_pdu_to_retransmit(
 				  break;
 			  }
 
+          }//Assertion(eNB)_PRAN_DesignDocument_annex No.770 No.771 No.772
 		  }
-
 		  sn = RLC_AM_NEXT_SN(sn);
 	  } while((sn != sn_end) && (rlc_pP->retrans_num_pdus > 0));
 
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c
index c0ce57708b0cf3033f0ced09a5857f8a54e2268a..301761c9e5c5e3c6e1f43ef2087ce8c3ab706438 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c
@@ -53,8 +53,17 @@ boolean_t rlc_am_rx_check_vr_reassemble(
 			if (pdu_info_p->rf) {
 				pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data);
 				next_waited_so = 0;
+//Assertion(eNB)_PRAN_DesignDocument_annex No.785
+                if(pdu_cursor_mgnt_p->all_segments_received <= 0)
+                {
+                   LOG_E(RLC, "AM Rx Check Reassembly head SN=%d with PDU segments != vrR=%d should be fully received LCID=%d\n",
+                         sn_ref,rlc_pP->vr_r,rlc_pP->channel_id);
+                   return FALSE;
+                }
+/*
 				AssertFatal(pdu_cursor_mgnt_p->all_segments_received > 0,"AM Rx Check Reassembly head SN=%d with PDU segments != vrR=%d should be fully received LCID=%d\n",
 						sn_ref,rlc_pP->vr_r,rlc_pP->channel_id);
+*/
 				while ((cursor_p != NULL) && (pdu_info_p->sn == sn_ref) && (pdu_info_p->so == next_waited_so)) {
 					if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) {
 						pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING;
@@ -80,8 +89,17 @@ boolean_t rlc_am_rx_check_vr_reassemble(
 			if ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r)) {
 				pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data);
 				next_waited_so = 0;
+//Assertion(eNB)_PRAN_DesignDocument_annex No.786
+              if(pdu_cursor_mgnt_p->all_segments_received != 0)
+              {
+                 LOG_E(RLC, "AM Rx Check Reassembly vr=%d should be partly received SNHead=%d LCID=%d\n",
+                       rlc_pP->vr_r,sn_ref,rlc_pP->channel_id);
+                 return FALSE;
+              }
+/*
 				AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly vr=%d should be partly received SNHead=%d LCID=%d\n",
 						rlc_pP->vr_r,sn_ref,rlc_pP->channel_id);
+*/
 				while ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r) && (pdu_info_p->so == next_waited_so)) {
 					if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) {
 						pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING;
@@ -100,8 +118,17 @@ boolean_t rlc_am_rx_check_vr_reassemble(
 
 			pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data);
 			next_waited_so = 0;
+//Assertion(eNB)_PRAN_DesignDocument_annex No.787
+            if(pdu_cursor_mgnt_p->all_segments_received != 0)
+            {
+               LOG_E(RLC, "AM Rx Check Reassembly SNHead=vr=%d should be partly received LCID=%d\n",
+                     rlc_pP->vr_r,rlc_pP->channel_id);
+               return FALSE;
+            }
+/*
 			AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly SNHead=vr=%d should be partly received LCID=%d\n",
 					rlc_pP->vr_r,rlc_pP->channel_id);
+*/
 			while ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r) && (pdu_info_p->so == next_waited_so)) {
 				if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) {
 					pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING;
@@ -333,8 +360,15 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
 	  /*****************************************************/
 	  // 1) Find previous cursor to the PDU to insert
 	  /*****************************************************/
+//Assertion(eNB)_PRAN_DesignDocument_annex No.791
+      if(cursor_p == NULL)
+      {
+        LOG_E(RLC, "AM Rx PDU Error, received buffer empty LcID=%d\n",rlc_pP->channel_id);
+        return RLC_AM_DATA_PDU_STATUS_HEADER_ERROR;
+      }
+/*
 	  AssertFatal(cursor_p != NULL,"AM Rx PDU Error, received buffer empty LcID=%d\n",rlc_pP->channel_id);
-
+*/
 	  do {
 		  pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
 
@@ -483,11 +517,20 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
 			  }
 		  }
 
+//Assertion(eNB)_PRAN_DesignDocument_annex No.792
+          if((so_start_segment > so_end_segment) || (pdu_rx_info_p->so > so_start_segment) ||
+		     (so_end_segment > pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1))
+          {
+            LOG_E(RLC, " AM RX PDU Segment Duplicate elimination error FirstSO=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n",
+			      pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn);
+            return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE;
+          }
+/*
 		  AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) &&
 				  (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1),
 				  " AM RX PDU Segment Duplicate elimination error FirstSO=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n",
 				  pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn);
-
+*/
 	  } // end pdu_info_cursor_p->so == 0
 	  else {
 		  // Handle most likely case : PDU Segment without duplicate is inserted before first stored PDU segment
@@ -527,12 +570,20 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
 					  so_end_segment = pdu_info_cursor_p->so - 1;
 				  }
 			  }
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.793
+              if((so_start_segment > so_end_segment) ||
+                 (so_end_segment > pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1))
+              {
+                 LOG_E(RLC, " AM RX PDU Segment Duplicate elimination at the end error FirstSO!=0 SOStart=%d OldSOEnd=%d newSOEnd =%d SN=%d\n",
+                       pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_end_segment,pdu_rx_info_p->sn);
+                 return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE;
+              }
+/*
 			  AssertFatal((so_start_segment <= so_end_segment) &&
 					  (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1),
 					  " AM RX PDU Segment Duplicate elimination at the end error FirstSO!=0 SOStart=%d OldSOEnd=%d newSOEnd =%d SN=%d\n",
 					  pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_end_segment,pdu_rx_info_p->sn);
-
+*/
 		  }
 		  else {
 			  // Second Case: Duplicate at the begining and potentially at the end
@@ -618,21 +669,38 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
 					  so_end_segment = pdu_info_cursor_p->so - 1;
 				  }
 			  }
-
+//Assertion(eNB)_PRAN_DesignDocument_annex No.794
+      if((so_start_segment > so_end_segment) || (pdu_rx_info_p->so > so_start_segment) ||
+         (so_end_segment > pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1))
+      {
+         LOG_E(RLC, " AM RX PDU Segment Duplicate elimination error FirstSO!=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n",
+              pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn);
+         return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE;
+      }
+/*
 			  AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) &&
 					  (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1),
 					  " AM RX PDU Segment Duplicate elimination error FirstSO!=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n",
 					  pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn);
+*/
 		  }
 
 	  } // end pdu_info_cursor_p->so != 0
 
 
 	  /* Last step :  duplicate bytes had been removed, build a new PDU segment */
+//Assertion(eNB)_PRAN_DesignDocument_annex No.795
+      if((pdu_rx_info_p->so == so_start_segment) && (so_end_segment == pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1))
+      {
+         LOG_E(RLC, " AM RX PDU Segment Duplicate elimination error FirstSO!=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n",
+              pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn);
+         return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE;
+      }
+/*
 	  AssertFatal((pdu_rx_info_p->so != so_start_segment) || (so_end_segment != pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1),
 			  " AM RX PDU Segment Duplicate elimination error FirstSO!=0 OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n",
 			  pdu_rx_info_p->so,pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1,so_start_segment,so_end_segment,pdu_rx_info_p->sn);
-
+*/
 	  mem_block_t* trunc_segment = create_new_segment_from_pdu(tb_pP,so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1);
 	  if (trunc_segment != NULL) {
 		  LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT]  CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n",
@@ -672,8 +740,15 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu(
 	  /*****************************************************/
 	  // 1) Find previous cursor to the PDU to insert
 	  /*****************************************************/
+//Assertion(eNB)_PRAN_DesignDocument_annex No.788
+      if(cursor_p == NULL)
+      {
+         LOG_E(RLC, "AM Rx PDU Error, received buffer empty LcID=%d\n",rlc_pP->channel_id);
+         return RLC_AM_DATA_PDU_STATUS_HEADER_ERROR;
+      }
+/*
 	  AssertFatal(cursor_p != NULL,"AM Rx PDU Error, received buffer empty LcID=%d\n",rlc_pP->channel_id);
-
+*/
 	  do {
 		  pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
 
@@ -749,9 +824,25 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu(
 	  else {
 		  /* First update cursor until discontinuity */
 		  previous_cursor_p = cursor_p;
+//Assertion(eNB)_PRAN_DesignDocument_annex No.789
+          if(pdu_info_cursor_p->rf == 0)
+          {
+             LOG_E(RLC, "AM Rx PDU Error, stored SN=%d should be a PDU segment\n",pdu_info_cursor_p->sn);
+             return RLC_AM_DATA_PDU_STATUS_HEADER_ERROR;
+          }
+/*
 		  AssertFatal(pdu_info_cursor_p->rf != 0,"AM Rx PDU Error, stored SN=%d should be a PDU segment\n",pdu_info_cursor_p->sn);
+*/
+//Assertion(eNB)_PRAN_DesignDocument_annex No.790
+          if(((rlc_am_rx_pdu_management_t *) (cursor_p->data))->all_segments_received != 0)
+          {
+             LOG_E(RLC, "AM Rx PDU Error, stored SN=%d already fully received\n",pdu_info_cursor_p->sn);
+             return RLC_AM_DATA_PDU_STATUS_SN_DUPLICATE;
+          }
+/*
 		  AssertFatal(((rlc_am_rx_pdu_management_t *) (cursor_p->data))->all_segments_received == 0,
 				  "AM Rx PDU Error, stored SN=%d already fully received\n",pdu_info_cursor_p->sn);
+*/
 		  sdu_size_t          next_waited_so = 0;
 		  while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) && (pdu_info_cursor_p->so == next_waited_so)) {
 			  next_waited_so += pdu_info_cursor_p->payload_size;
@@ -1558,7 +1649,8 @@ list2_insert_before_element (
 
     return element_to_insert_pP;
   } else {
-    assert(2==1);
+    //assert(2==1);
+    LOG_E(RLC, "list2_insert_before_element error. element_to_insert_pP %p, element_pP %p\n", element_to_insert_pP,element_pP);
     return NULL;
   }
 }
@@ -1585,7 +1677,8 @@ list2_insert_after_element (
 
     return element_to_insert_pP;
   } else {
-    assert(2==1);
+    //assert(2==1);
+    LOG_E(RLC, "list2_insert_after_element error. element_to_insert_pP %p, element_pP %p\n", element_to_insert_pP,element_pP);
     return NULL;
   }
 }
@@ -1635,7 +1728,12 @@ rlc_am_rx_list_display (
       //if (cursor_p == cursor_p->next) {
       //    rlc_am_v9_3_0_test_print_trace();
       //}
-      assert(cursor_p != cursor_p->next);
+      //assert(cursor_p != cursor_p->next);
+      if(cursor_p == cursor_p->next)
+      {
+        LOG_E(RLC, "rlc_am_rx_list_display error. cursor_p %p, cursor_p->next %p\n", cursor_p, cursor_p->next);
+        break;
+      }
       cursor_p = cursor_p->next;
       loop++;
     }
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
index fe99e137a43bfc413f31b0e93ce5ebf03906f71d..03dd524a5caa6dbd5731e2d8f12f33135c9b7e9c 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c
@@ -299,7 +299,12 @@ void rlc_am_segment_10 (
 
       pdu_mngt_p->sdus_index[pdu_mngt_p->nb_sdus++] = sdu_buffer_index;
       sdu_mngt_p->pdus_index[sdu_mngt_p->nb_pdus++] = rlc_pP->vt_s % RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE;
-      assert(sdu_mngt_p->nb_pdus < RLC_AM_MAX_SDU_FRAGMENTS);
+      //assert(sdu_mngt_p->nb_pdus < RLC_AM_MAX_SDU_FRAGMENTS);
+      if(sdu_mngt_p->nb_pdus >= RLC_AM_MAX_SDU_FRAGMENTS) {
+        LOG_E(RLC,PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] loop error. %d %d\n",
+          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), sdu_mngt_p->nb_pdus, RLC_AM_MAX_SDU_FRAGMENTS);
+        break;
+      }
       sdu_buffer_index = (sdu_buffer_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
     }
 
@@ -353,6 +358,8 @@ void rlc_am_segment_10 (
               PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
               pdu_remaining_size);
         //msg ("[FRAME %05d][%s][RLC_AM][MOD %u/%u][RB %u][SEGMENT] pdu_mem_p %p pdu_p %p pdu_p->data %p data %p data_sdu_p %p pdu_remaining_size %d\n", rlc_pP->module_id, rlc_pP->rb_id, ctxt_pP->frame, pdu_mem_p, pdu_p, pdu_p->data, data, data_sdu_p,pdu_remaining_size);
+        rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui;
+        rlc_am_mui.rrc_mui_num++;
 
         memcpy(data, data_sdu_p, pdu_remaining_size);
         pdu_mngt_p->payload_size += pdu_remaining_size;
@@ -371,6 +378,9 @@ void rlc_am_segment_10 (
         LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Exactly Filling remaining PDU with %d remaining bytes of SDU\n",
               PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
               pdu_remaining_size);
+        rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui;
+        rlc_am_mui.rrc_mui_num++;
+
         memcpy(data, data_sdu_p, pdu_remaining_size);
         pdu_mngt_p->payload_size += pdu_remaining_size;
 
@@ -387,6 +397,8 @@ void rlc_am_segment_10 (
         continue_fill_pdu_with_sdu = 0;
         pdu_remaining_size = 0;
       } else if ((sdu_mngt_p->sdu_remaining_size + (li_length_in_bytes ^ 3)) < pdu_remaining_size ) {
+        rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui;
+        rlc_am_mui.rrc_mui_num++;
         if (fill_num_li == (RLC_AM_MAX_SDU_IN_PDU - 1)) {
           LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] [SIZE %d] REACHING RLC_AM_MAX_SDU_IN_PDU LIs -> STOP SEGMENTATION FOR THIS PDU SDU\n",
                 PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
@@ -462,11 +474,14 @@ void rlc_am_segment_10 (
           rlc_pP->current_sdu_index = (rlc_pP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
         }
       } else {
-        LOG_T(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Filling  PDU with %d all remaining bytes of SDU and reduce TB size by %d bytes\n",
+        LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] Filling  PDU with %d all remaining bytes of SDU and reduce TB size by %d bytes\n",
               PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
               sdu_mngt_p->sdu_remaining_size,
               pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
-        assert(1!=1);
+        //assert(1!=1);
+        rlc_am_mui.rrc_mui[rlc_am_mui.rrc_mui_num] = sdu_mngt_p->mui;
+        rlc_am_mui.rrc_mui_num++;
+
         memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
         pdu_mngt_p->payload_size += sdu_mngt_p->sdu_remaining_size;
         pdu_remaining_size = pdu_remaining_size - sdu_mngt_p->sdu_remaining_size;
@@ -520,7 +535,11 @@ void rlc_am_segment_10 (
     pdu_tb_req_p->data_ptr        = (unsigned char*)pdu_p;
     pdu_tb_req_p->tb_size         = data_pdu_size - pdu_remaining_size;
 //#warning "why 3000: changed to RLC_SDU_MAX_SIZE "
-    assert(pdu_tb_req_p->tb_size < RLC_SDU_MAX_SIZE );
+    //assert(pdu_tb_req_p->tb_size < RLC_SDU_MAX_SIZE );
+    if(pdu_tb_req_p->tb_size >= RLC_SDU_MAX_SIZE) {
+      LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEGMENT] tb_size error. %d, %d\n",
+            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_tb_req_p->tb_size, RLC_SDU_MAX_SIZE);
+    }
     rlc_am_pdu_polling(ctxt_pP, rlc_pP, pdu_p, pdu_mngt_p->payload_size,true);
 
     //list_add_tail_eurecom (pdu_mem_p, &rlc_pP->segmentation_pdu_list);
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 3ace3cc51f827022f0ee136092d0568c36385229..a9059df11c7b57eb485770497684a020ab58a661 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
@@ -153,7 +153,10 @@ rlc_am_write16_bit_field(
   signed int bits_to_writeP,
   const uint16_t valueP)
 {
-  assert(bits_to_writeP <= 16);
+  //assert(bits_to_writeP <= 16);
+  if(bits_to_writeP > 16) {
+    LOG_E(RLC, "bits_to_writeP error. %d\n", bits_to_writeP);
+  }
 
   if (bits_to_writeP > 8) {
     rlc_am_write8_bit_field(data_ppP,bit_pos_pP,  bits_to_writeP - 8, (uint8_t)(valueP >> 8));
@@ -211,6 +214,9 @@ rlc_am_get_control_pdu_infos(
         if (!pdu_info_pP->nack_list[pdu_info_pP->num_nack - 1].e1) {
           nack_to_read = 0;
           *total_size_pP = *total_size_pP - (sdu_size_t)((uint64_t)byte_pos_p + (uint64_t)((bit_pos + 7)/8) - (uint64_t)header_pP);
+          if (*total_size_pP != 0) {
+            LOG_E(RLC, "[RLC_AM_GET_CONTROL_PDU_INFOS][FIRST]header_pP->b1=%d,header_pP->b2=%d\n",header_pP->b1,header_pP->b2);
+          }
           return 0;
         }
 
@@ -224,7 +230,9 @@ rlc_am_get_control_pdu_infos(
     } else {
       *total_size_pP = *total_size_pP - 2;
     }
-
+    if (*total_size_pP != 0) {
+      LOG_E(RLC, "[RLC_AM_GET_CONTROL_PDU_INFOS][SECOND]header_pP->b1=%d,header_pP->b2=%d\n",header_pP->b1,header_pP->b2);
+    }
     return 0;
   } else {
     return -1;
@@ -308,8 +316,13 @@ rlc_am_receive_process_control_pdu(
     //     POLL_SN:
     //     - if t-PollRetransmit is running:
     //         - stop and reset t-PollRetransmit.
-    assert(ack_sn < RLC_AM_SN_MODULO);
-    assert(rlc_pP->control_pdu_info.num_nack < RLC_AM_MAX_NACK_IN_STATUS_PDU);
+    //assert(ack_sn < RLC_AM_SN_MODULO);
+    //assert(rlc_pP->control_pdu_info.num_nack < RLC_AM_MAX_NACK_IN_STATUS_PDU);
+    if(ack_sn >= RLC_AM_SN_MODULO || rlc_pP->control_pdu_info.num_nack >= RLC_AM_MAX_NACK_IN_STATUS_PDU) {
+      LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" illegal ack_sn %d, num_nack %d\n",
+            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), ack_sn, rlc_pP->control_pdu_info.num_nack);
+      return;
+    }
 
     /* Note : ackSn can be equal to current vtA only in case the status pdu contains a list of nack_sn with same value = vtA with SOStart/SOEnd */
     /* and meaning the report is not complete due to not enough ressources to fill all SOStart/SOEnd of this NACK_SN */
@@ -387,13 +400,15 @@ rlc_am_receive_process_control_pdu(
 
 
     } else {
-      LOG_N(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN %d OUT OF WINDOW vtA=%d vtS=%d\n",
+      LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN %d OUT OF WINDOW vtA=%d vtS=%d\n",
             PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,rlc_pP->vt_a,rlc_pP->vt_s);
+      *tb_size_in_bytes_pP = 0;
       status = FALSE;
     }
   } else {
-    LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT" ERROR IN DECODING CONTROL PDU\n",
+    LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" ERROR IN DECODING CONTROL PDU\n",
           PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
+    *tb_size_in_bytes_pP = 0;
     status = FALSE;
   }
 
@@ -610,10 +625,13 @@ rlc_am_send_status_pdu(
 
       /* Now process all Segments of sn_cursor if PDU not fully received */
       if ((!status_report_completed) && (all_segments_received == 0) && (sn_cursor != rlc_pP->vr_ms)) {
-    	  AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id);
+    	  //AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id);
+      	if(sn_nack != sn_cursor){
+      		LOG_E(RLC, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id);
+      	}
 
     	  /* First ensure there is enough TBS for at least 1 SOStart/SOEnd, else break */
-    	  if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
+        else if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
     		  /* Init loop flags */
               /* Check lsf */
     		  segment_loop_end = (pdu_info_cursor_p->lsf == 1);
@@ -756,8 +774,14 @@ rlc_am_send_status_pdu(
     } // End main while NACK_SN
 
     /* Clear E1 of last nack_sn entry */
-	AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n",
-	        rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id);
+//	AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n",
+//	        rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id);
+  	if (!((control_pdu_info.num_nack) || (all_segments_received == 0))){
+  		LOG_E(RLC, "RLC AM Tx Status PDU Data Error no NACK_SN vrR=%d vrMS=%d lastSN_NACK=%d Completed=%d NbBytesAvailable=%d LcId=%d\n",
+		        rlc_pP->vr_r,rlc_pP->vr_ms,sn_nack,status_report_completed,(nb_bits_to_transmit >> 3),rlc_pP->channel_id);
+  		return;
+  	}
+  	
 	if (control_pdu_info.num_nack) {
 	    control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1  = 0;
 	}
@@ -795,8 +819,13 @@ rlc_am_send_status_pdu(
 
   /* encode the control pdu */
   pdu_size = (nb_bits_transmitted + 7) >> 3;
-  AssertFatal (pdu_size <= rlc_pP->nb_bytes_requested_by_mac, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n",
+//  AssertFatal (pdu_size <= rlc_pP->nb_bytes_requested_by_mac, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n",
+//		  pdu_size,rlc_pP->nb_bytes_requested_by_mac,nb_bits_transmitted, rlc_pP->channel_id);
+	if(pdu_size > rlc_pP->nb_bytes_requested_by_mac){
+		LOG_E(RLC, "RLC AM Tx Status PDU Data size=%d bigger than remaining TBS=%d nb_bits_transmitted=%d LcId=%d\n",
 		  pdu_size,rlc_pP->nb_bytes_requested_by_mac,nb_bits_transmitted, rlc_pP->channel_id);
+		return;
+	}
 
 
 #if TRACE_RLC_AM_STATUS_CREATION
@@ -806,6 +835,7 @@ rlc_am_send_status_pdu(
         pdu_size);
 #endif
   tb_p = get_free_mem_block(sizeof(struct mac_tb_req) + pdu_size, __func__);
+  if(tb_p == NULL) return;
   memset(tb_p->data, 0, sizeof(struct mac_tb_req) + pdu_size);
   //estimation only ((struct mac_tb_req*)(tb_p->data))->tb_size  = pdu_size;
   ((struct mac_tb_req*)(tb_p->data))->data_ptr         = (uint8_t*)&(tb_p->data[sizeof(struct mac_tb_req)]);
@@ -824,8 +854,14 @@ rlc_am_send_status_pdu(
         nb_bits_to_transmit >> 3);
 #endif
 
-  AssertFatal (pdu_size == ((nb_bits_transmitted + 7) >> 3), "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n",
+//  AssertFatal (pdu_size == ((nb_bits_transmitted + 7) >> 3), "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n",
+//  		  pdu_size,((nb_bits_transmitted + 7) >> 3), rlc_pP->channel_id);
+	if(pdu_size != ((nb_bits_transmitted + 7) >> 3)){
+		LOG_E(RLC, "RLC AM Tx Status PDU Data encoding size=%d different than expected=%d LcId=%d\n",
   		  pdu_size,((nb_bits_transmitted + 7) >> 3), rlc_pP->channel_id);
+		pdu_size = 0;
+		return;
+	}
 
   // remaining bytes to transmit for RLC (retrans pdus and new data pdus)
   rlc_pP->nb_bytes_requested_by_mac = rlc_pP->nb_bytes_requested_by_mac - pdu_size;
@@ -1150,6 +1186,7 @@ end_push_nack:
         pdu_size);
 #endif
   tb_p = get_free_mem_block(sizeof(struct mac_tb_req) + pdu_size, __func__);
+  if(tb_p == NULL) return;
   memset(tb_p->data, 0, sizeof(struct mac_tb_req) + pdu_size);
   //estimation only ((struct mac_tb_req*)(tb_p->data))->tb_size  = pdu_size;
   ((struct mac_tb_req*)(tb_p->data))->data_ptr         = (uint8_t*)&(tb_p->data[sizeof(struct mac_tb_req)]);
diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c
index ff969c0b6ee8f4fb45916b71bf6670973258a93b..d9eb6de7cccf4c1de70f3d19ca42e466bb7ef23e 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c
@@ -534,7 +534,7 @@ void rlc_am_v9_3_0_test_send_sdu(rlc_am_entity_t *am_txP, int sdu_indexP)
     assert(g_send_id_write_index[am_txP->rb_id] < TEST_MAX_SEND_SDU);
   } else {
     printf("Out of memory error\n");
-    exit(-1);
+//    exit(-1);
   }
 }
 //-----------------------------------------------------------------------------
@@ -577,7 +577,7 @@ void rlc_am_v9_3_0_test_mac_rlc_loop (struct mac_data_ind *data_indP,  struct ma
           data_indP->no_tb  += 1;
         } else {
           printf("Out of memory error\n");
-          exit(-1);
+//          exit(-1);
         }
       } else {
         printf("[RLC-LOOP] DROPPING 1 TB\n");
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 1e3b8b916d5d4b0392fe15282920aeb4360b2b06..cae015306236e9cf5dadce749d6eabc6dbac0531 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
@@ -87,9 +87,16 @@ 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 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);
+				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 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->mem_block == NULL){
+		  		LOG_E(RLC, "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);
+			  	sn = RLC_AM_PREV_SN(sn);
+  				continue;
+		  	}
+		  	
 		    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/RLC/AM_v9.3.0/rlc_am_timer_reordering.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c
index fd0feceeb0d13181b2545e04e089aafb6daad358..19b9b41ca67f40fe666a794afffad9723e5c8fe9 100644
--- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c
+++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_reordering.c
@@ -70,7 +70,12 @@ rlc_am_check_timer_reordering(
                              PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP,rlc_pP));
 #endif
 
-      AssertFatal (rlc_pP->vr_x != RLC_SN_UNDEFINED, "RLC AM TReordering Expiry vrX not defined LcId=%d\n", rlc_pP->channel_id);
+      //AssertFatal (rlc_pP->vr_x != RLC_SN_UNDEFINED, "RLC AM TReordering Expiry vrX not defined LcId=%d\n", rlc_pP->channel_id);
+      if(rlc_pP->vr_x == RLC_SN_UNDEFINED){
+      	LOG_E(RLC, "RLC AM TReordering Expiry vrX not defined LcId=%d\n", rlc_pP->channel_id);
+      	return;
+      }
+      	
 
       rlc_pP->t_reordering.running   = 0;
       rlc_pP->t_reordering.timed_out = 1;
@@ -81,8 +86,12 @@ rlc_am_check_timer_reordering(
       cursor    =  rlc_pP->receiver_buffer.head;
       rlc_usn_t vr_ms_new = rlc_pP->vr_x;
 
-      AssertFatal (cursor != NULL, "RLC AM TReordering Expiry Rx PDU list empty LcId=%d\n", rlc_pP->channel_id);
-
+      //AssertFatal (cursor != NULL, "RLC AM TReordering Expiry Rx PDU list empty LcId=%d\n", rlc_pP->channel_id);
+      if(cursor == NULL){
+      	LOG_E(RLC, "RLC AM TReordering Expiry Rx PDU list empty LcId=%d\n", rlc_pP->channel_id);
+      	return;
+      }
+      	
       /* go to memblock up to vrX*/
       pdu_info =  &((rlc_am_rx_pdu_management_t*)(cursor->data))->pdu_info;
       while ((cursor != NULL) && (RLC_AM_DIFF_SN(pdu_info->sn,rlc_pP->vr_r) < RLC_AM_DIFF_SN(vr_ms_new,rlc_pP->vr_r))) {
diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c
index 70c1f37221d6d2193e1a29b6f659a5d7976ec51e..78d7cc515f4ae713991cd7ec51c964242a232c10 100644
--- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c
+++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c
@@ -83,6 +83,7 @@ void rlc_tm_init (
 
   if ((rlcP->input_sdus_alloc == NULL) && (rlcP->size_input_sdus_buffer > 0)) {
     rlcP->input_sdus_alloc = get_free_mem_block (rlcP->size_input_sdus_buffer * sizeof (void *), __func__);
+    if(rlcP->input_sdus_alloc == NULL) return;
     rlcP->input_sdus = (mem_block_t **) (rlcP->input_sdus_alloc->data);
     memset (rlcP->input_sdus, 0, rlcP->size_input_sdus_buffer * sizeof (void *));
   }
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
index 0be2ef168644dbf1575a3f29d071d3fbeb5e557b..d8f151a5ff8d59315c922cec65a0c3b09f106cc5 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um.c
@@ -421,6 +421,7 @@ rlc_um_rx (const protocol_ctxt_t* const ctxt_pP, void *argP, struct mac_data_ind
     LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" TX UNKNOWN PROTOCOL STATE %02X hex\n",
           PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,l_rlc_p),
           l_rlc_p->protocol_state);
+    list_free (&data_indP.data);
   }
 }
 
@@ -567,7 +568,13 @@ rlc_um_mac_data_request (const protocol_ctxt_t* const ctxt_pP, void *rlc_pP,cons
       l_rlc_p->stat_tx_data_pdu   += 1;
       l_rlc_p->stat_tx_data_bytes += tb_size_in_bytes;
 
-      AssertFatal( tb_size_in_bytes > 0 , "RLC UM PDU LENGTH %d", tb_size_in_bytes);
+      //AssertFatal( tb_size_in_bytes > 0 , "RLC UM PDU LENGTH %d", tb_size_in_bytes);
+      if(tb_size_in_bytes <= 0) {
+        LOG_E(RLC, "RLC UM PDU LENGTH %d\n", tb_size_in_bytes);
+        tb_p = tb_p->next;
+        continue;
+      }
+        
 #if TRACE_RLC_UM_PDU || MESSAGE_CHART_GENERATOR
       rlc_um_get_pdu_infos(ctxt_pP, l_rlc_p,(rlc_um_pdu_sn_10_t*) ((struct mac_tb_req*) (tb_p->data))->data_ptr, tb_size_in_bytes, &pdu_info, l_rlc_p->rx_sn_length);
 #endif
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c
index fcd88acbb7e96c250c59741345d7ef0873485ad1..21cfa57b64e3c102e86e024b825f8cd1b00d7a0b 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c
@@ -94,7 +94,7 @@ void config_req_rlc_um_asn1 (
   const DL_UM_RLC_t       * const dl_rlc_pP,
   const rb_id_t             rb_idP,
   const logical_chan_id_t   chan_idP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
  ,const uint32_t            sourceL2Id
  ,const uint32_t            destinationL2Id
 #endif
@@ -111,16 +111,31 @@ void config_req_rlc_um_asn1 (
 #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
 
   if (mbms_flagP) {
-    AssertFatal(dl_rlc_pP, "No RLC UM DL config");
-    AssertFatal(ul_rlc_pP == NULL, "RLC UM UL config present");
+    //AssertFatal(dl_rlc_pP, "No RLC UM DL config");
+    if(dl_rlc_pP == NULL) {
+      LOG_E(RLC, "No RLC UM DL config\n");
+      return;
+    }
+    //AssertFatal(ul_rlc_pP == NULL, "RLC UM UL config present");
+    if(ul_rlc_pP != NULL) {
+      LOG_E(RLC, "RLC UM UL config present\n");
+      return;
+    }
+    
     key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_service_idP, mbms_session_idP);
     h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
-    AssertFatal (h_rc == HASH_TABLE_OK, "RLC NOT FOUND enb id %u rnti %i enb flag %u service id %u, session id %u",
-                 ctxt_pP->module_id,
-                 ctxt_pP->rnti,
-                 ctxt_pP->enb_flag,
-                 mbms_service_idP,
-                 mbms_session_idP);
+    //AssertFatal (h_rc == HASH_TABLE_OK, "RLC NOT FOUND enb id %u rnti %i enb flag %u service id %u, session id %u",
+    //             ctxt_pP->module_id,
+    //             ctxt_pP->rnti,
+    //             ctxt_pP->enb_flag,
+    //             mbms_service_idP,
+    //             mbms_session_idP);
+    if(h_rc != HASH_TABLE_OK) {
+      LOG_E(RLC, "RLC NOT FOUND enb id %u rnti %i enb flag %u service id %u, session id %u\n",
+        ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_service_idP, mbms_session_idP);
+      return;
+    }
+    
     rlc_p = &rlc_union_p->rlc.um;
   }
   if ((sourceL2Id >0 ) && (destinationL2Id >0)){
@@ -131,12 +146,17 @@ void config_req_rlc_um_asn1 (
      key  = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
   }
     h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
-    AssertFatal (h_rc == HASH_TABLE_OK, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %u, srb flag %u",
-                 ctxt_pP->module_id,
-                 ctxt_pP->rnti,
-                 ctxt_pP->enb_flag,
-                 rb_idP,
-                 srb_flagP);
+    //AssertFatal (h_rc == HASH_TABLE_OK, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %u, srb flag %u",
+    //             ctxt_pP->module_id,
+    //             ctxt_pP->rnti,
+    //             ctxt_pP->enb_flag,
+    //             rb_idP,
+    //             srb_flagP);
+    if(h_rc != HASH_TABLE_OK) {
+      LOG_E(RLC, "RLC NOT FOUND enb id %u ue id %i enb flag %u rb id %u, srb flag %u\n",
+        ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
+      return;
+    }
     rlc_p = &rlc_union_p->rlc.um;
 
   //-----------------------------------------------------------------------------
@@ -277,7 +297,11 @@ rlc_um_init (
 )
 {
 
-  AssertFatal(rlc_pP, "Bad RLC UM pointer (NULL)");
+  //AssertFatal(rlc_pP, "Bad RLC UM pointer (NULL)");
+  if(rlc_pP == NULL) {
+    LOG_E(RLC, "Bad RLC UM pointer (NULL)\n");
+    return;
+  }
 
   if (rlc_pP->initialized) {
     LOG_D(RLC,PROTOCOL_RLC_UM_CTXT_FMT" [INIT] ALREADY DONE, DOING NOTHING\n",
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h
index fc64e95d995983184a55e99077f0ae474f7890b6..a73d6f86729c9dc2a622572af12666426e2ba8a6 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.h
@@ -116,7 +116,7 @@ public_rlc_um_control_primitives(   void config_req_rlc_um_asn1 (
                                       const DL_UM_RLC_t       * const dl_rlc_pP,
                                       const rb_id_t            rb_idP,
                                       const logical_chan_id_t  chan_idP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                       ,const uint32_t          sourceL2Id
                                       ,const uint32_t          destinationL2Id
 #endif
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c
index fe718392310a8ef4e9c854775cf46d5883a4b41c..cd92cf2c5e877b11aaae42b218e20c1085c9a0a0 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_dar.c
@@ -47,7 +47,11 @@ signed int rlc_um_get_pdu_infos(
 
   pdu_info_pP->num_li = 0;
 
-  AssertFatal( total_sizeP > 0 , "RLC UM PDU LENGTH %d", total_sizeP);
+  //AssertFatal( total_sizeP > 0 , "RLC UM PDU LENGTH %d", total_sizeP);
+  if(total_sizeP <= 0) {
+    LOG_E(RLC, "RLC UM PDU LENGTH %d\n", total_sizeP);
+    return -1;
+  }
 
   if (sn_lengthP == 10) {
     pdu_info_pP->fi           = (header_pP->b1 >> 3) & 0x03;
@@ -62,7 +66,11 @@ signed int rlc_um_get_pdu_infos(
     pdu_info_pP->header_size  = 1;
     pdu_info_pP->payload      = &header_pP->b2;
   } else {
-    AssertFatal( sn_lengthP == 5 || sn_lengthP == 10, "RLC UM SN LENGTH %d", sn_lengthP);
+    //AssertFatal( sn_lengthP == 5 || sn_lengthP == 10, "RLC UM SN LENGTH %d", sn_lengthP);
+    if(!(sn_lengthP == 5 || sn_lengthP == 10)) {
+      LOG_E(RLC, "RLC UM SN LENGTH %d\n", sn_lengthP);
+      return -1;
+    }
   }
 
 
@@ -77,15 +85,23 @@ signed int rlc_um_get_pdu_infos(
       li_length_in_bytes = li_length_in_bytes ^ 3;
 
       if (li_length_in_bytes  == 2) {
-        AssertFatal( total_sizeP >= ((uint64_t)(&e_li_p->b2) - (uint64_t)header_pP),
-                     "DECODING PDU TOO FAR PDU size %d", total_sizeP);
+        //AssertFatal( total_sizeP >= ((uint64_t)(&e_li_p->b2) - (uint64_t)header_pP),
+        //             "DECODING PDU TOO FAR PDU size %d", total_sizeP);
+        if(total_sizeP < ((uint64_t)(&e_li_p->b2) - (uint64_t)header_pP)) {
+          LOG_E(RLC, "DECODING PDU TOO FAR PDU size %d\n", total_sizeP);
+          return -1;
+        }
         pdu_info_pP->li_list[pdu_info_pP->num_li] = ((uint16_t)(e_li_p->b1 << 4)) & 0x07F0;
         pdu_info_pP->li_list[pdu_info_pP->num_li] |= (((uint8_t)(e_li_p->b2 >> 4)) & 0x000F);
         li_to_read = e_li_p->b1 & 0x80;
         pdu_info_pP->header_size  += 2;
       } else {
-        AssertFatal( total_sizeP >= ((uint64_t)(&e_li_p->b3) - (uint64_t)header_pP),
-                     "DECODING PDU TOO FAR PDU size %d", total_sizeP);
+        //AssertFatal( total_sizeP >= ((uint64_t)(&e_li_p->b3) - (uint64_t)header_pP),
+        //             "DECODING PDU TOO FAR PDU size %d", total_sizeP);
+        if(total_sizeP < ((uint64_t)(&e_li_p->b3) - (uint64_t)header_pP)) {
+          LOG_E(RLC, "DECODING PDU TOO FAR PDU size %d\n", total_sizeP);
+          return -1;
+        }
         pdu_info_pP->li_list[pdu_info_pP->num_li] = ((uint16_t)(e_li_p->b2 << 8)) & 0x0700;
         pdu_info_pP->li_list[pdu_info_pP->num_li] |=  e_li_p->b3;
         li_to_read = e_li_p->b2 & 0x08;
@@ -93,10 +109,16 @@ signed int rlc_um_get_pdu_infos(
         pdu_info_pP->header_size  += 1;
       }
 
-      AssertFatal( pdu_info_pP->num_li <= RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU,
-                   PROTOCOL_RLC_UM_CTXT_FMT"[GET PDU INFO]  SN %04d TOO MANY LIs ",
+      //AssertFatal( pdu_info_pP->num_li <= RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU,
+      //             PROTOCOL_RLC_UM_CTXT_FMT"[GET PDU INFO]  SN %04d TOO MANY LIs ",
+      //             PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
+      //             pdu_info_pP->sn);
+      if(pdu_info_pP->num_li > RLC_UM_SEGMENT_NB_MAX_LI_PER_PDU) {
+        LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT"[GET PDU INFO]  SN %04d TOO MANY LIs \n",
                    PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
                    pdu_info_pP->sn);
+        return -1;
+      }
 
       sum_li += pdu_info_pP->li_list[pdu_info_pP->num_li];
       pdu_info_pP->num_li = pdu_info_pP->num_li + 1;
@@ -308,9 +330,17 @@ rlc_um_try_reassembly(
               __LINE__);
 #endif
       }
-      AssertFatal(size >= 0, "invalid size!");
-      AssertFatal((e==0) || (e==1), "invalid e!");
-      AssertFatal((fi >= 0) && (fi <= 3), "invalid fi!");
+      //AssertFatal(size >= 0, "invalid size!");
+      //AssertFatal((e==0) || (e==1), "invalid e!");
+      //AssertFatal((fi >= 0) && (fi <= 3), "invalid fi!");
+      if((size < 0) || ((e!=0) && (e!=1)) || ((fi < 0) || (fi > 3))){
+        LOG_E(RLC, "invalid size %d, e %d, fi %d\n", size, e, fi);
+        sn = (sn + 1) % rlc_pP->rx_sn_modulo;
+        if ((sn == rlc_pP->vr_uh) || (sn == end_snP)) {
+          continue_reassembly = 0;
+        }
+        continue;
+      }
 
       if (e == RLC_E_FIXED_PART_DATA_FIELD_FOLLOW) {
         switch (fi) {
@@ -400,11 +430,14 @@ rlc_um_try_reassembly(
           break;
 
         default:
-          AssertFatal( 0 , PROTOCOL_RLC_UM_CTXT_FMT" fi=%d! TRY REASSEMBLY SHOULD NOT GO HERE (%s:%u)\n",
-                       PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
-                       fi,
-                       __FILE__,
-                       __LINE__);
+          //AssertFatal( 0 , PROTOCOL_RLC_UM_CTXT_FMT" fi=%d! TRY REASSEMBLY SHOULD NOT GO HERE (%s:%u)\n",
+          //             PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
+          //             fi,
+          //             __FILE__,
+          //             __LINE__);
+          LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" fi=%d! TRY REASSEMBLY SHOULD NOT GO HERE (%s:%u)\n",
+                     PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP), fi, __FILE__, __LINE__);
+          
         }
       } else {
         if (rlc_um_read_length_indicators(&data_p, e_li_p, li_array, &num_li, &size ) >= 0) {
@@ -543,11 +576,14 @@ rlc_um_try_reassembly(
               // data_p is already ok, done by last loop above
               rlc_um_reassembly (ctxt_pP, rlc_pP, data_p, size);
             } else {
-              AssertFatal( 0 !=0, PROTOCOL_RLC_UM_CTXT_FMT" size=%d! SHOULD NOT GO HERE (%s:%u)\n",
-                           PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
-                           size,
-                           __FILE__,
-                           __LINE__);
+              //AssertFatal( 0 !=0, PROTOCOL_RLC_UM_CTXT_FMT" size=%d! SHOULD NOT GO HERE (%s:%u)\n",
+              //             PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
+              //             size,
+              //             __FILE__,
+              //             __LINE__);
+              LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" size=%d! SHOULD NOT GO HERE (%s:%u)\n",
+                PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP), size, __FILE__, __LINE__);
+              
               //rlc_pP->stat_rx_data_pdu_dropped += 1;
               rlc_pP->stat_rx_data_bytes_dropped += size;
             }
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c
index bc61ed302ecda6cc92a3502114ff0fbc3e2b5cb3..fa0bf4b288b2c6a1bc996d418b450e305b044f86 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_fsm.c
@@ -52,7 +52,7 @@ rlc_um_fsm_notify_event (
       LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" FSM WARNING PROTOCOL ERROR - EVENT %02X hex NOT EXPECTED FROM NULL_STATE\n",
             PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP, rlc_pP),
             eventP);
-      AssertFatal(1==0,"RLC-UM FSM WARNING PROTOCOL ERROR - EVENT NOT EXPECTED FROM NULL_STATE");
+      //AssertFatal(1==0,"RLC-UM FSM WARNING PROTOCOL ERROR - EVENT NOT EXPECTED FROM NULL_STATE");
       return 0;
     }
 
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c
index 98a44ceeeb0fccb77a78e4016410294eace7ab53..91ae265f172d1c0c801c449c40372c121215f9c2 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_segment.c
@@ -411,7 +411,11 @@ rlc_um_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP
 #if TRACE_RLC_PAYLOAD
     rlc_util_print_hex_octets(RLC, pdu_mem_p->data, data_pdu_size);
 #endif
-    AssertFatal( pdu_tb_req_p->tb_size > 0 , "SEGMENT10: FINAL RLC UM PDU LENGTH %d", pdu_tb_req_p->tb_size);
+    //AssertFatal( pdu_tb_req_p->tb_size > 0 , "SEGMENT10: FINAL RLC UM PDU LENGTH %d", pdu_tb_req_p->tb_size);
+    if(pdu_tb_req_p->tb_size <= 0) {
+      LOG_E(RLC, "SEGMENT10: FINAL RLC UM PDU LENGTH %d\n", pdu_tb_req_p->tb_size);
+      break;
+    }
     pdu_p = NULL;
     pdu_mem_p = NULL;
 
@@ -744,13 +748,11 @@ rlc_um_segment_5 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP)
         sdu_mngt_p    = NULL;
 
       } else {
-#if TRACE_RLC_UM_SEGMENT
-        LOG_D(RLC, PROTOCOL_RLC_UM_CTXT_FMT" Filling  PDU with %d all remaining bytes of SDU and reduce TB size by %d bytes\n",
+        LOG_E(RLC, PROTOCOL_RLC_UM_CTXT_FMT" Filling  PDU with %d all remaining bytes of SDU and reduce TB size by %d bytes\n",
               PROTOCOL_RLC_UM_CTXT_ARGS(ctxt_pP,rlc_pP),
               sdu_mngt_p->sdu_remaining_size,
               pdu_remaining_size - sdu_mngt_p->sdu_remaining_size);
-#endif
-        assert(1!=1);
+        //assert(1!=1);
         memcpy(data, data_sdu_p, sdu_mngt_p->sdu_remaining_size);
         // reduce the size of the PDU
         continue_fill_pdu_with_sdu = 0;
@@ -792,7 +794,11 @@ rlc_um_segment_5 (const protocol_ctxt_t* const ctxt_pP, rlc_um_entity_t *rlc_pP)
 #if TRACE_RLC_PAYLOAD
     rlc_util_print_hex_octets(RLC, (unsigned char*)pdu_mem_p->data, data_pdu_size);
 #endif
-    AssertFatal( pdu_tb_req_p->tb_size > 0 , "SEGMENT5: FINAL RLC UM PDU LENGTH %d", pdu_tb_req_p->tb_size);
+    //AssertFatal( pdu_tb_req_p->tb_size > 0 , "SEGMENT5: FINAL RLC UM PDU LENGTH %d", pdu_tb_req_p->tb_size);
+    if(pdu_tb_req_p->tb_size <= 0) {
+      LOG_E(RLC, "SEGMENT5: FINAL RLC UM PDU LENGTH %d\n", pdu_tb_req_p->tb_size);
+      break;
+    }
 
     pdu_p = NULL;
     pdu_mem_p = NULL;
diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
index 2c1fa9333f0136c8ae42e61fd428fa4140974bca..4d238ea84175da06fa29faaad63813b505c3eafe 100644
--- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
+++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_test.c
@@ -317,7 +317,7 @@ void rlc_um_v9_3_0_test_send_sdu(rlc_um_entity_t *um_txP, int sdu_indexP)
     assert(g_send_id_write_index[um_txP->rb_id] < TEST_MAX_SEND_SDU);
   } else {
     printf("Out of memory error\n");
-    exit(-1);
+//    exit(-1);
   }
 }
 
@@ -406,9 +406,8 @@ void rlc_um_v9_3_0_test_mac_rlc_loop (struct mac_data_ind* data_indP,  struct ma
 
       if (*drop_countP == 0) {
         tb_dst  = get_free_mem_block(sizeof (mac_rlc_max_rx_header_size_t) + tb_size, __func__);
-        memset(tb_dst->data, 0, sizeof (mac_rlc_max_rx_header_size_t) + tb_size);
-
         if (tb_dst != NULL) {
+          memset(tb_dst->data, 0, sizeof (mac_rlc_max_rx_header_size_t) + tb_size);
           //printf("[RLC-LOOP] Testing tb_dst (1)\n");
           check_free_mem_block(tb_dst, __func__);
           tb_dst->next = NULL;
@@ -427,7 +426,7 @@ void rlc_um_v9_3_0_test_mac_rlc_loop (struct mac_data_ind* data_indP,  struct ma
           check_free_mem_block(tb_dst, __func__);
         } else {
           printf("Out of memory error\n");
-          exit(-1);
+//          exit(-1);
         }
       } else {
         printf("[RLC-LOOP] DROPPING 1 TB\n");
diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
index 99a0b494ac9fa988640fe9148e4946da19c8c49f..67bf20d0148d1936bf6f0574baf5814fe6bac926 100644
--- a/openair2/LAYER2/RLC/rlc.c
+++ b/openair2/LAYER2/RLC/rlc.c
@@ -135,7 +135,12 @@ rlc_op_status_t rlc_stat_req     (
   hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
   hashtable_rc_t         h_rc;
 
-  AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+  //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+	if(rb_idP >= NB_RB_MAX){
+		LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+		return RLC_OP_STATUS_BAD_PARAMETER;
+	}
+	
   key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
   h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
 
@@ -315,7 +320,7 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
                                   confirm_t    confirmP,
                                   sdu_size_t   sdu_sizeP,
                                   mem_block_t *sdu_pP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                   ,const uint32_t * const sourceL2Id
                                   ,const uint32_t * const destinationL2Id
 #endif
@@ -353,13 +358,30 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
 #endif
 
   if (MBMS_flagP) {
-    AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
+    //AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
+  	if(rb_idP >= NB_RB_MBMS_MAX){
+  		LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
+  		return RLC_OP_STATUS_BAD_PARAMETER;
+  	}
   } else {
-    AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+    //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+  	if(rb_idP >= NB_RB_MAX){
+  		LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+  		return RLC_OP_STATUS_BAD_PARAMETER;
+  	}
   }
 
-  DevAssert(sdu_pP != NULL);
-  DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0);
+  //DevAssert(sdu_pP != NULL);
+	if(sdu_pP == NULL){
+		LOG_E(RLC, "sdu_pP == NULL\n");
+		return RLC_OP_STATUS_BAD_PARAMETER;
+	}
+	
+  //DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0);
+  if(sdu_sizeP <= 0) {
+    LOG_E(RLC, "sdu_sizeP %d, file %s, line %d\n", sdu_sizeP, __FILE__ ,__LINE__);
+    return RLC_OP_STATUS_BAD_PARAMETER;
+  }
 
 #if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
   DevCheck(MBMS_flagP == 0, MBMS_flagP, 0, 0);
@@ -396,6 +418,8 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
   } else {
     rlc_mode = RLC_MODE_NONE;
     //AssertFatal (0 , "RLC not configured key %ju\n", key);
+  	LOG_E(RLC, "not configured key %lu\n", key);
+  	return RLC_OP_STATUS_OUT_OF_RESSOURCES;
   }
 
   if (MBMS_flagP == 0) {
@@ -440,6 +464,7 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
         return RLC_OP_STATUS_OK;
       } else {
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
+        free_mem_block(sdu_pP, __func__);
         return RLC_OP_STATUS_INTERNAL_ERROR;
       }
 
@@ -473,6 +498,7 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
         return RLC_OP_STATUS_OK;
       } else {
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
+        free_mem_block(sdu_pP, __func__);
         return RLC_OP_STATUS_INTERNAL_ERROR;
       }
 
@@ -495,6 +521,7 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
       } else {
         //handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : out of memory\n", __FILE__, __LINE__);
         VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
+        free_mem_block(sdu_pP, __func__);
         return RLC_OP_STATUS_INTERNAL_ERROR;
       }
 
@@ -529,6 +556,7 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
           return RLC_OP_STATUS_OK;
         } else {
           VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
+          free_mem_block(sdu_pP, __func__);
           return RLC_OP_STATUS_BAD_PARAMETER;
         }
       } else {
@@ -622,7 +650,11 @@ rlc_module_init (void)
   rlc_rrc_data_conf = NULL;
 
   rlc_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, rb_free_rlc_union);
-  AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed");
+  //AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed");
+  if(rlc_coll_p == NULL) {
+    LOG_E(RLC, "UNRECOVERABLE error, RLC hashtable_create failed\n");
+    return -1;
+  }
 
   for (module_id1=0; module_id1 < MAX_MOBILES_PER_ENB; module_id1++) {
 #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h
index e3787d84178958c6101275b715f5156ba11f8dcd..8f4773a36e246ffb56af4f662ba3682c4ef7cf98 100644
--- a/openair2/LAYER2/RLC/rlc.h
+++ b/openair2/LAYER2/RLC/rlc.h
@@ -399,7 +399,7 @@ public_rlc_rrc(rlc_op_status_t rrc_rlc_remove_rlc   (const protocol_ctxt_t* cons
 * \return     A status about the processing, OK or error code.
 */
 private_rlc_rrc(rlc_union_t*  rrc_rlc_add_rlc      (const protocol_ctxt_t* const, const srb_flag_t,  const  MBMS_flag_t MBMS_flagP, const  rb_id_t, logical_chan_id_t, rlc_mode_t
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   ,const uint32_t  sourceL2Id,
   const uint32_t  destinationL2Id
 #endif
@@ -465,7 +465,7 @@ public_rlc_rrc(void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_d
 * \return     A status about the processing, OK or error code.
 */
 public_rlc_mac(tbs_size_t            mac_rlc_data_req     (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const  eNB_flag_t, const  MBMS_flag_t, logical_chan_id_t, const tb_size_t,char*
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                            ,const uint32_t sourceL2Id
                                                            ,const uint32_t destinationL2Id
 #endif
@@ -500,7 +500,7 @@ public_rlc_mac(void                  mac_rlc_data_ind     (const module_id_t, co
 * \return     The maximum number of bytes that the RLC instance can send in the next transmission sequence.
 */
 public_rlc_mac(mac_rlc_status_resp_t mac_rlc_status_ind   (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const  eNB_flag_t, const  MBMS_flag_t, logical_chan_id_t, tb_size_t
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                                            ,const uint32_t sourceL2Id
                                                            ,const uint32_t destinationL2Id
 #endif
@@ -555,7 +555,7 @@ public_rlc(rlc_op_status_t rlc_data_req     (
              const confirm_t ,
              const sdu_size_t ,
              mem_block_t * const
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
              ,const uint32_t * const
              ,const uint32_t * const
 #endif
diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c
index c4fc2872c682a87f1fd3a1cf23634f518d946124..6ba7e883b16e3fc78527f51c45d7252f83bc5cbf 100644
--- a/openair2/LAYER2/RLC/rlc_mac.c
+++ b/openair2/LAYER2/RLC/rlc_mac.c
@@ -127,7 +127,7 @@ tbs_size_t mac_rlc_data_req(
   const logical_chan_id_t channel_idP,
   const tb_size_t         tb_sizeP,
   char             *buffer_pP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   ,const uint32_t sourceL2Id
   ,const uint32_t destinationL2Id
 #endif
@@ -157,9 +157,17 @@ tbs_size_t mac_rlc_data_req(
 #endif // DEBUG_MAC_INTERFACE
 
   if (MBMS_flagP) {
-    AssertFatal (channel_idP < RLC_MAX_MBMS_LC,        "channel id is too high (%u/%d)!\n",     channel_idP, RLC_MAX_MBMS_LC);
+    //AssertFatal (channel_idP < RLC_MAX_MBMS_LC,        "channel id is too high (%u/%d)!\n",     channel_idP, RLC_MAX_MBMS_LC);
+  	if(channel_idP >= RLC_MAX_MBMS_LC){
+  		LOG_E(RLC, "channel id is too high (%u/%d)!\n", channel_idP, RLC_MAX_MBMS_LC);
+  		return 0;
+  	}
   } else {
-    AssertFatal (channel_idP < NB_RB_MAX,        "channel id is too high (%u/%d)!\n",     channel_idP, NB_RB_MAX);
+    //AssertFatal (channel_idP < NB_RB_MAX,        "channel id is too high (%u/%d)!\n",     channel_idP, NB_RB_MAX);
+  	if(channel_idP >= NB_RB_MAX){
+  		LOG_E(RLC, "channel id is too high (%u/%d)!\n", channel_idP, NB_RB_MAX);
+  		return 0;
+  	}
   }
 
   if (MBMS_flagP) {
@@ -171,7 +179,7 @@ tbs_size_t mac_rlc_data_req(
     }
   } else {
     key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     if ((sourceL2Id > 0) && (destinationL2Id > 0))
        key = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(module_idP, rntiP, enb_flagP, channel_idP, sourceL2Id, destinationL2Id, srb_flag);
 #endif
@@ -183,7 +191,8 @@ tbs_size_t mac_rlc_data_req(
     rlc_mode = rlc_union_p->mode;
   } else {
     rlc_mode = RLC_MODE_NONE;
-    AssertFatal (0 , "RLC not configured lcid %u RNTI %x!\n", channel_idP, rntiP);
+    //AssertFatal (0 , "RLC not configured lcid %u RNTI %x!\n", channel_idP, rntiP);
+  	LOG_E(RLC, "RLC not configured lcid %u RNTI %x!\n", channel_idP, rntiP);
   }
 
   switch (rlc_mode) {
@@ -192,6 +201,7 @@ tbs_size_t mac_rlc_data_req(
     break;
 
   case RLC_MODE_AM:
+    rlc_am_mui.rrc_mui_num = 0;
     if (!enb_flagP) rlc_am_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.am,tb_sizeP);
 	data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am,enb_flagP);
     ret_tb_size =mac_rlc_serialize_tb(buffer_pP, data_request.data);
@@ -224,7 +234,7 @@ tbs_size_t mac_rlc_data_req(
 void mac_rlc_data_ind     (
   const module_id_t         module_idP,
   const rnti_t              rntiP,
-  const module_id_t         eNB_index,
+  const eNB_index_t         eNB_index,
   const frame_t             frameP,
   const eNB_flag_t          enb_flagP,
   const MBMS_flag_t         MBMS_flagP,
@@ -289,6 +299,7 @@ void mac_rlc_data_ind     (
   switch (rlc_mode) {
   case RLC_MODE_NONE:
     //handle_event(WARNING,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no radio bearer configured :%d\n", __FILE__, __LINE__, channel_idP);
+    list_free (&data_ind.data);
     break;
 
   case RLC_MODE_AM:
@@ -318,7 +329,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
   const MBMS_flag_t       MBMS_flagP,
   const logical_chan_id_t channel_idP,
   const tb_size_t         tb_sizeP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   ,const uint32_t sourceL2Id
   ,const uint32_t destinationL2Id
 #endif
@@ -351,7 +362,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(
 
     key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id);
   } else {
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     if ((sourceL2Id > 0) && (destinationL2Id > 0)) {
        key = RLC_COLL_KEY_SOURCE_DEST_VALUE(module_idP, rntiP, enb_flagP, channel_idP, sourceL2Id, destinationL2Id, srb_flag);
     } else
@@ -441,8 +452,12 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
   /* Assumptions : for UE only */
   /* At each TTI, Buffer Occupancy is first computed in mac_rlc_status_ind called by MAC ue_scheduler() function */
   /* Then this function is called during MAC multiplexing ue_get_sdu(), and it may be call several times for the same bearer if it is in AM mode and there are several PDU types to transmit */
-  AssertFatal(enb_flagP == FALSE,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP);
-
+  //AssertFatal(enb_flagP == FALSE,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP);
+	if(enb_flagP != FALSE){
+		LOG_E(RLC, "Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%u\n", channel_idP);
+		return 0;
+	}
+	
 
   key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
 
diff --git a/openair2/LAYER2/RLC/rlc_mpls.c b/openair2/LAYER2/RLC/rlc_mpls.c
index 900741fe2672300f22522a07133b9ef280bed8de..8c6cea379b91a2d94585598ad79edb39ca951c84 100644
--- a/openair2/LAYER2/RLC/rlc_mpls.c
+++ b/openair2/LAYER2/RLC/rlc_mpls.c
@@ -41,7 +41,7 @@ rlc_op_status_t mpls_rlc_data_req     (
   //-----------------------------------------------------------------------------
   // third arg should be set to 1 or 0
   return rlc_data_req(ctxtP, SRB_FLAG_NO, MBMS_FLAG_NO, rb_idP, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, sdu_sizeP, sduP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                       ,NULL, NULL
 #endif
                       );
diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c
index 34e4dee37aad2791ec962cfdde188956a918b0df..63fa212c318c9ec4cab443ccd1fb50e94de99517 100644
--- a/openair2/LAYER2/RLC/rlc_rrc.c
+++ b/openair2/LAYER2/RLC/rlc_rrc.c
@@ -107,7 +107,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
           case RLC_Config_PR_am:
             if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                 ,0,
                                 0
 #endif
@@ -127,7 +127,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
           case RLC_Config_PR_um_Bi_Directional:
             if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                 ,0,
                                 0
 #endif
@@ -141,7 +141,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.ul_UM_RLC,
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.dl_UM_RLC,
                 rb_id, lc_id
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,0, 0
 #endif
                );
@@ -155,7 +155,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
           case RLC_Config_PR_um_Uni_Directional_UL:
             if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                  ,0,
                                  0
 #endif
@@ -169,7 +169,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_UL.ul_UM_RLC,
                 NULL,
                 rb_id, lc_id
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,0, 0
 #endif
                );
@@ -183,7 +183,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
           case RLC_Config_PR_um_Uni_Directional_DL:
             if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                  ,0,
                                  0
 #endif
@@ -197,7 +197,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                 NULL,
                 &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_DL.dl_UM_RLC,
                 rb_id, lc_id
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,0, 0
 #endif
                );
@@ -230,7 +230,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
           config_am_pP->ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t4;
 
           if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                ,0,
                                0
 #endif
@@ -299,7 +299,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
         case RLC_Config_PR_am:
           if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_AM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                ,0,
                                0
 #endif
@@ -315,7 +315,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
         case RLC_Config_PR_um_Bi_Directional:
           if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                ,sourceL2Id,
                                destinationL2Id
 #endif
@@ -329,7 +329,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.ul_UM_RLC,
               &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.dl_UM_RLC,
               drb_id, lc_id
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
               ,sourceL2Id,
               destinationL2Id
 #endif
@@ -340,7 +340,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
         case RLC_Config_PR_um_Uni_Directional_UL:
           if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                               ,0,
                                0
 #endif
@@ -354,7 +354,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_UL.ul_UM_RLC,
               NULL,
               drb_id, lc_id
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,0, 0
 #endif
                );
@@ -364,7 +364,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
 
         case RLC_Config_PR_um_Uni_Directional_DL:
           if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                               ,0,
                                0
 #endif
@@ -378,7 +378,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
               NULL,
               &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_DL.dl_UM_RLC,
               drb_id, lc_id
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,0, 0
 #endif
                );
@@ -444,7 +444,10 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
                           rb_id,
                           lc_id,
                           RLC_MODE_UM, 0, 0);
-          AssertFatal(rlc_union_p != NULL, "ADD MBMS RLC UM FAILED");
+          //AssertFatal(rlc_union_p != NULL, "ADD MBMS RLC UM FAILED");
+          if(rlc_union_p == NULL){
+            LOG_E(RLC, "ADD MBMS RLC UM FAILED\n");
+          }
         }
 
         LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n",
@@ -466,7 +469,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP
           NULL,
           &dl_um_rlc,
           rb_id, lc_id
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
           ,0, 0
 #endif
                );
@@ -586,7 +589,11 @@ rlc_op_status_t rrc_rlc_remove_rlc   (
   }
 
 
-  AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+  //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+	if(rb_idP >= NB_RB_MAX){
+		LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+		return RLC_OP_STATUS_BAD_PARAMETER;
+	}
 
   h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
 
@@ -647,7 +654,7 @@ rlc_union_t* rrc_rlc_add_rlc   (
   const rb_id_t           rb_idP,
   const logical_chan_id_t chan_idP,
   const rlc_mode_t        rlc_modeP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   ,const uint32_t sourceL2Id,
   const uint32_t  destinationL2Id
 #endif
@@ -667,8 +674,17 @@ rlc_union_t* rrc_rlc_add_rlc   (
 
 
   if (MBMS_flagP == FALSE) {
-    AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
-    AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC);
+    //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+    //AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC);
+  	if(rb_idP >= NB_RB_MAX){
+  		LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+  		return NULL;
+  	}
+  	if(chan_idP >= RLC_MAX_LC){
+  		LOG_E(RLC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC);
+  		return NULL;
+  	}
+
   }
 
 #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
@@ -709,8 +725,12 @@ rlc_union_t* rrc_rlc_add_rlc   (
           (srb_flagP) ? "SRB" : "DRB",
           rb_idP,
           (srb_flagP) ? "SRB" : "DRB");
-    AssertFatal(rlc_union_p->mode == rlc_modeP, "Error rrc_rlc_add_rlc , already exist but RLC mode differ");
-    return rlc_union_p;
+    //AssertFatal(rlc_union_p->mode == rlc_modeP, "Error rrc_rlc_add_rlc , already exist but RLC mode differ");
+  	if(rlc_union_p->mode != rlc_modeP){
+  		LOG_E(RLC, "Error rrc_rlc_add_rlc , already exist but RLC mode differ\n");
+  		return NULL;
+  	}
+  	return rlc_union_p;
   } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) {
     rlc_union_p = calloc(1, sizeof(rlc_union_t));
     h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p);
@@ -772,13 +792,17 @@ rlc_op_status_t rrc_rlc_config_req   (
         PROTOCOL_CTXT_ARGS(ctxt_pP),
         rb_idP);
 
-  AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+  //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+	if(rb_idP >= NB_RB_MAX){
+		LOG_E(RLC, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
+		return RLC_OP_STATUS_BAD_PARAMETER;
+	}
 
   switch (actionP) {
 
   case CONFIG_ACTION_ADD:
     if (rrc_rlc_add_rlc(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, rb_idP, rlc_infoP.rlc_mode
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                         ,0,
                         0
 #endif
@@ -857,7 +881,7 @@ rlc_op_status_t rrc_rlc_data_req     (
   if (sdu != NULL) {
     memcpy (sdu->data, sduP, sdu_sizeP);
     return rlc_data_req(ctxt_pP, SRB_FLAG_YES, MBMS_flagP, rb_idP, muiP, confirmP, sdu_sizeP, sdu
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                         ,NULL, NULL
 #endif
                         );
diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c
index e8ff5fc7ac66d9917f1624e0615a5ee94899e70a..84f425ef3c004646069f1e0496620a6cca4327a9 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/common.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/common.c
@@ -248,7 +248,7 @@ ue_ip_common_ip2wireless(
   //---------------------------------------------------------------------------
   struct pdcp_data_req_header_s     pdcph;
   ue_ip_priv_t                     *priv_p=netdev_priv(ue_ip_dev[instP]);
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   ipversion_t         *ipv_p             = NULL;
   unsigned int         hard_header_len   = 0;
   unsigned char       *src_addr          = 0;
diff --git a/openair2/NETWORK_DRIVER/UE_IP/local.h b/openair2/NETWORK_DRIVER/UE_IP/local.h
index 976222967d326d885dc02288b12562e7bc953665..e590109b131ed0f1fe537ce93bcb202de35b948b 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/local.h
+++ b/openair2/NETWORK_DRIVER/UE_IP/local.h
@@ -57,6 +57,7 @@
 #include "platform_types.h"
 #include "sap.h"
 
+#define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+(c))
 
 typedef struct ue_ip_priv_s {
   int                        irq;
@@ -89,7 +90,7 @@ typedef struct pdcp_data_req_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   traffic_type;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   uint32_t sourceL2Id;
   uint32_t destinationL2Id;
 #endif
@@ -100,7 +101,7 @@ typedef struct pdcp_data_ind_header_s {
   sdu_size_t          data_size;
   signed int          inst;
   ip_traffic_type_t   dummy_traffic_type;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   uint32_t sourceL2Id;
   uint32_t destinationL2Id;
 #endif
diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c
index 997f42019f91ed1e8322bb17d3f644c27e6f0394..b8529d50369340127e2856de4b17a2db3711556d 100644
--- a/openair2/PHY_INTERFACE/IF_Module.c
+++ b/openair2/PHY_INTERFACE/IF_Module.c
@@ -17,7 +17,7 @@ extern int oai_nfapi_sr_indication(nfapi_sr_indication_t *ind);
 extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
 extern uint8_t nfapi_mode;
 extern uint16_t sf_ahead;
-
+uint16_t frame_cnt=0;
 void handle_rach(UL_IND_t *UL_info) {
   int i;
 
@@ -546,6 +546,10 @@ void UL_indication(UL_IND_t *UL_info)
         UL_info->frame,UL_info->subframe,
         module_id,CC_id,
         UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs);
+  if(UL_info->frame==1023&&UL_info->subframe==6){ // dl scheduling (0,0)
+      frame_cnt= (frame_cnt + 1)%7; // to prevent frame_cnt get too big
+      LOG_D(MAC,"current (%d,%d) frame count dl is %d\n",UL_info->frame,UL_info->subframe,frame_cnt);
+  }
 
   if (nfapi_mode != 1)
   {
@@ -574,7 +578,11 @@ void UL_indication(UL_IND_t *UL_info)
   handle_harq(UL_info);
 
   // clear HI prior to handling ULSCH
-  mac->HI_DCI0_req[CC_id].hi_dci0_request_body.number_of_hi                     = 0;
+  uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_id] , UL_info->subframe);
+  if(sf_ahead_dl!=255){
+      mac->HI_DCI0_req[CC_id][(UL_info->subframe+sf_ahead_dl)%10].hi_dci0_request_body.number_of_hi                     = 0;
+      LOG_D(MAC,"current (%d,%d) clear HI_DCI0_req[0][%d]\n",UL_info->frame,UL_info->subframe,(UL_info->subframe+sf_ahead_dl)%10);
+  }
   
   handle_ulsch(UL_info);
 
@@ -593,9 +601,9 @@ void UL_indication(UL_IND_t *UL_info)
       sched_info->frame       = (UL_info->frame + ((UL_info->subframe>(9-sf_ahead)) ? 1 : 0)) % 1024;
       sched_info->subframe    = (UL_info->subframe+sf_ahead)%10;
       sched_info->DL_req      = &mac->DL_req[CC_id];
-      sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id];
+      sched_info->HI_DCI0_req = &mac->HI_DCI0_req[CC_id][sched_info->subframe];
       if ((mac->common_channels[CC_id].tdd_Config==NULL) ||
-          (is_UL_sf(&mac->common_channels[CC_id],(sched_info->subframe+sf_ahead)%10)>0))
+          (is_UL_sf(&mac->common_channels[CC_id],sched_info->subframe)>0))
         sched_info->UL_req      = &mac->UL_req[CC_id];
       else
         sched_info->UL_req      = NULL;
diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c
index 66ab3b1dd471370578999bbebc22eb350baf99d8..d0e185ca9dc70faad3b94b87caf0119472b66986 100644
--- a/openair2/RRC/LTE/L2_interface.c
+++ b/openair2/RRC/LTE/L2_interface.c
@@ -376,6 +376,7 @@ mac_rrc_data_ind(
    */
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0);
 
+    if((srb_idP & RAB_OFFSET) == CCCH) {
     Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
     LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
     
@@ -410,7 +411,17 @@ mac_rrc_data_ind(
       Srb_info->Rx_buffer.payload_size = sdu_lenP;
       rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id);
     }
-
+    }
+    if((srb_idP & RAB_OFFSET) == DCCH) {
+      struct rrc_eNB_ue_context_s*    ue_context_p = NULL;
+      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP);
+      if(ue_context_p){
+        rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt,
+            ue_context_p,
+            0);
+        ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+      }
+    }
 #endif
 
   return(0);
diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c
index d72cc2f5bee1aa2d10fbb61838c9fda1eac997c8..155c0ebb90e10e58c83bef13daaa138c2dfc198a 100644
--- a/openair2/RRC/LTE/L2_interface_common.c
+++ b/openair2/RRC/LTE/L2_interface_common.c
@@ -57,6 +57,11 @@ rrc_data_req(
 )
 //------------------------------------------------------------------------------
 {
+  if(sdu_sizeP == 255)
+  {
+    LOG_I(RRC,"sdu_sizeP == 255");
+    return FALSE;
+  }
   MSC_LOG_TX_MESSAGE(
     ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE,
     ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE,
diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c
index 569e2f008b13dcc0db29f65e42f266efcb176ba3..90751ecf25c927c4b13055c45fb60b84f9eb58e4 100644
--- a/openair2/RRC/LTE/L2_interface_ue.c
+++ b/openair2/RRC/LTE/L2_interface_ue.c
@@ -67,7 +67,7 @@ mac_rrc_data_req_ue(
 #endif
 
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
      LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id);
      LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size);
 
@@ -331,7 +331,7 @@ rrc_data_req_ue(
            sdu_sizeP,
            buffer_pP,
            modeP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,NULL, NULL
 #endif
            );
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
index 81282059a1f215f3d6fa10c052c022db43664b3a..d46f6b2701b8c76c3930d9ceeee42403b71b1ed6 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
@@ -598,7 +598,7 @@ uint8_t do_SIB23(uint8_t Mod_id,
   uint8_t                           MBMS_flag     = RC.rrc[Mod_id]->carrier[CC_id].MBMS_flag;
 #endif
 
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
   //TTN - for D2D
   SystemInformationBlockType18_r12_t     **sib18        = &RC.rrc[Mod_id]->carrier[CC_id].sib18;
   SystemInformationBlockType19_r12_t     **sib19        = &RC.rrc[Mod_id]->carrier[CC_id].sib19;
@@ -649,7 +649,7 @@ uint8_t do_SIB23(uint8_t Mod_id,
 
 #endif
 
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
   //TTN - for D2D
   sib18_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member));
   sib19_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member));
@@ -761,10 +761,10 @@ uint8_t do_SIB23(uint8_t Mod_id,
     = configuration->pucch_nRB_CQI[CC_id];
   (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN
     = configuration->pucch_nCS_AN[CC_id];
-#if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
+//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0))
   (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN
     = configuration->pucch_n1_AN[CC_id];
-#endif
+//#endif
 
   // SRS Config
   if (configuration->srs_enable[CC_id]==1) {
@@ -1003,7 +1003,7 @@ uint8_t do_SIB23(uint8_t Mod_id,
 
   // SIB13
   // fill in all elements of SIB13 if present
-#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
+#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0))
 
   if (MBMS_flag > 0 ) {
     //  Notification for mcch change
@@ -1063,7 +1063,7 @@ uint8_t do_SIB23(uint8_t Mod_id,
 #endif
 
 
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
   //TTN - for D2D
   // SIB18
   //commRxPool_r12
@@ -1860,6 +1860,8 @@ do_RRCConnectionSetup(
 
   RRCConnectionSetup_t* rrcConnectionSetup = NULL;
 
+  LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[ctxt_pP->module_id][CC_id]->frame_parms;
+
   memset((void *)&dl_ccch_msg,0,sizeof(DL_CCCH_Message_t));
   dl_ccch_msg.message.present           = DL_CCCH_MessageType_PR_c1;
   dl_ccch_msg.message.choice.c1.present = DL_CCCH_MessageType__c1_PR_rrcConnectionSetup;
@@ -2125,7 +2127,28 @@ do_RRCConnectionSetup(
   // SchedulingRequestConfig
 
   physicalConfigDedicated2->schedulingRequestConfig->present = SchedulingRequestConfig_PR_setup;
-  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) {
+    physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid;
+  } else {
+      switch (carrier->sib1->tdd_Config->subframeAssignment) {
+      case 1:
+          switch(frame_parms->N_RB_UL){
+          case 25:
+              physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 15 - ue_context_pP->local_uid/4;
+              break;
+          case 50:
+              physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 31 - ue_context_pP->local_uid/4;
+              break;
+          case 100:
+              physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 63 - ue_context_pP->local_uid/4;
+              break;
+          }
+          break;
+      default:
+          physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid;
+          break;
+      }
+  }
 
   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)
@@ -2184,9 +2207,12 @@ do_RRCConnectionSetup(
                                    (void*)&dl_ccch_msg,
                                    buffer,
                                    100);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -2255,9 +2281,12 @@ do_SecurityModeCommand(
                                    (void*)&dl_dcch_msg,
                                    buffer,
                                    100);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -2331,9 +2360,12 @@ do_UECapabilityEnquiry(
                                    (void*)&dl_dcch_msg,
                                    buffer,
                                    100);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -2532,9 +2564,12 @@ do_RRCConnectionReconfiguration(
                                    (void*)&dl_dcch_msg,
                                    buffer,
                                    RRC_BUF_SIZE);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %zd)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #ifdef XER_PRINT
   xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)&dl_dcch_msg);
 #endif
@@ -2745,9 +2780,12 @@ do_RRCConnectionReestablishment(
                                    (void*)&dl_ccch_msg,
                                    buffer,
                                    100);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -2803,9 +2841,12 @@ do_RRCConnectionReestablishmentReject(
                                    (void*)&dl_ccch_msg,
                                    buffer,
                                    100);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -2862,9 +2903,12 @@ do_RRCConnectionReject(
                                    (void*)&dl_ccch_msg,
                                    buffer,
                                    100);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %ld)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -3051,9 +3095,12 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id,
                                    (void*)mcch_message,
                                    buffer,
                                    100);
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -3180,12 +3227,12 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_
                                    (void*)&ul_dcch_msg,
                                    buffer,
                                    100);
-
-
-
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
-
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #if defined(ENABLE_ITTI)
 # if !defined(DISABLE_XER_SPRINT)
   {
@@ -3311,9 +3358,12 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin
           Mod_id, paging_record_p->cn_Domain, ue_paging_identity.presenceMask, pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count);
 
   enc_rval = uper_encode_to_buffer(&asn_DEF_PCCH_Message, (void*)&pcch_msg, buffer, RRC_BUF_SIZE);
-
-  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
-               enc_rval.failed_type->name, enc_rval.encoded);
+  if(enc_rval.encoded == -1)
+  {
+     LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n",
+           enc_rval.failed_type->name, enc_rval.encoded);
+     return -1;
+  }
 #ifdef XER_PRINT
   xer_fprint(stdout, &asn_DEF_PCCH_Message, (void*)&pcch_msg);
 #endif
diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c
index f4fae43db32a26513df5c5eca1bea580a921aa38..32f4f05aaec103068572ef5933ccad57bc61af48 100644
--- a/openair2/RRC/LTE/rrc_UE.c
+++ b/openair2/RRC/LTE/rrc_UE.c
@@ -85,7 +85,7 @@
 
 #include "openair2/LAYER2/MAC/mac_extern.h"
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 #include "SL-Preconfiguration-r12.h"
 
 //for D2D
@@ -138,7 +138,7 @@ static void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol
 static void rrc_ue_generate_MeasurementReport(protocol_ctxt_t* const ctxt_pP, uint8_t eNB_index );
 
 static uint8_t check_trigger_meas_event(
-  uint8_t module_idP,
+  module_id_t module_idP,
   frame_t frameP,
   uint8_t eNB_index,
   uint8_t ue_cnx_index,
@@ -454,7 +454,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index )
 			   UE->DRB_configList,
 			   (DRB_ToReleaseList_t*) NULL,
 			   0xff, NULL, NULL, NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                            , (PMCH_InfoList_r9_t *) NULL
 #endif
                            ,NULL);
@@ -463,7 +463,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index )
 			  (SRB_ToAddModList_t*)NULL,
 			  UE->DRB_configList,
 			  (DRB_ToReleaseList_t*)NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
 			  ,(PMCH_InfoList_r9_t *)NULL
 #endif
 			  );
@@ -1094,7 +1094,7 @@ rrc_ue_process_measConfig(
 			  0,
 			  0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -1613,7 +1613,7 @@ rrc_ue_process_radioResourceConfigDedicated(
 				0,
 				0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -1678,7 +1678,7 @@ rrc_ue_process_radioResourceConfigDedicated(
 				0,
 				0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -1792,7 +1792,7 @@ rrc_ue_process_radioResourceConfigDedicated(
 			      UE_rrc_inst[ue_mod_idP].num_active_cba_groups, //
 			      UE_rrc_inst[ue_mod_idP].cba_rnti[0]
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -2394,7 +2394,7 @@ rrc_ue_process_mobilityControlInfo(
 			,0,
 			0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -3282,7 +3282,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index,
 			0,
 			0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -3981,7 +3981,7 @@ uint64_t arfcn_to_freq(long arfcn) {
 			      ,0,
 			      0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -4167,7 +4167,7 @@ uint64_t arfcn_to_freq(long arfcn) {
 			      ,0,
 			      0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -4178,7 +4178,7 @@ uint64_t arfcn_to_freq(long arfcn) {
       }
 #endif
 
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
       //SIB18
     case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250:
        if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8192) == 0) {
@@ -4398,7 +4398,7 @@ void ue_meas_filtering( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_
         LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n",
               ctxt_pP->module_id, ctxt_pP->frame, eNB_index);
         result = pdcp_data_req(ctxt_pP,  SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                ,NULL, NULL
 #endif
                                );
@@ -4694,7 +4694,7 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB
 			0,
 			0
 #endif
-#if defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
            ,
            0,
            NULL,
@@ -5270,7 +5270,7 @@ openair_rrc_top_init_ue(
 
 #endif
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /* TODO: this is disabled for the moment because the standard UE
    * crashes when calling this function.
    */
@@ -5516,7 +5516,7 @@ rrc_ue_process_sidelink_radioResourceConfig(
    }
 }
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 //-----------------------------------------------------------
 void
 rrc_control_socket_init(){
@@ -5748,7 +5748,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                UE->DRB_configList,
                (DRB_ToReleaseList_t*) NULL,
                0xff, NULL, NULL, NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                , (PMCH_InfoList_r9_t *) NULL
 #endif
                ,NULL);
@@ -5758,7 +5758,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                (SRB_ToAddModList_t*)NULL,
                UE->DRB_configList,
                (DRB_ToReleaseList_t*)NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                ,(PMCH_InfoList_r9_t *)NULL
                , 0, 0
 #endif
@@ -5768,7 +5768,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                (SRB_ToAddModList_t*)NULL,
                UE->DRB_configList,
                (DRB_ToReleaseList_t*)NULL
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,(PMCH_InfoList_r9_t *)NULL
                , sourceL2Id, groupL2Id
 #endif
@@ -5779,7 +5779,7 @@ void *rrc_control_socket_thread_fct(void *arg)
          rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0
                (RadioResourceConfigCommonSIB_t *)NULL,
                (struct PhysicalConfigDedicated *)NULL,
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                (SCellToAddMod_r10_t *)NULL,
                //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
 #endif
@@ -5796,7 +5796,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                NULL,
                NULL,
                NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                ,0,
                (MBSFN_AreaInfoList_r9_t *)NULL,
                (PMCH_InfoList_r9_t *)NULL
@@ -5807,7 +5807,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                0,
                0
 #endif
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                ,CONFIG_ACTION_ADD,
                &sourceL2Id,
                &groupL2Id
@@ -5851,7 +5851,7 @@ void *rrc_control_socket_thread_fct(void *arg)
          rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0
                     (RadioResourceConfigCommonSIB_t *)NULL,
                     (struct PhysicalConfigDedicated *)NULL,
-         #if defined(Rel10) || defined(Rel14)
+         #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                     (SCellToAddMod_r10_t *)NULL,
                     //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
          #endif
@@ -5868,7 +5868,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                     NULL,
                     NULL,
                     NULL
-         #if defined(Rel10) || defined(Rel14)
+         #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                     ,0,
                     (MBSFN_AreaInfoList_r9_t *)NULL,
                     (PMCH_InfoList_r9_t *)NULL
@@ -5879,7 +5879,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                     0,
                     0
          #endif
-         #if defined(Rel10) || defined(Rel14)
+         #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                     ,CONFIG_ACTION_REMOVE,
                     &sourceL2Id,
                     &destinationL2Id
@@ -5996,7 +5996,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                UE->DRB_configList,
                (DRB_ToReleaseList_t*) NULL,
                0xff, NULL, NULL, NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                , (PMCH_InfoList_r9_t *) NULL
 #endif
                ,NULL);
@@ -6006,7 +6006,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                (SRB_ToAddModList_t*)NULL,
                UE->DRB_configList,
                (DRB_ToReleaseList_t*)NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                ,(PMCH_InfoList_r9_t *)NULL
                , 0, 0
 #endif
@@ -6016,7 +6016,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                (SRB_ToAddModList_t*)NULL,
                UE->DRB_configList,
                (DRB_ToReleaseList_t*)NULL
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                ,(PMCH_InfoList_r9_t *)NULL
                , sourceL2Id, destinationL2Id
 #endif
@@ -6027,7 +6027,7 @@ void *rrc_control_socket_thread_fct(void *arg)
          rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0
                (RadioResourceConfigCommonSIB_t *)NULL,
                (struct PhysicalConfigDedicated *)NULL,
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                (SCellToAddMod_r10_t *)NULL,
                //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
 #endif
@@ -6044,7 +6044,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                NULL,
                NULL,
                NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                ,0,
                (MBSFN_AreaInfoList_r9_t *)NULL,
                (PMCH_InfoList_r9_t *)NULL
@@ -6055,7 +6055,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                0,
                0
 #endif
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                ,CONFIG_ACTION_ADD,
                &sourceL2Id,
                &destinationL2Id
@@ -6180,7 +6180,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                UE->DRB_configList,
                (DRB_ToReleaseList_t*) NULL,
                0xff, NULL, NULL, NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                , (PMCH_InfoList_r9_t *) NULL
 #endif
                ,NULL);
@@ -6190,7 +6190,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                (SRB_ToAddModList_t*)NULL,
                UE->DRB_configList,
                (DRB_ToReleaseList_t*)NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                ,(PMCH_InfoList_r9_t *)NULL
                , 0, 0
 #endif
@@ -6202,7 +6202,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                   (SRB_ToAddModList_t*)NULL,
                   UE->DRB_configList,
                   (DRB_ToReleaseList_t*)NULL
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                   ,(PMCH_InfoList_r9_t *)NULL
                   , sourceL2Id, destinationL2Id
 #endif
@@ -6212,7 +6212,7 @@ void *rrc_control_socket_thread_fct(void *arg)
             rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0
                   (RadioResourceConfigCommonSIB_t *)NULL,
                   (struct PhysicalConfigDedicated *)NULL,
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                   (SCellToAddMod_r10_t *)NULL,
                   //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
 #endif
@@ -6229,7 +6229,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                   NULL,
                   NULL,
                   NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                   ,0,
                   (MBSFN_AreaInfoList_r9_t *)NULL,
                   (PMCH_InfoList_r9_t *)NULL
@@ -6240,7 +6240,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                   0,
                   0
 #endif
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                   ,CONFIG_ACTION_ADD,
                   &sourceL2Id,
                   &destinationL2Id
@@ -6251,7 +6251,7 @@ void *rrc_control_socket_thread_fct(void *arg)
             rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0
                   (RadioResourceConfigCommonSIB_t *)NULL,
                   (struct PhysicalConfigDedicated *)NULL,
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                   (SCellToAddMod_r10_t *)NULL,
                   //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10,
 #endif
@@ -6268,7 +6268,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                   NULL,
                   NULL,
                   NULL
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                   ,0,
                   (MBSFN_AreaInfoList_r9_t *)NULL,
                   (PMCH_InfoList_r9_t *)NULL
@@ -6279,7 +6279,7 @@ void *rrc_control_socket_thread_fct(void *arg)
                   0,
                   0
 #endif
-#if defined(Rel10) || defined(Rel14)
+#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                   ,CONFIG_ACTION_ADD,
                   &sourceL2Id,
                   NULL
diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h
index 4719eebd614d5ef178efdd9762936fe929d5877e..e21cb9255a6a0cc7cb275b3c21230383ae987820 100644
--- a/openair2/RRC/LTE/rrc_defs.h
+++ b/openair2/RRC/LTE/rrc_defs.h
@@ -192,7 +192,9 @@ void *send_UE_status_notification(void *);
 #include "AS-Context.h"
 #include "UE-EUTRA-Capability.h"
 #include "MeasResults.h"
+#if (RRC_VERSION >= MAKE_VERSION(12, 0, 0))
 #include "SidelinkUEInformation-r12.h"
+#endif
 
 /* for ImsiMobileIdentity_t */
 #include "MobileIdentity.h"
@@ -382,11 +384,7 @@ typedef enum SL_TRIGGER_e {
 // #define NUM_MAX_CBA_GROUP 4 // in the platform_constants
 
 /* TS 36.331: RRC-TransactionIdentifier ::= INTEGER (0..3) */
-#if defined(USRP_REC_PLAY)
-#define RRC_TRANSACTION_IDENTIFIER_NUMBER  1
-#else
 #define RRC_TRANSACTION_IDENTIFIER_NUMBER  3
-#endif
 
 typedef struct {
   unsigned short transport_block_size;                  /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */
@@ -602,6 +600,7 @@ typedef struct eNB_RRC_UE_s {
   uint32_t                           ue_reestablishment_timer;
   uint32_t                           ue_reestablishment_timer_thres;
   uint8_t                            e_rab_release_command_flag;
+  int8_t                             reestablishment_xid;
 } eNB_RRC_UE_t;
 
 typedef uid_t ue_uid_t;
@@ -760,7 +759,7 @@ typedef struct UE_RRC_INST_s {
   SystemInformationBlockType10_t *sib10[NB_CNX_UE];
   SystemInformationBlockType11_t *sib11[NB_CNX_UE];
   uint8_t                           *MIB;
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   //SIB18
   SystemInformationBlockType18_r12_t *sib18[NB_CNX_UE];
   SystemInformationBlockType19_r12_t *sib19[NB_CNX_UE];
@@ -828,7 +827,7 @@ typedef struct UE_RRC_INST_s {
   CipheringAlgorithm_r12_t                          ciphering_algorithm;
   e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   /// Used for Sidelink Preconfiguration
   DRB_ToAddModList_t *DRB_configList;
 #endif
diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c
index e3e60184455826112a72816f8ef6500c3435c373..492e8536c4d451feabb44063ec81818648f99a42 100644
--- a/openair2/RRC/LTE/rrc_eNB.c
+++ b/openair2/RRC/LTE/rrc_eNB.c
@@ -555,7 +555,7 @@ static void init_MBMS(
                             NULL,   // DRB_ToReleaseList
                             &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9)
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                             ,0, 0
 #endif
                             );
@@ -671,18 +671,6 @@ rrc_eNB_get_next_free_ue_context(
 					ctxt_pP->rnti);
 
   if (ue_context_p == NULL) {
-#if 0
-    RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
-      if (ue_context_p->ue_context.random_ue_identity == ue_identityP) {
-        LOG_D(RRC,
-              PROTOCOL_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist rand UE id 0x%"PRIx64", uid %u\n",
-              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-              ue_identityP,
-              ue_context_p->local_uid);
-        return NULL;
-      }
-    }
-#endif
     ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]);
 
     if (ue_context_p == NULL) {
@@ -903,14 +891,10 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*
   (void)ue_module_id;
 #endif
   rnti_t rnti = ue_context_pP->ue_context.rnti;
-  int i, j , CC_id, pdu_number;
-  LTE_eNB_ULSCH_t *ulsch = NULL;
-  LTE_eNB_DLSCH_t *dlsch = NULL;
-  nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
-  PHY_VARS_eNB *eNB_PHY = NULL;
-  eNB_MAC_INST *eNB_MAC = RC.mac[enb_mod_idP];
-
-  AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB inst invalid (%d/%d) for UE %x!", enb_mod_idP, NB_eNB_INST, rnti);
+  if (enb_mod_idP >= NB_eNB_INST) {
+      LOG_I(RRC, "eNB inst invalid (%d/%d) for UE %x!\n",enb_mod_idP, NB_eNB_INST,rnti);
+      return;
+  }
   /*  ue_context_p = rrc_eNB_get_ue_context(
                    &RC.rrc[enb_mod_idP],
                    rntiP
@@ -921,8 +905,9 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*
     LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", enb_mod_idP, rnti);
 
 #if defined(ENABLE_USE_MME)
-   if( ue_context_pP->ue_context.ul_failure_timer >= 8 ) {
-	LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti);
+   if((ue_context_pP->ue_context.ul_failure_timer >= 20000) &&
+      (mac_eNB_get_rrc_status(enb_mod_idP,rnti) >= RRC_CONNECTED)) {
+    LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti);
     rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); // send cause 21: connection with ue lost
     /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered)
      * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before
@@ -933,55 +918,133 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*
      return;
     }
 #endif
-    for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-      eNB_PHY = RC.eNB[enb_mod_idP][CC_id];
-      for (i=0; i<MAX_MOBILES_PER_ENB; i++) {
-        ulsch = eNB_PHY->ulsch[i];
-        if((ulsch != NULL) && (ulsch->rnti == rnti)){
-          void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
-          LOG_I(RRC, "clean_eNb_ulsch UE %x \n", rnti);
-          clean_eNb_ulsch(ulsch);
-        }
-      }
-      for (i=0; i<MAX_MOBILES_PER_ENB; i++) {
-        dlsch = eNB_PHY->dlsch[i][0];
-        if((dlsch != NULL) && (dlsch->rnti == rnti)){
-          void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
-          LOG_I(RRC, "clean_eNb_dlsch UE %x \n", rnti);
-          clean_eNb_dlsch(dlsch);
-        }
-      }
+    // add UE info to freeList
+    LOG_I(RRC, "put UE %x into freeList\n", rnti);
+    put_UE_in_freelist(enb_mod_idP, rnti, 1);
+  }
+}
 
-      if (rrc_agent_registered[enb_mod_idP]) {
-        agent_rrc_xface[enb_mod_idP]->flexran_agent_notify_ue_state_change(enb_mod_idP,
-                              rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
-      }
+void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti)
+{
 
-      for(j = 0; j < 10; j++){
-        ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
-        if(ul_req_tmp){
-          pdu_number = ul_req_tmp->number_of_pdus;
-          for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
-            if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti){
-              LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
-              if(pdu_index < pdu_number -1){
-                memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
+    eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
+    pthread_mutex_lock(&lock_ue_freelist);
+    UE_free_list_t                           *free_list = &eNB_MAC->UE_free_list;
+    free_list->UE_free_ctrl[free_list->head_freelist].rnti = 0;
+    free_list->head_freelist = (free_list->head_freelist + 1) % (NUMBER_OF_UE_MAX+1);
+    free_list->num_UEs--;
+    pthread_mutex_unlock(&lock_ue_freelist);
+}
+
+void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag)
+{
+    UE_free_list_t                           *free_list = NULL;
+    eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
+    pthread_mutex_lock(&lock_ue_freelist);
+    free_list = &eNB_MAC->UE_free_list;
+    free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti;
+    free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag;
+    free_list->num_UEs++;
+    free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1);
+    pthread_mutex_unlock(&lock_ue_freelist);
+}
+
+void release_UE_in_freeList(module_id_t mod_id)
+{
+    int i, j , CC_id, pdu_number;
+    protocol_ctxt_t                           ctxt;
+    LTE_eNB_ULSCH_t                          *ulsch = NULL;
+    LTE_eNB_DLSCH_t                          *dlsch = NULL;
+    nfapi_ul_config_request_body_t           *ul_req_tmp = NULL;
+    PHY_VARS_eNB                             *eNB_PHY = NULL;
+    struct rrc_eNB_ue_context_s              *ue_context_pP = NULL;
+    eNB_MAC_INST                             *eNB_MAC = RC.mac[mod_id];
+    boolean_t                                 remove_UEContext;
+    rnti_t                                    rnti;
+    int                                       head, tail, ue_num;
+
+    pthread_mutex_lock(&lock_ue_freelist);
+    head = eNB_MAC->UE_free_list.head_freelist;
+    tail = eNB_MAC->UE_free_list.tail_freelist;
+    if(head == tail){
+        pthread_mutex_unlock(&lock_ue_freelist);
+        return;
+    }
+    if(tail < head){
+        tail = head + eNB_MAC->UE_free_list.num_UEs;
+    }
+    pthread_mutex_unlock(&lock_ue_freelist);
+
+    for(ue_num = head; ue_num < tail; ue_num++){
+        ue_num = ue_num % (NUMBER_OF_UE_MAX+1);
+        rnti = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].rnti;
+        if(rnti != 0){
+            remove_UEContext = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].removeContextFlg;
+            PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id);
+            for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+              eNB_PHY = RC.eNB[mod_id][CC_id];
+              for (i=0; i<MAX_MOBILES_PER_ENB; i++) {
+                ulsch = eNB_PHY->ulsch[i];
+                if((ulsch != NULL) && (ulsch->rnti == rnti)){
+                  void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
+                  LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti);
+                  clean_eNb_ulsch(ulsch);
+                }
+                if(eNB_PHY->uci_vars[i].rnti == rnti){
+                  LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti);
+                  memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI));
+                }
+              }
+              for (i=0; i<MAX_MOBILES_PER_ENB; i++) {
+                dlsch = eNB_PHY->dlsch[i][0];
+                if((dlsch != NULL) && (dlsch->rnti == rnti)){
+                  void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch);
+                  LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti);
+                  clean_eNb_dlsch(dlsch);
+                }
+              }
+
+              if (rrc_agent_registered[mod_id]) {
+                agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change(mod_id,
+                            rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
+              }
+
+              for(j = 0; j < 10; j++){
+                ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
+                if(ul_req_tmp){
+                  pdu_number = ul_req_tmp->number_of_pdus;
+                  for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
+                    if((ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) ||
+                       (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) ||
+                       (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti) ||
+                       (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) ||
+                       (ul_req_tmp->ul_config_pdu_list[pdu_index].srs_pdu.srs_pdu_rel8.rnti == rnti)){
+                        LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number);
+                        if(pdu_index < pdu_number -1){
+                          memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
+                        }
+                        ul_req_tmp->number_of_pdus--;
+                    }
+                  }
+                }
               }
-              ul_req_tmp->number_of_pdus--;
             }
-          }
+            rrc_mac_remove_ue(mod_id,rnti);
+            rrc_rlc_remove_ue(&ctxt);
+            pdcp_remove_UE(&ctxt);
+
+            if(remove_UEContext){
+                ue_context_pP = rrc_eNB_get_ue_context(
+                                 RC.rrc[mod_id],rnti);
+                if(ue_context_pP){
+                    rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id],
+                        (struct rrc_eNB_ue_context_s*) ue_context_pP);
+                }
+            }
+            LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti);
+            remove_UE_from_freelist(mod_id, rnti);
         }
-      }
     }
-    rrc_mac_remove_ue(enb_mod_idP,rnti);
-    rrc_rlc_remove_ue(&ctxt);
-    pdcp_remove_UE(&ctxt);
-
-    rrc_eNB_remove_ue_context(
-      &ctxt,
-      RC.rrc[enb_mod_idP],
-      (struct rrc_eNB_ue_context_s*) ue_context_pP);
-  }
 }
 
 //-----------------------------------------------------------------------------
@@ -1292,21 +1355,26 @@ rrc_eNB_generate_RRCConnectionReestablishment(
                      ue_context_pP->ue_context.rnti,
                      RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
 
-
   LOG_I(RRC,
         PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionReestablishment (bytes %d)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
 
-  // activate release timer, if RRCComplete not received after 10 frames, remove UE
-  //ue_context_pP->ue_context.ue_release_timer = 1;
-  // remove UE after 10 frames after RRCConnectionReestablishmentRelease is triggered
-  //ue_context_pP->ue_context.ue_release_timer_thres = 100;
-    // activate release timer, if RRCComplete not received after 100 frames, remove UE
   int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
-  RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
+  if(UE_id != -1){
+    // activate release timer, if RRCComplete not received after 100 frames, remove UE
+    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
+    // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered
+    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000;
+  }else{
+    LOG_E(RRC,
+             PROTOCOL_RRC_CTXT_UE_FMT" Generating RRCConnectionReestablishment without UE_id(MAC) rnti %x\n",
+            PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
+  }
+  // activate release timer, if RRCComplete not received after 100 frames, remove UE
+  ue_context_pP->ue_context.ue_reestablishment_timer = 1;
   // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered
-  RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000;
+  ue_context_pP->ue_context.ue_reestablishment_timer_thres = 1000;
 }
 
 //-----------------------------------------------------------------------------
@@ -1360,12 +1428,15 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);
 
   ue_context_pP->ue_context.Status = RRC_CONNECTED;
+  ue_context_pP->ue_context.reestablishment_xid = next_xid;
 
   SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid];
   // get old configuration of SRB2
   if (*SRB_configList2 != NULL) {
-    LOG_D(RRC, "SRB_configList2(%p) count is %d\n           SRB_configList2->list.array[0] addr is %p",
+    if((*SRB_configList2)->list.count!=0){
+      LOG_D(RRC, "SRB_configList2(%p) count is %d\n           SRB_configList2->list.array[0] addr is %p",
           SRB_configList2, (*SRB_configList2)->list.count,  (*SRB_configList2)->list.array[0]);
+    }
     for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) {
       if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ){
         LOG_D(RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid);
@@ -1377,9 +1448,13 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[next_xid];
   DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[next_xid];
 
-  if (*SRB_configList2) {
-    free(*SRB_configList2);
-    LOG_D(RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid);
+  if(SRB_configList2!=NULL){
+    if (*SRB_configList2) {
+      free(*SRB_configList2);
+      LOG_D(RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid);
+    }
+  }else{
+      LOG_E(RRC, "SRB_configList2 is null\n");
   }
   *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
   if (SRB2_config != NULL) {
@@ -1399,9 +1474,13 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
 
 
 
-  if (*DRB_configList2) {
-    free(*DRB_configList2);
-    LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
+  if(DRB_configList2!=NULL){
+    if (*DRB_configList2) {
+      free(*DRB_configList2);
+      LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
+    }
+  }else{
+      LOG_E(RRC, "DRB_configList2 is null\n");
   }
   *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
 
@@ -1441,7 +1520,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
 
   for (j = 0, i = 0; i < NB_RB_MAX; i++) {
-    if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED) {
+    if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) {
       create_tunnel_req.eps_bearer_id[j]       = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
       create_tunnel_req.sgw_S1u_teid[j]        = ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
 
@@ -1858,74 +1937,81 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   }
 
 #endif
+  if(size==65535){
+    LOG_E(RRC,"RRC decode err!!! do_RRCConnectionReconfiguration\n");
+    put_UE_in_freelist(ctxt_pP->module_id, reestablish_rnti, 0);
+    return;
+  }else{
+    LOG_I(RRC,
+          "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
+          ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
 
-  LOG_I(RRC,
-        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n",
-        ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti);
-
-  LOG_D(RRC,
-        "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
-        ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
-
-  MSC_LOG_TX_MESSAGE(
-    MSC_RRC_ENB,
-    MSC_RRC_UE,
-    buffer,
-    size,
-    MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u",
-    MSC_AS_TIME_ARGS(ctxt_pP),
-    ue_context_pP->ue_context.rnti,
-    rrc_eNB_mui,
-    size);
-
-  rrc_data_req(
-         ctxt_pP,
-         DCCH,
-         rrc_eNB_mui++,
-         SDU_CONFIRM_NO,
-         size,
-         buffer,
-         PDCP_TRANSMISSION_MODE_CONTROL);
-
-  // delete UE data of prior RNTI.  UE use current RNTI.
-  protocol_ctxt_t ctxt_prior = *ctxt_pP;
-  ctxt_prior.rnti = reestablish_rnti;
-
-  LTE_eNB_ULSCH_t *ulsch = NULL;
-  nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
-  PHY_VARS_eNB *eNB_PHY = NULL;
-  eNB_MAC_INST *eNB_MAC = RC.mac[ctxt_prior.module_id];
-  for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
-    eNB_PHY = RC.eNB[ctxt_prior.module_id][CC_id];
-    for (int i=0; i<MAX_MOBILES_PER_ENB; i++) {
-      ulsch = eNB_PHY->ulsch[i];
-      if((ulsch != NULL) && (ulsch->rnti == ctxt_prior.rnti)){
-        void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
-        LOG_I(RRC, "clean_eNb_ulsch UE %x \n", ctxt_prior.rnti);
-        clean_eNb_ulsch(ulsch);
-        break;
-      }
-    }
-
-    for(int j = 0; j < 10; j++){
-      ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
-      if(ul_req_tmp){
-        int pdu_number = ul_req_tmp->number_of_pdus;
-        for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
-          if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == ctxt_prior.rnti){
-            LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", ctxt_prior.rnti, pdu_index, pdu_number);
-            if(pdu_index < pdu_number -1){
-               memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
-            }
-            ul_req_tmp->number_of_pdus--;
-          }
-        }
-      }
-    }
+    LOG_D(RRC,
+          "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n",
+          ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH);
+
+    MSC_LOG_TX_MESSAGE(
+      MSC_RRC_ENB,
+      MSC_RRC_UE,
+      buffer,
+      size,
+      MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u",
+      MSC_AS_TIME_ARGS(ctxt_pP),
+      ue_context_pP->ue_context.rnti,
+      rrc_eNB_mui,
+      size);
+
+    rrc_data_req(
+           ctxt_pP,
+           DCCH,
+           rrc_eNB_mui++,
+           SDU_CONFIRM_NO,
+           size,
+           buffer,
+           PDCP_TRANSMISSION_MODE_CONTROL);
   }
-  rrc_mac_remove_ue(ctxt_prior.module_id, ctxt_prior.rnti);
-  rrc_rlc_remove_ue(&ctxt_prior);
-  pdcp_remove_UE(&ctxt_prior);
+  // delete UE data of prior RNTI.  UE use current RNTI.
+//  protocol_ctxt_t ctxt_prior = *ctxt_pP;
+//  ctxt_prior.rnti = reestablish_rnti;
+//
+//  LTE_eNB_ULSCH_t *ulsch = NULL;
+//  nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
+//  PHY_VARS_eNB *eNB_PHY = NULL;
+//  eNB_MAC_INST *eNB_MAC = RC.mac[ctxt_prior.module_id];
+//  for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+//    eNB_PHY = RC.eNB[ctxt_prior.module_id][CC_id];
+//    for (int i=0; i<MAX_MOBILES_PER_ENB; i++) {
+//      ulsch = eNB_PHY->ulsch[i];
+//      if((ulsch != NULL) && (ulsch->rnti == ctxt_prior.rnti)){
+//        void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch);
+//        LOG_I(RRC, "clean_eNb_ulsch UE %x \n", ctxt_prior.rnti);
+//        clean_eNb_ulsch(ulsch);
+//        break;
+//      }
+//    }
+//
+//    for(int j = 0; j < 10; j++){
+//      ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body;
+//      if(ul_req_tmp){
+//        int pdu_number = ul_req_tmp->number_of_pdus;
+//        for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){
+//          if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == ctxt_prior.rnti){
+//            LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", ctxt_prior.rnti, pdu_index, pdu_number);
+//            if(pdu_index < pdu_number -1){
+//               memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t));
+//            }
+//            ul_req_tmp->number_of_pdus--;
+//          }
+//        }
+//      }
+//    }
+//  }
+//  rrc_mac_remove_ue(ctxt_prior.module_id, ctxt_prior.rnti);
+//  rrc_rlc_remove_ue(&ctxt_prior);
+//  pdcp_remove_UE(&ctxt_prior);
+  // add UE info to freeList for RU_thread to remove the UE instead of remove it here
+  LOG_I(RRC, "[RRCConnectionReestablishment]put UE %x into freeList\n", reestablish_rnti);
+  put_UE_in_freelist(ctxt_pP->module_id, reestablish_rnti, 0);
 }
 
 //-----------------------------------------------------------------------------
@@ -1941,8 +2027,14 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject(
   int                                 cnt;
 #endif
   int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
-  RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
-  RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20;
+  if(UE_id != -1){
+    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1;
+    RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20;
+  }else{
+    LOG_E(RRC,
+            PROTOCOL_RRC_CTXT_UE_FMT" Generating RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n",
+            PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
+  }
 
   T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
@@ -1993,19 +2085,18 @@ rrc_eNB_generate_RRCConnectionRelease(
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
 
   memset(buffer, 0, RRC_BUF_SIZE);
-
   size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id));
   // set release timer
   //ue_context_pP->ue_context.ue_release_timer=1;
   // remove UE after 10 frames after RRCConnectionRelease is triggered
   //ue_context_pP->ue_context.ue_release_timer_thres=100;
     // set release timer
-  ue_context_pP->ue_context.ue_release_timer_rrc = 1;
+//  ue_context_pP->ue_context.ue_release_timer_rrc = 1;
   // remove UE after 10 frames after RRCConnectionRelease is triggered
-  ue_context_pP->ue_context.ue_release_timer_thres_rrc = 100;
+//  ue_context_pP->ue_context.ue_release_timer_thres_rrc = 100;
   ue_context_pP->ue_context.ue_reestablishment_timer = 0;
   ue_context_pP->ue_context.ue_release_timer = 0;
-  ue_context_pP->ue_context.ue_release_timer_s1 = 0;
+  //ue_context_pP->ue_context.ue_release_timer_s1 = 0;
   LOG_I(RRC,
         PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
@@ -2028,7 +2119,23 @@ rrc_eNB_generate_RRCConnectionRelease(
     ue_context_pP->ue_context.rnti,
     rrc_eNB_mui,
     size);
-
+  pthread_mutex_lock(&rrc_release_freelist);
+  for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
+    if(rrc_release_info.RRC_release_ctrl[release_num].flag == 0){
+      if(ue_context_pP->ue_context.ue_release_timer_s1 > 0){
+        rrc_release_info.RRC_release_ctrl[release_num].flag = 1;
+      }else{
+        rrc_release_info.RRC_release_ctrl[release_num].flag = 2;
+      }
+      rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt_pP->rnti;
+      rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = rrc_eNB_mui;
+      rrc_release_info.num_UEs++;
+      LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num,
+             ctxt_pP->rnti, rrc_eNB_mui,rrc_release_info.RRC_release_ctrl[release_num].flag);
+      break;
+    }
+  }
+  pthread_mutex_unlock(&rrc_release_freelist);
   rrc_data_req(
 	       ctxt_pP,
 	       DCCH,
@@ -4383,11 +4490,16 @@ check_handovers(
                                ue_context_p->ue_context.handover_info->size,
                                ue_context_p->ue_context.handover_info->buf,
                                PDCP_TRANSMISSION_MODE_CONTROL
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
                                ,NULL, NULL
 #endif
                                );
-        AssertFatal(result == TRUE, "PDCP data request failed!\n");
+        //AssertFatal(result == TRUE, "PDCP data request failed!\n");
+        if(result != TRUE)
+        {
+          LOG_I(RRC, "PDCP data request failed!\n");
+          return;
+        }
         ue_context_p->ue_context.handover_info->ho_complete = 0xF2;
       }
     }
@@ -5773,9 +5885,6 @@ rrc_eNB_generate_RRCConnectionSetup(
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
         RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
 
-  // activate release timer, if RRCSetupComplete not received after 10 frames, remove UE
-  //ue_context_pP->ue_context.ue_release_timer=1;
-  // remove UE after 10 frames after RRCConnectionRelease is triggered
   //ue_context_pP->ue_context.ue_release_timer_thres=100;
      // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE
    ue_context_pP->ue_context.ue_release_timer=1;
@@ -6125,26 +6234,57 @@ rrc_eNB_decode_ccch(
         break;
       }
       int UE_id = find_UE_id(ctxt_pP->module_id, c_rnti);
-      if(ue_context_p->ue_context.ue_reestablishment_timer > 0 || RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0){
-          LOG_I(RRC,
-                PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishment(Previous) don't complete, let's reject the UE\n",
-                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+      if(UE_id == -1){
+          LOG_E(RRC,
+                PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest without UE_id(MAC) rnti %x, let's reject the UE\n",
+                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti);
           rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
           break;
       }
+
+      if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) &&
+         (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)){
+    	  LOG_E(RRC,
+                PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the Previous UE\n",
+                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+          RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000;
+          ue_context_p->ue_context.ue_reestablishment_timer = 0;
+      }
+
+      if(ue_context_p->ue_context.ue_reestablishment_timer > 0){
+    	  LOG_E(RRC,
+                PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE\n",
+                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+          ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+          protocol_ctxt_t  ctxt_old_p;
+          PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p,
+                                        ctxt_pP->instance,
+                                        ENB_FLAG_YES,
+                                        c_rnti,
+                                        ctxt_pP->frame,
+                                        ctxt_pP->subframe);
+          rrc_eNB_process_RRCConnectionReconfigurationComplete(&ctxt_old_p,
+                                                                ue_context_p,
+                                                                ue_context_p->ue_context.reestablishment_xid);
+          for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+            if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
+              ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
+            } else {
+              ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
+            }
+          }
+      }
       LOG_D(RRC,
             PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n",
             PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
             ue_context_p);
+      /* reset timers */
       ue_context_p->ue_context.ul_failure_timer = 0;
       ue_context_p->ue_context.ue_release_timer = 0;
       ue_context_p->ue_context.ue_reestablishment_timer = 0;
       ue_context_p->ue_context.ue_release_timer_s1 = 0;
       ue_context_p->ue_context.ue_release_timer_rrc = 0;
-
-      /* reset timers */
-      ue_context_p->ue_context.ul_failure_timer = 0;
-      ue_context_p->ue_context.ue_release_timer = 0;
+      ue_context_p->ue_context.reestablishment_xid = -1;
 
       // insert C-RNTI to map
       for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
@@ -6272,26 +6412,18 @@ rrc_eNB_decode_ccch(
         rrcConnectionRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest.criticalExtensions.choice.rrcConnectionRequest_r8;
         {
           if (InitialUE_Identity_PR_randomValue == rrcConnectionRequest->ue_Identity.present) {
-            AssertFatal(rrcConnectionRequest->ue_Identity.choice.randomValue.size == 5,
-                        "wrong InitialUE-Identity randomValue size, expected 5, provided %d",
-                        rrcConnectionRequest->ue_Identity.choice.randomValue.size);
+          if(rrcConnectionRequest->ue_Identity.choice.randomValue.size != 5)
+          {
+            LOG_I(RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %d",
+                         rrcConnectionRequest->ue_Identity.choice.randomValue.size);
+            return -1;
+          }
             memcpy(((uint8_t*) & random_value) + 3,
                    rrcConnectionRequest->ue_Identity.choice.randomValue.buf,
                    rrcConnectionRequest->ue_Identity.choice.randomValue.size);
             /* if there is already a registered UE (with another RNTI) with this random_value,
              * the current one must be removed from MAC/PHY (zombie UE)
              */
-#if 0
-            if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) {
-              LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n",
-                    ctxt_pP->rnti, ue_context_p->ue_context.rnti, ctxt_pP->rnti);
-	      rrc_mac_remove_ue(ctxt_pP->module_id, ctxt_pP->rnti);
-              ue_context_p = NULL;
-              return 0;
-            } else {
-              ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
-            }
-#endif
             if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) {
               LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n",
                     ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti);
@@ -6321,6 +6453,7 @@ rrc_eNB_decode_ccch(
               ue_context_p->ue_context.ue_reestablishment_timer = 0;
               ue_context_p->ue_context.ue_release_timer_s1 = 0;
               ue_context_p->ue_context.ue_release_timer_rrc = 0;
+              ue_context_p->ue_context.reestablishment_xid = -1;
             } else {
 	      LOG_I(RRC," S-TMSI doesn't exist, setting Initialue_identity_s_TMSI.m_tmsi to %p => %x\n",ue_context_p,m_tmsi);
 //              ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, NOT_A_RANDOM_UE_IDENTITY);
@@ -6600,6 +6733,11 @@ rrc_eNB_decode_dcch(
       break;
 
     case UL_DCCH_MessageType__c1_PR_measurementReport:
+      // to avoid segmentation fault
+      if(!ue_context_p){
+        LOG_I(RRC, "Processing measurementReport UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
+        break;
+      }
       LOG_D(RRC,
             PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND "
             "%d bytes (measurementReport) ---> RRC_eNB\n",
@@ -6614,6 +6752,11 @@ rrc_eNB_decode_dcch(
       break;
 
     case UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete:
+      // to avoid segmentation fault
+      if(!ue_context_p){
+        LOG_I(RRC, "Processing RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
+        break;
+      }
 #ifdef RRC_MSG_PRINT
       LOG_F(RRC,"[MSG] RRC Connection Reconfiguration Complete\n");
 
@@ -6644,18 +6787,44 @@ rrc_eNB_decode_dcch(
           present ==
           RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8) {
 	/*NN: revise the condition */
+	/*FK: left the condition as is for the case MME is used (S1 mode) but setting  dedicated_DRB = 1 otherwise (noS1 mode) so that no second RRCReconfiguration message activationg more DRB is sent as this causes problems with the nasmesh driver.*/
+#if defined(ENABLE_USE_MME)
         if (ue_context_p->ue_context.Status == RRC_RECONFIGURED){
 	  dedicated_DRB = 1;
 	  LOG_I(RRC,
 		PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n",
 		PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
-	}else {
+          //clear
+          int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
+          if(UE_id == -1){
+            LOG_E(RRC,
+                  PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n",
+                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
+            break;
+          }
+          if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1){
+            LOG_I(RRC,
+                  PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n",
+                  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+            dedicated_DRB = 2;
+            RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0;
+          }
+	} else {
 	  dedicated_DRB = 0;
 	  ue_context_p->ue_context.Status = RRC_RECONFIGURED;
-	  LOG_I(RRC,
-		PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n",
-		PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+          LOG_I(RRC,
+                PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n",
+                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
 	}
+        ue_context_p->ue_context.reestablishment_xid = -1;
+#else
+	dedicated_DRB = 1;
+	ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+	LOG_I(RRC,
+	    PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n",
+	    PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+#endif
+	
 	rrc_eNB_process_RRCConnectionReconfigurationComplete(
           ctxt_pP,
           ue_context_p,
@@ -6712,7 +6881,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
                              ue_context_p,
                              ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
           }
-	}else {
+  }else if(dedicated_DRB == 0){
           if(ue_context_p->ue_context.reestablishment_cause == ReestablishmentCause_spare1){
 	    rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP,
 						       ue_context_p);
@@ -6726,7 +6895,15 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
               }
             }
           }
-	}
+  }else if(dedicated_DRB == 2){
+             for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+               if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
+                 ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
+               } else {
+                 ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
+               }
+             }
+         }
       }    
 #else  // establish a dedicated bearer 
       if (dedicated_DRB == 0 ) {
@@ -6769,8 +6946,6 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
             DCCH,
             sdu_sizeP);
        {
-        int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
-        RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
         rnti_t reestablish_rnti = 0;
         // select C-RNTI from map
         for (i = 0; i < MAX_MOBILES_PER_ENB; i++) {
@@ -6794,6 +6969,16 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
                 PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
           break;
         }
+        //clear
+        int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti);
+        if(UE_id == -1){
+          LOG_E(RRC,
+                PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n",
+                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti);
+          break;
+        }
+        RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
+        ue_context_p->ue_context.ue_reestablishment_timer = 0;
 
         if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present ==
             RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) {
@@ -6816,6 +7001,11 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
       break;
 
     case UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete:
+      // to avoid segmentation fault
+      if(!ue_context_p){
+        LOG_I(RRC, "Processing RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
+        break;
+      }
 #ifdef RRC_MSG_PRINT
       LOG_F(RRC,"[MSG] RRC Connection SetupComplete\n");
 
@@ -6871,7 +7061,11 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
     case UL_DCCH_MessageType__c1_PR_securityModeComplete:
       T(T_ENB_RRC_SECURITY_MODE_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
         T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-
+      // to avoid segmentation fault
+      if(!ue_context_p){
+        LOG_I(RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
+        break;
+      }
 #ifdef RRC_MSG_PRINT
       LOG_F(RRC,"[MSG] RRC Security Mode Complete\n");
 
@@ -6956,7 +7150,11 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
     case UL_DCCH_MessageType__c1_PR_ueCapabilityInformation:
       T(T_ENB_RRC_UE_CAPABILITY_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
         T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
-
+      // to avoid segmentation fault
+      if(!ue_context_p){
+          LOG_I(RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
+          break;
+      }
 #ifdef RRC_MSG_PRINT
       LOG_F(RRC,"[MSG] RRC UECapablility Information \n");
 
@@ -7050,6 +7248,11 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
     case UL_DCCH_MessageType__c1_PR_ulInformationTransfer:
       T(T_ENB_RRC_UL_INFORMATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
         T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
+      // to avoid segmentation fault
+      if(!ue_context_p){
+          LOG_I(RRC, "Processing ulInformationTransfer UE %x, ue_context_p is NULL\n", ctxt_pP->rnti);
+          break;
+      }
 
       LOG_D(RRC,"[MSG] RRC UL Information Transfer \n");
 #ifdef RRC_MSG_PRINT
@@ -7243,6 +7446,10 @@ rrc_enb_task(
   int                                 CC_id;
 
   protocol_ctxt_t                     ctxt;
+
+  pthread_mutex_init(&lock_ue_freelist, NULL);
+  pthread_mutex_init(&rrc_release_freelist, NULL);
+  memset(&rrc_release_info,0,sizeof(RRC_release_list_t));
   itti_mark_task_ready(TASK_RRC_ENB);
   LOG_I(RRC,"Entering main loop of RRC message task\n");
   while (1) {
@@ -7280,9 +7487,10 @@ rrc_enb_task(
 
       LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n",
 	    instance,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
-      AssertFatal(RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size < RRC_BUFFER_SIZE_MAX,
-		  "CCCH message has size %d > %d\n",
-		  RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX);
+      if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= RRC_BUFFER_SIZE_MAX) {
+          LOG_I(RRC, "CCCH message has size %d > %d\n",RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX);
+          break;
+      }
       memcpy(srb_info_p->Rx_buffer.Payload,
              RRC_MAC_CCCH_DATA_IND(msg_p).sdu,
              RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
@@ -7310,7 +7518,10 @@ rrc_enb_task(
 
       // Message buffer has been processed, free it now.
       result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_IND(msg_p).sdu_p);
-      AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+      if (result != EXIT_SUCCESS) {
+          LOG_I(RRC, "Failed to free memory (%d)!\n",result);
+          break;
+      }
       break;
 
 #   if defined(ENABLE_USE_MME)
@@ -7358,8 +7569,8 @@ rrc_enb_task(
       /* Nothing to do. Apparently everything is done in S1AP processing */
       //LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n",
       //instance, msg_name_p);
-      if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)
-          && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) {
+     if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)
+         && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) {
         rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc =
         rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc;
       }
@@ -7379,7 +7590,10 @@ rrc_enb_task(
     }
 
     result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
-    AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+    if (result != EXIT_SUCCESS) {
+        LOG_I(RRC, "Failed to free memory (%d)!\n",result);
+        continue;
+    }
     msg_p = NULL;
   }
 }
@@ -7592,7 +7806,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(
                    (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL,
                    (SL_CommConfig_r12_t*)&sl_CommConfig,
                    (SL_DiscConfig_r12_t*)NULL
-  #if defined(Rel10) || defined(Rel14)
+  #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                                            , (SCellToAddMod_r10_t*)NULL
   #endif
                                            );
@@ -7615,7 +7829,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(
                    (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL,
                    (SL_CommConfig_r12_t*)NULL,
                    (SL_DiscConfig_r12_t*)&sl_DiscConfig
-  #if defined(Rel10) || defined(Rel14)
+  #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0))
                                            , (SCellToAddMod_r10_t*)NULL
   #endif
                                            );
@@ -7744,6 +7958,7 @@ rrc_rx_tx(
 
     // check for UL failure
     RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
+      ctxt_pP->rnti = ue_context_p->ue_id_rnti;
       if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) {
 	if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) {
 	  LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n",
@@ -7759,7 +7974,7 @@ rrc_rx_tx(
       }
       if (ue_context_p->ue_context.ul_failure_timer>0) {
 	ue_context_p->ue_context.ul_failure_timer++;
-	if (ue_context_p->ue_context.ul_failure_timer >= 8) {
+	if (ue_context_p->ue_context.ul_failure_timer >= 20000) {
 	  // remove UE after 20 seconds after MAC has indicated UL failure
 	  LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti);
 	  ue_to_be_removed = ue_context_p;
@@ -7772,7 +7987,53 @@ rrc_rx_tx(
             ue_context_p->ue_context.ue_release_timer_thres_s1) {
           LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n",
                          ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1);
+//          ue_context_p->ue_context.ue_release_timer_s1 = 0;
+#if defined(ENABLE_USE_MME)
+#if defined(ENABLE_ITTI)
+          rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p);
+#if 0
+          {
+            int      e_rab;
+            MessageDef *msg_delete_tunnels_p = NULL;
+            uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
+            MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
+            msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
+            memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
+            // do not wait response
+            GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
+            for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+              GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
+                ue_context_p->ue_context.enb_gtp_ebi[e_rab];
+              // erase data
+              ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
+              memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+              ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
+            }
+            itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
+            MSC_LOG_TX_MESSAGE(
+                    MSC_RRC_ENB,
+                    MSC_S1AP_ENB,
+                    NULL,0,
+                    "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
+                    eNB_ue_s1ap_id);
+
+            struct rrc_ue_s1ap_ids_s    *rrc_ue_s1ap_ids = NULL;
+            rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(
+                    RC.rrc[ctxt_pP->module_id],
+                    0,
+                    eNB_ue_s1ap_id);
+            if (NULL != rrc_ue_s1ap_ids) {
+              rrc_eNB_S1AP_remove_ue_ids(
+                         RC.rrc[ctxt_pP->module_id],
+                         rrc_ue_s1ap_ids);
+            }
+          }
+#endif
+#endif
+#else
           ue_to_be_removed = ue_context_p;
+#endif
+          ue_context_p->ue_context.ue_release_timer_s1 = 0;
           break;
         }
       }
@@ -7782,10 +8043,75 @@ rrc_rx_tx(
         if (ue_context_p->ue_context.ue_release_timer_rrc >=
           ue_context_p->ue_context.ue_release_timer_thres_rrc) {
           LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti);
+          ue_context_p->ue_context.ue_release_timer_rrc = 0;
           ue_to_be_removed = ue_context_p;
+          ue_context_p->ue_context.ue_release_timer_rrc = 0;
           break;
         }
       }
+       pthread_mutex_lock(&rrc_release_freelist);
+      if(rrc_release_info.num_UEs > 0){
+        uint16_t release_total = 0;
+        for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
+          if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){
+            release_total++;
+          }
+          if( (rrc_release_info.RRC_release_ctrl[release_num].flag > 2) &&
+            (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)){
+           ue_context_p->ue_context.ue_release_timer_rrc = 1;
+           ue_context_p->ue_context.ue_release_timer_thres_rrc = 100;
+#if defined(ENABLE_USE_MME)
+#if defined(ENABLE_ITTI)
+           int      e_rab;
+           MessageDef *msg_complete_p = NULL;
+           MessageDef *msg_delete_tunnels_p = NULL;
+           uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id;
+           if(rrc_release_info.RRC_release_ctrl[release_num].flag == 4){
+             MSC_LOG_TX_MESSAGE(
+                    MSC_RRC_ENB,
+                    MSC_S1AP_ENB,
+                     NULL,0,
+                    "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ",
+                     eNB_ue_s1ap_id);
+             msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE);
+             S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
+             itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p);
+           }
+           MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id);
+           msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ);
+           memset(&GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p)));
+           // do not wait response
+           GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
+           for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) {
+             GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] =
+               ue_context_p->ue_context.enb_gtp_ebi[e_rab];
+             // erase data
+             ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0;
+             memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab]));
+             ue_context_p->ue_context.enb_gtp_ebi[e_rab]  = 0;
+           }
+           itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p);
+           struct rrc_ue_s1ap_ids_s    *rrc_ue_s1ap_ids = NULL;
+           rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(
+                  RC.rrc[ctxt_pP->module_id],
+                  0,
+                  eNB_ue_s1ap_id);
+           if (NULL != rrc_ue_s1ap_ids) {
+             rrc_eNB_S1AP_remove_ue_ids(
+                        RC.rrc[ctxt_pP->module_id],
+                        rrc_ue_s1ap_ids);
+           }
+#endif
+#endif
+           rrc_release_info.RRC_release_ctrl[release_num].flag = 0;
+           rrc_release_info.num_UEs--;
+           break;
+         }
+         if(release_total >= rrc_release_info.num_UEs)
+           break;
+         }
+       }
+       pthread_mutex_unlock(&rrc_release_freelist);
 
       if (ue_context_p->ue_context.ue_reestablishment_timer>0) {
         ue_context_p->ue_context.ue_reestablishment_timer++;
@@ -7798,25 +8124,27 @@ rrc_rx_tx(
           break;
         }
       }
+
       if (ue_context_p->ue_context.ue_release_timer>0) {
 	ue_context_p->ue_context.ue_release_timer++;
 	if (ue_context_p->ue_context.ue_release_timer >= 
 	    ue_context_p->ue_context.ue_release_timer_thres) {
-	  LOG_I(RRC,"Removing UE %x instance, Release timer: %d, Release timer thres.: %d \n",ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer, ue_context_p->ue_context.ue_release_timer_thres);
+          LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti);
 	  ue_to_be_removed = ue_context_p;
+          ue_context_p->ue_context.ue_release_timer = 0;
 	  break;
 	}
       }
     }
     if (ue_to_be_removed) {
-      if(ue_to_be_removed->ue_context.ul_failure_timer >= 8) {
+      if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000) {
           ue_to_be_removed->ue_context.ue_release_timer_s1 = 1;
           ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100;
           ue_to_be_removed->ue_context.ue_release_timer = 0;
           ue_to_be_removed->ue_context.ue_reestablishment_timer = 0;
       }
       rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed);
-      if(ue_to_be_removed->ue_context.ul_failure_timer >= 8){
+      if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000){
         ue_to_be_removed->ue_context.ul_failure_timer = 0;
       }
     }
diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c
index a250151a80805359cab27dde611049aef2b88d0d..59a2c352946f08fe93e3885149fc4bdfc9d7231d 100644
--- a/openair2/RRC/LTE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c
@@ -1289,6 +1289,7 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const ch
                   instance,
                   eNB_ue_s1ap_id);
     */
+#if 0
     {
       int      e_rab;
       //int      mod_id = 0;
@@ -1344,7 +1345,7 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const ch
       		  rrc_ue_s1ap_ids);
       }
     }
-
+#endif
     return (0);
   }
 }
@@ -2039,6 +2040,11 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance
                                   buffer,
                                   S1AP_PAGING_IND(msg_p).ue_paging_identity,
                                   S1AP_PAGING_IND(msg_p).cn_domain);
+              if(length == -1)
+              {
+                LOG_I(RRC, "do_Paging error");
+                return -1;
+              }
               message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length);
               /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */
               memcpy (message_buffer, buffer, length);
diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h
index 0218456ccb114166b3b202725ce4351637b088f2..e16391aef10d483778f661628ffbd11710bdf7a6 100644
--- a/openair2/RRC/LTE/rrc_proto.h
+++ b/openair2/RRC/LTE/rrc_proto.h
@@ -106,7 +106,7 @@ rrc_ue_decode_dcch(
   const uint8_t                eNB_indexP
 );
 
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
 int decode_SL_Discovery_Message(
   const protocol_ctxt_t* const ctxt_pP,
   const uint8_t                eNB_index,
@@ -628,5 +628,11 @@ void openair_rrc_top_init_ue(
                         uint8_t cba_group_active,
                         uint8_t HO_active
 );
+pthread_mutex_t      rrc_release_freelist;
+RRC_release_list_t rrc_release_info;
+pthread_mutex_t      lock_ue_freelist;
+void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti);
+void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag);
+void release_UE_in_freeList(module_id_t mod_id);
 
 /** @}*/
diff --git a/openair2/UTIL/LOG/log.c b/openair2/UTIL/LOG/log.c
index ff6a5cd5739a85b1694324b88cb4785941805c33..48e606522c61665a73c084f85e41bb6c929280d4 100644
--- a/openair2/UTIL/LOG/log.c
+++ b/openair2/UTIL/LOG/log.c
@@ -49,6 +49,26 @@
 // main log variables
 
 
+typedef struct {
+	char* buf_p;
+	int buf_index;
+  int enable_flag;
+} log_mem_cnt_t;
+
+log_mem_cnt_t log_mem_d[2];
+int log_mem_flag=0;
+int log_mem_multi=1;
+volatile int log_mem_side=0;
+pthread_mutex_t log_mem_lock;
+pthread_cond_t log_mem_notify;
+pthread_t log_mem_thread;
+int log_mem_file_cnt=0;
+volatile int log_mem_write_flag=0;
+volatile int log_mem_write_side=0;
+
+char __log_mem_filename[1024]={0};
+char * log_mem_filename = &__log_mem_filename[0];
+
 mapping log_level_names[] = {
   {"emerg", LOG_EMERG},
   {"alert", LOG_ALERT},
@@ -495,6 +515,81 @@ int logInit (void)
   return 0;
 }
 
+extern int oai_exit;
+void * log_mem_write(void)
+{
+  int *fp;
+  char f_name[1024];
+  struct timespec slp_tm;
+  slp_tm.tv_sec = 0;
+  slp_tm.tv_nsec = 10000;
+  
+  pthread_setname_np( pthread_self(), "log_mem_write");
+
+  while (!oai_exit) {
+    pthread_mutex_lock(&log_mem_lock);
+    log_mem_write_flag=0;
+    pthread_cond_wait(&log_mem_notify, &log_mem_lock);
+    log_mem_write_flag=1;
+    pthread_mutex_unlock(&log_mem_lock);
+    // write!
+    if(log_mem_d[log_mem_write_side].enable_flag==0){
+      if(log_mem_file_cnt>1){
+        log_mem_file_cnt=1;
+        printf("log over write!!!\n");
+      }
+      snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt);
+      fp=open(f_name, O_WRONLY | O_CREAT, 0666);
+      write(fp, log_mem_d[log_mem_write_side].buf_p, log_mem_d[log_mem_write_side].buf_index);
+      close(fp);
+      log_mem_file_cnt++;
+      log_mem_d[log_mem_write_side].buf_index=0;
+      log_mem_d[log_mem_write_side].enable_flag=1;
+    }else{
+      printf("If you'd like to write log, you should set enable flag to 0!!!\n");
+      nanosleep(&slp_tm,NULL);
+    }
+  }
+}
+
+int logInit_log_mem (void)
+{
+  if(log_mem_flag==1){
+    if(log_mem_multi==1){
+      printf("log-mem multi!!!\n");
+      log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE);
+      log_mem_d[0].buf_index=0;
+      log_mem_d[0].enable_flag=1;
+      log_mem_d[1].buf_p = malloc(LOG_MEM_SIZE);
+      log_mem_d[1].buf_index=0;
+      log_mem_d[1].enable_flag=1;
+      log_mem_side=0;
+      if ((pthread_mutex_init (&log_mem_lock, NULL) != 0)
+          || (pthread_cond_init (&log_mem_notify, NULL) != 0)) {
+        log_mem_d[1].enable_flag=0;
+        return;
+      }
+      pthread_create(&log_mem_thread, NULL, log_mem_write, (void*)NULL);
+    }else{
+      printf("log-mem single!!!\n");
+      log_mem_d[0].buf_p = malloc(LOG_MEM_SIZE);
+      log_mem_d[0].buf_index=0;
+      log_mem_d[0].enable_flag=1;
+      log_mem_d[1].enable_flag=0;
+      log_mem_side=0;
+    }
+  }else{
+    log_mem_d[0].buf_p=NULL;
+    log_mem_d[1].buf_p=NULL;
+    log_mem_d[0].enable_flag=0;
+    log_mem_d[1].enable_flag=0;
+  }
+
+  printf("log init done\n");
+  
+  return 0;
+}
+
 void nfapi_log(char *file, char *func, int line, int comp, int level, const char* format, va_list args)
 {
   //logRecord_mt(file,func,line, pthread_self(), comp, level, format, ##args)
@@ -1296,6 +1391,7 @@ void logRecord_mt(const char *file, const char *func, int line, int comp,
    * big enough so that the buffer is never full.
    */
   char log_buffer[MAX_LOG_TOTAL];
+  int temp_index;
 
   /* for no gcc warnings */
   (void)log_start;
@@ -1393,7 +1489,41 @@ void logRecord_mt(const char *file, const char *func, int line, int comp,
 
   // OAI printf compatibility
   if ((g_log->onlinelog == 1) && (level != LOG_FILE))
+  if(log_mem_flag==1){
+    if(log_mem_d[log_mem_side].enable_flag==1){
+      temp_index=log_mem_d[log_mem_side].buf_index;
+      if(temp_index+len+1 < LOG_MEM_SIZE){
+        log_mem_d[log_mem_side].buf_index+=len;
+        memcpy(&log_mem_d[log_mem_side].buf_p[temp_index],log_buffer,len);
+      }else{
+        log_mem_d[log_mem_side].enable_flag=0;
+        if(log_mem_d[1-log_mem_side].enable_flag==1){
+          temp_index=log_mem_d[1-log_mem_side].buf_index;
+          if(temp_index+len+1 < LOG_MEM_SIZE){
+            log_mem_d[1-log_mem_side].buf_index+=len;
+            log_mem_side=1-log_mem_side;
+            memcpy(&log_mem_d[log_mem_side].buf_p[temp_index],log_buffer,len);
+            /* write down !*/
+            if (pthread_mutex_lock(&log_mem_lock) != 0) {
+              return;
+            }
+            if(log_mem_write_flag==0){
+              log_mem_write_side=1-log_mem_side;
+              if(pthread_cond_signal(&log_mem_notify) != 0) {
+              }
+            }
+            if(pthread_mutex_unlock(&log_mem_lock) != 0) {
+              return;
+            }
+          }else{
+            log_mem_d[1-log_mem_side].enable_flag=0;
+          }
+        }
+      }
+    }
+  }else{
     fwrite(log_buffer, len, 1, stdout);
+  }
 
   if (g_log->syslog) {
     syslog(g_log->level, "%s", log_buffer);
@@ -1720,7 +1850,40 @@ void log_set_instance_type (log_instance_type_t instance)
   log_instance_type = instance;
 }
 #endif
-
+  
+void output_log_mem(void){
+  int cnt,cnt2;
+  int *fp;
+  char f_name[1024];
+
+  if(log_mem_flag==1){
+    log_mem_d[0].enable_flag=0;
+    log_mem_d[1].enable_flag=0;
+    usleep(10); // wait for log writing
+    while(log_mem_write_flag==1){
+      usleep(100);
+    }
+    if(log_mem_multi==1){
+      snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt);
+      fp=open(f_name, O_WRONLY | O_CREAT, 0666);
+      write(fp, log_mem_d[0].buf_p, log_mem_d[0].buf_index);
+      close(fp);
+      free(log_mem_d[0].buf_p);
+      
+      snprintf(f_name,1024, "%s_%d.log",log_mem_filename,log_mem_file_cnt);
+      fp=open(f_name, O_WRONLY | O_CREAT, 0666);
+      write(fp, log_mem_d[1].buf_p, log_mem_d[1].buf_index);
+      close(fp);
+      free(log_mem_d[1].buf_p);
+    }else{
+      fp=open(log_mem_filename, O_WRONLY | O_CREAT, 0666);
+      write(fp, log_mem_d[0].buf_p, log_mem_d[0].buf_index);
+      close(fp);
+      free(log_mem_d[0].buf_p);
+    }
+  }
+}
+  
 #ifdef LOG_TEST
 
 int main(int argc, char *argv[])
diff --git a/openair2/UTIL/LOG/log.h b/openair2/UTIL/LOG/log.h
index d0ac13dac3be58bbbf465b2513b657ffa2f8a665..e47270c8cd0777a5828f2681e771d77f0189529f 100644
--- a/openair2/UTIL/LOG/log.h
+++ b/openair2/UTIL/LOG/log.h
@@ -253,6 +253,11 @@ typedef enum log_instance_type_e {
 void log_set_instance_type (log_instance_type_t instance);
 #endif
 
+#define LOG_MEM_SIZE 100*1024*1024
+#define LOG_MEM_FILE "./logmem.log"
+int logInit_log_mem(void);
+void output_log_mem(void);
+
 #ifdef LOG_MAIN
 log_t *g_log;
 #else
diff --git a/openair2/UTIL/LOG/log_extern.h b/openair2/UTIL/LOG/log_extern.h
index 611487ffea2b3e4796726986e48a54c349cac7db..0e7c49cc8d2e249a367b893e8b425d15e9730219 100644
--- a/openair2/UTIL/LOG/log_extern.h
+++ b/openair2/UTIL/LOG/log_extern.h
@@ -32,3 +32,6 @@ extern int log_shutdown;
 
 extern mapping log_level_names[];
 extern mapping log_verbosity_names[];
+
+extern int log_mem_flag;
+extern char * log_mem_filename;
diff --git a/openair2/UTIL/MEM/mem_block.c b/openair2/UTIL/MEM/mem_block.c
index 39447001fab293832c874cfe2957c30476b7ac26..6d1a289f08ea4ac93583a8fb910d6999ac565382 100644
--- a/openair2/UTIL/MEM/mem_block.c
+++ b/openair2/UTIL/MEM/mem_block.c
@@ -275,9 +275,9 @@ get_free_mem_block (uint32_t sizeP, const char* caller)
   } while (pool_selected++ < 12);
 
   LOG_E(PHY, "[MEM_MNGT][ERROR][FATAL] failed allocating MEM_BLOCK size %d byes (pool_selected=%d size=%d)\n", sizeP, pool_selected, size);
-  display_mem_load();
-  AssertFatal(1==0,"get_free_mem_block failed");
-
+//  display_mem_load();
+//  AssertFatal(1==0,"get_free_mem_block failed");
+  LOG_E(MAC,"[MEM_MNGT][ERROR][FATAL] get_free_mem_block failed!!!\n");
 #ifdef MEMBLOCK_BIG_LOCK
   if (pthread_mutex_unlock(&mtex)) abort();
 #endif
diff --git a/openair2/UTIL/TIMER/umts_timer.c b/openair2/UTIL/TIMER/umts_timer.c
index 9bbb6c2df9198d030ca0d8e24c6a3374e5761862..1691fac363865c4b77ccfc9a9a22e9ef6bee2008 100644
--- a/openair2/UTIL/TIMER/umts_timer.c
+++ b/openair2/UTIL/TIMER/umts_timer.c
@@ -94,6 +94,7 @@ umts_add_timer_list_up (list2_t * atimer_listP, void (*procP) (void *, void *),
   uint8_t              inserted = 0;
 
   mb = get_free_mem_block (sizeof (struct timer_unit), __func__);
+  if(mb==NULL) return NULL;
   ((struct timer_unit *) (mb->data))->proc = procP;
   ((struct timer_unit *) (mb->data))->protocol = protocolP;
   ((struct timer_unit *) (mb->data))->timer_id = timer_idP;
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index 784245c0d36cb1ef4e1902af160fb3bf4a9fab2e..e9eec349dc3d8c579c10e67b42b23bec9cd6e850 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -63,7 +63,7 @@ extern boolean_t pdcp_data_req(
   const sdu_size_t     sdu_buffer_sizeP,
   unsigned char *const sdu_buffer_pP,
   const pdcp_transmission_mode_t modeP
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
     ,const uint32_t * const sourceL2Id
     ,const uint32_t * const destinationL2Id
 #endif
@@ -363,7 +363,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req(
 			     buffer_len,
 			     buffer,
 			     PDCP_TRANSMISSION_MODE_DATA
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
               ,NULL, NULL
 #endif
               );
diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf
index e864f47edb1663570633f9daf064346e42dd289b..2571db70a059ac2ec190196b927a159c4a65d540 100644
--- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf
+++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb.band7.tm1.usrpb210.epc.local.conf
@@ -45,7 +45,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 1;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower             = -26;
         pdsch_p_b                              = 0;
         pusch_n_SB                             = 1;
diff --git a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf
index bd9014670e8626b901c604e89e1a757e10079a9d..e71e7e03f5d368597401d40916d1724aef9114d6 100755
--- a/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf
+++ b/openair3/TEST/EPC_TEST/TEST_1MME_1ENB_1UE_ATTACH_GUTI/enb1.conf
@@ -44,7 +44,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 1;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -26;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
index a99c9d7a5d01d95060c9909486bf6528be2b547c..d704b9604ca75d05aa97d92c23a48e0e5724b9fa 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
@@ -376,6 +376,7 @@ static void trx_usrp_end(openair0_device *device) {
     s->tx_md.end_of_burst = true;
     s->tx_stream->send("", 0, s->tx_md);
     s->tx_md.end_of_burst = false;
+    sleep(1);
 #if defined(USRP_REC_PLAY)
     }
 #endif
@@ -483,7 +484,11 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
     s->tx_md.start_of_burst = false;
     s->tx_md.end_of_burst = false;
   }
-  
+  if(flags==10){ // fail safe mode
+    s->tx_md.has_time_spec = false;
+    s->tx_md.start_of_burst = false;
+    s->tx_md.end_of_burst = true;
+  } 
   if (cc>1) {
     std::vector<void *> buff_ptrs;
     for (int i=0; i<cc; i++)
diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
index 47ba171f1b9805973d2076629037bb9e920d22c9..228d3a5857e2c335075b69ac0e7d82d94a878001 100644
--- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
+++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.h
@@ -47,7 +47,7 @@ typedef struct {
 } iqrec_t;
 #define DEF_NB_SF           120000               // default nb of sf or ms to capture (2 minutes at 5MHz)
 #define DEF_SF_FILE         "/home/nokia/iqfile" // default subframes file name
-#define DEF_SF_DELAY_READ   400                  // default read delay  µs (860=real)
+#define DEF_SF_DELAY_READ   700                  // default read delay  µs (860=real)
 #define DEF_SF_DELAY_WRITE  15                   // default write delay µs (15=real)
 #define DEF_SF_NB_LOOP      5                    // default nb loops
 
diff --git a/targets/ARCH/tcp_bridge/README.tcp_bridge_oai b/targets/ARCH/tcp_bridge/README.tcp_bridge_oai
index ef0588ddee4fecf4a765a2b42b18fb047c2df96a..103ba32123cd1610b5c800ae1ec7456b186e243c 100644
--- a/targets/ARCH/tcp_bridge/README.tcp_bridge_oai
+++ b/targets/ARCH/tcp_bridge/README.tcp_bridge_oai
@@ -4,6 +4,7 @@ To build the basic simulator:
     cd [openair top directory]
     . oaienv
     cd cmake_targets
+    ./build_oai -I -w USRP
     ./build_oai --basic-simulator
     cd ../common/utils/T/tracer
     make
diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h
index 98de4a024f5225e7d061dc3d1ba09c2ec8802bad..1c27f655851f12b0d58eab503ca6e4e52346fc4a 100644
--- a/targets/COMMON/openairinterface5g_limits.h
+++ b/targets/COMMON/openairinterface5g_limits.h
@@ -4,13 +4,23 @@
 #if defined(CBMIMO1) || defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_LMSSDR)
 #        define NUMBER_OF_eNB_MAX 1
 #        define NUMBER_OF_RU_MAX 2
-#        define NUMBER_OF_UE_MAX 16
-#        define NUMBER_OF_CONNECTED_eNB_MAX 3
+#        ifndef UE_EXPANSION
+#                define NUMBER_OF_UE_MAX 16
+#                define NUMBER_OF_CONNECTED_eNB_MAX 3
+#        else
+#                define NUMBER_OF_UE_MAX 256
+#                define NUMBER_OF_CONNECTED_eNB_MAX 1
+#        endif
 #else
 #        define NUMBER_OF_eNB_MAX 7
 #        define NUMBER_OF_RU_MAX 32
-#        define NUMBER_OF_UE_MAX 20
-#        define NUMBER_OF_CONNECTED_eNB_MAX 3
+#        ifndef UE_EXPANSION
+#                define NUMBER_OF_UE_MAX 20
+#                define NUMBER_OF_CONNECTED_eNB_MAX 3
+#        else
+#                define NUMBER_OF_UE_MAX 256
+#                define NUMBER_OF_CONNECTED_eNB_MAX 1
+#        endif
 #        if defined(STANDALONE) && STANDALONE==1
 #                undef  NUMBER_OF_eNB_MAX
 #                undef  NUMBER_OF_UE_MAX
@@ -19,7 +29,6 @@
 #                define NUMBER_OF_UE_MAX 3
 #                define NUMBER_OF_RU_MAX 3
 #        endif
-
 #        if defined(LARGE_SCALE) && LARGE_SCALE
 #                undef  NUMBER_OF_eNB_MAX
 #                undef  NUMBER_OF_UE_MAX
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
index 38e471ac545b36c4ee469867efa646d0e3d24780..73da2a8b3f37c65507ef1994f930021d7bacfd29 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.100PRB.usrpx310.conf
@@ -48,7 +48,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 1;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -16;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
index 2c11ea318701019d3e7a2e81b4889890b4f426a2..bd0503a4669b698fc568a782272a99571c76b6e8 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.usrpx310.conf
@@ -48,7 +48,7 @@ eNBs =
         pucch_delta_shift       			      = 1;
         pucch_nRB_CQI           			      = 1;
         pucch_nCS_AN            			      = 0;
-        pucch_n1_AN             			      = 32;
+        pucch_n1_AN             			      = 0;
         pdsch_referenceSignalPower 			      = -16;
         pdsch_p_b                  			      = 0;
         pusch_n_SB                 			      = 1;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
index 6c7c319a11239189d7c314f3d01c829441301cf2..3064a29c698ababb992a6fc3562efcd262a02276 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf
@@ -52,7 +52,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 1;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -27;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
@@ -164,6 +164,8 @@ MACRLCs = (
 	num_cc = 1;
 	tr_s_preference = "local_L1";
 	tr_n_preference = "local_RRC";
+        puSch10xSnr     =  200;
+        puCch10xSnr     =  200;
         }  
 );
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
new file mode 100644
index 0000000000000000000000000000000000000000..99df987b43797da367931ff5f08f2583bb1523e0
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.usrpb210.replay.conf
@@ -0,0 +1,273 @@
+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";
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    component_carriers = (
+      {
+      node_function             = "3GPP_eNODEB";
+      node_timing               = "synch_to_ext_device";
+      node_synch_ref            = 0;
+      frame_type					      = "FDD";
+      tdd_config 					      = 3;
+      tdd_config_s            			      = 0;
+      prefix_type             			      = "NORMAL";
+      eutra_band              			      = 7;
+      downlink_frequency      			      = 2685000000L;
+      uplink_frequency_offset 			      = -120000000;
+      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                                            = 115;
+      pbch_repetition                                 = "FALSE";
+      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           			      = 0;
+      pucch_nCS_AN            			      = 0;
+      pucch_n1_AN             			      = 0;
+      pdsch_referenceSignalPower 			      = -27;
+      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                                   = -104;
+      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;
+
+      //Parameters for SIB18
+      rxPool_sc_CP_Len                                       = "normal";
+      rxPool_sc_Period                                       = "sf40";
+      rxPool_data_CP_Len                                     = "normal";
+      rxPool_ResourceConfig_prb_Num                          = 20;
+      rxPool_ResourceConfig_prb_Start                        = 5;
+      rxPool_ResourceConfig_prb_End                          = 44;
+      rxPool_ResourceConfig_offsetIndicator_present          = "prSmall";
+      rxPool_ResourceConfig_offsetIndicator_choice           = 0;
+      rxPool_ResourceConfig_subframeBitmap_present           = "prBs40";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_buf              = "00000000000000000000";
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_size             = 5;
+      rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused      = 0;
+/*    rxPool_dataHoppingConfig_hoppingParameter                       = 0;
+      rxPool_dataHoppingConfig_numSubbands                            = "ns1";
+      rxPool_dataHoppingConfig_rbOffset                               = 0;
+      rxPool_commTxResourceUC-ReqAllowed                              = "TRUE";
+*/
+      // Parameters for SIB19
+      discRxPool_cp_Len                                               = "normal"
+      discRxPool_discPeriod                                           = "rf32"
+      discRxPool_numRetx                                              = 1;
+      discRxPool_numRepetition                                        = 2;
+      discRxPool_ResourceConfig_prb_Num                               = 5;
+      discRxPool_ResourceConfig_prb_Start                             = 3;
+      discRxPool_ResourceConfig_prb_End                               = 21;
+      discRxPool_ResourceConfig_offsetIndicator_present               = "prSmall";
+      discRxPool_ResourceConfig_offsetIndicator_choice                = 0;
+      discRxPool_ResourceConfig_subframeBitmap_present                = "prBs40";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf          = "f0ffffffff";
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_size         = 5;
+      discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused  = 0;
+
+      }
+    );
+
+
+    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       = "192.168.13.11";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.13.10/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "lo";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.13.10/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	num_cc = 1;
+	tr_s_preference = "local_L1";
+	tr_n_preference = "local_RRC";
+	phy_test_mode = 0;
+        }  
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 125;
+         eNB_instances  = [0];
+
+    }
+);  
+
+NETWORK_CONTROLLER :
+{
+    FLEXRAN_ENABLED        = "no";
+    FLEXRAN_INTERFACE_NAME = "lo";
+    FLEXRAN_IPV4_ADDRESS   = "127.0.0.1";
+    FLEXRAN_PORT           = 2210;
+    FLEXRAN_CACHE          = "/mnt/oai_agent_cache";
+    FLEXRAN_AWAIT_RECONF   = "no";
+};
+/*
+     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";
+    };
+*/
+
+     log_config :
+     {
+       global_log_level                      ="crit";
+       global_log_verbosity                  ="crit";
+       hw_log_level                          ="crit";
+       hw_log_verbosity                      ="crit";
+       phy_log_level                         ="crit";
+       phy_log_verbosity                     ="crit";
+       mac_log_level                         ="crit";
+       mac_log_verbosity                     ="crit";
+       rlc_log_level                         ="crit";
+       rlc_log_verbosity                     ="crit";
+       pdcp_log_level                        ="crit";
+       pdcp_log_verbosity                    ="crit";
+       rrc_log_level                         ="crit";
+       rrc_log_verbosity                     ="crit";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
index 087f379c4d7afa36127e4a9bbf506f386eb1689c..7d73e55c6c8e494e556bfb508eb6c9cd28ad81ef 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210-d2d.conf
@@ -52,7 +52,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 1;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -27;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
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 614a85d54ce536b6cbe05c2e2f302385a945751d..15e52c7cdd9131f49b59c71c55d84cdbce46387a 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
@@ -52,7 +52,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -27;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
@@ -199,6 +199,8 @@ MACRLCs = (
 	tr_s_preference = "local_L1";
 	tr_n_preference = "local_RRC";
 	phy_test_mode = 1;
+        puSch10xSnr     =  200;
+        puCch10xSnr     =  200;
         }  
 );
 
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
new file mode 100644
index 0000000000000000000000000000000000000000..1197c4ad937638de4825c6ac99237438bb7f18e6
--- /dev/null
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210_ue_expansion.conf
@@ -0,0 +1,210 @@
+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 =  "93";
+
+    tr_s_preference     = "local_mac"
+
+    ////////// Physical parameters:
+
+    component_carriers = (
+      {
+      node_function             = "3GPP_eNODEB";
+      node_timing               = "synch_to_ext_device";
+      node_synch_ref            = 0;
+      frame_type					      = "FDD";
+      tdd_config 					      = 3;
+      tdd_config_s            			      = 0;
+      prefix_type             			      = "NORMAL";
+      eutra_band              			      = 7;
+      downlink_frequency      			      = 2685000000L;
+      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;
+      pbch_repetition                                 = "FALSE";
+      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           			      = 0;
+      pucch_nCS_AN            			      = 0;
+      pucch_n1_AN             			      = 0;
+      pdsch_referenceSignalPower 			      = -27;
+      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                                     = "ONE";
+      srs_enable                                         = "DISABLE";
+      /*  srs_BandwidthConfig                                =;
+      srs_SubframeConfig                                 =;
+      srs_ackNackST                                      =;
+      srs_MaxUpPts                                       =;*/
+
+      pusch_p0_Nominal                                   = -96;
+      pusch_alpha                                        = "AL1";
+      pucch_p0_Nominal                                   = -104;
+      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;
+      ue_multiple_max                             = 20;
+      }
+    );
+
+
+    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       = "192.168.12.26";
+                              ipv6       = "192:168:30::17";
+                              active     = "yes";
+                              preference = "ipv4";
+                            }
+                          );
+
+    NETWORK_INTERFACES :
+    {
+
+        ENB_INTERFACE_NAME_FOR_S1_MME            = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1_MME              = "192.168.12.19/24";
+        ENB_INTERFACE_NAME_FOR_S1U               = "eth0";
+        ENB_IPV4_ADDRESS_FOR_S1U                 = "192.168.12.19/24";
+        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
+    };
+  }
+);
+
+MACRLCs = (
+	{
+	num_cc = 1;
+	tr_s_preference = "local_L1";
+	tr_n_preference = "local_RRC";
+        }  
+);
+
+L1s = (
+    	{
+	num_cc = 1;
+	tr_n_preference = "local_mac";
+        }  
+);
+
+RUs = (
+    {		  
+       local_rf       = "yes"
+         nb_tx          = 1
+         nb_rx          = 1
+         att_tx         = 0
+         att_rx         = 0;
+         bands          = [7];
+         max_pdschReferenceSignalPower = -27;
+         max_rxgain                    = 125;
+         eNB_instances  = [0];
+
+    }
+);  
+
+     log_config :
+     {
+       global_log_level                      ="info";
+       global_log_verbosity                  ="medium";
+       hw_log_level                          ="info";
+       hw_log_verbosity                      ="medium";
+       phy_log_level                         ="info";
+       phy_log_verbosity                     ="medium";
+       mac_log_level                         ="info";
+       mac_log_verbosity                     ="high";
+       rlc_log_level                         ="info";
+       rlc_log_verbosity                     ="medium";
+       pdcp_log_level                        ="info";
+       pdcp_log_verbosity                    ="medium";
+       rrc_log_level                         ="info";
+       rrc_log_verbosity                     ="medium";
+    };
+
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
index 4de676ec9a42b41a83d2eaa1eda524cd60a1cb0d..71a163209ded9e16fd01ac56ad8b0d73491dc11f 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi-STUB.conf
@@ -54,7 +54,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       #pdsch_referenceSignalPower 			      = -27;
       pdsch_referenceSignalPower 			      = -30;
       pdsch_p_b                  			      = 0;
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 03241ec694a8ea75b99cb2b06a5ba360eb002a7b..a6da42c2f563cbed744420b8f4832c81da5079c0 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
@@ -52,7 +52,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -27;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
index 42ab1e81c73435fd281af578355a27dcbc81b1ff..25b0cb1456369ffb4ef6cec09657b5954e5e08e5 100644
--- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
+++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.if4p5.50PRB.conf
@@ -55,7 +55,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -27;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 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 771bf094997b62110b0394945f74f3acec5c103d..2b5a0ca68469eae11ba2587f9aae402a8dba7fc5 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
@@ -55,7 +55,7 @@ eNBs =
       pucch_delta_shift       			      = 1;
       pucch_nRB_CQI           			      = 0;
       pucch_nCS_AN            			      = 0;
-      pucch_n1_AN             			      = 32;
+      pucch_n1_AN             			      = 0;
       pdsch_referenceSignalPower 			      = -27;
       pdsch_p_b                  			      = 0;
       pusch_n_SB                 			      = 1;
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index b84a289ffa7fa5eab1b715fb5e1584cf6238f725..a418d09a0f586f6752abf54e48097c64ee9e78db 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -217,6 +217,8 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
 #endif
   }
 
+  release_UE_in_freeList(eNB->Mod_id);
+
   // UE-specific RX processing for subframe n
   if (nfapi_mode == 0 || nfapi_mode == 1) {
     phy_procedures_eNB_uespec_RX(eNB, proc);
@@ -241,12 +243,43 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam
   eNB->if_inst->UL_indication(&eNB->UL_INFO);
 
   pthread_mutex_unlock(&eNB->UL_INFO_mutex);
+#if 0
+/* TODO: find a correct solution for this conflict */
+<<<<<<< HEAD
+
+  // *****************************************
+  // TX processing for subframe n+sf_ahead
+  // run PHY TX procedures the one after the other for all CCs to avoid race conditions
+  // (may be relaxed in the future for performance reasons)
+  // *****************************************
+  //if (wait_CCs(proc)<0) return(-1);
+  
+  if (oai_exit) return(-1);
+#ifndef PHY_TX_THREAD
+  phy_procedures_eNB_TX(eNB, proc, no_relay, NULL, 1);
+#endif
+  if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);
+=======
   
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
   if(oai_exit) return(-1);
   if(get_nprocs() <= 4){
     phy_procedures_eNB_TX(eNB, proc, 1);
   }
+>>>>>>> origin/develop
+#endif /* #if 0 */
+  /* this conflict resolution may be totally wrong, to be tested */
+  /* CONFLICT RESOLUTION: BEGIN */
+  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 );
+  if(oai_exit) return(-1);
+  if(get_nprocs() <= 4){
+#ifndef PHY_TX_THREAD
+    phy_procedures_eNB_TX(eNB, proc, 1);
+#endif
+  }
+  /* CONFLICT RESOLUTION: what about this release_thread call, has it to be done? if yes, where? */
+  //if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1);
+  /* CONFLICT RESOLUTION: END */
 
   stop_meas( &softmodem_stats_rxtx_sf );
 
@@ -777,6 +810,7 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) {
 }
 #endif
 
+
 /*!
  * \brief The prach receive thread of eNB.
  * \param param is a \ref eNB_proc_t structure which contains the info what to process.
@@ -1083,7 +1117,7 @@ void kill_eNB_proc(int inst) {
     pthread_join( proc->pthread_prach_br, (void**)&status );    
     pthread_mutex_destroy( &proc->mutex_prach_br );
     pthread_cond_destroy( &proc->cond_prach_br );
-#endif         
+#endif
     LOG_I(PHY, "Destroying UL_INFO mutex\n");
     pthread_mutex_destroy(&eNB->UL_INFO_mutex);
     for (i=0;i<2;i++) {
@@ -1148,7 +1182,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
   LOG_I(PHY, "Initialise transport\n");
 
   for (i=0; i<NUMBER_OF_UE_MAX; i++) {
-    LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
+    LOG_D(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
     for (j=0; j<2; j++) {
       eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp);
       if (!eNB->dlsch[i][j]) {
@@ -1160,7 +1194,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
       }
     }
     
-    LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
+    LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
     eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
     
     if (!eNB->ulsch[1+i]) {
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index 89c57849ca3a6e899dbd42a46856b74887a918c0..d86f2f6c6b76b2f4991439f4381974709d82fce1 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -114,6 +114,7 @@ static int DEFENBS[] = {0};
 
 #include "T.h"
 
+#include "pdcp.h"
 
 extern volatile int                    oai_exit;
 extern int emulate_rf;
@@ -680,6 +681,19 @@ void fh_if4p5_north_out(RU_t *ru) {
 
 }
 
+/* add fail safe for late command */
+typedef enum {
+	STATE_BURST_NORMAL = 0,
+	STATE_BURST_TERMINATE = 1,
+	STATE_BURST_STOP_1 = 2,
+	STATE_BURST_STOP_2 = 3,
+	STATE_BURST_RESTART = 4,
+} late_control_e;
+
+volatile late_control_e late_control=STATE_BURST_NORMAL;
+
+/* add fail safe for late command end */
+
 static void* emulatedRF_thread(void* param) {
   RU_proc_t *proc = (RU_proc_t *) param;
   int microsec = 500; // length of time to sleep, in miliseconds
@@ -740,9 +754,12 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
  
   proc->timestamp_rx = ts-ru->ts_offset;
 
-  //AssertFatal(rxs == fp->samples_per_tti,
-	      //"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
-  if (rxs != fp->samples_per_tti) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
+//  AssertFatal(rxs == fp->samples_per_tti,
+//	      "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
+  if(rxs != fp->samples_per_tti){
+    LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs);
+    late_control=STATE_BURST_TERMINATE;
+  }
 
   if (proc->first_rx == 1) {
     ru->ts_offset = proc->timestamp_rx;
@@ -760,6 +777,16 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
   proc->subframe_rx  = (proc->timestamp_rx / fp->samples_per_tti)%10;
   // synchronize first reception to frame 0 subframe 0
 
+#ifdef PHY_TX_THREAD
+  proc->timestamp_phy_tx = proc->timestamp_rx+((sf_ahead-1)*fp->samples_per_tti);
+  proc->subframe_phy_tx  = (proc->subframe_rx+(sf_ahead-1))%10;  
+  proc->frame_phy_tx     = (proc->subframe_rx>(9-(sf_ahead-1))) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
+#else
+  proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti);
+  proc->subframe_tx  = (proc->subframe_rx+sf_ahead)%10;
+  proc->frame_tx     = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
+#endif
+
   //proc->timestamp_tx = proc->timestamp_rx+(sf_ahead*fp->samples_per_tti);
   //proc->subframe_tx  = (proc->subframe_rx+sf_ahead)%10;
   //proc->frame_tx     = (proc->subframe_rx>(9-sf_ahead)) ? (proc->frame_rx+1)&1023 : proc->frame_rx;
@@ -798,8 +825,12 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) {
   
   if (rxs != fp->samples_per_tti)
   {
+#if defined(USRP_REC_PLAY)
+    exit_fun("Exiting IQ record/playback");
+#else    
     //exit_fun( "problem receiving samples" );
     LOG_E(PHY, "problem receiving samples");
+#endif    
   }
 }
 
@@ -834,7 +865,7 @@ void tx_rf(RU_t *ru) {
 	(prevSF_type == SF_UL) &&
 	(nextSF_type == SF_DL)) { 
       flags = 2; // start of burst
-      sf_extension = ru->N_TA_offset<<1;
+      sf_extension = ru->N_TA_offset;
     }
     
     if ((fp->frame_type == TDD) &&
@@ -842,15 +873,52 @@ void tx_rf(RU_t *ru) {
 	(prevSF_type == SF_UL) &&
 	(nextSF_type == SF_UL)) {
       flags = 4; // start of burst and end of burst (only one DL SF between two UL)
-      sf_extension = ru->N_TA_offset<<1;
+      sf_extension = ru->N_TA_offset;
     } 
-
+#if defined(__x86_64) || defined(__i386__)
+#ifdef __AVX2__
+  sf_extension = (sf_extension)&0xfffffff8;
+#else
+  sf_extension = (sf_extension)&0xfffffffc;
+#endif
+#elif defined(__arm__)
+  sf_extension = (sf_extension)&0xfffffffc;
+#endif
+    
     for (i=0; i<ru->nb_tx; i++)
       txp[i] = (void*)&ru->common.txdata[i][(proc->subframe_tx*fp->samples_per_tti)-sf_extension];
 
+    /* add fail safe for late command */
+    if(late_control!=STATE_BURST_NORMAL){//stop burst
+      switch (late_control) {
+      case STATE_BURST_TERMINATE:
+        flags=10; // end of burst and no time spec
+        late_control=STATE_BURST_STOP_1;
+        break;
+      
+      case STATE_BURST_STOP_1:
+        flags=0; // no send
+        late_control=STATE_BURST_STOP_2;
+        return;//no send
+       break;
+      
+      case STATE_BURST_STOP_2:
+        flags=0; // no send
+        late_control=STATE_BURST_RESTART;
+        return;//no send
+        break;
+      
+      case STATE_BURST_RESTART:
+        flags=2; // start burst
+        late_control=STATE_BURST_NORMAL;
+        break;
+      }
+    }
+    /* add fail safe for late command end */
+
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_RU, proc->frame_tx );
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_RU, proc->subframe_tx );
-    
+
     VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_tx-ru->openair0_cfg.tx_sample_advance)&0xffffffff );
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 );
     // prepare tx buffer pointers
@@ -867,8 +935,11 @@ void tx_rf(RU_t *ru) {
     VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 );
     
     
-    AssertFatal(txs ==  siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
-
+//    AssertFatal(txs ==  siglen+sf_extension,"TX : Timeout (sent %d/%d)\n",txs, siglen);
+    if( (txs !=  siglen+sf_extension) && (late_control==STATE_BURST_NORMAL) ){ /* add fail safe for late command */
+      late_control=STATE_BURST_TERMINATE;
+      LOG_E(PHY,"TX : Timeout (sent %d/%d) state =%d\n",txs, siglen,late_control);
+    }
   }
 }
 
@@ -1336,8 +1407,8 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
     cfg->tx_freq[i] = (double)fp->dl_CarrierFreq;
     cfg->rx_freq[i] = (double)fp->ul_CarrierFreq;
 
-    cfg->tx_gain[i] = ru->att_tx;
-    cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx;
+    cfg->tx_gain[i] = (double)ru->att_tx;
+    cfg->rx_gain[i] = ru->max_rxgain-(double)ru->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",
@@ -1435,6 +1506,12 @@ static void* ru_stats_thread(void* param) {
   return(NULL);
 }
 
+#ifdef PHY_TX_THREAD
+int first_phy_tx = 1;
+volatile int16_t phy_tx_txdataF_end;
+volatile int16_t phy_tx_end;
+#endif
+
 static void* ru_thread_tx( void* param ) {
   RU_t *ru         = (RU_t*)param;
   RU_proc_t *proc  = &ru->proc;
@@ -1504,7 +1581,13 @@ static void* ru_thread( void* param ) {
 
   // set default return value
   ru_thread_status = 0;
+#if defined(PRE_SCD_THREAD)
+  dlsch_ue_select_tbl_in_use = 1;
+#endif
 
+  struct timespec time_req, time_rem;
+  time_req.tv_sec = 0;
+  time_req.tv_nsec = 10000;
 
   // set default return value
   thread_top_init("ru_thread",1,400000,500000,500000);
@@ -1608,6 +1691,32 @@ static void* ru_thread( void* param ) {
     if (ru->fh_south_in) ru->fh_south_in(ru,&frame,&subframe);
     else AssertFatal(1==0, "No fronthaul interface at south port");
 
+#ifdef PHY_TX_THREAD
+    if(first_phy_tx == 0)
+    {
+        phy_tx_end = 0;
+        phy_tx_txdataF_end = 0;
+        if(pthread_mutex_lock(&ru->proc.mutex_phy_tx) != 0){
+          LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for phy tx thread (IC %d)\n", ru->proc.instance_cnt_phy_tx);
+          exit_fun( "error locking mutex_rxtx" );
+        }
+        if (ru->proc.instance_cnt_phy_tx==-1) {
+          ++ru->proc.instance_cnt_phy_tx;
+
+          // the thread can now be woken up
+          AssertFatal(pthread_cond_signal(&ru->proc.cond_phy_tx) == 0, "ERROR pthread_cond_signal for phy_tx thread\n");
+        }else{
+          LOG_E(PHY,"phy tx thread busy, skipping\n");
+          ++ru->proc.instance_cnt_phy_tx;
+        }
+        pthread_mutex_unlock( &ru->proc.mutex_phy_tx );
+    } else {
+        phy_tx_end = 1;
+        phy_tx_txdataF_end = 1;
+    }
+    first_phy_tx = 0;
+#endif
+
 /*
     LOG_D(PHY,"AFTER fh_south_in - SFN/SF:%d%d RU->proc[RX:%d%d TX:%d%d] RC.eNB[0][0]:[RX:%d%d TX(SFN):%d]\n",
         frame,subframe,
@@ -1641,9 +1750,42 @@ static void* ru_thread( void* param ) {
     // If this proc is to provide synchronization, do so
     wakeup_slaves(proc);
 
+#if defined(PRE_SCD_THREAD)
+    new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use;
+    dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use;
+    memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX);
+    memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX);
+    if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) {
+        LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n");
+        exit_fun("error locking mutex_time");
+    }
+
+    ru->proc.instance_pre_scd++;
+
+    if (ru->proc.instance_pre_scd == 0) {
+        if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) {
+            LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" );
+            exit_fun( "ERROR pthread_cond_signal cond_pre_scd" );
+        }
+    }else{
+        LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n",
+               frame,subframe,ru->proc.instance_pre_scd );
+    }
+
+    if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) {
+        LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n");
+        exit_fun("error unlocking mutex_pre_scd");
+    }
+#endif
+
     // wakeup all eNB processes waiting for this RU
     if (ru->num_eNB>0) wakeup_eNBs(ru);
     
+    // wait until eNBs are finished subframe RX n and TX n+sf_ahead
+    if(get_nprocs() > 4)
+      wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread");
+    
+#ifndef PHY_TX_THREAD
     if(get_nprocs() <= 4){
       // do TX front-end processing if needed (precoding and/or IDFTs)
       if (ru->feptx_prec) ru->feptx_prec(ru);
@@ -1657,7 +1799,12 @@ static void* ru_thread( void* param ) {
         if (ru->fh_north_out) ru->fh_north_out(ru);
       }
     }
-
+#else
+    while((!oai_exit)&&(phy_tx_end == 0)){
+        nanosleep(&time_req,&time_rem);
+        continue;
+    }
+#endif
   }
   
 
@@ -1752,6 +1899,168 @@ void *ru_thread_synch(void *arg) {
 
 }
 
+#if defined(PRE_SCD_THREAD)
+void* pre_scd_thread( void* param ){
+    static int              eNB_pre_scd_status;
+    protocol_ctxt_t         ctxt;
+    int                     frame;
+    int                     subframe;
+    int                     min_rb_unit[MAX_NUM_CCs];
+    int                     CC_id;
+    int                     Mod_id;
+    RU_t               *ru      = (RU_t*)param;
+    Mod_id = ru->eNB_list[0]->Mod_id;
+
+    frame = 0;
+    subframe = 4;
+    thread_top_init("pre_scd_thread",0,870000,1000000,1000000);
+
+    while (!oai_exit) {
+        if(oai_exit){
+            break;
+        }
+        pthread_mutex_lock(&ru->proc.mutex_pre_scd );
+        if (ru->proc.instance_pre_scd < 0) {
+          pthread_cond_wait(&ru->proc.cond_pre_scd, &ru->proc.mutex_pre_scd);
+        }
+        pthread_mutex_unlock(&ru->proc.mutex_pre_scd);
+        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, Mod_id, ENB_FLAG_YES,
+                 NOT_A_RNTI, frame, subframe,Mod_id);
+        pdcp_run(&ctxt);
+
+        for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+
+          rrc_rx_tx(&ctxt, CC_id);
+          min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id);
+        }
+
+        pre_scd_nb_rbs_required(Mod_id, frame, subframe,min_rb_unit,pre_nb_rbs_required[new_dlsch_ue_select_tbl_in_use]);
+
+        if (subframe==9) {
+          subframe=0;
+          frame++;
+          frame&=1023;
+        } else {
+          subframe++;
+        }
+        pthread_mutex_lock(&ru->proc.mutex_pre_scd );
+        ru->proc.instance_pre_scd--;
+        pthread_mutex_unlock(&ru->proc.mutex_pre_scd);
+    }
+    eNB_pre_scd_status = 0;
+    return &eNB_pre_scd_status;
+}
+#endif
+
+#ifdef PHY_TX_THREAD
+/*!
+ * \brief The phy tx thread of eNB.
+ * \param param is a \ref eNB_proc_t structure which contains the info what to process.
+ * \returns a pointer to an int. The storage is not on the heap and must not be freed.
+ */
+static void* eNB_thread_phy_tx( void* param ) {
+  static int eNB_thread_phy_tx_status;
+
+
+  RU_t *ru      = (RU_t*)param;
+  RU_proc_t *proc = &ru->proc;
+  PHY_VARS_eNB **eNB_list = ru->eNB_list;
+
+  eNB_rxtx_proc_t proc_rxtx;
+
+  // set default return value
+  eNB_thread_phy_tx_status = 0;
+
+  thread_top_init("eNB_thread_phy_tx",1,500000L,1000000L,20000000L);
+
+
+  while (!oai_exit) {
+
+    if (oai_exit) break;
+
+
+    if (wait_on_condition(&proc->mutex_phy_tx,&proc->cond_phy_tx,&proc->instance_cnt_phy_tx,"eNB_phy_tx_thread") < 0) break;
+
+    LOG_D(PHY,"Running eNB phy tx procedures\n");
+    if(ru->num_eNB == 1){
+       proc_rxtx.subframe_tx = proc->subframe_phy_tx;
+       proc_rxtx.frame_tx = proc->frame_phy_tx;
+       phy_procedures_eNB_TX(eNB_list[0], &proc_rxtx, 1);
+       phy_tx_txdataF_end = 1;
+       if(pthread_mutex_lock(&ru->proc.mutex_rf_tx) != 0){
+          LOG_E( PHY, "[RU] ERROR pthread_mutex_lock for rf tx thread (IC %d)\n", ru->proc.instance_cnt_rf_tx);
+          exit_fun( "error locking mutex_rf_tx" );
+        }
+        if (ru->proc.instance_cnt_rf_tx==-1) {
+          ++ru->proc.instance_cnt_rf_tx;
+          ru->proc.frame_tx = proc->frame_phy_tx;
+          ru->proc.subframe_tx = proc->subframe_phy_tx;
+          ru->proc.timestamp_tx = proc->timestamp_phy_tx;
+
+          // the thread can now be woken up
+          AssertFatal(pthread_cond_signal(&ru->proc.cond_rf_tx) == 0, "ERROR pthread_cond_signal for rf_tx thread\n");
+        }else{
+          LOG_E(PHY,"rf tx thread busy, skipping\n");
+          late_control=STATE_BURST_TERMINATE;
+        }
+        pthread_mutex_unlock( &ru->proc.mutex_rf_tx );
+    }
+    if (release_thread(&proc->mutex_phy_tx,&proc->instance_cnt_phy_tx,"eNB_thread_phy_tx") < 0) break;
+    phy_tx_end = 1;
+  }
+
+  LOG_I(PHY, "Exiting eNB thread PHY TX\n");
+
+  eNB_thread_phy_tx_status = 0;
+  return &eNB_thread_phy_tx_status;
+}
+
+
+static void* rf_tx( void* param ) {
+  static int rf_tx_status;
+
+  RU_t *ru      = (RU_t*)param;
+  RU_proc_t *proc = &ru->proc;
+
+  // set default return value
+  rf_tx_status = 0;
+
+  thread_top_init("rf_tx",1,500000L,1000000L,20000000L);
+  
+  while (!oai_exit) {
+
+    if (oai_exit) break;
+
+
+    if (wait_on_condition(&proc->mutex_rf_tx,&proc->cond_rf_tx,&proc->instance_cnt_rf_tx,"rf_tx_thread") < 0) break;
+
+    LOG_D(PHY,"Running eNB rf tx procedures\n");
+    if(ru->num_eNB == 1){
+       // do TX front-end processing if needed (precoding and/or IDFTs)
+       if (ru->feptx_prec) ru->feptx_prec(ru);
+       // do OFDM if needed
+       if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru);
+       if(!emulate_rf){
+         // do outgoing fronthaul (south) if needed
+         if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru);
+
+         if (ru->fh_north_out) ru->fh_north_out(ru);
+       }
+    }
+    if (release_thread(&proc->mutex_rf_tx,&proc->instance_cnt_rf_tx,"rf_tx") < 0) break;
+    if(proc->instance_cnt_rf_tx >= 0){
+      late_control=STATE_BURST_TERMINATE;
+      LOG_E(PHY,"detect rf tx busy change mode TX failsafe\n");
+    }
+  }
+
+  LOG_I(PHY, "Exiting rf TX\n");
+
+  rf_tx_status = 0;
+  return &rf_tx_status;
+}
+#endif
+
 
  
 int start_if(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB) {
@@ -1841,6 +2150,15 @@ void init_RU_proc(RU_t *ru) {
   pthread_cond_init( &proc->cond_prach_br, NULL);
   pthread_attr_init( &proc->attr_prach_br);
 #endif  
+
+#ifdef PHY_TX_THREAD
+  proc->instance_cnt_phy_tx       = -1;
+  pthread_mutex_init( &proc->mutex_phy_tx, NULL);
+  pthread_cond_init( &proc->cond_phy_tx, NULL);
+  proc->instance_cnt_rf_tx       = -1;
+  pthread_mutex_init( &proc->mutex_rf_tx, NULL);
+  pthread_cond_init( &proc->cond_rf_tx, NULL);
+#endif
   
 #ifndef DEADLINE_SCHEDULER
   attr_FH        = &proc->attr_FH;
@@ -1855,6 +2173,21 @@ void init_RU_proc(RU_t *ru) {
 #endif
   
   pthread_create( &proc->pthread_FH, attr_FH, ru_thread, (void*)ru );
+
+#if defined(PRE_SCD_THREAD)
+    proc->instance_pre_scd = -1;
+    pthread_mutex_init( &proc->mutex_pre_scd, NULL);
+    pthread_cond_init( &proc->cond_pre_scd, NULL);
+    pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void*)ru);
+    pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread");
+#endif
+
+#ifdef PHY_TX_THREAD
+    pthread_create( &proc->pthread_phy_tx, NULL, eNB_thread_phy_tx, (void*)ru );
+    pthread_setname_np( proc->pthread_phy_tx, "phy_tx_thread" );
+    pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void*)ru );
+#endif
+
   if(emulate_rf)
     pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc );
 
@@ -2436,6 +2769,34 @@ void init_RU(char *rf_config_file) {
 
 
 
+void stop_ru(RU_t *ru) {
+  int *status;
+  printf("Stopping RU %p processing threads\n",(void*)ru);
+#if defined(PRE_SCD_THREAD)
+  if(ru){
+    ru->proc.instance_pre_scd = 0;
+    pthread_cond_signal( &ru->proc.cond_pre_scd );
+    pthread_join(ru->proc.pthread_pre_scd, (void**)&status );
+    pthread_mutex_destroy(&ru->proc.mutex_pre_scd );
+    pthread_cond_destroy(&ru->proc.cond_pre_scd );
+  }
+#endif
+#ifdef PHY_TX_THREAD
+  if(ru){
+      ru->proc.instance_cnt_phy_tx = 0;
+      pthread_cond_signal(&ru->proc.cond_phy_tx);
+      pthread_join( ru->proc.pthread_phy_tx, (void**)&status );
+      pthread_mutex_destroy( &ru->proc.mutex_phy_tx );
+      pthread_cond_destroy( &ru->proc.cond_phy_tx );
+      ru->proc.instance_cnt_rf_tx = 0;
+      pthread_cond_signal(&ru->proc.cond_rf_tx);
+      pthread_join( ru->proc.pthread_rf_tx, (void**)&status );
+      pthread_mutex_destroy( &ru->proc.mutex_rf_tx );
+      pthread_cond_destroy( &ru->proc.cond_rf_tx );
+  }
+#endif
+}
+
 void stop_RU(int nb_ru)
 {
   for (int inst = 0; inst < nb_ru; inst++) {
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 7163d8bd7dc1ab8a9bdb6b5ac0d17de484c20683..73f5797327198d49f2daf9a1959d13058514a811 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -144,6 +144,8 @@ static int8_t                     threequarter_fs=0;
 uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
 int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
 
+char logmem_filename[1024] = {0};
+
 // This is a dummy declaration (dlsch_demodulation.c is no longer compiled for eNodeB)
 int16_t dlsch_demod_shift = 0;
 
@@ -340,10 +342,14 @@ void exit_fun(const char* s)
     if (RC.ru == NULL)
         exit(-1); // likely init not completed, prevent crash or hang, exit now...
     for (ru_id=0; ru_id<RC.nb_RU;ru_id++) {
-      if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func)
+      if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) {
 	RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
-      if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func)
+        RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
+      }
+      if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) {
 	RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);  
+        RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
+      }
     }
 
 
@@ -553,6 +559,12 @@ static void get_options(void) {
   if (start_telnetsrv) {
      load_module_shlib("telnetsrv",NULL,0);
   }
+  if (strlen(logmem_filename) > 0) {
+    log_mem_filename = &logmem_filename[0];
+    log_mem_flag = 1;
+    printf("Enabling OPT for log save at memory %s\n",log_mem_filename);
+    logInit_log_mem();
+  }
 
 #if T_TRACER
   paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
@@ -1284,6 +1296,10 @@ int main( int argc, char **argv )
   printf("stopping MODEM threads\n");
 
   // cleanup
+  for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
+    stop_ru(RC.ru[ru_id]);
+  }
+
     stop_eNB(NB_eNB_INST);
     stop_RU(NB_RU);
     /* release memory used by the RU/eNB threads (incomplete), after all
@@ -1314,11 +1330,14 @@ int main( int argc, char **argv )
   // *** Handle per CC_id openair0
 
     for(ru_id=0; ru_id<NB_RU; ru_id++) {
-      if (RC.ru[ru_id]->rfdevice.trx_end_func)
-	RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);  
-      if (RC.ru[ru_id]->ifdevice.trx_end_func)
-	RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);  
-
+      if (RC.ru[ru_id]->rfdevice.trx_end_func) {
+        RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
+        RC.ru[ru_id]->rfdevice.trx_end_func = NULL;
+      }
+      if (RC.ru[ru_id]->ifdevice.trx_end_func) {
+        RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);
+        RC.ru[ru_id]->ifdevice.trx_end_func = NULL;
+      }
     }
   if (ouput_vcd)
     VCD_SIGNAL_DUMPER_CLOSE();
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index c375d28106cdf04de3d65d37644d3a7dd5cc3a58..8aae82faf0622bfbeda1696154985b164fa0aa3c 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -201,6 +201,7 @@
 {"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},			   \
+{"log-mem",                       NULL,                  0,                strptr:(char **)&logmem_filename,    defstrval:"./logmem.log",          TYPE_STRING,   sizeof(logmem_filename)},    \
 }
 #define CMDLINE_ONLINELOG_IDX     0 
 #define CMDLINE_GLOGLEVEL_IDX     1
@@ -263,6 +264,7 @@ extern void kill_eNB_proc(int inst);
 
 // In lte-ru.c
 extern void init_RU(const char*);
+extern void stop_ru(RU_t *ru);
 extern void init_RU_proc(RU_t *ru);
 extern void stop_RU(int nb_ru);
 extern void kill_RU_proc(int inst);
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index 40075429182531d06d61b1654ec9cd9ad7765d9a..f3d62f489a4fc3c72a1ec63a35d0f4b9616c456f 100644
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -471,6 +471,7 @@ void *l2l1_task(void *arg) {
 extern int16_t dlsch_demod_shift;
 
 static void get_options(void) {
+  char logmem_filename[1024] = {0};
   int CC_id;
   int tddflag, nonbiotflag;
   char *loopfile=NULL;
@@ -903,7 +904,7 @@ int main( int argc, char **argv )
 #endif
 
 //TTN for D2D
-#ifdef Rel14
+#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
   printf ("RRC control socket\n");
   rrc_control_socket_init();
   printf ("PDCP PC5S socket\n");
@@ -1106,41 +1107,7 @@ int main( int argc, char **argv )
   
   pthread_cond_init(&sync_cond,NULL);
   pthread_mutex_init(&sync_mutex, NULL);
-  
-#ifdef XFORMS
-  int UE_id;
-  
-  printf("XFORMS\n");
-
-  if (do_forms==1) {
-    fl_initialize (&argc, argv, NULL, 0, 0);
-    
-      form_stats = create_form_stats_form();
-      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
-      UE_id = 0;
-      form_ue[UE_id] = create_lte_phy_scope_ue();
-      sprintf (title, "LTE DL SCOPE UE");
-      fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
-      
-      /*
-	if (openair_daq_vars.use_ia_receiver) {
-	fl_set_button(form_ue[UE_id]->button_0,1);
-	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
-	} else {
-	fl_set_button(form_ue[UE_id]->button_0,0);
-	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
-	}*/
-      fl_set_button(form_ue[UE_id]->button_0,0);
-      fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
-    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
-    
-    if (ret == 0)
-      pthread_setname_np( forms_thread, "xforms" );
-    
-    printf("Scope thread created, ret=%d\n",ret);
-  }
-  
-#endif
+ 
   
   rt_sleep_ns(10*100000000ULL);
 
@@ -1231,6 +1198,41 @@ int main( int argc, char **argv )
 	printf("error reading from file\n");
     }
     //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
+
+#ifdef XFORMS
+  int UE_id;
+  
+  printf("XFORMS\n");
+
+  if (do_forms==1) {
+    fl_initialize (&argc, argv, NULL, 0, 0);
+    
+      form_stats = create_form_stats_form();
+      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
+      UE_id = 0;
+      form_ue[UE_id] = create_lte_phy_scope_ue();
+      sprintf (title, "LTE DL SCOPE UE");
+      fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
+      
+      /*
+	if (openair_daq_vars.use_ia_receiver) {
+	fl_set_button(form_ue[UE_id]->button_0,1);
+	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
+	} else {
+	fl_set_button(form_ue[UE_id]->button_0,0);
+	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
+	}*/
+      fl_set_button(form_ue[UE_id]->button_0,0);
+      fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
+    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
+    
+    if (ret == 0)
+      pthread_setname_np( forms_thread, "xforms" );
+    
+    printf("Scope thread created, ret=%d\n",ret);
+  }
+  
+#endif
   
   printf("Sending sync to all threads\n");
   
diff --git a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c
index 1cadea371519748a748ced15b74876e55b19e0dc..3e1dd2ea8e16cc4373ea8584e5da508b171830a9 100644
--- a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c
+++ b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c
@@ -148,7 +148,7 @@ void pdcp_rlc_test_mac_rlc_loop (struct mac_data_ind *data_indP,  struct mac_dat
           data_indP->no_tb  += 1;
         } else {
           printf("Out of memory error\n");
-          exit(-1);
+//          exit(-1);
         }
       } else {
         printf("[RLC-LOOP] DROPPING 1 TB\n");