diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 57d630d4c46d5c2fb79f6862d764295ec22624ac..e58b19b2baaa3b07f1570fc4954a7d2d8dab6b92 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1937,6 +1937,7 @@ add_executable(oaisim_nos1
   ${OPENAIR_BIN_DIR}/messages_xml.h
   ${OPENAIR_TARGETS}/RT/USER/lte-ue.c
   ${OPENAIR_TARGETS}/RT/USER/lte-ru.c
+  ${OPENAIR_TARGETS}/RT/USER/lte-enb.c
   ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
   ${OPENAIR_TARGETS}/SIMU/USER/channel_sim.c
   ${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 6dba45653cd4082c2386200766085a882b24a2ac..9e79cb64201873252f7d69c0b0b19aa8e31dbe46 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -835,6 +835,8 @@ typedef struct {
     int32_t cqi_req_timer;
     int32_t ul_inactivity_timer;
     int32_t ul_failure_timer;
+    uint32_t ue_reestablishment_reject_timer;
+    uint32_t ue_reestablishment_reject_timer_thres;
     int32_t ul_scheduled;
     int32_t ra_pdcch_order_sent;
     int32_t ul_out_of_sync;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index 3acc4cd8962ce8fb39edb708a12e9c8d5ca4fd33..8d201320ea1d689bc994137587234157f65954f7 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -163,7 +163,7 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
 						   (nfapi_ul_config_srs_pdu));
 				ul_config_pdu->srs_pdu.srs_pdu_rel8.size =
 				    (uint8_t)
-				    sizeof(nfapi_ul_config_srs_pdu);;
+				    sizeof(nfapi_ul_config_srs_pdu);
 				ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti =
 				    UE_list->UE_template[CC_id][UE_id].
 				    rnti;
@@ -707,6 +707,50 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
 	      ul_inactivity_timer,
 	      RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
 	check_ul_failure(module_idP, CC_id, i, frameP, subframeP);
+ 
+      if (RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer > 0) {
+         RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ue_reestablishment_reject_timer++;
+         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 < NUMBER_OF_UE_MAX; 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;
+              }
+            }
+
+             for (int ii=0; ii<NUMBER_OF_UE_MAX; ii++) {
+                 LTE_eNB_ULSCH_t *ulsch = NULL;
+                 ulsch = RC.eNB[module_idP][CC_id]->ulsch[ii];
+                 if((ulsch != NULL) && (ulsch->rnti == rnti)){
+                     LOG_I(MAC, "clean_eNb_ulsch UE %x \n", rnti);
+                     clean_eNb_ulsch(ulsch);
+                     break;
+                 }
+             }
+
+             for(int j = 0; j < 10; j++){
+                 nfapi_ul_config_request_body_t *ul_req_tmp = NULL;
+                 ul_req_tmp = &RC.mac[module_idP]->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 == rnti){
+                             LOG_I(MAC, "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--;
+                         }
+                     }
+                 }
+             }
+             rrc_mac_remove_ue(module_idP,rnti);
+         }
+      }
 
     }
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index af4721858a28175be5e665b92c2250bc67cb963d..293c783285108f724f5a37cdc860365e7f4ac002 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -2075,6 +2075,7 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP
 	       sizeof(UE_sched_ctrl));
 	memset((void *) &UE_list->eNB_UE_stats[cc_idP][UE_id], 0,
 	       sizeof(eNB_UE_STATS));
+    UE_list->UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0;
 
 	UE_list->UE_sched_ctrl[UE_id].ta_update = 31;
 
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index ecc9291ee86d61d224aac5e7e23608f70a0ab69e..1a31d3d700c8c697e8080ce551a02fac8175e9ab 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -1196,7 +1196,7 @@ rrc_eNB_generate_RRCConnectionReestablishment(
   ue_context_pP->ue_context.ue_reestablishment_timer_thres = 1000;
 #else
   // activate release timer, if RRCComplete not received after 10 frames, remove UE
-  ue_context_pP->ue_context.ue_release_timer = 1;
+  //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;
 #endif
@@ -1781,6 +1781,38 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete(
   // 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<NUMBER_OF_UE_MAX; i++) {
+      ulsch = eNB_PHY->ulsch[i];
+      if((ulsch != NULL) && (ulsch->rnti == ctxt_prior.rnti)){
+        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);
@@ -1798,6 +1830,9 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject(
 #ifdef RRC_MSG_PRINT
   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;
 
   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));
@@ -1859,7 +1894,7 @@ rrc_eNB_generate_RRCConnectionRelease(
   ue_context_pP->ue_context.ue_release_timer_s1 = 0;
 #else
   // set release timer
-  ue_context_pP->ue_context.ue_release_timer=1;
+  //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;
 #endif
@@ -4704,6 +4739,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
   uint8_t                            *kRRCenc = NULL;
   uint8_t                            *kRRCint = NULL;
   uint8_t                            *kUPenc = NULL;
+  ue_context_pP->ue_context.ue_reestablishment_timer = 0;
 
   DRB_ToAddModList_t*                 DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid];
   SRB_ToAddModList_t*                 SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid];
@@ -5106,7 +5142,7 @@ rrc_eNB_generate_RRCConnectionSetup(
    ue_context_pP->ue_context.ue_release_timer_thres=1000;
 #else
   // activate release timer, if RRCSetupComplete not received after 10 frames, remove UE
-  ue_context_pP->ue_context.ue_release_timer=1;
+  //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;
 #endif
@@ -5453,11 +5489,27 @@ rrc_eNB_decode_ccch(
         rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
         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));
+          rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
+          break;
+      }
       LOG_D(RRC,
             PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n",
             PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
             ue_context_p);
+      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;
 
        /* reset timers */
        ue_context_p->ue_context.ul_failure_timer = 0;
@@ -6048,6 +6100,13 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
 						       ue_context_p);
           } else {
             ue_context_p->ue_context.reestablishment_cause = ReestablishmentCause_spare1;
+            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;
+              }
+            }
           }
 	}
       }    
@@ -6092,6 +6151,8 @@ 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 < NUMBER_OF_UE_MAX; i++) {
diff --git a/openair2/RRC/LITE/rrc_eNB_UE_context.c b/openair2/RRC/LITE/rrc_eNB_UE_context.c
index 28eace8f5aae76a21f3829363b4a8858c5e9d956..0ae3d7ca151fbed5b997f51ac09b5bde03f1e0c6 100644
--- a/openair2/RRC/LITE/rrc_eNB_UE_context.c
+++ b/openair2/RRC/LITE/rrc_eNB_UE_context.c
@@ -155,7 +155,21 @@ rrc_eNB_get_ue_context(
   memset(&temp, 0, sizeof(struct rrc_eNB_ue_context_s));
   /* eNB ue rrc id = 24 bits wide */
   temp.ue_id_rnti = rntiP;
+#if 0
   return RB_FIND(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
+#endif
+  struct rrc_eNB_ue_context_s   *ue_context_p = NULL;
+  ue_context_p = RB_FIND(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, &temp);
+  if ( ue_context_p != NULL) {
+    return ue_context_p;
+  } else {
+    RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(rrc_instance_pP->rrc_ue_head)) {
+      if (ue_context_p->ue_context.rnti == rntiP) {
+        return ue_context_p;
+      }
+    }
+    return NULL;
+  }
 }
 
 
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index d152840dd49b9aa1e46708adf3f44c43189d2325..7c87cbc073d302a369955c06eec270b9d1873898 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -814,40 +814,81 @@ int gtpv1u_update_s1u_tunnel(
     const rnti_t                                  prior_rnti
     )
 {
+
   /* Local tunnel end-point identifier */
   teid_t                   s1u_teid             = 0;
   gtpv1u_teid_data_t      *gtpv1u_teid_data_p   = NULL;
   gtpv1u_ue_data_t        *gtpv1u_ue_data_p     = NULL;
+  gtpv1u_ue_data_t        *gtpv1u_ue_data_new_p     = NULL;
   //MessageDef              *message_p            = NULL;
   hashtable_rc_t           hash_rc              = HASH_TABLE_KEY_NOT_EXISTS;
-  int                      i;
-  ebi_t                    eps_bearer_id        = 0;
+  int                      i,j;
+  uint8_t                  bearers_num = 0,bearers_total = 0;
 
   //-----------------------
   // PDCP->GTPV1U mapping
   //-----------------------
   hash_rc = hashtable_get(RC.gtpv1u_data_g->ue_mapping, prior_rnti, (void **)&gtpv1u_ue_data_p);
-  AssertFatal(hash_rc == HASH_TABLE_OK, "Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti);
+  if(hash_rc != HASH_TABLE_OK){
+    LOG_E(GTPU,"Error get ue_mapping(rnti=%x) from GTPV1U hashtable error\n", prior_rnti);
+    return -1;
+  }
 
-  gtpv1u_ue_data_p->ue_id       = create_tunnel_req_pP->rnti;
-  hash_rc = hashtable_insert(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_p);
+  gtpv1u_ue_data_new_p = calloc (1, sizeof(gtpv1u_ue_data_t));
+  memcpy(gtpv1u_ue_data_new_p,gtpv1u_ue_data_p,sizeof(gtpv1u_ue_data_t));
+  gtpv1u_ue_data_new_p->ue_id       = create_tunnel_req_pP->rnti;
+
+  hash_rc = hashtable_insert(RC.gtpv1u_data_g->ue_mapping, create_tunnel_req_pP->rnti, gtpv1u_ue_data_new_p);
   AssertFatal(hash_rc == HASH_TABLE_OK, "Error inserting ue_mapping in GTPV1U hashtable");
   LOG_I(GTPU, "inserting ue_mapping(rnti=%x) in GTPV1U hashtable\n",
       create_tunnel_req_pP->rnti);
 
+  hash_rc = hashtable_remove(RC.gtpv1u_data_g->ue_mapping, prior_rnti);
+  LOG_I(GTPU, "hashtable_remove ue_mapping(rnti=%x) in GTPV1U hashtable\n",
+		  prior_rnti);
   //-----------------------
   // GTPV1U->PDCP mapping
   //-----------------------
-  for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
-    eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i];
-    s1u_teid = gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB;
-    hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void**)&gtpv1u_teid_data_p);
-    AssertFatal(hash_rc == HASH_TABLE_OK, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", s1u_teid);
+  bearers_total =gtpv1u_ue_data_new_p->num_bearers;
+  for(j = 0;j<GTPV1U_MAX_BEARERS_ID;j++){
 
-    gtpv1u_teid_data_p->ue_id         = create_tunnel_req_pP->rnti;
-    gtpv1u_teid_data_p->eps_bearer_id = eps_bearer_id;
+    if(gtpv1u_ue_data_new_p->bearers[j].state != BEARER_IN_CONFIG)
+      continue;
+
+    bearers_num++;
+    for (i = 0; i < create_tunnel_req_pP->num_tunnels; i++) {
+      if(j == (create_tunnel_req_pP->eps_bearer_id[i]-GTPV1U_BEARER_OFFSET))
+        break;
+    }
+    if(i < create_tunnel_req_pP->num_tunnels){
+      s1u_teid = gtpv1u_ue_data_new_p->bearers[j].teid_eNB;
+      hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, s1u_teid, (void**)&gtpv1u_teid_data_p);
+      if (hash_rc == HASH_TABLE_OK) {
+        gtpv1u_teid_data_p->ue_id         = create_tunnel_req_pP->rnti;
+        gtpv1u_teid_data_p->eps_bearer_id = create_tunnel_req_pP->eps_bearer_id[i];
+
+        LOG_I(GTPU, "updata teid_mapping te_id %u (prior_rnti %x rnti %x) in GTPV1U hashtable\n",
+              s1u_teid,prior_rnti,create_tunnel_req_pP->rnti);
+      }else{
+        LOG_W(GTPU, "Error get teid mapping(s1u_teid=%u) from GTPV1U hashtable", s1u_teid);
+      }
+    }else{
+      s1u_teid = gtpv1u_ue_data_new_p->bearers[j].teid_eNB;
+      hash_rc = hashtable_remove(RC.gtpv1u_data_g->teid_mapping, s1u_teid);
+
+      if (hash_rc != HASH_TABLE_OK) {
+        LOG_D(GTPU, "Removed user rnti %x , enb S1U teid %u not found\n", prior_rnti, s1u_teid);
+      }
+      gtpv1u_ue_data_new_p->bearers[j].state = BEARER_DOWN;
+      gtpv1u_ue_data_new_p->num_bearers--;
+      LOG_I(GTPU, "delete teid_mapping te_id %u (rnti%x) bearer_id %d in GTPV1U hashtable\n",
+            s1u_teid,prior_rnti,j+GTPV1U_BEARER_OFFSET);;
+    }
+    if(bearers_num > bearers_total)
+      break;
   }
   return 0;
+
 }
 
 //-----------------------------------------------------------------------------