diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 32f06de02524a7a657c5a9e9d78b8defad6476a3..3a561cc60a1e1effa02d9d3feaec2cf429c8cc72 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -2005,6 +2005,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/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
index 36dae6431c6e69edd57661c824653cb6b22f1363..bf63d5abbefb8857d02c0cafe74ee523ce38895b 100644
--- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c
@@ -6560,7 +6560,7 @@ uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
   else
     ul_subframe = ((n+4)%10);
 
-  if (subframe_select(frame_parms,ul_subframe) != SF_UL) return(255);
+  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;
diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
index 1b3e634e6c23f94b3e7279bd95f38a1fe2171970..e067137a14b8ff180f67702b906317999efbb7c3 100644
--- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
+++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c
@@ -178,9 +178,26 @@ void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch)
         //ulsch->harq_processes[i]->phich_active = 0; //this will be done later after transmission of PHICH
         ulsch->harq_processes[i]->phich_ACK = 0;
         ulsch->harq_processes[i]->round = 0;
+        ulsch->harq_processes[i]->rar_alloc = 0;
+        ulsch->harq_processes[i]->first_rb = 0;
+        ulsch->harq_processes[i]->nb_rb = 0;
+        ulsch->harq_processes[i]->TBS = 0;
+        ulsch->harq_processes[i]->Or1 = 0;
+        ulsch->harq_processes[i]->Or2 = 0;
+        for ( int j = 0; j < 2; j++ ) {
+          ulsch->harq_processes[i]->o_RI[j] = 0;
+        }
+        ulsch->harq_processes[i]->O_ACK = 0;
+        ulsch->harq_processes[i]->srs_active = 0;
+        ulsch->harq_processes[i]->rvidx = 0;
+        ulsch->harq_processes[i]->Msc_initial = 0;
+        ulsch->harq_processes[i]->Nsymb_initial = 0;
       }
     }
-
+    ulsch->beta_offset_cqi_times8 = 0;
+    ulsch->beta_offset_ri_times8 = 0;
+    ulsch->beta_offset_harqack_times8 = 0;
+    ulsch->Msg3_active = 0;
   }
 }
 
@@ -2044,3 +2061,4 @@ uint32_t ulsch_decoding_emul(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc,
 
 }
 #endif
+
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index 0e44a7f8bd6f184923f7798791b933422768fc7f..6f52867d2d0c590c819c602d8f2bd35d3772e495 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -989,6 +989,7 @@ typedef struct PHY_VARS_eNB_s {
   LTE_eNB_ULSCH_t     *ulsch[NUMBER_OF_UE_MAX+1];      // Nusers + number of RA
   LTE_eNB_DLSCH_t     *dlsch_SI,*dlsch_ra,*dlsch_p;
   LTE_eNB_DLSCH_t     *dlsch_MCH;
+  LTE_eNB_DLSCH_t     *dlsch_PCH;
   LTE_eNB_UE_stats     UE_stats[NUMBER_OF_UE_MAX];
   LTE_eNB_UE_stats    *UE_stats_ptr[NUMBER_OF_UE_MAX];
 
diff --git a/openair1/SCHED/defs.h b/openair1/SCHED/defs.h
index e29bbf7aad220952cc5ab1b240658ce0ba006fd3..7fb9e6991d58e187bf06d9d9383b8ce724c637f4 100644
--- a/openair1/SCHED/defs.h
+++ b/openair1/SCHED/defs.h
@@ -213,6 +213,13 @@ void prach_procedures(PHY_VARS_eNB *eNB,
 		      int br_flag
 #endif
 		      );
+
+/*! \brief Function to compute subframe Number(DL and S) as a function of Frame type and TDD Configuration
+  @param frame_parms Pointer to DL frame parameter descriptor
+  @returns Subframe Number (DL,S)
+*/
+int subframe_num(LTE_DL_FRAME_PARMS *frame_parms);
+
 /*! \brief Function to compute subframe type as a function of Frame type and TDD Configuration (implements Table 4.2.2 from 36.211, p.11 from version 8.6) and subframe index.
   @param frame_parms Pointer to DL frame parameter descriptor
   @param subframe Subframe index
diff --git a/openair1/SCHED/phy_procedures_lte_common.c b/openair1/SCHED/phy_procedures_lte_common.c
index 01c44d6078f6df559cfaf0b99643d14d388eb736..bbb6986ce9c7c3ac375e79eb170e5c4c77b2ab72 100644
--- a/openair1/SCHED/phy_procedures_lte_common.c
+++ b/openair1/SCHED/phy_procedures_lte_common.c
@@ -709,6 +709,26 @@ uint16_t get_Np(uint8_t N_RB_DL,uint8_t nCCE,uint8_t plus1)
     return(Np[0+plus1]);
 }
 
+int subframe_num(LTE_DL_FRAME_PARMS *frame_parms){
+    if (frame_parms->frame_type == FDD)
+        return 10;
+
+    switch (frame_parms->tdd_config) {
+    case 1:
+        return 6;
+    case 3:
+        return 7;
+    case 4:
+        return 8;
+    case 5:
+        return 9;
+    default:
+      LOG_E(PHY,"Unsupported TDD configuration %d\n",frame_parms->tdd_config);
+      AssertFatal(frame_parms->tdd_config==1 || frame_parms->tdd_config==3 || frame_parms->tdd_config==4 || frame_parms->tdd_config==5,"subframe x Unsupported TDD configuration");
+      return(255);
+    }
+}
+
 lte_subframe_t subframe_select(LTE_DL_FRAME_PARMS *frame_parms,unsigned char subframe)
 {
 
diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c
index db729187cba2328ebb329f12a0643f7b2530444a..4aa9600c06585ba25da7eda923e50320096c7d03 100644
--- a/openair1/SCHED/phy_procedures_lte_eNb.c
+++ b/openair1/SCHED/phy_procedures_lte_eNb.c
@@ -887,10 +887,10 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc)
 	if (uci->type == SR) {
 	  if (SR_payload == 1) {
 	    fill_sr_indication(eNB,uci->rnti,frame,subframe,metric_SR);
-	    return;
+        continue;
 	  }
 	  else {
-	    return;
+        continue;
 	  }
 	}
       case HARQ:
diff --git a/openair2/COMMON/mac_messages_def.h b/openair2/COMMON/mac_messages_def.h
index c1135a34ae05cbae7143d4be13f5eba70f31861e..fcb45431491b940a8646600b2bccec82626b4951 100644
--- a/openair2/COMMON/mac_messages_def.h
+++ b/openair2/COMMON/mac_messages_def.h
@@ -40,3 +40,5 @@ MESSAGE_DEF(RRC_MAC_CCCH_DATA_IND,      MESSAGE_PRIORITY_MED_PLUS, RrcMacCcchDat
 
 MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ,      MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataReq,           rrc_mac_mcch_data_req)
 MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND,      MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd,           rrc_mac_mcch_data_ind)
+
+MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ,      MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq,           rrc_mac_pcch_data_req)
diff --git a/openair2/COMMON/mac_messages_types.h b/openair2/COMMON/mac_messages_types.h
index 5f27a0fe69ea20b1673c6e8110f28f1c3d68983d..d7fd44f072a35d0de25c04777ba62e7b7d6ca96e 100644
--- a/openair2/COMMON/mac_messages_types.h
+++ b/openair2/COMMON/mac_messages_types.h
@@ -43,11 +43,13 @@
 
 #define RRC_MAC_MCCH_DATA_REQ(mSGpTR)           (mSGpTR)->ittiMsg.rrc_mac_mcch_data_req
 #define RRC_MAC_MCCH_DATA_IND(mSGpTR)           (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind
+#define RRC_MAC_PCCH_DATA_REQ(mSGpTR)           (mSGpTR)->ittiMsg.rrc_mac_pcch_data_req
 
 // Some constants from "LAYER2/MAC/defs.h"
 #define BCCH_SDU_SIZE                           (512)
 #define CCCH_SDU_SIZE                           (512)
 #define MCCH_SDU_SIZE                           (512)
+#define PCCH_SDU_SIZE                           (512)
 
 //-------------------------------------------------------------------------------------------//
 // Messages between RRC and MAC layers
@@ -114,4 +116,10 @@ typedef struct RrcMacMcchDataInd_s {
   uint8_t   mbsfn_sync_area;
 } RrcMacMcchDataInd;
 
+typedef struct RrcMacPcchDataReq_s {
+  uint32_t  frame;
+  uint32_t  sdu_size;
+  uint8_t   sdu[PCCH_SDU_SIZE];
+  uint8_t   enb_index;
+} RrcMacPcchDataReq;
 #endif /* MAC_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/pdcp_messages_def.h b/openair2/COMMON/pdcp_messages_def.h
index da0d770def60982456d1312874e6828215aed70f..c4be4b2957416ed4fcc96ee17f16514b683129a6 100644
--- a/openair2/COMMON/pdcp_messages_def.h
+++ b/openair2/COMMON/pdcp_messages_def.h
@@ -30,3 +30,4 @@
 // Messages between RRC and PDCP layers
 MESSAGE_DEF(RRC_DCCH_DATA_REQ,          MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataReq,              rrc_dcch_data_req)
 MESSAGE_DEF(RRC_DCCH_DATA_IND,          MESSAGE_PRIORITY_MED_PLUS, RrcDcchDataInd,              rrc_dcch_data_ind)
+MESSAGE_DEF(RRC_PCCH_DATA_REQ,          MESSAGE_PRIORITY_MED_PLUS, RrcPcchDataReq,              rrc_pcch_data_req)
diff --git a/openair2/COMMON/pdcp_messages_types.h b/openair2/COMMON/pdcp_messages_types.h
index 033e73e86bbd8370f442d566238d7f01ed78e965..c90490b0fd36077c99f1c023ec33655244b01ca0 100644
--- a/openair2/COMMON/pdcp_messages_types.h
+++ b/openair2/COMMON/pdcp_messages_types.h
@@ -33,6 +33,7 @@
 // Defines to access message fields.
 #define RRC_DCCH_DATA_REQ(mSGpTR)               (mSGpTR)->ittiMsg.rrc_dcch_data_req
 #define RRC_DCCH_DATA_IND(mSGpTR)               (mSGpTR)->ittiMsg.rrc_dcch_data_ind
+#define RRC_PCCH_DATA_REQ(mSGpTR)               (mSGpTR)->ittiMsg.rrc_pcch_data_req
 
 //-------------------------------------------------------------------------------------------//
 // Messages between RRC and PDCP layers
@@ -60,4 +61,13 @@ typedef struct RrcDcchDataInd_s {
   uint8_t      eNB_index; // LG: needed in UE
 } RrcDcchDataInd;
 
+typedef struct RrcPcchDataReq_s {
+  uint32_t     sdu_size;
+  uint8_t      *sdu_p;
+  uint8_t      mode;
+  uint16_t     rnti;
+  uint8_t      ue_index;
+  uint8_t      CC_id;
+} RrcPcchDataReq;
+
 #endif /* PDCP_MESSAGES_TYPES_H_ */
diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h
index d3d853c7e714532e36d12119e19e0f8520ccf624..a39953d8f77e777ca79b1e4644be41690ae3f799 100644
--- a/openair2/COMMON/s1ap_messages_def.h
+++ b/openair2/COMMON/s1ap_messages_def.h
@@ -33,6 +33,11 @@ MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG, MESSAGE_PRIORITY_MED, IttiMsgT
 MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_LOG    , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_ue_context_release_log)
 MESSAGE_DEF(S1AP_E_RAB_SETUP_REQUEST_LOG    , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_e_rab_setup_request_log)
 MESSAGE_DEF(S1AP_E_RAB_SETUP_RESPONSE_LOG    , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_e_rab_setup_response_log)
+MESSAGE_DEF(S1AP_E_RAB_MODIFY_REQUEST_LOG     , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_e_rab_modify_request_log)
+MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESPONSE_LOG    , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_e_rab_modify_response_log)
+MESSAGE_DEF(S1AP_PAGING_LOG    , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_paging_log)
+MESSAGE_DEF(S1AP_E_RAB_RELEASE_REQUEST_LOG   , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_e_rab_release_request_log)
+MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE_LOG  , MESSAGE_PRIORITY_MED, IttiMsgText                      , s1ap_e_rab_release_response_log)
 
 /* eNB application layer -> S1AP messages */
 MESSAGE_DEF(S1AP_REGISTER_ENB_REQ          , MESSAGE_PRIORITY_MED, s1ap_register_enb_req_t          , s1ap_register_enb_req)
@@ -54,6 +59,8 @@ MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_
 MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_FAIL , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_modification_fail_t , s1ap_ue_ctxt_modification_fail)
 MESSAGE_DEF(S1AP_E_RAB_SETUP_RESP          , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_resp_t          , s1ap_e_rab_setup_resp)
 MESSAGE_DEF(S1AP_E_RAB_SETUP_REQUEST_FAIL  , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_req_fail_t      , s1ap_e_rab_setup_request_fail)
+MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP          , MESSAGE_PRIORITY_MED, s1ap_e_rab_modify_resp_t          , s1ap_e_rab_modify_resp)
+MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE    , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t        , s1ap_e_rab_release_resp)
 
 /* S1AP -> RRC messages */
 MESSAGE_DEF(S1AP_DOWNLINK_NAS              , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t              , s1ap_downlink_nas )
@@ -61,6 +68,8 @@ MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, s1ap_initial_
 MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_REQ  , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_modification_req_t  , s1ap_ue_ctxt_modification_req)
 MESSAGE_DEF(S1AP_PAGING_IND                , MESSAGE_PRIORITY_MED, s1ap_paging_ind_t                , s1ap_paging_ind )
 MESSAGE_DEF(S1AP_E_RAB_SETUP_REQ            , MESSAGE_PRIORITY_MED, s1ap_e_rab_setup_req_t        , s1ap_e_rab_setup_req )
+MESSAGE_DEF(S1AP_E_RAB_MODIFY_REQ           , MESSAGE_PRIORITY_MED, s1ap_e_rab_modify_req_t        , s1ap_e_rab_modify_req )
+MESSAGE_DEF(S1AP_E_RAB_RELEASE_COMMAND     , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_command_t     , s1ap_e_rab_release_command)
 MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMMAND, MESSAGE_PRIORITY_MED, s1ap_ue_release_command_t        , s1ap_ue_release_command)
 
 /* S1AP <-> RRC messages (can be initiated either by MME or eNB) */
diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h
index c17097d4ecb9b3b3ea02d13e8d618e863dc69df1..4a5f492b0baa3f4685c8de48f342ff6075e02d8f 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -41,6 +41,7 @@
 #define S1AP_UE_CTXT_MODIFICATION_FAIL(mSGpTR)  (mSGpTR)->ittiMsg.s1ap_ue_ctxt_modification_fail
 #define S1AP_E_RAB_SETUP_RESP(mSGpTR)           (mSGpTR)->ittiMsg.s1ap_e_rab_setup_resp
 #define S1AP_E_RAB_SETUP_FAIL(mSGpTR)           (mSGpTR)->ittiMsg.s1ap_e_rab_setup_req_fail
+#define S1AP_E_RAB_MODIFY_RESP(mSGpTR)           (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp
 
 #define S1AP_DOWNLINK_NAS(mSGpTR)               (mSGpTR)->ittiMsg.s1ap_downlink_nas
 #define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR)  (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
@@ -48,9 +49,12 @@
 #define S1AP_UE_CONTEXT_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_command
 #define S1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_release_complete
 #define S1AP_E_RAB_SETUP_REQ(mSGpTR)              (mSGpTR)->ittiMsg.s1ap_e_rab_setup_req
-#define S1AP_PAGIND_IND(mSGpTR)                 (mSGpTR)->ittiMsg.s1ap_paging_ind
+#define S1AP_E_RAB_MODIFY_REQ(mSGpTR)              (mSGpTR)->ittiMsg.s1ap_e_rab_modify_req
+#define S1AP_PAGING_IND(mSGpTR)                 (mSGpTR)->ittiMsg.s1ap_paging_ind
 
 #define S1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR)     (mSGpTR)->ittiMsg.s1ap_ue_release_req
+#define S1AP_E_RAB_RELEASE_COMMAND(mSGpTR)      (mSGpTR)->ittiMsg.s1ap_e_rab_release_command
+#define S1AP_E_RAB_RELEASE_RESPONSE(mSGpTR)     (mSGpTR)->ittiMsg.s1ap_e_rab_release_resp
 
 //-------------------------------------------------------------------------------------------//
 /* Maximum number of e-rabs to be setup/deleted in a single message.
@@ -175,6 +179,11 @@ typedef struct s1ap_gummei_s {
   uint16_t mme_group_id;
 } s1ap_gummei_t;
 
+typedef struct s1ap_imsi_s {
+  uint8_t  buffer[S1AP_IMSI_LENGTH];
+  uint8_t  length;
+} s1ap_imsi_t;
+
 typedef struct s_tmsi_s {
   uint8_t  mme_code;
   uint32_t m_tmsi;
@@ -189,7 +198,7 @@ typedef enum ue_paging_identity_presenceMask_e {
 typedef struct ue_paging_identity_s {
   ue_paging_identity_presenceMask_t presenceMask;
   union {
-    char     imsi[S1AP_IMSI_LENGTH];
+    s1ap_imsi_t  imsi;
     s_tmsi_t s_tmsi;
   } choice;
 } ue_paging_identity_t;
@@ -260,11 +269,29 @@ typedef struct e_rab_setup_s {
   uint32_t gtp_teid;
 } e_rab_setup_t;
 
+typedef struct e_rab_modify_s {
+  /* Unique e_rab_id for the UE. */
+  uint8_t e_rab_id;
+} e_rab_modify_t;
+
+typedef enum S1ap_Cause_e {
+  S1AP_CAUSE_NOTHING,  /* No components present */
+  S1AP_CAUSE_RADIO_NETWORK,
+  S1AP_CAUSE_TRANSPORT,
+  S1AP_CAUSE_NAS,
+  S1AP_CAUSE_PROTOCOL,
+  S1AP_CAUSE_MISC,
+  /* Extensions may appear below */
+
+} s1ap_Cause_t;
+
 typedef struct e_rab_failed_s {
   /* Unique e_rab_id for the UE. */
   uint8_t e_rab_id;
   /* Cause of the failure */
   //     cause_t cause;
+  s1ap_Cause_t cause;
+  uint8_t cause_value;
 } e_rab_failed_t;
 
 typedef enum s1ap_ue_ctxt_modification_present_s {
@@ -460,6 +487,12 @@ typedef struct s1ap_initial_context_setup_req_s {
   e_rab_t  e_rab_param[S1AP_MAX_E_RAB];
 } s1ap_initial_context_setup_req_t;
 
+typedef struct tai_plmn_identity_s {
+  uint16_t mcc;
+  uint16_t mnc;
+  uint8_t  mnc_digit_length;
+} plmn_identity_t;
+
 typedef struct s1ap_paging_ind_s {
   /* UE identity index value.
    * Specified in 3GPP TS 36.304
@@ -472,6 +505,15 @@ typedef struct s1ap_paging_ind_s {
   /* Indicates origin of paging */
   cn_domain_t cn_domain;
 
+  /* PLMN_identity in TAI of Paging*/
+  plmn_identity_t plmn_identity[256];
+
+  /* TAC in TAIList of Paging*/
+  int16_t tac[256];
+
+  /* size of TAIList*/
+  int16_t tai_size;
+
   /* Optional fields */
   paging_drx_t paging_drx;
 
@@ -520,16 +562,6 @@ typedef struct s1ap_ue_release_command_s {
 
 
 //-------------------------------------------------------------------------------------------//
-typedef enum S1ap_Cause_e {
-  S1AP_CAUSE_NOTHING,  /* No components present */
-  S1AP_CAUSE_RADIO_NETWORK,
-  S1AP_CAUSE_TRANSPORT,
-  S1AP_CAUSE_NAS,
-  S1AP_CAUSE_PROTOCOL,
-  S1AP_CAUSE_MISC,
-  /* Extensions may appear below */
-
-} s1ap_Cause_t;
 // S1AP <-- RRC messages
 typedef struct s1ap_ue_release_req_s {
   unsigned      eNB_ue_s1ap_id:24;
@@ -537,4 +569,78 @@ typedef struct s1ap_ue_release_req_s {
   long          cause_value;
 } s1ap_ue_release_req_t, s1ap_ue_release_resp_t;
 
+typedef struct s1ap_e_rab_modify_req_s {
+  /* UE id for initial connection to S1AP */
+  uint16_t ue_initial_id;
+
+  /* MME UE id  */
+  uint16_t mme_ue_s1ap_id;
+
+  /* eNB ue s1ap id as initialized by S1AP layer */
+  unsigned eNB_ue_s1ap_id:24;
+
+  /* Number of e_rab to be modify in the list */
+  uint8_t nb_e_rabs_tomodify;
+
+  /* E RAB modify request */
+  e_rab_t e_rab_modify_params[S1AP_MAX_E_RAB];
+} s1ap_e_rab_modify_req_t;
+
+typedef struct s1ap_e_rab_modify_resp_s {
+  unsigned  eNB_ue_s1ap_id:24;
+
+  /* Number of e_rab modify-ed in the list */
+  uint8_t       nb_of_e_rabs;
+  /* list of e_rab modify-ed by RRC layers */
+  e_rab_modify_t e_rabs[S1AP_MAX_E_RAB];
+
+  /* Number of e_rab failed to be modify in list */
+  uint8_t        nb_of_e_rabs_failed;
+  /* list of e_rabs that failed to be modify */
+  e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
+} s1ap_e_rab_modify_resp_t;
+
+typedef struct e_rab_release_s {
+  /* Unique e_rab_id for the UE. */
+  uint8_t                     e_rab_id;
+} e_rab_release_t;
+
+typedef struct s1ap_e_rab_release_command_s {
+  /* MME UE id  */
+  uint16_t mme_ue_s1ap_id;
+
+  /* eNB ue s1ap id as initialized by S1AP layer */
+  unsigned eNB_ue_s1ap_id:24;
+
+  /* The NAS PDU should be forwarded by the RRC layer to the NAS layer */
+  nas_pdu_t                   nas_pdu;
+
+  /* Number of e_rab to be released in the list */
+  uint8_t nb_e_rabs_torelease;
+
+  /* E RAB release command */
+  e_rab_release_t e_rab_release_params[S1AP_MAX_E_RAB];
+
+} s1ap_e_rab_release_command_t;
+
+typedef struct s1ap_e_rab_release_resp_s {
+  /* MME UE id  */
+  uint16_t mme_ue_s1ap_id;
+
+  /* eNB ue s1ap id as initialized by S1AP layer */
+  unsigned eNB_ue_s1ap_id:24;
+
+  /* Number of e_rab released in the list */
+  uint8_t       nb_of_e_rabs_released;
+
+  /* list of e_rabs released */
+  e_rab_release_t e_rab_release[S1AP_MAX_E_RAB];
+
+  /* Number of e_rab failed to be released in list */
+  uint8_t        nb_of_e_rabs_failed;
+  /* list of e_rabs that failed to be released */
+  e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
+
+} s1ap_e_rab_release_resp_t;
+
 #endif /* S1AP_MESSAGES_TYPES_H_ */
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index 43d8167fe604315290e416dbd8190fbfcffae392..78a74f00d3f1a48b705cc15a03dc880e5d5f226e 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -163,6 +163,8 @@
 /*!\brief maximum number of slices / groups */
 #define MAX_NUM_SLICES 4
 
+#define U_PLANE_INACTIVITY_VALUE 6000
+
 /* 
  * eNB part 
  */
@@ -472,6 +474,15 @@ typedef struct {
     /// BCCH MCS
     uint32_t ccch_mcs;
 
+  /// num PCCH PDU per CC
+  uint32_t total_num_pcch_pdu;
+  /// PCCH buffer size
+  uint32_t pcch_buffer;
+  /// total PCCH buffer size
+  uint32_t total_pcch_buffer;
+  /// BCCH MCS
+  uint32_t pcch_mcs;
+
 /// num active users
     uint16_t num_dlactive_UEs;
     ///  available number of PRBs for a give SF
@@ -824,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;
@@ -855,6 +868,7 @@ 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;
 } UE_sched_ctrl;
 /*! \brief eNB template for the Random access information */
 typedef struct {
@@ -982,6 +996,10 @@ typedef struct {
     uint32_t BCCH_alloc_pdu;
     /// Outgoing CCCH pdu for PHY
     CCCH_PDU CCCH_pdu;
+    /// Outgoing PCCH DCI allocation
+    uint32_t PCCH_alloc_pdu;
+    /// Outgoing PCCH pdu for PHY
+    PCCH_PDU PCCH_pdu;
     /// Outgoing RAR pdu for PHY
     RAR_PDU RAR_pdu;
     /// Template for RA computations
@@ -1102,6 +1120,8 @@ typedef struct eNB_MAC_INST_s {
     time_stats_t schedule_mch;
     /// processing time of eNB ULSCH reception
     time_stats_t rx_ulsch_sdu;	// include rlc_data_ind
+    /// processing time of eNB PCH scheduler
+    time_stats_t schedule_pch;
 } eNB_MAC_INST;
 
 /* 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c
index f03a3961f67c5d10c6272dd61595cffefe2a7bec..42835a5a8824089a97088e88b66ee042665b195b 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler.c
@@ -164,7 +164,7 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
                                 ul_config_pdu->srs_pdu.srs_pdu_rel8.tl.tag                          = NFAPI_UL_CONFIG_REQUEST_SRS_PDU_REL8_TAG;
 				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;
@@ -546,7 +546,7 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
 
 	UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
 	// check threshold
-	if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
+	if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 20000) {
 	    // inform RRC of failure and clear timer
 	    LOG_I(MAC,
 		  "UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",
@@ -558,6 +558,12 @@ check_ul_failure(module_id_t module_idP, int CC_id, int UE_id,
 	}
     }				// ul_failure_timer>0
 
+    UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer++;
+    if(UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer > (U_PLANE_INACTIVITY_VALUE*subframe_num(&RC.eNB[module_idP][CC_id]->frame_parms))){
+       LOG_D(MAC,"UE %d rnti %x: U-Plane Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti); 
+       mac_eNB_rrc_uplane_failure(module_idP,CC_id,frameP,subframeP,rnti);
+       UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer  = 0;
+    }// time > 60s
 }
 
 void
@@ -702,6 +708,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);
+         }
+      }
 
     }
 
@@ -731,6 +781,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP,
 	schedule_mib(module_idP, frameP, subframeP);
     // This schedules SI for legacy LTE and eMTC starting in subframeP
     schedule_SI(module_idP, frameP, subframeP);
+    // This schedules Paging in subframeP
+    schedule_PCH(module_idP,frameP,subframeP);
     // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
     schedule_RA(module_idP, frameP, subframeP);
     // copy previously scheduled UL resources (ULSCH + HARQ)
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index fe6c045fe71de4389240952c5dec3f9e3c8950d7..31ef50feaeb77280b3d2830a339599ebe39c4ee7 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -1073,6 +1073,7 @@ schedule_ue_spec(module_id_t module_idP,
 				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;
@@ -1655,7 +1656,13 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP,
 		BCCH_pdu.payload[0]);
     }
 
-    UE_id = find_UE_id(module_idP, rntiP);
+    if (rntiP==P_RNTI) {
+        LOG_D(MAC,"[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP);
+
+        return((unsigned char *)&eNB->common_channels[CC_id].PCCH_pdu.payload[0]);
+    }
+
+  UE_id = find_UE_id(module_idP,rntiP);
 
     if (UE_id != -1) {
 	LOG_D(MAC,
@@ -1770,3 +1777,351 @@ set_ue_dai(sub_frame_t subframeP,
 	break;
     }
 }
+
+void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP)
+{
+  /* DCI:format 1A/1C P-RNTI:0xFFFE */
+  /* PDU:eNB_rrc_inst[Mod_idP].common_channels[CC_id].PCCH_pdu.payload */
+  uint16_t                       pcch_sdu_length;
+  int                            mcs = -1;
+  int                            CC_id;
+  eNB_MAC_INST                   *eNB      = RC.mac[module_idP];
+  COMMON_channels_t              *cc;
+  uint8_t                        *vrb_map;
+  int                            n_rb_dl;
+  int                            first_rb = -1;
+  nfapi_dl_config_request_pdu_t  *dl_config_pdu;
+  nfapi_tx_request_pdu_t         *TX_req;
+  nfapi_dl_config_request_body_t *dl_req;
+#ifdef FORMAT1C
+  int                            gap_index = 0;      /* indicate which gap(1st or 2nd) is used (0:1st) */
+  const int                      GAP_MAP [9][2] = {
+                                                    {-1, 0},        /* N_RB_DL [6-10] -1: |N_RB/2| 0: N/A*/
+                                                    {4, 0},         /* N_RB_DL [11] */
+                                                    {8, 0},         /* N_RB_DL [12-19] */
+                                                    {12, 0},        /* N_RB_DL [20-26] */
+                                                    {18, 0},        /* N_RB_DL [27-44] */
+                                                    {27, 0},        /* N_RB_DL [45-49] */
+                                                    {27, 9},        /* N_RB_DL [50-63] */
+                                                    {32, 16},       /* N_RB_DL [64-79] */
+                                                    {48, 16}        /* N_RB_DL [80-110] */
+                                                  };
+  uint8_t                        n_rb_step = 0;
+  uint8_t                        n_gap = 0;
+  uint8_t                        n_vrb_dl = 0;
+  uint8_t                        Lcrbs = 0;
+  uint16_t                       rb_bit    = 168;    /* RB bit number value is unsure */
+  #endif
+
+  start_meas(&eNB->schedule_pch);
+
+  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
+    cc              = &eNB->common_channels[CC_id];
+    vrb_map         = (void*)&cc->vrb_map;
+    n_rb_dl         = to_prb(cc->mib->message.dl_Bandwidth);
+    dl_req          = &eNB->DL_req[CC_id].dl_config_request_body;
+    for (uint16_t i = 0; i < NUMBER_OF_UE_MAX; i++) {
+      if (UE_PF_PO[CC_id][i].enable_flag != TRUE) {
+        continue;
+      }
+      if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) {
+      pcch_sdu_length = mac_rrc_data_req(module_idP,
+                                           CC_id,
+                                           frameP,
+                                           PCCH,1,
+                                           &cc->PCCH_pdu.payload[0],
+                                           1,
+                                           module_idP,
+                                           i); // used for ue index
+      if (pcch_sdu_length == 0) {
+        LOG_D(MAC,"[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP,frameP, subframeP);
+        continue;
+      }
+      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) ||
+        (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
+        switch (n_rb_dl) {
+#if 0
+        case 6:
+          n_gap = n_rb_dl/2;  /* expect: 3 */
+          n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));;  /* expect: 6 */
+          first_rb = 0;
+          break;
+        case 15:
+          n_gap = GAP_MAP[2][0];  /* expect: 8 */
+          n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 14 */
+          first_rb = 6;
+          break;
+#endif
+        case 25:
+          n_gap = GAP_MAP[3][0];  /* expect: 12 */
+          n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 24 */
+          first_rb = 10;
+          break;
+        case 50:
+          n_gap = GAP_MAP[6][gap_index];  /* expect: 27 or 9 */
+          if (gap_index > 0) {
+            n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap);  /* 36 */
+          } else {
+            n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 46 */
+          }
+          first_rb = 24;
+          break;
+        case 100:
+          n_gap = GAP_MAP[8][gap_index];  /* expect: 48 or 16 */
+          if (gap_index > 0) {
+            n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap);  /* expect: 96 */
+          } else {
+            n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 96 */
+          }
+          first_rb = 48;
+          break;
+        }
+      } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) {  // SIB + paging
+        switch (n_rb_dl) {
+#if 0
+        case 6:
+          n_gap = n_rb_dl/2;  /* expect: 3 */
+          n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));;  /* expect: 6 */
+          first_rb = 0;
+          break;
+        case 15:
+          n_gap = GAP_MAP[2][0];  /* expect: 8 */
+          n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 14 */
+          first_rb = 10;
+          break;
+#endif
+        case 25:
+          n_gap = GAP_MAP[3][0];  /* expect: 12 */
+          n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 24 */
+          first_rb = 14;
+          break;
+        case 50:
+          n_gap = GAP_MAP[6][gap_index];  /* expect: 27 or 9 */
+          if (gap_index > 0) {
+            n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap);  /* 36 */
+          } else {
+            n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 46 */
+          }
+          first_rb = 28;
+          break;
+        case 100:
+          n_gap = GAP_MAP[8][gap_index];  /* expect: 48 or 16 */
+          if (gap_index > 0) {
+            n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap);  /* expect: 96 */
+          } else {
+            n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap));  /* expect: 96 */
+          }
+          first_rb = 52;
+          break;
+        }
+      }
+      /* Get MCS for length of PCH */
+      if (pcch_sdu_length <= TBStable1C[0]) {
+        mcs=0;
+      } else if (pcch_sdu_length <= TBStable1C[1]) {
+        mcs=1;
+      } else if (pcch_sdu_length <= TBStable1C[2]) {
+        mcs=2;
+      } else if (pcch_sdu_length <= TBStable1C[3]) {
+        mcs=3;
+      } else if (pcch_sdu_length <= TBStable1C[4]) {
+        mcs=4;
+      } else if (pcch_sdu_length <= TBStable1C[5]) {
+        mcs=5;
+      } else if (pcch_sdu_length <= TBStable1C[6]) {
+        mcs=6;
+      } else if (pcch_sdu_length <= TBStable1C[7]) {
+        mcs=7;
+      } else if (pcch_sdu_length <= TBStable1C[8]) {
+        mcs=8;
+      } else if (pcch_sdu_length <= TBStable1C[9]) {
+        mcs=9;
+      } else {
+        /* unexpected: pcch sdb size is over max value*/
+        LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n",
+             module_idP, frameP,CC_id, pcch_sdu_length);
+        return;
+      }
+      rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1;
+      /* calculate N_RB_STEP and Lcrbs */
+      if (n_rb_dl < 50) {
+        n_rb_step = 2;
+        Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2);
+      } else {
+        n_rb_step = 4;
+        Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4);
+      }
+      for(i = 0;i < Lcrbs ;i++){
+        vrb_map[first_rb+i] = 1;
+      }
+#else
+      //NO SIB
+      if ((subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) ||
+        (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) {
+        switch (n_rb_dl) {
+        case 25:
+          first_rb = 10;
+          break;
+        case 50:
+          first_rb = 24;
+          break;
+        case 100:
+          first_rb = 48;
+          break;
+        }
+      } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) {  // SIB + paging
+        switch (n_rb_dl) {
+        case 25:
+          first_rb = 14;
+          break;
+        case 50:
+          first_rb = 28;
+          break;
+        case 100:
+          first_rb = 52;
+          break;
+        }
+      }
+
+      vrb_map[first_rb] = 1;
+      vrb_map[first_rb+1] = 1;
+      vrb_map[first_rb+2] = 1;
+      vrb_map[first_rb+3] = 1;
+      /* Get MCS for length of PCH */
+      if (pcch_sdu_length <= get_TBS_DL(0,3)) {
+        mcs=0;
+      } else if (pcch_sdu_length <= get_TBS_DL(1,3)) {
+        mcs=1;
+      } else if (pcch_sdu_length <= get_TBS_DL(2,3)) {
+        mcs=2;
+      } else if (pcch_sdu_length <= get_TBS_DL(3,3)) {
+        mcs=3;
+      } else if (pcch_sdu_length <= get_TBS_DL(4,3)) {
+        mcs=4;
+      } else if (pcch_sdu_length <= get_TBS_DL(5,3)) {
+        mcs=5;
+      } else if (pcch_sdu_length <= get_TBS_DL(6,3)) {
+        mcs=6;
+      } else if (pcch_sdu_length <= get_TBS_DL(7,3)) {
+        mcs=7;
+      } else if (pcch_sdu_length <= get_TBS_DL(8,3)) {
+        mcs=8;
+      } else if (pcch_sdu_length <= get_TBS_DL(9,3)) {
+        mcs=9;
+      }
+#endif
+      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));
+#ifdef FORMAT1C
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                  = NFAPI_DL_DCI_FORMAT_1C;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding       = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.ngap                        = n_gap;
+#else
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                  = NFAPI_DL_DCI_FORMAT_1A;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process                = 0;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc                         = 1; // no TPC
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1        = 1;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1        = 1;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding       = getRIV(n_rb_dl,first_rb,4);
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
+#endif
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level           = 4;
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                        = 0xFFFE; // P-RNTI
+      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type                   = 2;    // P-RNTI : 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.mcs_1                       = mcs;
+
+      // Rel10 fields
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start                           = 3;
+      // Rel13 fields
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type                               = 0; // regular UE
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type                    = 2; // not BR
+      dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io            = 0xFFFF;
+
+      if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) {
+        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_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;
+        dl_config_pdu->pdu_size                                                        = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu));
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index                              = eNB->pdu_index[CC_id];
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti                                   = 0xFFFE;
+#ifdef FORMAT1C
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 3;   // format 1C
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step);
+#else
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type               = 2;   // format 1A/1B/1D
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding                  = getRIV(n_rb_dl,first_rb,4);
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0;   // localized
+#endif
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation                             = 2; //QPSK
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version                     = 1;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks                       = 1;// first block
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag  = 0;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme                    = (cc->p_eNB==1 ) ? 0 : 1;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers                       = 1;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands                     = 1;
+        // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index                         = ;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity                   = 1;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa                                     = 4; // 0 dB
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index               = 0;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap                                   = 0;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb                                   = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode                      = (cc->p_eNB==1 ) ? 1 : 2;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband                 = 1;
+        dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector                          = 1;
+        // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector                    = ;
+        dl_req->number_pdu++;
+
+        eNB->TX_req[CC_id].sfn_sf                                                     = (frameP<<4)+subframeP;
+        TX_req                                                                         = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus];
+        TX_req->pdu_length                                                             = pcch_sdu_length;
+        TX_req->pdu_index                                                              = eNB->pdu_index[CC_id]++;
+        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.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);
+        continue;
+      }
+
+      if (opt_enabled == 1) {
+        trace_pdu(1,
+                  &eNB->common_channels[CC_id].PCCH_pdu.payload[0],
+                  pcch_sdu_length,
+                  0xffff,
+                  PCCH,
+                  P_RNTI,
+                  eNB->frame,
+                  eNB->subframe,
+                  0,
+                  0);
+        LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
+              module_idP, frameP, CC_id, 0xffff, pcch_sdu_length);
+      }
+      eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1;
+                    eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length;
+                    eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length;
+                    eNB->eNB_stats[CC_id].pcch_mcs=mcs;
+      //paging first_rb log
+      LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n",
+             module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb);
+
+      pthread_mutex_lock(&ue_pf_po_mutex);
+      memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t));
+      pthread_mutex_unlock(&ue_pf_po_mutex);
+    }
+    }
+  }
+  /* this might be misleading when pcch is inactive */
+  stop_meas(&eNB->schedule_pch);
+  return;
+}
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
index 1bffb83d49efc74c5b6647049990bc1c85fdcaf3..3e574a56c36432dd69790fa3dc6958fa1b5a757d 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
@@ -2094,6 +2094,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;
 
@@ -2124,47 +2125,68 @@ int rrc_mac_remove_ue(module_id_t mod_idP, rnti_t rntiP)
 //------------------------------------------------------------------------------
 {
     int i;
+    int j;
     UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list;
-    int UE_id = find_UE_id(mod_idP, rntiP);
+    int UE_id = find_UE_id(mod_idP,rntiP);
     int pCC_id;
 
     if (UE_id == -1) {
-	LOG_W(MAC, "rrc_mac_remove_ue: UE %x not found\n", rntiP);
-	return 0;
+      LOG_W(MAC,"rrc_mac_remove_ue: UE %x not found\n", rntiP);
+      return 0;
     }
 
-    pCC_id = UE_PCCID(mod_idP, UE_id);
+    pCC_id = UE_PCCID(mod_idP,UE_id);
 
-    LOG_I(MAC, "Removing UE %d from Primary CC_id %d (rnti %x)\n", UE_id,
-	  pCC_id, rntiP);
-    dump_ue_list(UE_list, 0);
+    LOG_I(MAC,"Removing UE %d from Primary CC_id %d (rnti %x)\n",UE_id,pCC_id, rntiP);
+    dump_ue_list(UE_list,0);
 
     UE_list->active[UE_id] = FALSE;
     UE_list->num_UEs--;
 
-    if (UE_list->head == UE_id)
-	UE_list->head = UE_list->next[UE_id];
-    else
-	UE_list->next[prev(UE_list, UE_id, 0)] = UE_list->next[UE_id];
-    if (UE_list->head_ul == UE_id)
-	UE_list->head_ul = UE_list->next_ul[UE_id];
-    else
-	UE_list->next_ul[prev(UE_list, UE_id, 0)] =
-	    UE_list->next_ul[UE_id];
+    if (UE_list->head == UE_id) UE_list->head=UE_list->next[UE_id];
+    else UE_list->next[prev(UE_list,UE_id,0)]=UE_list->next[UE_id];
+    if (UE_list->head_ul == UE_id) UE_list->head_ul=UE_list->next_ul[UE_id];
+    else UE_list->next_ul[prev(UE_list,UE_id,0)]=UE_list->next_ul[UE_id];
 
     // clear all remaining pending transmissions
-    UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0] = 0;
-    UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1] = 0;
-    UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2] = 0;
-    UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3] = 0;
-
-    UE_list->UE_template[pCC_id][UE_id].ul_SR = 0;
-    UE_list->UE_template[pCC_id][UE_id].rnti = NOT_A_RNTI;
-    UE_list->UE_template[pCC_id][UE_id].ul_active = FALSE;
-    eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
-    eNB_ulsch_info[mod_idP][pCC_id][UE_id].status = S_UL_NONE;
-    eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti = NOT_A_RNTI;
-    eNB_dlsch_info[mod_idP][pCC_id][UE_id].status = S_DL_NONE;
+    /*  UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID0]  = 0;
+    UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID1]  = 0;
+    UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID2]  = 0;
+    UE_list->UE_template[pCC_id][UE_id].bsr_info[LCGID3]  = 0;
+
+    UE_list->UE_template[pCC_id][UE_id].ul_SR             = 0;
+    UE_list->UE_template[pCC_id][UE_id].rnti              = NOT_A_RNTI;
+    UE_list->UE_template[pCC_id][UE_id].ul_active         = FALSE;
+   */
+    memset (&UE_list->UE_template[pCC_id][UE_id],0,sizeof(UE_TEMPLATE));
+
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_retx = 0;
+    for ( j = 0; j < NB_RB_MAX; j++ ) {
+      UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_tx[j] = 0;
+      UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_tx[j] = 0;
+    }
+    UE_list->eNB_UE_stats[pCC_id][UE_id].num_retransmission = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_sdu_bytes = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_rbs_used_rx = 0;
+    for ( j = 0; j < NB_RB_MAX; j++ ) {
+      UE_list->eNB_UE_stats[pCC_id][UE_id].num_pdu_rx[j] = 0;
+      UE_list->eNB_UE_stats[pCC_id][UE_id].num_bytes_rx[j] = 0;
+    }
+    UE_list->eNB_UE_stats[pCC_id][UE_id].num_errors_rx = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_pdu_bytes_rx = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_pdus_rx = 0;
+    UE_list->eNB_UE_stats[pCC_id][UE_id].total_num_errors_rx = 0;
+
+    eNB_ulsch_info[mod_idP][pCC_id][UE_id].rnti                        = NOT_A_RNTI;
+    eNB_ulsch_info[mod_idP][pCC_id][UE_id].status                      = S_UL_NONE;
+    eNB_dlsch_info[mod_idP][pCC_id][UE_id].rnti                        = NOT_A_RNTI;
+    eNB_dlsch_info[mod_idP][pCC_id][UE_id].status                      = S_DL_NONE;
+ 
+    eNB_ulsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
+    eNB_dlsch_info[mod_idP][pCC_id][UE_id].serving_num = 0;
 
     // check if this has an RA process active
     RA_t *ra;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index def57639f626de3327e668e74494cb84e7604dca..dbae220301dea309b4f085a89b521d5e287f6890 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -732,6 +732,8 @@ rx_sdu(const module_id_t enb_mod_idP,
 			    num_pdu_rx[rx_lcids[i]] += 1;
 			UE_list->eNB_UE_stats[CC_idP][UE_id].
 			    num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
+                        //clear uplane_inactivity_timer
+	                UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
 		    } else {	/* rx_length[i] */
 			UE_list->eNB_UE_stats[CC_idP][UE_id].
 			    num_errors_rx += 1;
diff --git a/openair2/LAYER2/MAC/extern.h b/openair2/LAYER2/MAC/extern.h
index 50ea5634b93dd13ca57c40875e4fda4d9930e2a7..d0c8706ad6728ab8cbfae407c77a1a429671c493 100644
--- a/openair2/LAYER2/MAC/extern.h
+++ b/openair2/LAYER2/MAC/extern.h
@@ -101,4 +101,4 @@ extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
 extern DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
 extern DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
 
-#endif				//DEF_H
+#endif //DEF_H
diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h
index bbd6d6a36d84d365e6a63bc8b2222303a3a9bf02..46a8b005e4476d8fb81a3bcbe46e0a0e204b325d 100644
--- a/openair2/LAYER2/MAC/proto.h
+++ b/openair2/LAYER2/MAC/proto.h
@@ -426,6 +426,14 @@ void set_ue_dai(sub_frame_t subframeP,
 		int UE_id,
 		uint8_t CC_id, uint8_t tdd_config, UE_list_t * UE_list);
 
+/** \brief First stage of PCH Scheduling. Gets a PCH SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length.  It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs).
+@param Mod_id Instance ID of eNB
+@param frame Frame index
+@param subframe Subframe number on which to act
+@param paging_ue_index
+*/
+void schedule_PCH(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP);
+
 uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP,
 					unsigned char group_id);
 uint8_t UE_is_to_be_scheduled(module_id_t module_idP, int CC_id,
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index b362e8887a08066b969d160d7d86222cbff06e2e..894abeb100a5e5ca2fdccae21181661723ad89de 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -68,6 +68,8 @@
 extern int otg_enabled;
 #endif
 
+#include "common/ran_context.h"
+extern RAN_CONTEXT_t RC;
 
 //-----------------------------------------------------------------------------
 /*
@@ -948,6 +950,21 @@ pdcp_run (
         AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
         break;
 
+      case RRC_PCCH_DATA_REQ:
+      {
+        sdu_size_t     sdu_buffer_sizeP;
+        sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size;
+        uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id;
+        uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index;
+        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP;
+        if (sdu_buffer_sizeP > 0) {
+        	memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP);
+        }
+        //paging pdcp log
+        LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP);
+      }
+      break;
+
       default:
         LOG_E(PDCP, "Received unexpected message %s\n", msg_name);
         break;
@@ -1037,6 +1054,13 @@ pdcp_remove_UE(
 
   // check and remove SRBs first
 
+  for(int i = 0;i<NUMBER_OF_UE_MAX;i++){
+    if(pdcp_eNB_UE_instance_to_rnti[i] == ctxt_pP->rnti){
+      pdcp_eNB_UE_instance_to_rnti[i] = NOT_A_RNTI;
+      break;
+    }
+  }
+
   for (srb_id=0; srb_id<2; srb_id++) {
     key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_YES);
     h_rc = hashtable_remove(pdcp_coll_p, key);
@@ -1344,7 +1368,7 @@ rrc_pdcp_config_asn1_req (
     for (cnt=0; cnt<drb2release_list_pP->list.count; cnt++) {
       pdrb_id_p = drb2release_list_pP->list.array[cnt];
       drb_id =  *pdrb_id_p;
-      key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, srb_id, SRB_FLAG_NO);
+      key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO);
       h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p);
 
       if (h_rc != HASH_TABLE_OK) {
@@ -1472,7 +1496,17 @@ pdcp_config_req_asn1 (
     if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
       pdcp_pP->is_ue = FALSE;
       //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti;
-      pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
+//      pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
+      if( srb_flagP == SRB_FLAG_NO ) {
+          for(int i = 0;i<NUMBER_OF_UE_MAX;i++){
+              if(pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] == NOT_A_RNTI){
+                  break;
+              }
+              pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
+          }
+          pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index] = ctxt_pP->rnti;
+          pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
+      }
       //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % NUMBER_OF_UE_MAX;
     } else {
       pdcp_pP->is_ue = TRUE;
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index e65bbf1db06880384dd925c95b4807f141177937..37ff231198b7c6d35336fba8a2f46e1a98823e63 100644
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -589,7 +589,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
           if (ctxt_cpy.enb_flag) {
             ctxt.module_id = 0;
             rab_id      = pdcp_read_header_g.rb_id % maxDRB;
-            ctxt.rnti          = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index];
+            ctxt.rnti          = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / maxDRB];
           } else {
             ctxt.module_id = 0;
             rab_id      = pdcp_read_header_g.rb_id % maxDRB;
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 faf7763e4fae992fa6e175ca2c4e69ea1d70c796..15dc90f175a183dab9d247afeb081aad21db975a 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
@@ -125,6 +125,7 @@ rlc_tm_cleanup (
   // RX SIDE
   if ((rlcP->output_sdu_in_construction)) {
     free_mem_block (rlcP->output_sdu_in_construction, __func__);
+    rlcP->output_sdu_in_construction = NULL;
   }
 
   memset(rlcP, 0, sizeof(rlc_tm_entity_t));
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 423aca55e9242f6db9ed647b6327cfbbed7c9b7f..4e2723a8f476489bb16fe1eb677f6e0ed4550ab2 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
@@ -343,6 +343,7 @@ rlc_um_cleanup (
 
   if ((rlc_pP->output_sdu_in_construction)) {
     free_mem_block (rlc_pP->output_sdu_in_construction, __func__);
+    rlc_pP->output_sdu_in_construction = NULL;
   }
 
   if (rlc_pP->dar_buffer) {
diff --git a/openair2/LAYER2/openair2_proc.c b/openair2/LAYER2/openair2_proc.c
index 7801279be2058fc2fc6f653084f70ef4b4c52d0d..a5a8135feda8037c2b3131c8ceedd63a1585d876 100644
--- a/openair2/LAYER2/openair2_proc.c
+++ b/openair2/LAYER2/openair2_proc.c
@@ -131,6 +131,12 @@ int dump_eNB_l2_stats(char *buffer, int length)
 		     eNB->eNB_stats[CC_id].bcch_buffer,
 		     eNB->eNB_stats[CC_id].total_bcch_buffer,
 		     eNB->eNB_stats[CC_id].bcch_mcs);
+
+      len += sprintf(&buffer[len],"PCCH , NB_TX_MAC = %d, transmitted bytes (TTI %d, total %d) MCS (TTI %d)\n",
+         eNB->eNB_stats[CC_id].total_num_pcch_pdu,
+         eNB->eNB_stats[CC_id].pcch_buffer,
+         eNB->eNB_stats[CC_id].total_pcch_buffer,
+         eNB->eNB_stats[CC_id].pcch_mcs);
       
       eNB->eNB_stats[CC_id].dlsch_bitrate=((eNB->eNB_stats[CC_id].dlsch_bytes_tx*8)/((eNB->frame + 1)*10));
       eNB->eNB_stats[CC_id].total_dlsch_pdus_tx+=eNB->eNB_stats[CC_id].dlsch_pdus_tx;
diff --git a/openair2/RRC/LITE/L2_interface.c b/openair2/RRC/LITE/L2_interface.c
index 3077b9ba80220d757f0f3cf091047b8b5c82be05..47adc80f959389eaa6a8acbc64e994add6867563 100644
--- a/openair2/RRC/LITE/L2_interface.c
+++ b/openair2/RRC/LITE/L2_interface.c
@@ -249,6 +249,44 @@ mac_rrc_data_req(
       return (Sdu_size);
     }
 
+    if( (Srb_id & RAB_OFFSET ) == PCCH) {
+      LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);
+
+      // check if data is there for MAC
+      if(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] > 0) { //Fill buffer
+        LOG_D(RRC,"[eNB %d] PCCH (%p) has %d bytes\n",Mod_idP,&RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area],
+               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]);
+
+#if 0 //defined(ENABLE_ITTI)
+        {
+          MessageDef *message_p;
+          int pcch_size = RC.rrc[Mod_idP]->arrier[CC_id].sizeof_paging[mbsfn_sync_area];
+          int sdu_size = sizeof(RRC_MAC_PCCH_DATA_REQ (message_p).sdu);
+
+          if (pcch_size > sdu_size) {
+            LOG_E(RRC, "SDU larger than PCCH SDU buffer size (%d, %d)", pcch_size, sdu_size);
+            pcch_size = sdu_size;
+          }
+
+          message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_MAC_PCCH_DATA_REQ);
+          RRC_MAC_PCCH_DATA_REQ (message_p).frame = frameP;
+          RRC_MAC_PCCH_DATA_REQ (message_p).sdu_size = pcch_size;
+          memset (RRC_MAC_PCCH_DATA_REQ (message_p).sdu, 0, PCCH_SDU_SIZE);
+          memcpy (RRC_MAC_PCCH_DATA_REQ (message_p).sdu, RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], pcch_size);
+          RRC_MAC_PCCH_DATA_REQ (message_p).enb_index = eNB_index;
+
+          itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
+        }
+#endif
+
+        memcpy(buffer_pP, RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]);
+        Sdu_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area];
+        RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] = 0;
+      }
+
+      return (Sdu_size);
+    }
+
 #if defined(Rel10) || defined(Rel14)
 
     if((Srb_id & RAB_OFFSET) == MCCH) {
@@ -770,12 +808,34 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
 
   if (ue_context_p != NULL) {
     LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
-    ue_context_p->ue_context.ul_failure_timer=1;
+    if(ue_context_p->ue_context.ul_failure_timer == 0)
+      ue_context_p->ue_context.ul_failure_timer=1;
   }
   else {
     LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
   }
-  rrc_mac_remove_ue(Mod_instP,rntiP);
+//  rrc_mac_remove_ue(Mod_instP,rntiP);
+}
+
+void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
+                const int CC_idP,
+                const frame_t frameP,
+                const sub_frame_t subframeP,
+                const rnti_t rntiP)
+{
+    struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+    ue_context_p = rrc_eNB_get_ue_context(
+                     RC.rrc[Mod_instP],
+                     rntiP);
+    if (ue_context_p != NULL) {
+      LOG_I(RRC,"Frame %d, Subframe %d: UE %x U-Plane failure, activating timer\n",frameP,subframeP,rntiP);
+
+      if(ue_context_p->ue_context.ul_failure_timer == 0)
+          ue_context_p->ue_context.ul_failure_timer=19999;
+    }
+    else {
+      LOG_W(RRC,"Frame %d, Subframe %d: U-Plane failure: UE %x unknown \n",frameP,subframeP,rntiP);
+    }
 }
 
 void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, 
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.c b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
index a05b27ddc361f93e62c6bb6bac70803b662ac152..db5ce5db9537e088340448ada83a135a8048894b 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.c
@@ -54,6 +54,8 @@
 #include "UL-DCCH-Message.h"
 #include "DL-CCCH-Message.h"
 #include "DL-DCCH-Message.h"
+#include "PCCH-Message.h"
+#include "openair3/UTILS/conversions.h"
 #include "EstablishmentCause.h"
 #include "RRCConnectionSetup.h"
 #include "SRB-ToAddModList.h"
@@ -89,6 +91,7 @@
 #endif
 
 #include "common/ran_context.h"
+#include "secu_defs.h"
 
 //#include "PHY/defs.h"
 #ifndef USER_MODE
@@ -230,7 +233,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich
 
   AssertFatal(phich_Resource <= PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n");
   mib->message.phich_Config.phich_Resource = phich_Resource;
-  AssertFatal(phich_Resource <= PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n");
+  AssertFatal(phich_duration <= PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n");
   mib->message.phich_Config.phich_Duration = phich_duration;
   LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x,sfn %x\n",
          (uint32_t)mib->message.dl_Bandwidth,
@@ -1964,6 +1967,214 @@ do_RRCConnectionReconfiguration(
   return((enc_rval.encoded+7)/8);
 }
 
+//------------------------------------------------------------------------------
+uint8_t
+do_RRCConnectionReestablishment(
+  const protocol_ctxt_t*     const ctxt_pP,
+  rrc_eNB_ue_context_t*      const ue_context_pP,
+  int                              CC_id,
+  uint8_t*                   const buffer,
+  const uint8_t                    transmission_mode,
+  const uint8_t                    Transaction_id,
+  SRB_ToAddModList_t               **SRB_configList,
+  struct PhysicalConfigDedicated   **physicalConfigDedicated)
+{
+  asn_enc_rval_t enc_rval;
+
+  long* logicalchannelgroup = NULL;
+  struct SRB_ToAddMod* SRB1_config = NULL;
+  struct SRB_ToAddMod* SRB2_config = NULL;
+  struct SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL;
+  struct SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL;
+  struct LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL;
+  eNB_RRC_INST *rrc               = RC.rrc[ctxt_pP->module_id];
+
+#ifdef CBA
+  struct PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL;
+  long* betaOffset_CBA_Index = NULL;
+  long* cShift_CBA = NULL;
+#endif
+  PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL;
+
+  DL_CCCH_Message_t dl_ccch_msg;
+
+  RRCConnectionReestablishment_t* rrcConnectionReestablishment = NULL;
+
+  int i = 0;
+  SRB_ToAddModList_t **SRB_configList2 = NULL;
+  SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id];
+  if (*SRB_configList2) {
+    free(*SRB_configList2);
+  }
+  *SRB_configList2 = CALLOC(1, sizeof(SRB_ToAddModList_t));
+
+  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_rrcConnectionReestablishment;
+  rrcConnectionReestablishment          = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionReestablishment;
+
+  // RRCConnectionReestablishment
+  // Configure SRB1
+
+
+  // get old configuration of SRB2
+  if (*SRB_configList != NULL) {
+    for (i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) {
+      LOG_D(RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n",
+          i, (*SRB_configList)->list.array[i]->srb_Identity);
+      if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ){
+        SRB2_config = (*SRB_configList)->list.array[i];
+      } else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ){
+        SRB1_config = (*SRB_configList)->list.array[i];
+      }
+    }
+  }
+
+  if (SRB1_config == NULL) {
+    // default SRB1 configuration
+    LOG_W(RRC,"SRB1 configuration does not exist in SRB configuration list, use default\n");
+    /// SRB1
+    SRB1_config = CALLOC(1, sizeof(*SRB1_config));
+
+    SRB1_config->srb_Identity = 1;
+    SRB1_rlc_config = CALLOC(1, sizeof(*SRB1_rlc_config));
+    SRB1_config->rlc_Config   = SRB1_rlc_config;
+
+    SRB1_rlc_config->present = SRB_ToAddMod__rlc_Config_PR_explicitValue;
+    SRB1_rlc_config->choice.explicitValue.present=RLC_Config_PR_am;
+  #if defined(ENABLE_ITTI)
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit;
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU          = rrc->srb1_poll_pdu;
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte         = rrc->srb1_poll_byte;
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = rrc->srb1_max_retx_threshold;
+    SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering     = rrc->srb1_timer_reordering;
+    SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit;
+  #else
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms20;;
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU          = PollPDU_p4;;
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte         = PollByte_kBinfinity;
+    SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8;
+    SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering     = T_Reordering_ms35;
+    SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms0;
+  #endif
+
+    SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config));
+    SRB1_config->logicalChannelConfig = SRB1_lchan_config;
+
+    SRB1_lchan_config->present = SRB_ToAddMod__logicalChannelConfig_PR_explicitValue;
+    SRB1_ul_SpecificParameters = CALLOC(1, sizeof(*SRB1_ul_SpecificParameters));
+
+    SRB1_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB1_ul_SpecificParameters;
+    SRB1_ul_SpecificParameters->priority = 1;
+
+    //assign_enum(&SRB1_ul_SpecificParameters->prioritisedBitRate,LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity);
+    SRB1_ul_SpecificParameters->prioritisedBitRate=LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
+
+    //assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50);
+    SRB1_ul_SpecificParameters->bucketSizeDuration=LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
+
+    logicalchannelgroup = CALLOC(1, sizeof(long));
+    *logicalchannelgroup = 0;
+    SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup;
+  }
+
+  if (SRB2_config == NULL) {
+    LOG_W(RRC,"SRB2 configuration does not exist in SRB configuration list\n");
+  } else {
+    ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
+  }
+
+  if (*SRB_configList) {
+    free(*SRB_configList);
+  }
+
+  *SRB_configList = CALLOC(1, sizeof(SRB_ToAddModList_t));
+
+  ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config);
+
+  physicalConfigDedicated2 = *physicalConfigDedicated;
+
+  rrcConnectionReestablishment->rrc_TransactionIdentifier = Transaction_id;
+  rrcConnectionReestablishment->criticalExtensions.present = RRCConnectionReestablishment__criticalExtensions_PR_c1;
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.present = RRCConnectionReestablishment__criticalExtensions__c1_PR_rrcConnectionReestablishment_r8;
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.srb_ToAddModList = *SRB_configList;
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.drb_ToAddModList = NULL;
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.drb_ToReleaseList = NULL;
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.sps_Config = NULL;
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2;
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.mac_MainConfig = NULL;
+
+  uint8_t KeNB_star[32] = { 0 };
+  uint16_t pci = rrc->carrier[CC_id].physCellId;
+  uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
+                  rrc->carrier[CC_id].dl_CarrierFreq);
+  bool     is_rel8_only = true;
+  if (earfcn_dl > 65535) {
+    is_rel8_only = false;
+  }
+
+  LOG_D(RRC, "pci=%d, eutra_band=%d, downlink_frequency=%d, earfcn_dl=%u, is_rel8_only=%s\n",
+      pci,
+      RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band,
+      rrc->carrier[CC_id].dl_CarrierFreq,
+      earfcn_dl,
+      is_rel8_only == true ? "true": "false");
+#if defined(ENABLE_SECURITY)
+  if (ue_context_pP->ue_context.nh_ncc >= 0) {
+    derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KeNB_star);
+    rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = ue_context_pP->ue_context.nh_ncc;
+  } else { // first HO 
+    derive_keNB_star (ue_context_pP->ue_context.kenb, pci, earfcn_dl, is_rel8_only, KeNB_star);
+    // LG: really 1
+    rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = 0;
+  }
+
+  // copy KeNB_star to ue_context_pP->ue_context.kenb
+  memcpy (ue_context_pP->ue_context.kenb, KeNB_star, 32);
+  ue_context_pP->ue_context.kenb_ncc = 0;
+#else
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = 0;
+#endif
+
+  rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nonCriticalExtension = NULL;
+
+#ifdef XER_PRINT
+  xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg);
+#endif
+  enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message,
+                                   (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 defined(ENABLE_ITTI)
+# if !defined(DISABLE_XER_SPRINT)
+  {
+    char        message_string[20000];
+    size_t      message_string_size;
+
+    if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) {
+      MessageDef *msg_p;
+
+      msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText));
+      msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size;
+      memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size);
+
+      itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p);
+    }
+  }
+# endif
+#endif
+
+#ifdef USER_MODE
+  LOG_D(RRC,"RRCConnectionReestablishment Encoded %zd bits (%zd bytes)\n",
+        enc_rval.encoded,(enc_rval.encoded+7)/8);
+#endif
+
+  return((enc_rval.encoded+7)/8);
+}
+
 //------------------------------------------------------------------------------
 uint8_t
 do_RRCConnectionReestablishmentReject(
@@ -2451,6 +2662,73 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans
   return encoded;
 }
 
+uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain)
+{
+  LOG_D(RRC, "[eNB %d] do_Paging start\n", Mod_id);
+  asn_enc_rval_t enc_rval;
+
+  PCCH_Message_t pcch_msg;
+  PagingRecord_t *paging_record_p;
+  int j;
+
+  pcch_msg.message.present           = PCCH_MessageType_PR_c1;
+  pcch_msg.message.choice.c1.present = PCCH_MessageType__c1_PR_paging;
+
+  pcch_msg.message.choice.c1.choice.paging.pagingRecordList = CALLOC(1,sizeof(*pcch_msg.message.choice.c1.choice.paging.pagingRecordList));
+
+  pcch_msg.message.choice.c1.choice.paging.systemInfoModification = NULL;
+  pcch_msg.message.choice.c1.choice.paging.etws_Indication = NULL;
+  pcch_msg.message.choice.c1.choice.paging.nonCriticalExtension = NULL;
+
+  asn_set_empty(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list);
+  pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count = 0;
+
+  if ((paging_record_p = calloc(1, sizeof(PagingRecord_t))) == NULL) {
+    /* Possible error on calloc */
+    return (-1);
+  }
+
+  memset(paging_record_p, 0, sizeof(PagingRecord_t));
+
+  /* convert ue_paging_identity_t to PagingUE_Identity_t */
+  if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_s_tmsi) {
+    paging_record_p->ue_Identity.present = PagingUE_Identity_PR_s_TMSI;
+    MME_CODE_TO_OCTET_STRING(ue_paging_identity.choice.s_tmsi.mme_code,
+                             &paging_record_p->ue_Identity.choice.s_TMSI.mmec);
+    paging_record_p->ue_Identity.choice.s_TMSI.mmec.bits_unused = 0;
+    M_TMSI_TO_OCTET_STRING(ue_paging_identity.choice.s_tmsi.m_tmsi,
+                             &paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI);
+    paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI.bits_unused = 0;
+  } else if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_imsi) {
+    IMSI_Digit_t imsi_digit[21];
+    for (j = 0; j< ue_paging_identity.choice.imsi.length; j++) {  /* IMSI size */
+      imsi_digit[j] = (IMSI_Digit_t)ue_paging_identity.choice.imsi.buffer[j];
+      ASN_SEQUENCE_ADD(&paging_record_p->ue_Identity.choice.imsi.list, &imsi_digit[j]);
+    }
+  }
+
+  /* set cn_domain */
+  if (cn_domain == CN_DOMAIN_PS) {
+    paging_record_p->cn_Domain = PagingRecord__cn_Domain_ps;
+  } else {
+    paging_record_p->cn_Domain = PagingRecord__cn_Domain_cs;
+  }
+  /* add to list */
+  ASN_SEQUENCE_ADD(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list, paging_record_p);
+  LOG_D(RRC, "[eNB %d] do_Paging paging_record: cn_Domain %ld, ue_paging_identity.presenceMask %d, PagingRecordList.count %d\n",
+          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);
+#ifdef XER_PRINT
+  xer_fprint(stdout, &asn_DEF_PCCH_Message, (void*)&pcch_msg);
+#endif
+
+  return((enc_rval.encoded+7)/8);
+}
+
 uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer)
 {
   ssize_t encoded;
diff --git a/openair2/RRC/LITE/MESSAGES/asn1_msg.h b/openair2/RRC/LITE/MESSAGES/asn1_msg.h
index 6241e2963fbacb6538a115a1707aa3af530856d1..270d9bc58fea6c3b3764bca0770893c9b72197ee 100644
--- a/openair2/RRC/LITE/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/LITE/MESSAGES/asn1_msg.h
@@ -195,6 +195,28 @@ do_RRCConnectionReconfiguration(
     , SCellToAddMod_r10_t  *SCell_config
 #endif
                                         );
+/**
+\brief Generate an RRCConnectionReestablishment DL-CCCH-Message (eNB).  This routine configures SRB_ToAddMod (SRB1/SRB2) and
+PhysicalConfigDedicated IEs.  The latter does not enable periodic CQI reporting (PUCCH format 2/2a/2b) or SRS.
+@param ctxt_pP Running context
+@param ue_context_pP UE context
+@param CC_id         Component Carrier ID
+@param buffer Pointer to PER-encoded ASN.1 description of DL-CCCH-Message PDU
+@param transmission_mode Transmission mode for UE (1-9)
+@param Transaction_id Transaction_ID for this message
+@param SRB_configList Pointer (returned) to SRB1_config/SRB2_config(later) IEs for this UE
+@param physicalConfigDedicated Pointer (returned) to PhysicalConfigDedicated IE for this UE
+@returns Size of encoded bit stream in bytes*/
+uint8_t
+do_RRCConnectionReestablishment(
+  const protocol_ctxt_t*     const ctxt_pP,
+  rrc_eNB_ue_context_t*      const ue_context_pP,
+  int                              CC_id,
+  uint8_t*                   const buffer,
+  const uint8_t                    transmission_mode,
+  const uint8_t                    Transaction_id,
+  SRB_ToAddModList_t               **SRB_configList,
+  struct PhysicalConfigDedicated   **physicalConfigDedicated);
 
 /**
 \brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB).
@@ -249,6 +271,8 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_
 
 uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer);
 
+uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain);
+
 uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer);
 
 OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer);
diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h
index 9d7f7fdf2d169d4104de8c5ff5662d51aa2bfc85..0a661849988efbea794cc129772db7074a56fb01 100644
--- a/openair2/RRC/LITE/defs.h
+++ b/openair2/RRC/LITE/defs.h
@@ -296,12 +296,15 @@ typedef enum e_rab_satus_e {
   E_RAB_STATUS_DONE, // from the eNB perspective
   E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
   E_RAB_STATUS_FAILED,
+  E_RAB_STATUS_TORELEASE  // to release DRB between eNB and UE
 } e_rab_status_t;
 
 typedef struct e_rab_param_s {
   e_rab_t param;
   uint8_t status;
   uint8_t xid; // transaction_id
+  s1ap_Cause_t cause;
+  uint8_t cause_value;
 } __attribute__ ((__packed__)) e_rab_param_t;
 #endif
 
@@ -379,6 +382,7 @@ typedef struct eNB_RRC_UE_s {
   SRB_ToAddModList_t*                SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
   DRB_ToAddModList_t*                DRB_configList;
   DRB_ToAddModList_t*                DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
+  DRB_ToReleaseList_t*               DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
   uint8_t                            DRB_active[8];
   struct PhysicalConfigDedicated*    physicalConfigDedicated;
   struct SPS_Config*                 sps_Config;
@@ -398,6 +402,9 @@ typedef struct eNB_RRC_UE_s {
 #if defined(ENABLE_SECURITY)
   /* KeNB as derived from KASME received from EPC */
   uint8_t kenb[32];
+  int8_t  kenb_ncc;
+  uint8_t nh[32];
+  int8_t  nh_ncc;
 #endif
   /* Used integrity/ciphering algorithms */
   CipheringAlgorithm_r12_t                          ciphering_algorithm;
@@ -427,9 +434,15 @@ typedef struct eNB_RRC_UE_s {
   uint8_t                           setup_e_rabs;
   /* Number of e_rab to be setup in the list */
   uint8_t                            nb_of_e_rabs;
+  /* Number of e_rab to be modified in the list */
+  uint8_t                            nb_of_modify_e_rabs;
+  uint8_t                            nb_of_failed_e_rabs;
+  e_rab_param_t                      modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
   /* list of e_rab to be setup by RRC layers */
   e_rab_param_t                      e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
-
+  //release e_rabs
+  uint8_t                            nb_release_of_e_rabs;
+  e_rab_failed_t                     e_rabs_release_failed[S1AP_MAX_E_RAB];
   // LG: For GTPV1 TUNNELS
   uint32_t                           enb_gtp_teid[S1AP_MAX_E_RAB];
   transport_layer_addr_t             enb_gtp_addrs[S1AP_MAX_E_RAB];
@@ -438,6 +451,13 @@ typedef struct eNB_RRC_UE_s {
   uint32_t                           ul_failure_timer;
   uint32_t                           ue_release_timer;
   uint32_t                           ue_release_timer_thres;
+  uint32_t                           ue_release_timer_s1;
+  uint32_t                           ue_release_timer_thres_s1;
+  uint32_t                           ue_release_timer_rrc;
+  uint32_t                           ue_release_timer_thres_rrc;
+  uint32_t                           ue_reestablishment_timer;
+  uint32_t                           ue_reestablishment_timer_thres;
+  uint8_t                            e_rab_release_command_flag;
 } eNB_RRC_UE_t;
 
 typedef uid_t ue_uid_t;
@@ -501,6 +521,8 @@ typedef struct {
 #endif
   SRB_INFO                          SI;
   SRB_INFO                          Srb0;
+  uint8_t                           *paging[NUMBER_OF_UE_MAX];
+  uint32_t                           sizeof_paging[NUMBER_OF_UE_MAX];
 } rrc_eNB_carrier_data_t;
 
 typedef struct eNB_RRC_INST_s {
@@ -628,6 +650,8 @@ typedef struct UE_RRC_INST_s {
 #if defined(ENABLE_SECURITY)
   /* KeNB as computed from parameters within USIM card */
   uint8_t kenb[32];
+  uint8_t nh[32];
+  int8_t  nh_ncc;
 #endif
 
   /* Used integrity/ciphering algorithms */
@@ -635,6 +659,14 @@ typedef struct UE_RRC_INST_s {
   e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm;
 } UE_RRC_INST;
 
+typedef struct UE_PF_PO_s {
+  boolean_t enable_flag;  /* flag indicate whether current object is used */
+  uint16_t ue_index_value;  /* UE index value */
+  uint8_t PF_min;  /* minimal value of Paging Frame (PF) */
+  uint8_t PO;  /* Paging Occasion (PO) */
+  uint32_t T;  /* DRX cycle */
+} UE_PF_PO_t;
+
 #include "proto.h"
 
 #endif
diff --git a/openair2/RRC/LITE/extern.h b/openair2/RRC/LITE/extern.h
index 77dcaac5e69492b9895d87434850adb42c923aec..71d8c9d0dcf8780dd91542ee1b5019ae12aa38d6 100644
--- a/openair2/RRC/LITE/extern.h
+++ b/openair2/RRC/LITE/extern.h
@@ -77,6 +77,11 @@ extern uint32_t timeToTrigger_ms[16];
 extern float RSRP_meas_mapping[100];
 extern float RSRQ_meas_mapping[33];
 
+extern UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+extern pthread_mutex_t ue_pf_po_mutex;
+
+extern uint16_t reestablish_rnti_map[NUMBER_OF_UE_MAX][2];
+
 #endif
 
 
diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h
index b3d5beb2922f26316695a32c742a13eda1647908..3e00bc9769ea2b4edd8903aebde5eaa5aaba70fb 100644
--- a/openair2/RRC/LITE/proto.h
+++ b/openair2/RRC/LITE/proto.h
@@ -254,6 +254,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
   const uint8_t                ho_state
 );
 
+int freq_to_arfcn10(int band, unsigned long freq);
+
 void
 rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
   const protocol_ctxt_t* const ctxt_pP,
@@ -261,6 +263,18 @@ rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
   const uint8_t                ho_state
 );
 
+/**\brief release Data Radio Bearer between ENB and UE
+   \param ctxt_pP Running context
+   \param ue_context_pP UE context of UE receiving the message*/
+void
+rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(
+  const protocol_ctxt_t*   const ctxt_pP,
+  rrc_eNB_ue_context_t*    const ue_context_pP,
+  uint8_t                  xid,
+  uint32_t                 nas_length,
+  uint8_t*                 nas_buffer
+);
+
 void 
 rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP,
 			  rrc_eNB_ue_context_t*  ue_context_pP);
@@ -324,6 +338,12 @@ void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
 			    const sub_frame_t subframeP,
 			    const rnti_t rnti);
 
+void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP,
+                const int CC_id,
+                const frame_t frameP,
+                const sub_frame_t subframeP,
+                const rnti_t rnti);
+
 void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, 
 			    const int CC_id, 
 			    const frame_t frameP,
diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c
index 65e1a25b1708e404cd07508c2754ffe3a2669085..4bccf7d6beebef71be5c5b9430112639a88b99fd 100644
--- a/openair2/RRC/LITE/rrc_common.c
+++ b/openair2/RRC/LITE/rrc_common.c
@@ -333,26 +333,58 @@ rrc_rx_tx(
     RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) {
       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/20000\n",
+	  LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n",
 		ue_context_p->ue_context.rnti,
 		ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi,
 		ue_context_p->ue_context.ul_failure_timer);
 	}
 	else {
-	  LOG_I(RRC,"UE rnti %x failure timer %d/20000\n",
+	  LOG_I(RRC,"UE rnti %x failure timer %d/8\n",
 		ue_context_p->ue_context.rnti,
 		ue_context_p->ue_context.ul_failure_timer);
 	}
       }
       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 >= 20000) {
+	if (ue_context_p->ue_context.ul_failure_timer >= 8) {
 	  // 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;
 	  break;
 	}
       }
+      if (ue_context_p->ue_context.ue_release_timer_s1>0) {
+        ue_context_p->ue_context.ue_release_timer_s1++;
+        if (ue_context_p->ue_context.ue_release_timer_s1 >=
+            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_to_be_removed = ue_context_p;
+          break;
+        }
+      }
+
+      if (ue_context_p->ue_context.ue_release_timer_rrc>0) {
+        ue_context_p->ue_context.ue_release_timer_rrc++;
+        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_to_be_removed = ue_context_p;
+          break;
+        }
+      }
+
+      if (ue_context_p->ue_context.ue_reestablishment_timer>0) {
+        ue_context_p->ue_context.ue_reestablishment_timer++;
+        if (ue_context_p->ue_context.ue_reestablishment_timer >=
+            ue_context_p->ue_context.ue_reestablishment_timer_thres) {
+          LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti);
+          ue_context_p->ue_context.ul_failure_timer = 20000;
+          ue_to_be_removed = ue_context_p;
+          ue_context_p->ue_context.ue_reestablishment_timer = 0;
+          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 >= 
@@ -363,9 +395,18 @@ rrc_rx_tx(
 	}
       }
     }
-    if (ue_to_be_removed)
+    if (ue_to_be_removed) {
+      if(ue_to_be_removed->ue_context.ul_failure_timer >= 8) {
+          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){
+        ue_to_be_removed->ue_context.ul_failure_timer = 0;
+      }
+    }
 #ifdef RRC_LOCALIZATION
 
     /* for the localization, only primary CC_id might be relevant*/
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index ad9b63c798d563126f241fa117673771c118ae26..c9ef58129b92b4580a6479622510b0b55085172e 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -84,6 +84,7 @@
 #endif
 
 #include "pdcp.h"
+#include "gtpv1u_eNB_task.h"
 
 #if defined(ENABLE_ITTI)
 #   include "intertask_interface.h"
@@ -575,6 +576,7 @@ 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,
@@ -585,6 +587,7 @@ rrc_eNB_get_next_free_ue_context(
         return NULL;
       }
     }
+#endif
     ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]);
 
     if (ue_context_p == NULL) {
@@ -683,11 +686,29 @@ rrc_eNB_free_mem_UE_context(
     ue_context_pP->ue_context.SRB_configList = NULL;
   }
 
+  for(i = 0;i < RRC_TRANSACTION_IDENTIFIER_NUMBER;i++){
+      if (ue_context_pP->ue_context.SRB_configList2[i]) {
+          free(ue_context_pP->ue_context.SRB_configList2[i]);
+          ue_context_pP->ue_context.SRB_configList2[i] = NULL;
+      }
+  }
+
   if (ue_context_pP->ue_context.DRB_configList) {
     ASN_STRUCT_FREE(asn_DEF_DRB_ToAddModList, ue_context_pP->ue_context.DRB_configList);
     ue_context_pP->ue_context.DRB_configList = NULL;
   }
 
+  for(i = 0;i < RRC_TRANSACTION_IDENTIFIER_NUMBER;i++){
+      if (ue_context_pP->ue_context.DRB_configList2[i]) {
+          free(ue_context_pP->ue_context.DRB_configList2[i]);
+          ue_context_pP->ue_context.DRB_configList2[i] = NULL;
+      }
+      if (ue_context_pP->ue_context.DRB_Release_configList2[i]) {
+          free(ue_context_pP->ue_context.DRB_Release_configList2[i]);
+          ue_context_pP->ue_context.DRB_Release_configList2[i] = NULL;
+      }
+  }
+
   memset(ue_context_pP->ue_context.DRB_active, 0, sizeof(ue_context_pP->ue_context.DRB_active));
 
   if (ue_context_pP->ue_context.physicalConfigDedicated) {
@@ -724,10 +745,14 @@ rrc_eNB_free_mem_UE_context(
     ue_context_pP->ue_context.mac_MainConfig = NULL;
   }
 
-  if (ue_context_pP->ue_context.measGapConfig) {
+/*  if (ue_context_pP->ue_context.measGapConfig) {
     ASN_STRUCT_FREE(asn_DEF_MeasGapConfig, ue_context_pP->ue_context.measGapConfig);
     ue_context_pP->ue_context.measGapConfig = NULL;
-  }
+  }*/
+    if (ue_context_pP->ue_context.handover_info) {
+      ASN_STRUCT_FREE(asn_DEF_Handover, ue_context_pP->ue_context.handover_info);
+      ue_context_pP->ue_context.handover_info = NULL;
+    }
 
   //SRB_INFO                           SI;
   //SRB_INFO                           Srb0;
@@ -782,7 +807,11 @@ 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;
+  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);
   /*  ue_context_p = rrc_eNB_get_ue_context(
@@ -795,6 +824,8 @@ 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);
     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
@@ -802,6 +833,8 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*
      *  in order to allow the UE to perform the NAS recovery
      *  procedure, see TS 23.401 [17].
      */
+     return;
+    }
 #else
 #if defined(OAI_EMU)
     AssertFatal(ue_context_pP->local_uid < NUMBER_OF_UE_MAX, "local_uid invalid (%d<%d) for UE %x!", ue_context_pP->local_uid, NUMBER_OF_UE_MAX, rnti);
@@ -811,7 +844,33 @@ rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s*
     oai_emulation.info.eNB_ue_module_id_to_rnti[enb_mod_idP][ue_module_id] = NOT_A_RNTI;
 #endif
 #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<NUMBER_OF_UE_MAX; i++) {
+        ulsch = eNB_PHY->ulsch[i];
+        if((ulsch != NULL) && (ulsch->rnti == rnti)){
+          LOG_I(RRC, "clean_eNb_ulsch UE %x \n", rnti);
+          clean_eNb_ulsch(ulsch);
+          break;
+        }
+      }
 
+      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));
+              }
+              ul_req_tmp->number_of_pdus--;
+            }
+          }
+        }
+      }
+    }
     rrc_mac_remove_ue(enb_mod_idP,rnti);
     rrc_rlc_remove_ue(&ctxt);
     pdcp_remove_UE(&ctxt);
@@ -1027,216 +1086,968 @@ rrc_eNB_generate_RRCConnectionReject(
 
 //-----------------------------------------------------------------------------
 void
-rrc_eNB_generate_RRCConnectionReestablishmentReject(
-  const protocol_ctxt_t* const ctxt_pP,
+rrc_eNB_generate_RRCConnectionReestablishment(
+  const protocol_ctxt_t*         const ctxt_pP,
   rrc_eNB_ue_context_t*          const ue_context_pP,
-  const int                    CC_id
+  const int                            CC_id
 )
 //-----------------------------------------------------------------------------
 {
-#ifdef RRC_MSG_PRINT
+  LogicalChannelConfig_t             *SRB1_logicalChannelConfig;
+  SRB_ToAddModList_t                 **SRB_configList;
+  SRB_ToAddMod_t                     *SRB1_config;
   int                                 cnt;
-#endif
 
-  T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
+  T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
 
+  SRB_configList = &ue_context_pP->ue_context.SRB_configList;
   RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
-    do_RRCConnectionReestablishmentReject(ctxt_pP->module_id,
-                          (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload);
+    do_RRCConnectionReestablishment(ctxt_pP,
+                                    ue_context_pP,
+                                    CC_id,
+                                    (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload,
+                                    (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2
+                                    rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),
+                                    SRB_configList,
+                                    &ue_context_pP->ue_context.physicalConfigDedicated);
 
 #ifdef RRC_MSG_PRINT
-  LOG_F(RRC,"[MSG] RRCConnectionReestablishmentReject\n");
+  LOG_F(RRC,"[MSG] RRCConnectionReestablishment\n");
 
   for (cnt = 0; cnt < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size; cnt++) {
-    LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->Srb0.Tx_buffer.Payload)[cnt]);
+    LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload)[cnt]);
   }
 
   LOG_F(RRC,"\n");
 #endif
 
-  MSC_LOG_TX_MESSAGE(
-    MSC_RRC_ENB,
-    MSC_RRC_UE,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
-    MSC_AS_TIME_FMT" RRCConnectionReestablishmentReject UE %x size %u",
-    MSC_AS_TIME_ARGS(ctxt_pP),
-    ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti,
-    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
+  // configure SRB1 for UE
 
-  LOG_I(RRC,
-        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionReestablishmentReject (bytes %d)\n",
-        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
-}
+  if (*SRB_configList != NULL) {
+    for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) {
+      if ((*SRB_configList)->list.array[cnt]->srb_Identity == 1) {
+        SRB1_config = (*SRB_configList)->list.array[cnt];
 
-//-----------------------------------------------------------------------------
-void
-rrc_eNB_generate_RRCConnectionRelease(
-  const protocol_ctxt_t* const ctxt_pP,
-  rrc_eNB_ue_context_t*          const ue_context_pP
-)
-//-----------------------------------------------------------------------------
-{
+        if (SRB1_config->logicalChannelConfig) {
+          if (SRB1_config->logicalChannelConfig->present ==
+              SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) {
+            SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue;
+          } else {
+            SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
+          }
+        } else {
+          SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue;
+        }
 
-  uint8_t                             buffer[RRC_BUF_SIZE];
-  uint16_t                            size;
+        LOG_D(RRC,
+              PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ  (SRB1) ---> MAC_eNB\n",
+              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+        rrc_mac_config_req_eNB(ctxt_pP->module_id,
+                           ue_context_pP->ue_context.primaryCC_id,
+                           0,0,0,0,0,
+#ifdef Rel14 
+			 0,
+#endif
+                           ctxt_pP->rnti,
+                           (BCCH_BCH_Message_t *) NULL, 
+                           (RadioResourceConfigCommonSIB_t *) NULL,
+                           (RadioResourceConfigCommonSIB_t *) NULL,
+                           (struct PhysicalConfigDedicated* ) ue_context_pP->ue_context.physicalConfigDedicated,
+#if defined(Rel10) || defined(Rel14)
+                           (SCellToAddMod_r10_t *)NULL,
+                           //(struct PhysicalConfigDedicatedSCell_r10 *)NULL,
+#endif
+                           (MeasObjectToAddMod_t **) NULL,
+                           ue_context_pP->ue_context.mac_MainConfig,
+                           1,
+                           SRB1_logicalChannelConfig,
+                           ue_context_pP->ue_context.measGapConfig,
+                           (TDD_Config_t *) NULL,
+                           NULL,
+                           (SchedulingInfoList_t *) NULL,
+                           0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL
+#if defined(Rel10) || defined(Rel14)
+                           , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL
+#endif
+#ifdef Rel14
+                           ,(SystemInformationBlockType1_v1310_IEs_t *)NULL 
+#endif
+        );
+        break;
+      }
+    }
+  }
 
-  T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
-    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
+  MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
+                     MSC_RRC_UE,
+                     RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header,
+                     RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+                     MSC_AS_TIME_FMT" RRCConnectionReestablishment UE %x size %u",
+                     MSC_AS_TIME_ARGS(ctxt_pP),
+                     ue_context_pP->ue_context.rnti,
+                     RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
 
-  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;
   LOG_I(RRC,
-        PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n",
-        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-        size);
-
-  LOG_D(RRC,
-        PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n",
+        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionReestablishment (bytes %d)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
-        size,
-        rrc_eNB_mui,
-        DCCH);
-
-  MSC_LOG_TX_MESSAGE(
-    MSC_RRC_ENB,
-    MSC_RRC_UE,
-    buffer,
-    size,
-    MSC_AS_TIME_FMT" rrcConnectionRelease UE %x MUI %d size %u",
-    MSC_AS_TIME_ARGS(ctxt_pP),
-    ue_context_pP->ue_context.rnti,
-    rrc_eNB_mui,
-    size);
+        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
 
-  rrc_data_req(
-	       ctxt_pP,
-	       DCCH,
-	       rrc_eNB_mui++,
-	       SDU_CONFIRM_NO,
-	       size,
-	       buffer,
-	       PDCP_TRANSMISSION_MODE_CONTROL);
+  // 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;
+  // 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;
 }
 
-uint8_t qci_to_priority[9]={2,4,3,5,1,6,7,8,9};
-
-// TBD: this directive can be remived if we create a similar e_rab_param_t structure in RRC context
-#if defined(ENABLE_ITTI) 
 //-----------------------------------------------------------------------------
 void
-rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP,
-						     rrc_eNB_ue_context_t*          const ue_context_pP,
-						     const uint8_t                ho_state
-						     )
+rrc_eNB_process_RRCConnectionReestablishmentComplete(
+  const protocol_ctxt_t* const ctxt_pP,
+  const rnti_t const reestablish_rnti,
+  rrc_eNB_ue_context_t*         ue_context_pP,
+  const uint8_t xid,
+  RRCConnectionReestablishmentComplete_r8_IEs_t * rrcConnectionReestablishmentComplete
+)
 //-----------------------------------------------------------------------------
 {
-  
+  LOG_I(RRC,
+        PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n",
+        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+
+  T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
+    T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
+
+  DRB_ToAddModList_t*                 DRB_configList = ue_context_pP->ue_context.DRB_configList;
+  SRB_ToAddModList_t*                 SRB_configList = ue_context_pP->ue_context.SRB_configList;
+  SRB_ToAddModList_t**                SRB_configList2 = NULL;
+  DRB_ToAddModList_t**                DRB_configList2 = NULL;
+  struct SRB_ToAddMod                *SRB2_config = NULL;
+  struct DRB_ToAddMod                *DRB_config = NULL;
+  int i = 0;
+# if defined(ENABLE_USE_MME)
+  int j = 0;
+  hashtable_rc_t                      h_rc;
+#endif
   uint8_t                             buffer[RRC_BUF_SIZE];
   uint16_t                            size;
-  int i;
-  
-  struct DRB_ToAddMod                *DRB_config                       = NULL;
-  struct RLC_Config                  *DRB_rlc_config                   = NULL;
-  struct PDCP_Config                 *DRB_pdcp_config                  = NULL;
-  struct PDCP_Config__rlc_AM         *PDCP_rlc_AM                      = NULL;
-  struct PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = NULL;
-  struct LogicalChannelConfig        *DRB_lchan_config                 = NULL;
-  struct LogicalChannelConfig__ul_SpecificParameters
-    *DRB_ul_SpecificParameters        = NULL;
-  //  DRB_ToAddModList_t**                DRB_configList=&ue_context_pP->ue_context.DRB_configList; 
-  DRB_ToAddModList_t*                DRB_configList=ue_context_pP->ue_context.DRB_configList; 
-  DRB_ToAddModList_t**                DRB_configList2=NULL;
-  //DRB_ToAddModList_t**                RRC_DRB_configList=&ue_context_pP->ue_context.DRB_configList;
-
+  MeasObjectToAddModList_t           *MeasObj_list                     = NULL;
+  MeasObjectToAddMod_t               *MeasObj                          = NULL;
+  ReportConfigToAddModList_t         *ReportConfig_list                = NULL;
+  ReportConfigToAddMod_t             *ReportConfig_per, *ReportConfig_A1,
+                                     *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5;
+  MeasIdToAddModList_t               *MeasId_list                      = NULL;
+  MeasIdToAddMod_t                   *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5;
+  RSRP_Range_t                       *rsrp                             = NULL;
+  struct MeasConfig__speedStatePars  *Sparams                          = NULL;
+  QuantityConfig_t                   *quantityConfig                   = NULL;
+  CellsToAddMod_t                    *CellToAdd                        = NULL;
+  CellsToAddModList_t                *CellsToAddModList                = NULL;
   struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
   DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
   /* for no gcc warnings */
   (void)dedicatedInfoNas;
+  C_RNTI_t                           *cba_RNTI                         = NULL;
+  uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);
+
+  ue_context_pP->ue_context.Status = RRC_CONNECTED;
+
+  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",
+          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);
+        SRB2_config = (*SRB_configList2)->list.array[i];
+        break;
+      }
+    }
+  }
+  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);
+  }
+  *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2));
+  if (SRB2_config != NULL) {
+    // Add SRB2 to SRB configuration list
+
+    ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config);
+    ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config);
+
+    LOG_D(RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n",
+            SRB2_config->srb_Identity);
+    LOG_D(RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n",
+                SRB2_config->srb_Identity, next_xid);
+  } else {
+    // SRB configuration list only contains SRB1.
+    LOG_W(RRC,"SRB2 configuration does not exist in SRB configuration list\n");
+  }
+
 
-  long  *logicalchannelgroup_drb;
-  int drb_identity_index=0;
 
-  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
-  DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid];
   if (*DRB_configList2) {
     free(*DRB_configList2);
+    LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid);
   }
-  //*DRB_configList = CALLOC(1, sizeof(*DRB_configList));
-  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); 
-  /* Initialize NAS list */
-  dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
+  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2));
 
-  int e_rab_done=0;
-  
-  for ( i = 0  ;
-	i < ue_context_pP->ue_context.setup_e_rabs ;
-	i++){
-    
-    // bypass the new and already configured erabs
-    if (ue_context_pP->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE) {
-      drb_identity_index++;
-      continue;
+  if (DRB_configList != NULL) {
+    LOG_D(RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n");
+    for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) {
+      DRB_config = DRB_configList->list.array[i];
+
+      // Add DRB to DRB configuration list, for RRCConnectionReconfigurationComplete
+      ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
     }
-        
-    DRB_config = CALLOC(1, sizeof(*DRB_config));
+  }
+  ue_context_pP->ue_context.Srb1.Active = 1;
+  //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2;
+
+# if defined(ENABLE_USE_MME)
+  rrc_ue_s1ap_ids_t* rrc_ue_s1ap_ids_p = NULL;
+  uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id;
+  uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
+  eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)];
+  if (eNB_ue_s1ap_id > 0) {
+    h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&rrc_ue_s1ap_ids_p);
+    if  (h_rc == HASH_TABLE_OK) {
+      rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
+    }
+  }
+  if (ue_initial_id != 0) {
+    h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&rrc_ue_s1ap_ids_p);
+    if  (h_rc == HASH_TABLE_OK) {
+      rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti;
+    }
+  }
 
-    DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
-    // allowed value 5..15, value : x+4
-    *(DRB_config->eps_BearerIdentity) = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation  
+  gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
 
-    DRB_config->drb_Identity =  1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
-    // 1 + drb_identiy_index;  
+  /* Save e RAB information for later */
+  memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
 
-    DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
-    *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
-    
-    DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
-    DRB_config->rlc_Config = DRB_rlc_config;
+  for (j = 0, i = 0; i < NB_RB_MAX; i++) {
+    if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED) {
+      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;
 
-    DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
-    DRB_config->pdcp_Config = DRB_pdcp_config;
-    DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
-    *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity;
-    DRB_pdcp_config->rlc_AM = NULL;
-    DRB_pdcp_config->rlc_UM = NULL;
+      memcpy(&create_tunnel_req.sgw_addr[j],
+             &ue_context_pP->ue_context.e_rab[i].param.sgw_addr,
+             sizeof(transport_layer_addr_t));
+      j++;
+    }
+  }
 
+  create_tunnel_req.rnti       = ctxt_pP->rnti; // warning put zero above
+  create_tunnel_req.num_tunnels    = j;
 
-    switch (ue_context_pP->ue_context.e_rab[i].param.qos.qci){
-      /*
-       * type: realtime data with medium packer error rate
-       * action: swtich to RLC UM
-       */
-    case 1: // 100ms, 10^-2, p2, GBR
-    case 2: // 150ms, 10^-3, p4, GBR
-    case 3: // 50ms, 10^-3, p3, GBR
-    case 4:  // 300ms, 10^-6, p5 
-    case 7: // 100ms, 10^-3, p7, GBR
-    case 9: // 300ms, 10^-6, p9
-    case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR
-    case 66: // 100ms, 10^-2, p2, non-mission critical  voice , GBR
-      // RLC 
-      DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional;
-      DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
-      DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
-      DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35;
-      // PDCP
-      PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
-      DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
-      PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
-      break;
-      
-      /*
-       * type: non-realtime data with low packer error rate
-       * action: swtich to RLC AM
-       */
+  gtpv1u_update_s1u_tunnel(
+            ctxt_pP->instance,
+            &create_tunnel_req,
+            reestablish_rnti);
+#endif
+  /* Update RNTI in ue_context */
+  ue_context_pP->ue_id_rnti                    = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else
+  ue_context_pP->ue_context.rnti               = ctxt_pP->rnti;
+# if defined(ENABLE_USE_MME)
+  uint8_t send_security_mode_command = FALSE;
+  rrc_pdcp_config_security(
+      ctxt_pP,
+      ue_context_pP,
+      send_security_mode_command);
+  LOG_D(RRC, "set security successfully \n");
+#endif
+  // Measurement ID list
+  MeasId_list = CALLOC(1, sizeof(*MeasId_list));
+  memset((void *)MeasId_list, 0, sizeof(*MeasId_list));
+
+  MeasId0 = CALLOC(1, sizeof(*MeasId0));
+  MeasId0->measId = 1;
+  MeasId0->measObjectId = 1;
+  MeasId0->reportConfigId = 1;
+  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId0);
+
+  MeasId1 = CALLOC(1, sizeof(*MeasId1));
+  MeasId1->measId = 2;
+  MeasId1->measObjectId = 1;
+  MeasId1->reportConfigId = 2;
+  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId1);
+
+  MeasId2 = CALLOC(1, sizeof(*MeasId2));
+  MeasId2->measId = 3;
+  MeasId2->measObjectId = 1;
+  MeasId2->reportConfigId = 3;
+  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId2);
+
+  MeasId3 = CALLOC(1, sizeof(*MeasId3));
+  MeasId3->measId = 4;
+  MeasId3->measObjectId = 1;
+  MeasId3->reportConfigId = 4;
+  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId3);
+
+  MeasId4 = CALLOC(1, sizeof(*MeasId4));
+  MeasId4->measId = 5;
+  MeasId4->measObjectId = 1;
+  MeasId4->reportConfigId = 5;
+  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId4);
+
+  MeasId5 = CALLOC(1, sizeof(*MeasId5));
+  MeasId5->measId = 6;
+  MeasId5->measObjectId = 1;
+  MeasId5->reportConfigId = 6;
+  ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5);
+
+  //  rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list;
+
+  // Add one EUTRA Measurement Object
+  MeasObj_list = CALLOC(1, sizeof(*MeasObj_list));
+  memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list));
+
+  // Configure MeasObject
+
+  MeasObj = CALLOC(1, sizeof(*MeasObj));
+  memset((void *)MeasObj, 0, sizeof(*MeasObj));
+
+  MeasObj->measObjectId = 1;
+  MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA;
+  MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz
+  //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz
+  MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25;
+  MeasObj->measObject.choice.measObjectEUTRA.presenceAntennaPort1 = 1;
+  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf = CALLOC(1, sizeof(uint8_t));
+  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.buf[0] = 0;
+  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.size = 1;
+  MeasObj->measObject.choice.measObjectEUTRA.neighCellConfig.bits_unused = 6;
+  MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL;   // Default is 15 or 0dB
+
+  MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList =
+    (CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList));
+
+  CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList;
+
+  // Add adjacent cell lists (6 per eNB)
+  for (i = 0; i < 6; i++) {
+    CellToAdd = (CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd));
+    CellToAdd->cellIndex = i + 1;
+    CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i);
+    CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0;
+
+    ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd);
+  }
+
+  ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj);
+  //  rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list;
+
+  // Report Configurations for periodical, A1-A5 events
+  ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list));
+
+  ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per));
+
+  ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1));
+
+  ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2));
+
+  ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3));
+
+  ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4));
+
+  ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5));
+
+  ReportConfig_per->reportConfigId = 1;
+  ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
+  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present =
+    ReportConfigEUTRA__triggerType_PR_periodical;
+  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose =
+    ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells;
+  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp;
+  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both;
+  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
+  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120;
+  ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity;
+
+  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per);
+
+  ReportConfig_A1->reportConfigId = 2;
+  ReportConfig_A1->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present =
+    ReportConfigEUTRA__triggerType_PR_event;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
+    ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
+  a1_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1.
+  a1_Threshold.choice.threshold_RSRP = 10;
+
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120;
+  ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity;
+
+  ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1);
+
+  if (RC.rrc[ctxt_pP->module_id]->HO_flag == 1 /*HO_MEASURMENT */ ) {
+    LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n",
+          ctxt_pP->module_id, ctxt_pP->frame);
+    ReportConfig_A2->reportConfigId = 3;
+    ReportConfig_A2->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present =
+      ReportConfigEUTRA__triggerType_PR_event;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
+      ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA2.a2_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA2.a2_Threshold.choice.threshold_RSRP = 10;
+
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
+      ReportConfigEUTRA__triggerQuantity_rsrp;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120;
+    ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity;
+
+    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2);
+
+    ReportConfig_A3->reportConfigId = 4;
+    ReportConfig_A3->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present =
+      ReportConfigEUTRA__triggerType_PR_event;
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
+      ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3;
+
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset = 1;   //10;
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA3.reportOnLeave = 1;
+
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
+      ReportConfigEUTRA__triggerQuantity_rsrp;
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both;
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120;
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity;
+
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; // FIXME ...hysteresis is of type long!
+    ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger =
+      TimeToTrigger_ms40;
+    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3);
+
+    ReportConfig_A4->reportConfigId = 5;
+    ReportConfig_A4->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present =
+      ReportConfigEUTRA__triggerType_PR_event;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
+      ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA4.a4_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA4.a4_Threshold.choice.threshold_RSRP = 10;
+
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
+      ReportConfigEUTRA__triggerQuantity_rsrp;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120;
+    ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity;
+
+    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4);
+
+    ReportConfig_A5->reportConfigId = 6;
+    ReportConfig_A5->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present =
+      ReportConfigEUTRA__triggerType_PR_event;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present =
+      ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA5.a5_Threshold1.present = ThresholdEUTRA_PR_threshold_RSRP;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA5.a5_Threshold2.present = ThresholdEUTRA_PR_threshold_RSRP;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA5.a5_Threshold1.choice.threshold_RSRP = 10;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.
+    eventA5.a5_Threshold2.choice.threshold_RSRP = 10;
+
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerQuantity =
+      ReportConfigEUTRA__triggerQuantity_rsrp;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = ReportInterval_ms120;
+    ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = ReportConfigEUTRA__reportAmount_infinity;
+
+    ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5);
+    //  rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list;
+
+    rsrp = CALLOC(1, sizeof(RSRP_Range_t));
+    *rsrp = 20;
+
+    Sparams = CALLOC(1, sizeof(*Sparams));
+    Sparams->present = MeasConfig__speedStatePars_PR_setup;
+    Sparams->choice.setup.timeToTrigger_SF.sf_High = SpeedStateScaleFactors__sf_Medium_oDot75;
+    Sparams->choice.setup.timeToTrigger_SF.sf_Medium = SpeedStateScaleFactors__sf_High_oDot5;
+    Sparams->choice.setup.mobilityStateParameters.n_CellChangeHigh = 10;
+    Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5;
+    Sparams->choice.setup.mobilityStateParameters.t_Evaluation = MobilityStateParameters__t_Evaluation_s60;
+    Sparams->choice.setup.mobilityStateParameters.t_HystNormal = MobilityStateParameters__t_HystNormal_s120;
+
+    quantityConfig = CALLOC(1, sizeof(*quantityConfig));
+    memset((void *)quantityConfig, 0, sizeof(*quantityConfig));
+    quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct QuantityConfigEUTRA));
+    memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA));
+    quantityConfig->quantityConfigCDMA2000 = NULL;
+    quantityConfig->quantityConfigGERAN = NULL;
+    quantityConfig->quantityConfigUTRA = NULL;
+    quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP =
+      CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP)));
+    quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ =
+      CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)));
+    *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = FilterCoefficient_fc4;
+    *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = FilterCoefficient_fc4;
+
+    LOG_I(RRC,
+          "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n",
+          ctxt_pP->module_id, ctxt_pP->frame);
+    // store the information in an intermediate structure for Hanodver management
+    //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof());
+    ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info)));
+    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t));
+    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2;
+    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t));
+    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = DRB_configList;
+    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL;
+    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig =
+      CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig));
+    memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig,
+           (void *)ue_context_pP->ue_context.mac_MainConfig, sizeof(MAC_MainConfig_t));
+    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated =
+      CALLOC(1, sizeof(PhysicalConfigDedicated_t));
+    memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated,
+           (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(PhysicalConfigDedicated_t));
+    ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL;
+    //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t));
+
+  }
+
+#ifdef CBA
+  //struct PUSCH_CBAConfigDedicated_vlola  *pusch_CBAConfigDedicated_vlola;
+  uint8_t                            *cba_RNTI_buf;
+  cba_RNTI = CALLOC(1, sizeof(C_RNTI_t));
+  cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t));
+  cba_RNTI->buf = cba_RNTI_buf;
+  cba_RNTI->size = 2;
+  cba_RNTI->bits_unused = 0;
+
+  // associate UEs to the CBa groups as a function of their UE id
+  if (rrc_inst->num_active_cba_groups) {
+    cba_RNTI->buf[0] = rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups] & 0xff;
+    cba_RNTI->buf[1] = 0xff;
+    LOG_D(RRC,
+          "[eNB %d] Frame %d: cba_RNTI = %x in group %d is attribued to UE %d\n",
+          enb_mod_idP, frameP,
+          rrc_inst->cba_rnti[ue_mod_idP % rrc_inst->num_active_cba_groups],
+          ue_mod_idP % rrc_inst->num_active_cba_groups, ue_mod_idP);
+  } else {
+    cba_RNTI->buf[0] = 0x0;
+    cba_RNTI->buf[1] = 0x0;
+    LOG_D(RRC, "[eNB %d] Frame %d: no cba_RNTI is configured for UE %d\n", enb_mod_idP, frameP, ue_mod_idP);
+  }
+
+#endif
+
+#if defined(ENABLE_ITTI)
+  /* Initialize NAS list */
+  dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
+
+  /* Add all NAS PDUs to the list */
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
+    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
+      dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t));
+      memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
+      OCTET_STRING_fromBuf(dedicatedInfoNas,
+         (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
+                           ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
+      LOG_D(RRC, "Add dedicatedInfoNas(%d) to dedicatedInfoNASList\n", i);
+      ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
+    }
+
+    /* TODO parameters yet to process ... */
+    {
+      //      ue_context_pP->ue_context.e_rab[i].param.qos;
+      //      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
+      //      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
+    }
+
+    /* TODO should test if e RAB are Ok before! */
+    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE;
+    LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n",
+    i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE");
+  }
+
+  /* If list is empty free the list and reset the address */
+  if (dedicatedInfoNASList->list.count == 0) {
+    free(dedicatedInfoNASList);
+    dedicatedInfoNASList = NULL;
+  }
+
+#endif
+
+  // send RRCConnectionReconfiguration
+  memset(buffer, 0, RRC_BUF_SIZE);
+
+  size = do_RRCConnectionReconfiguration(ctxt_pP,
+                                         buffer,
+                                         next_xid,   //Transaction_id,
+                                         (SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList
+                                         (DRB_ToAddModList_t*)DRB_configList,
+                                         (DRB_ToReleaseList_t*)NULL,  // DRB2_list,
+                                         (struct SPS_Config*)NULL,    // maybe ue_context_pP->ue_context.sps_Config,
+                                         (struct PhysicalConfigDedicated*)ue_context_pP->ue_context.physicalConfigDedicated,
+#ifdef EXMIMO_IOT
+                                         NULL, NULL, NULL,NULL,
+#else
+                                         (MeasObjectToAddModList_t*)MeasObj_list,  // MeasObj_list,
+                                         (ReportConfigToAddModList_t*)ReportConfig_list,  // ReportConfig_list,
+                                         (QuantityConfig_t*)quantityConfig,  //quantityConfig,
+                                         (MeasIdToAddModList_t*)NULL,
+#endif
+                                         (MAC_MainConfig_t*)ue_context_pP->ue_context.mac_MainConfig,
+                                         (MeasGapConfig_t*)NULL,
+                                         (MobilityControlInfo_t*)NULL,
+                                         (struct MeasConfig__speedStatePars*)Sparams, // Sparams,
+                                         (RSRP_Range_t*)rsrp, // rsrp,
+                                         (C_RNTI_t*)cba_RNTI,  // cba_RNTI
+                                         (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList //dedicatedInfoNASList
+#if defined(Rel10) || defined(Rel14)
+                                         , (SCellToAddMod_r10_t*)NULL
+#endif
+                                        );
+
+#ifdef RRC_MSG_PRINT
+  LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n");
+  for (i = 0; i < size; i++) {
+    LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]);
+  }
+  LOG_F(RRC,"\n");
+  ////////////////////////////////////////
+#endif
+
+#if defined(ENABLE_ITTI)
+
+  /* Free all NAS PDUs */
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
+    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
+      /* Free the NAS PDU buffer and invalidate it */
+      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
+    }
+  }
+
+#endif
+
+  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<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);
+}
+
+//-----------------------------------------------------------------------------
+void
+rrc_eNB_generate_RRCConnectionReestablishmentReject(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_t*          const ue_context_pP,
+  const int                    CC_id
+)
+//-----------------------------------------------------------------------------
+{
+#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));
+
+  RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size =
+    do_RRCConnectionReestablishmentReject(ctxt_pP->module_id,
+                          (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload);
+
+#ifdef RRC_MSG_PRINT
+  LOG_F(RRC,"[MSG] RRCConnectionReestablishmentReject\n");
+
+  for (cnt = 0; cnt < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size; cnt++) {
+    LOG_F(RRC,"%02x ", ((uint8_t*)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload)[cnt]);
+  }
+
+  LOG_F(RRC,"\n");
+#endif
+
+  MSC_LOG_TX_MESSAGE(
+    MSC_RRC_ENB,
+    MSC_RRC_UE,
+    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header,
+    RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size,
+    MSC_AS_TIME_FMT" RRCConnectionReestablishmentReject UE %x size %u",
+    MSC_AS_TIME_ARGS(ctxt_pP),
+    ue_context_pP == NULL ? -1 : 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 RRCConnectionReestablishmentReject (bytes %d)\n",
+        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+        RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size);
+}
+
+//-----------------------------------------------------------------------------
+void
+rrc_eNB_generate_RRCConnectionRelease(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_t*          const ue_context_pP
+)
+//-----------------------------------------------------------------------------
+{
+
+  uint8_t                             buffer[RRC_BUF_SIZE];
+  uint16_t                            size;
+
+  T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
+    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;
+  // 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_reestablishment_timer = 0;
+  ue_context_pP->ue_context.ue_release_timer = 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),
+        size);
+
+  LOG_D(RRC,
+        PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n",
+        PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+        size,
+        rrc_eNB_mui,
+        DCCH);
+
+  MSC_LOG_TX_MESSAGE(
+    MSC_RRC_ENB,
+    MSC_RRC_UE,
+    buffer,
+    size,
+    MSC_AS_TIME_FMT" rrcConnectionRelease 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);
+}
+
+uint8_t qci_to_priority[9]={2,4,3,5,1,6,7,8,9};
+
+// TBD: this directive can be remived if we create a similar e_rab_param_t structure in RRC context
+#if defined(ENABLE_ITTI) 
+//-----------------------------------------------------------------------------
+void
+rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP,
+						     rrc_eNB_ue_context_t*          const ue_context_pP,
+						     const uint8_t                ho_state
+						     )
+//-----------------------------------------------------------------------------
+{
+  
+  uint8_t                             buffer[RRC_BUF_SIZE];
+  uint16_t                            size;
+  int i;
+  
+  struct DRB_ToAddMod                *DRB_config                       = NULL;
+  struct RLC_Config                  *DRB_rlc_config                   = NULL;
+  struct PDCP_Config                 *DRB_pdcp_config                  = NULL;
+  struct PDCP_Config__rlc_AM         *PDCP_rlc_AM                      = NULL;
+  struct PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = NULL;
+  struct LogicalChannelConfig        *DRB_lchan_config                 = NULL;
+  struct LogicalChannelConfig__ul_SpecificParameters
+    *DRB_ul_SpecificParameters        = NULL;
+  //  DRB_ToAddModList_t**                DRB_configList=&ue_context_pP->ue_context.DRB_configList; 
+  DRB_ToAddModList_t*                DRB_configList=ue_context_pP->ue_context.DRB_configList; 
+  DRB_ToAddModList_t**                DRB_configList2=NULL;
+  //DRB_ToAddModList_t**                RRC_DRB_configList=&ue_context_pP->ue_context.DRB_configList;
+
+  struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
+  DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
+  /* for no gcc warnings */
+  (void)dedicatedInfoNas;
+
+  long  *logicalchannelgroup_drb;
+//  int drb_identity_index=0;
+
+  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   //Transaction_id,
+  DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid];
+  if (*DRB_configList2) {
+    free(*DRB_configList2);
+  }
+  //*DRB_configList = CALLOC(1, sizeof(*DRB_configList));
+  *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); 
+  /* Initialize NAS list */
+  dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
+
+  int e_rab_done=0;
+  
+  for ( i = 0  ;
+	i < ue_context_pP->ue_context.setup_e_rabs ;
+	i++){
+
+    if (e_rab_done >= ue_context_pP->ue_context.nb_of_e_rabs){
+        break;
+    }
+    
+    // bypass the new and already configured erabs
+    if (ue_context_pP->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE) {
+//      drb_identity_index++;
+      continue;
+    }
+        
+    DRB_config = CALLOC(1, sizeof(*DRB_config));
+
+    DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
+    // allowed value 5..15, value : x+4
+    *(DRB_config->eps_BearerIdentity) = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation  
+
+ //   DRB_config->drb_Identity =  1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
+    // 1 + drb_identiy_index;  
+    DRB_config->drb_Identity = i+1;
+
+    DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
+    *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2
+    
+    DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config));
+    DRB_config->rlc_Config = DRB_rlc_config;
+
+    DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config));
+    DRB_config->pdcp_Config = DRB_pdcp_config;
+    DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long));
+    *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity;
+    DRB_pdcp_config->rlc_AM = NULL;
+    DRB_pdcp_config->rlc_UM = NULL;
+
+
+    switch (ue_context_pP->ue_context.e_rab[i].param.qos.qci){
+      /*
+       * type: realtime data with medium packer error rate
+       * action: swtich to RLC UM
+       */
+    case 1: // 100ms, 10^-2, p2, GBR
+    case 2: // 150ms, 10^-3, p4, GBR
+    case 3: // 50ms, 10^-3, p3, GBR
+    case 4:  // 300ms, 10^-6, p5 
+    case 7: // 100ms, 10^-3, p7, GBR
+    case 9: // 300ms, 10^-6, p9
+    case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR
+    case 66: // 100ms, 10^-2, p2, non-mission critical  voice , GBR
+      // RLC 
+      DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional;
+      DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
+      DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
+      DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35;
+      // PDCP
+      PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
+      DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
+      PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
+      break;
+      
+      /*
+       * type: non-realtime data with low packer error rate
+       * action: swtich to RLC AM
+       */
     case 5:  // 100ms, 10^-6, p1 , IMS signaling 
     case 6:  // 300ms, 10^-6, p6 
     case 8: // 300ms, 10^-6, p8 
@@ -1261,6 +2072,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
       LOG_E(RRC,"not supported qci %d\n", ue_context_pP->ue_context.e_rab[i].param.qos.qci);
       ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_FAILED; 
       ue_context_pP->ue_context.e_rab[i].xid = xid;
+      e_rab_done++;
       continue;
     }
 
@@ -1281,49 +2093,317 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
       //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
     DRB_ul_SpecificParameters->bucketSizeDuration =
       LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
-    
-    logicalchannelgroup_drb = CALLOC(1, sizeof(long));
-    *logicalchannelgroup_drb = 1;//(i+1) % 3;
-    DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
+    
+    logicalchannelgroup_drb = CALLOC(1, sizeof(long));
+    *logicalchannelgroup_drb = 1;//(i+1) % 3;
+    DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
+
+    ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
+    ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
+    //ue_context_pP->ue_context.DRB_configList2[drb_identity_index] = &(*DRB_configList);
+    
+    LOG_I(RRC,"EPS ID %ld, DRB ID %ld (index %d), QCI %d, priority %ld, LCID %ld LCGID %ld \n",
+	  *DRB_config->eps_BearerIdentity,
+	  DRB_config->drb_Identity, i,
+	  ue_context_pP->ue_context.e_rab[i].param.qos.qci,
+	  DRB_ul_SpecificParameters->priority,
+	  *(DRB_config->logicalChannelIdentity),
+	  *DRB_ul_SpecificParameters->logicalChannelGroup	  
+	  );
+
+    e_rab_done++;
+    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; 
+    ue_context_pP->ue_context.e_rab[i].xid = xid;
+    
+    {
+      if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
+	dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t));
+	memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
+	OCTET_STRING_fromBuf(dedicatedInfoNas, 
+			     (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
+			     ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
+	ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
+	LOG_I(RRC,"add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length, i);
+      } 
+      else {
+	LOG_W(RRC,"Not received activate dedicated EPS bearer context request\n");
+      }
+      /* TODO parameters yet to process ... */
+      {
+	//      ue_context_pP->ue_context.e_rab[i].param.qos;
+	//      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
+	//      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
+      }
+    }
+    
+  }
+
+  /* If list is empty free the list and reset the address */
+  if (dedicatedInfoNASList != NULL) {
+    if (dedicatedInfoNASList->list.count == 0) {
+      free(dedicatedInfoNASList);
+      dedicatedInfoNASList = NULL;
+      LOG_W(RRC,"dedlicated NAS list is empty, free the list and reset the address\n");
+    }				
+  } else {
+    LOG_W(RRC,"dedlicated NAS list is empty\n");
+  }
+
+  memset(buffer, 0, RRC_BUF_SIZE);
+
+   size = do_RRCConnectionReconfiguration(ctxt_pP,
+					  buffer,
+					  xid,
+					  (SRB_ToAddModList_t*)NULL, 
+					  (DRB_ToAddModList_t*)*DRB_configList2,
+					  (DRB_ToReleaseList_t*)NULL,  // DRB2_list,
+                                         (struct SPS_Config*)NULL,    // *sps_Config,
+					  NULL, NULL, NULL, NULL,NULL,
+					  NULL, NULL,  NULL, NULL, NULL, NULL, 
+					  (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList
+#if defined(Rel10) || defined(Rel14)
+                                         , (SCellToAddMod_r10_t*)NULL
+#endif
+                                        );
+ 
+
+#ifdef RRC_MSG_PRINT
+  LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n");
+  for (i = 0; i < size; i++) {
+    LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]);
+  }
+  LOG_F(RRC,"\n");
+  ////////////////////////////////////////
+#endif
+
+#if defined(ENABLE_ITTI)
+
+  /* Free all NAS PDUs */
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
+    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
+      /* Free the NAS PDU buffer and invalidate it */
+      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
+    }
+  }
+#endif
+
+ LOG_I(RRC,
+        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE RNTI %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" dedicated 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);
+
+
+}
+int
+rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP,
+                             rrc_eNB_ue_context_t*          const ue_context_pP,
+                             const uint8_t                ho_state
+                             )
+//-----------------------------------------------------------------------------
+{
+  uint8_t                             buffer[RRC_BUF_SIZE];
+  uint16_t                            size;
+  int i, j;
+
+  struct DRB_ToAddMod                *DRB_config                       = NULL;
+  struct RLC_Config                  *DRB_rlc_config                   = NULL;
+  struct PDCP_Config                 *DRB_pdcp_config                  = NULL;
+  struct PDCP_Config__rlc_AM         *PDCP_rlc_AM                      = NULL;
+  struct PDCP_Config__rlc_UM         *PDCP_rlc_UM                      = NULL;
+  struct LogicalChannelConfig        *DRB_lchan_config                 = NULL;
+  struct LogicalChannelConfig__ul_SpecificParameters
+  *DRB_ul_SpecificParameters        = NULL;
+  DRB_ToAddModList_t*                 DRB_configList = ue_context_pP->ue_context.DRB_configList;
+  DRB_ToAddModList_t*                DRB_configList2 = NULL;
+
+  struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
+  DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
+  /* for no gcc warnings */
+  (void)dedicatedInfoNas;
+
+  uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id);   // Transaction_id,
+  DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2));
+  /* Initialize NAS list */
+  dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
+
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_modify_e_rabs; i++) {
+    // bypass the new and already configured erabs
+    if (ue_context_pP->ue_context.modify_e_rab[i].status >= E_RAB_STATUS_DONE) {
+      ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
+      continue;
+    }
+
+    if (ue_context_pP->ue_context.modify_e_rab[i].cause != S1AP_CAUSE_NOTHING) {
+      // set xid of failure RAB
+      ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
+      ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED;
+      continue;
+    }
+
+    DRB_config = NULL;
+    // search exist DRB_config
+    for (j = 0; j < DRB_configList->list.count; j++) {
+      if((uint8_t)*(DRB_configList->list.array[j]->eps_BearerIdentity) == ue_context_pP->ue_context.modify_e_rab[i].param.e_rab_id) {
+        DRB_config = DRB_configList->list.array[j];
+        break;
+      }
+    }
+    if (NULL == DRB_config) {
+      ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
+      ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED;
+      // TODO use which cause
+      ue_context_pP->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
+      ue_context_pP->ue_context.modify_e_rab[i].cause_value = 0;//S1ap_CauseRadioNetwork_unspecified;
+      ue_context_pP->ue_context.nb_of_failed_e_rabs++;
+      continue;
+    }
+
+    DRB_rlc_config = DRB_config->rlc_Config;
+
+    DRB_pdcp_config = DRB_config->pdcp_Config;
+    *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity;
+    switch (ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci) {
+    /*
+     * type: realtime data with medium packer error rate
+     * action: swtich to RLC UM
+     */
+    case 1: // 100ms, 10^-2, p2, GBR
+    case 2: // 150ms, 10^-3, p4, GBR
+    case 3: // 50ms, 10^-3, p3, GBR
+    case 4:  // 300ms, 10^-6, p5
+    case 7: // 100ms, 10^-3, p7, GBR
+    case 9: // 300ms, 10^-6, p9
+    case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR
+    case 66: // 100ms, 10^-2, p2, non-mission critical  voice , GBR
+      // RLC
+      DRB_rlc_config->present = RLC_Config_PR_um_Bi_Directional;
+      DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
+      DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = SN_FieldLength_size10;
+      DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35;
+      // PDCP
+      if (DRB_pdcp_config->rlc_AM) {
+        free(DRB_pdcp_config->rlc_AM);
+        DRB_pdcp_config->rlc_AM = NULL;
+      }
+      if (DRB_pdcp_config->rlc_UM) {
+        free(DRB_pdcp_config->rlc_UM);
+        DRB_pdcp_config->rlc_UM = NULL;
+      }
+      PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM));
+      DRB_pdcp_config->rlc_UM = PDCP_rlc_UM;
+      PDCP_rlc_UM->pdcp_SN_Size = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits;
+      break;
+
+    /*
+     * type: non-realtime data with low packer error rate
+     * action: swtich to RLC AM
+     */
+    case 5:  // 100ms, 10^-6, p1 , IMS signaling
+    case 6:  // 300ms, 10^-6, p6
+    case 8: // 300ms, 10^-6, p8
+    case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority
+    case 70: // 200ms, 10^-6, p5.5, mision critical data
+       // RLC
+       DRB_rlc_config->present = RLC_Config_PR_am;
+       DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50;
+       DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16;
+       DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity;
+       DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8;
+       DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35;
+       DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25;
+
+       // PDCP
+       if (DRB_pdcp_config->rlc_AM) {
+         free(DRB_pdcp_config->rlc_AM);
+         DRB_pdcp_config->rlc_AM = NULL;
+       }
+       if (DRB_pdcp_config->rlc_UM) {
+         free(DRB_pdcp_config->rlc_UM);
+         DRB_pdcp_config->rlc_UM = NULL;
+       }
+       PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
+       DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
+       PDCP_rlc_AM->statusReportRequired = FALSE;
+
+       break;
+    default :
+      LOG_E(RRC, "not supported qci %d\n", ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci);
+      ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED;
+      ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
+      ue_context_pP->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
+      ue_context_pP->ue_context.modify_e_rab[i].cause_value = 37;//S1ap_CauseRadioNetwork_not_supported_QCI_value;
+      ue_context_pP->ue_context.nb_of_failed_e_rabs++;
+      continue;
+    }
+
+    DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed;
+
+    DRB_lchan_config = DRB_config->logicalChannelConfig;
+    DRB_ul_SpecificParameters = DRB_lchan_config->ul_SpecificParameters;
+
+    if (ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci < 9 )
+      DRB_ul_SpecificParameters->priority = qci_to_priority[ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci-1] + 3;
+    else
+      DRB_ul_SpecificParameters->priority= 4;
+
+    DRB_ul_SpecificParameters->prioritisedBitRate = LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
+
+    DRB_ul_SpecificParameters->bucketSizeDuration =
+      LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
 
-    ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config);
-    ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config);
-    //ue_context_pP->ue_context.DRB_configList2[drb_identity_index] = &(*DRB_configList);
-    
-    LOG_I(RRC,"EPS ID %ld, DRB ID %ld (index %d), QCI %d, priority %ld, LCID %ld LCGID %ld \n",
-	  *DRB_config->eps_BearerIdentity,
-	  DRB_config->drb_Identity, i,
-	  ue_context_pP->ue_context.e_rab[i].param.qos.qci,
-	  DRB_ul_SpecificParameters->priority,
-	  *(DRB_config->logicalChannelIdentity),
-	  *DRB_ul_SpecificParameters->logicalChannelGroup	  
-	  );
+    ASN_SEQUENCE_ADD(&(DRB_configList2)->list, DRB_config);
+
+    LOG_I(RRC, "EPS ID %ld, DRB ID %ld (index %d), QCI %d, priority %ld, LCID %ld LCGID %ld \n",
+      *DRB_config->eps_BearerIdentity,
+      DRB_config->drb_Identity, i,
+      ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci,
+      DRB_ul_SpecificParameters->priority,
+      *(DRB_config->logicalChannelIdentity),
+      *DRB_ul_SpecificParameters->logicalChannelGroup
+      );
+
+    //e_rab_done++;
+    ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_DONE;
+    ue_context_pP->ue_context.modify_e_rab[i].xid = xid;
 
-    e_rab_done++;
-    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; 
-    ue_context_pP->ue_context.e_rab[i].xid = xid;
-    
     {
-      if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
-	dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t));
-	memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
-	OCTET_STRING_fromBuf(dedicatedInfoNas, 
-			     (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer,
-			     ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length);
-	ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
-	LOG_I(RRC,"add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length, i);
-      } 
-      else {
-	LOG_W(RRC,"Not received activate dedicated EPS bearer context request\n");
+      if (ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer != NULL) {
+        dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t));
+        memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
+        OCTET_STRING_fromBuf(dedicatedInfoNas,
+                 (char*)ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer,
+                 ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.length);
+        ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
+        LOG_I(RRC, "add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.length, i);
       }
-      /* TODO parameters yet to process ... */
-      {
-	//      ue_context_pP->ue_context.e_rab[i].param.qos;
-	//      ue_context_pP->ue_context.e_rab[i].param.sgw_addr;
-	//      ue_context_pP->ue_context.e_rab[i].param.gtp_teid;
+      else {
+        LOG_W(RRC, "Not received activate dedicated EPS bearer context request\n");
       }
     }
-    
   }
 
   /* If list is empty free the list and reset the address */
@@ -1332,28 +2412,28 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
       free(dedicatedInfoNASList);
       dedicatedInfoNASList = NULL;
       LOG_W(RRC,"dedlicated NAS list is empty, free the list and reset the address\n");
-    }				
+    }
   } else {
     LOG_W(RRC,"dedlicated NAS list is empty\n");
   }
 
   memset(buffer, 0, RRC_BUF_SIZE);
 
-   size = do_RRCConnectionReconfiguration(ctxt_pP,
-					  buffer,
-					  xid,
-					  (SRB_ToAddModList_t*)NULL, 
-					  (DRB_ToAddModList_t*)*DRB_configList2,
-					  (DRB_ToReleaseList_t*)NULL,  // DRB2_list,
-                                         (struct SPS_Config*)NULL,    // *sps_Config,
-					  NULL, NULL, NULL, NULL,NULL,
-					  NULL, NULL,  NULL, NULL, NULL, NULL, 
-					  (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList
+  size = do_RRCConnectionReconfiguration(ctxt_pP,
+                                          buffer,
+                                          xid,
+                                          (SRB_ToAddModList_t*)NULL,
+                                          (DRB_ToAddModList_t*)DRB_configList2,
+                                          (DRB_ToReleaseList_t*)NULL,  // DRB2_list,
+                                          (struct SPS_Config*)NULL,    // *sps_Config,
+                                          NULL, NULL, NULL, NULL,NULL,
+                                          NULL, NULL,  NULL, NULL, NULL, NULL,
+                                          (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList
 #if defined(Rel10) || defined(Rel14)
-                                         , (SCellToAddMod_r10_t*)NULL
+                                          , (SCellToAddMod_r10_t*)NULL
 #endif
-                                        );
- 
+                                          );
+
 
 #ifdef RRC_MSG_PRINT
   LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n");
@@ -1367,11 +2447,11 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
 #if defined(ENABLE_ITTI)
 
   /* Free all NAS PDUs */
-  for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) {
-    if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) {
+  for (i = 0; i < ue_context_pP->ue_context.nb_of_modify_e_rabs; i++) {
+    if (ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer != NULL) {
       /* Free the NAS PDU buffer and invalidate it */
-      free(ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer);
-      ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
+      free(ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer);
+      ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer = NULL;
     }
   }
 #endif
@@ -1403,7 +2483,125 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
     size,
     buffer,
     PDCP_TRANSMISSION_MODE_CONTROL);
+  return 0;
+}
 
+//-----------------------------------------------------------------------------
+void
+rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(  const protocol_ctxt_t*   const ctxt_pP,
+        rrc_eNB_ue_context_t*    const ue_context_pP,
+        uint8_t                  xid,
+        uint32_t                 nas_length,
+        uint8_t*                 nas_buffer)
+//-----------------------------------------------------------------------------
+{
+    uint8_t                             buffer[RRC_BUF_SIZE];
+    int                                 i;
+    uint16_t                            size  = 0;
+    DRB_ToReleaseList_t**                DRB_Release_configList2=NULL;
+    DRB_Identity_t* DRB_release;
+    struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
+
+    DRB_Release_configList2=&ue_context_pP->ue_context.DRB_Release_configList2[xid];
+    if (*DRB_Release_configList2) {
+      free(*DRB_Release_configList2);
+    }
+    *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2));
+
+    for(i = 0; i < NB_RB_MAX; i++){
+        if((ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_TORELEASE) && ue_context_pP->ue_context.e_rab[i].xid == xid){
+            DRB_release = CALLOC(1, sizeof(DRB_Identity_t));
+            *DRB_release = i+1;
+            ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release);
+            //free(DRB_release);
+        }
+    }
+
+    /* If list is empty free the list and reset the address */
+    if (nas_length > 0) {
+        DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
+        dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList));
+        dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t));
+        memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t));
+                       OCTET_STRING_fromBuf(dedicatedInfoNas,
+                              (char*)nas_buffer,
+                              nas_length);
+        ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas);
+        LOG_I(RRC,"add NAS info with size %d\n",nas_length);
+    } else {
+      LOG_W(RRC,"dedlicated NAS list is empty\n");
+    }
+
+    memset(buffer, 0, RRC_BUF_SIZE);
+    size = do_RRCConnectionReconfiguration(ctxt_pP,
+                                    buffer,
+                                    xid,
+                                    NULL,
+                                    NULL,
+                                    (DRB_ToReleaseList_t*)*DRB_Release_configList2,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    NULL,
+                                    (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList
+#if defined(Rel10) || defined(Rel14)
+                                    , (SCellToAddMod_r10_t*)NULL
+#endif
+                                   );
+    ue_context_pP->ue_context.e_rab_release_command_flag = 1;
+
+#ifdef RRC_MSG_PRINT
+  LOG_F(RRC,"[MSG] RRC Connection Reconfiguration\n");
+  for (i = 0; i < size; i++) {
+    LOG_F(RRC,"%02x ", ((uint8_t*)buffer)[i]);
+  }
+  LOG_F(RRC,"\n");
+  ////////////////////////////////////////
+#endif
+
+#if defined(ENABLE_ITTI)
+  /* Free all NAS PDUs */
+  if (nas_length > 0) {
+      /* Free the NAS PDU buffer and invalidate it */
+      free(nas_buffer);
+  }
+#endif
+
+  LOG_I(RRC,
+        "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE RNTI %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" dedicated 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);
 
 }
 #endif 
@@ -2138,7 +3336,113 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons
 	       PDCP_TRANSMISSION_MODE_CONTROL);
 }
 
-
+typedef enum { BAND_TYPE_FDD, BAND_TYPE_TDD } band_type;
+
+typedef struct {
+  band_type t;
+  int band;
+  unsigned long ul_minfreq, ul_maxfreq;
+  unsigned long dl_minfreq, dl_maxfreq;
+} band_freq;
+
+static band_freq bands[] = {
+  { BAND_TYPE_FDD, 1, 1920000000UL, 1980000000UL, 2110000000UL, 2170000000UL },
+  { BAND_TYPE_FDD, 2, 1850000000UL, 1910000000UL, 1930000000UL, 1990000000UL },
+  { BAND_TYPE_FDD, 3, 1710000000UL, 1785000000UL, 1805000000UL, 1880000000UL },
+  { BAND_TYPE_FDD, 4, 1710000000UL, 1755000000UL, 2110000000UL, 2155000000UL },
+  { BAND_TYPE_FDD, 5, 824000000UL, 849000000UL, 869000000UL, 894000000UL },
+    /* to remove? */{ BAND_TYPE_FDD, 6, 830000000UL, 840000000UL, 875000000UL, 885000000UL },
+  { BAND_TYPE_FDD, 7, 2500000000UL, 2570000000UL, 2620000000UL, 2690000000UL },
+  { BAND_TYPE_FDD, 8, 880000000UL, 915000000UL, 925000000UL, 960000000UL },
+  { BAND_TYPE_FDD, 9, 1749900000UL, 1784900000UL, 1844900000UL, 1879900000UL },
+  { BAND_TYPE_FDD, 10, 1710000000UL, 1770000000UL, 2110000000UL, 2170000000UL },
+  { BAND_TYPE_FDD, 11, 1427900000UL, 1447900000UL, 1475900000UL, 1495900000UL },
+  { BAND_TYPE_FDD, 12, 699000000UL, 716000000UL, 729000000UL, 746000000UL },
+  { BAND_TYPE_FDD, 13, 777000000UL, 787000000UL, 746000000UL, 756000000UL },
+  { BAND_TYPE_FDD, 14, 788000000UL, 798000000UL, 758000000UL, 768000000UL },
+  { BAND_TYPE_FDD, 17, 704000000UL, 716000000UL, 734000000UL, 746000000UL },
+  { BAND_TYPE_FDD, 18, 815000000UL, 830000000UL, 860000000UL, 875000000UL },
+  { BAND_TYPE_FDD, 19, 830000000UL, 845000000UL, 875000000UL, 890000000UL },
+  { BAND_TYPE_FDD, 20, 832000000UL, 862000000UL, 791000000UL, 821000000UL },
+  { BAND_TYPE_FDD, 21, 1447900000UL, 1462900000UL, 1495900000UL, 1510900000UL },
+  { BAND_TYPE_FDD, 22, 3410000000UL, 3490000000UL, 3510000000UL, 3590000000UL },
+  { BAND_TYPE_FDD, 23, 2000000000UL, 2020000000UL, 2180000000UL, 2200000000UL },
+  { BAND_TYPE_FDD, 24, 1626500000UL, 1660500000UL, 1525000000UL, 1559000000UL },
+  { BAND_TYPE_FDD, 25, 1850000000UL, 1915000000UL, 1930000000UL, 1995000000UL },
+
+  { BAND_TYPE_TDD, 33, 1900000000UL, 1920000000UL, 1900000000UL, 1920000000UL },
+  { BAND_TYPE_TDD, 34, 2010000000UL, 2025000000UL, 2010000000UL, 2025000000UL },
+  { BAND_TYPE_TDD, 35, 1850000000UL, 1910000000UL, 1850000000UL, 1910000000UL },
+  { BAND_TYPE_TDD, 36, 1930000000UL, 1990000000UL, 1930000000UL, 1990000000UL },
+  { BAND_TYPE_TDD, 37, 1910000000UL, 1930000000UL, 1910000000UL, 1930000000UL },
+  { BAND_TYPE_TDD, 38, 2570000000UL, 2620000000UL, 2570000000UL, 2620000000UL },
+  { BAND_TYPE_TDD, 39, 1880000000UL, 1920000000UL, 1880000000UL, 1920000000UL },
+  { BAND_TYPE_TDD, 40, 2300000000UL, 2400000000UL, 2300000000UL, 2400000000UL },
+  { BAND_TYPE_TDD, 41, 2496000000UL, 2690000000UL, 2496000000UL, 2690000000UL },
+  { BAND_TYPE_TDD, 42, 3400000000UL, 3600000000UL, 3400000000UL, 3600000000UL },
+  { BAND_TYPE_TDD, 43, 3600000000UL, 3800000000UL, 3600000000UL, 3800000000UL },
+};
+
+typedef struct {
+  int band;
+  unsigned long dl_flow;
+  int dl_off;
+  int dl_offmin, dl_offmax;
+  unsigned long ul_flow;
+  int ul_off;
+  int ul_offmin, ul_offmax;
+} earfcn;
+
+static earfcn earfcn_table[] = {
+  { 1, 2110000000UL, 0, 0, 599, 1920000000UL, 18000, 18000, 18599 },
+  { 2, 1930000000UL, 600, 600, 1199, 1850000000UL, 18600, 18600, 19199 },
+  { 3, 1805000000UL, 1200, 1200, 1949, 1710000000UL, 19200, 19200, 19949 },
+  { 4, 2110000000UL, 1950, 1950, 2399, 1710000000UL, 19950, 19950, 20399 },
+  { 5, 869000000UL, 2400, 2400, 2649, 824000000UL, 20400, 20400, 20649 },
+  { 6, 875000000UL, 2650, 2650, 2749, 830000000UL, 20650, 20650, 20749 },
+  { 7, 2620000000UL, 2750, 2750, 3449, 2500000000UL, 20750, 20750, 21449 },
+  { 8, 925000000UL, 3450, 3450, 3799, 880000000UL, 21450, 21450, 21799 },
+  { 9, 1844900000UL, 3800, 3800, 4149, 1749900000UL, 21800, 21800, 22149 },
+  { 10, 2110000000UL, 4150, 4150, 4749, 1710000000UL, 22150, 22150, 22749 },
+  { 11, 1475900000UL, 4750, 4750, 4949, 1427900000UL, 22750, 22750, 22949 },
+  { 12, 729000000UL, 5010, 5010, 5179, 699000000UL, 23010, 23010, 23179 },
+  { 13, 746000000UL, 5180, 5180, 5279, 777000000UL, 23180, 23180, 23279 },
+  { 14, 758000000UL, 5280, 5280, 5379, 788000000UL, 23280, 23280, 23379 },
+  { 17, 734000000UL, 5730, 5730, 5849, 704000000UL, 23730, 23730, 23849 },
+  { 18, 860000000UL, 5850, 5850, 5999, 815000000UL, 23850, 23850, 23999 },
+  { 19, 875000000UL, 6000, 6000, 6149, 830000000UL, 24000, 24000, 24149 },
+  { 20, 791000000UL, 6150, 6150, 6449, 832000000UL, 24150, 24150, 24449 },
+  { 21, 1495900000UL, 6450, 6450, 6599, 1447900000UL, 24450, 24450, 24599 },
+  { 22, 3510000000UL, 6600, 6600, 7399, 3410000000UL, 24600, 24600, 25399 },
+  { 23, 2180000000UL, 7500, 7500, 7699, 2000000000UL, 25500, 25500, 25699 },
+  { 24, 1525000000UL, 7700, 7700, 8039, 1626500000UL, 25700, 25700, 26039 },
+  { 25, 1930000000UL, 8040, 8040, 8689, 1850000000UL, 26040, 26040, 26689 },
+  { 33, 1900000000UL, 36000, 36000, 36199, 1900000000UL, 36000, 36000, 36199 },
+  { 34, 2010000000UL, 36200, 36200, 36349, 2010000000UL, 36200, 36200, 36349 },
+  { 35, 1850000000UL, 36350, 36350, 36949, 1850000000UL, 36350, 36350, 36949 },
+  { 36, 1930000000UL, 36950, 36950, 37549, 1930000000UL, 36950, 36950, 37549 },
+  { 37, 1910000000UL, 37550, 37550, 37749, 1910000000UL, 37550, 37550, 37749 },
+  { 38, 2570000000UL, 37750, 37750, 38249, 2570000000UL, 37750, 37750, 38249 },
+  { 39, 1880000000UL, 38250, 38250, 38649, 1880000000UL, 38250, 38250, 38649 },
+  { 40, 2300000000UL, 38650, 38650, 39649, 2300000000UL, 38650, 38650, 39649 },
+  { 41, 2496000000UL, 39650, 39650, 41589, 2496000000UL, 39650, 39650, 41589 },
+  { 42, 3400000000UL, 41590, 41590, 43589, 3400000000UL, 41590, 41590, 43589 },
+  { 43, 3600000000UL, 43590, 43590, 45589, 3600000000UL, 43590, 43590, 45589 },
+};
+  
+int freq_to_arfcn10(int band, unsigned long freq)
+{ 
+  int N = sizeof(earfcn_table) / sizeof(earfcn_table[0]); 
+  int i;
+  
+  for (i = 0; i < N; i++) if (bands[i].band == band) break; 
+  if (i == N) return -1;
+  
+  if (!(bands[i].dl_minfreq < freq && freq < bands[i].dl_maxfreq))
+    return -1;
+  
+  return (freq - earfcn_table[i].dl_flow) / 100000UL + earfcn_table[i].dl_off;
+}
 
 //-----------------------------------------------------------------------------
 int
@@ -3436,9 +4740,12 @@ 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];
+  DRB_ToReleaseList_t*                DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid];
+  DRB_Identity_t*                     drb_id_p      = NULL;
 
   T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame),
     T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
@@ -3472,7 +4779,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
     ctxt_pP,
     SRB_configList, //NULL,  //LG-RK 14/05/2014 SRB_configList,
     DRB_configList, 
-    (DRB_ToReleaseList_t *) NULL,
+//    (DRB_ToReleaseList_t *) NULL,
+    DRB_Release_configList2,
     /*RC.rrc[ctxt_pP->module_id]->ciphering_algorithm[ue_mod_idP] |
              (RC.rrc[ctxt_pP->module_id]->integrity_algorithm[ue_mod_idP] << 4),
      */
@@ -3489,7 +4797,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
     ctxt_pP,
     SRB_configList, // NULL,  //LG-RK 14/05/2014 SRB_configList,
     DRB_configList,
-    (DRB_ToReleaseList_t *) NULL
+//    (DRB_ToReleaseList_t *) NULL
+    DRB_Release_configList2
 #if defined(Rel10) || defined(Rel14)
     , (PMCH_InfoList_r9_t *) NULL
 #endif
@@ -3516,6 +4825,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
 	      SRB_configList->list.array[i]->srb_Identity);
       }
     }
+    free(SRB_configList);
+    ue_context_pP->ue_context.SRB_configList2[xid] = NULL;
   }
   
   // Loop through DRBs and establish if necessary
@@ -3691,6 +5002,22 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete(
         }
       }
     }
+   free(DRB_configList);
+    ue_context_pP->ue_context.DRB_configList2[xid] = NULL;
+  }
+
+  if(DRB_Release_configList2 != NULL){
+      for (i = 0; i < DRB_Release_configList2->list.count; i++) {
+          if (DRB_Release_configList2->list.array[i]) {
+              drb_id_p = DRB_Release_configList2->list.array[i];
+              drb_id = *drb_id_p;
+              if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) {
+                  ue_context_pP->ue_context.DRB_active[drb_id] = 0;
+              }
+          }
+      }
+      free(DRB_Release_configList2);
+      ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL;
   }
 }
 
@@ -3810,9 +5137,13 @@ rrc_eNB_generate_RRCConnectionSetup(
         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;
+  //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;
+  //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;
+   // remove UE after 10 frames after RRCConnectionRelease is triggered
+   ue_context_pP->ue_context.ue_release_timer_thres=1000;
 }
 
 
@@ -3935,6 +5266,10 @@ openair_rrc_eNB_init(
             , configuration
 #endif
            );
+    for (int ue_id = 0; ue_id < NUMBER_OF_UE_MAX; ue_id++) {
+        RC.rrc[ctxt.module_id]->carrier[CC_id].sizeof_paging[ue_id] = 0;
+        RC.rrc[ctxt.module_id]->carrier[CC_id].paging[ue_id] = (uint8_t*) malloc16(256);
+    }
   }
 
   rrc_init_global_param();
@@ -4074,7 +5409,7 @@ rrc_eNB_decode_ccch(
         T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti));
 
 #ifdef RRC_MSG_PRINT
-      LOG_F(RRC,"[MSG] RRC Connection Reestablishement Request\n");
+      LOG_F(RRC,"[MSG] RRC Connection Reestablishment Request\n");
 
       for (i = 0; i < Srb_info->Rx_buffer.payload_size; i++) {
         LOG_F(RRC,"%02x ", ((uint8_t*)Srb_info->Rx_buffer.Payload)[i]);
@@ -4109,9 +5444,157 @@ rrc_eNB_decode_ccch(
       }
       */
       /* reject all reestablishment attempts for the moment */
-      rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP,
-                       rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti),
-                       CC_id);
+//      rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP,
+//                       rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti),
+//                       CC_id);
+{
+      uint16_t                          c_rnti = 0;
+
+      if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) {
+        LOG_E(RRC,
+              PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n",
+              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+              rrcConnectionReestablishmentRequest->ue_Identity.physCellId,
+              RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId);
+        rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id);
+        break;
+      }
+      LOG_D(RRC, "physCellId is %ld\n", rrcConnectionReestablishmentRequest->ue_Identity.physCellId);
+
+      for (i = 0; i < rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.size; i++) {
+        LOG_D(RRC, "rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[%d] = %x\n",
+            i, rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[i]);
+      }
+
+      if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 ||
+          rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) {
+        LOG_E(RRC,
+              PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest c_RNTI range error, 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;
+
+      }
+
+      c_rnti = BIT_STRING_to_uint16(&rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI);
+      LOG_D(RRC, "c_rnti is %x\n", c_rnti);
+
+      ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], c_rnti);
+      if (ue_context_p == NULL) {
+        LOG_E(RRC,
+              PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest without UE context, 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;
+      }
+      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;
+
+      // insert C-RNTI to map
+      for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+        if (reestablish_rnti_map[i][0] == 0) {
+          reestablish_rnti_map[i][0] = ctxt_pP->rnti;
+          reestablish_rnti_map[i][1] = c_rnti;
+          break;
+        }
+      }
+      LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
+            i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
+
+#if defined(ENABLE_ITTI)
+      ue_context_p->ue_context.reestablishment_cause = rrcConnectionReestablishmentRequest->reestablishmentCause;
+      LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection reestablishment request from UE physCellId %ld cause %ld\n",
+            PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+            rrcConnectionReestablishmentRequest->ue_Identity.physCellId,
+            ue_context_p->ue_context.reestablishment_cause);
+#else
+        LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection restablishment request for UE\n",
+              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+#endif
+
+#ifndef NO_RRM
+      send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id));
+#else
+
+      ue_context_p->ue_context.primaryCC_id = CC_id;
+
+      //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH;
+      Idx = DCCH;
+      // SRB1
+      ue_context_p->ue_context.Srb1.Active = 1;
+      ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx;
+      memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0],
+             &DCCH_LCHAN_DESC,
+             LCHAN_DESC_SIZE);
+      memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1],
+             &DCCH_LCHAN_DESC,
+             LCHAN_DESC_SIZE);
+
+      // SRB2: set  it to go through SRB1 with id 1 (DCCH)
+      ue_context_p->ue_context.Srb2.Active = 1;
+      ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx;
+      memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0],
+             &DCCH_LCHAN_DESC,
+             LCHAN_DESC_SIZE);
+      memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1],
+             &DCCH_LCHAN_DESC,
+             LCHAN_DESC_SIZE);
+
+      rrc_eNB_generate_RRCConnectionReestablishment(ctxt_pP, ue_context_p, CC_id);
+      LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n",
+            PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
+            Idx);
+
+      MSC_LOG_TX_MESSAGE(MSC_RRC_ENB,
+                         MSC_PDCP_ENB,
+                         NULL,
+                         0,
+                         MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB",
+                         MSC_AS_TIME_ARGS(ctxt_pP),
+                         ue_context_p->ue_context.rnti);
+
+      rrc_pdcp_config_asn1_req(ctxt_pP,
+                               ue_context_p->ue_context.SRB_configList,
+                               (DRB_ToAddModList_t *) NULL,
+                               (DRB_ToReleaseList_t*) NULL,
+                               0xff,
+                               NULL,
+                               NULL,
+                               NULL
+#   if defined(Rel10) || defined(Rel14)
+                               , (PMCH_InfoList_r9_t *) NULL
+#   endif
+                               ,NULL);
+
+      rrc_rlc_config_asn1_req(ctxt_pP,
+                              ue_context_p->ue_context.SRB_configList,
+                              (DRB_ToAddModList_t*) NULL,
+                              (DRB_ToReleaseList_t*) NULL
+#   if defined(Rel10) || defined(Rel14)
+                              , (PMCH_InfoList_r9_t *) NULL
+#   endif
+                             );
+#endif //NO_RRM
+      }
       break;
 
     case UL_CCCH_MessageType__c1_PR_rrcConnectionRequest:
@@ -4160,6 +5643,7 @@ rrc_eNB_decode_ccch(
             /* 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);
@@ -4169,6 +5653,13 @@ rrc_eNB_decode_ccch(
             } 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);
+              ue_context_p->ue_context.ul_failure_timer = 20000;
+            }
+            ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value);
           } else if (InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) {
             /* Save s-TMSI */
             S_TMSI_t   s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI;
@@ -4189,9 +5680,13 @@ rrc_eNB_decode_ccch(
               /* 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;
             } 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);
+//              ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, NOT_A_RANDOM_UE_IDENTITY);
+              ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP,random_value);
               if (ue_context_p == NULL)
                 LOG_E(RRC, "%s:%d:%s: rrc_eNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__);
               if (ue_context_p != NULL) {
@@ -4237,6 +5732,7 @@ rrc_eNB_decode_ccch(
 
 #if defined(ENABLE_ITTI)
           ue_context_p->ue_context.establishment_cause = rrcConnectionRequest->establishmentCause;
+          ue_context_p->ue_context.reestablishment_cause = ReestablishmentCause_spare1;
 	  if (stmsi_received==0)
 	    LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE random UE identity (0x%" PRIx64 ") MME code %u TMSI %u cause %ld\n",
 		  PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
@@ -4369,6 +5865,12 @@ rrc_eNB_decode_dcch(
   UE_EUTRA_Capability_t              *UE_EUTRA_Capability = NULL;
   int i;
   struct rrc_eNB_ue_context_s*        ue_context_p = NULL;
+#if defined(ENABLE_ITTI)
+#   if defined(ENABLE_USE_MME)
+  MessageDef *                        msg_delete_tunnels_p = NULL;
+  uint8_t                             xid;
+#endif
+#endif
 
   int dedicated_DRB=0; 
 
@@ -4529,12 +6031,60 @@ rrc_eNB_decode_dcch(
 #   if defined(ENABLE_USE_MME)
       if (EPC_MODE_ENABLED == 1) {
 	if (dedicated_DRB == 1){
-	  rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP,
-					     ue_context_p,
-					     ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+//	  rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP,
+//					     ue_context_p,
+//					     ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) {
+            rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(ctxt_pP,
+                             ue_context_p,
+                             ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+
+            ue_context_p->ue_context.nb_of_modify_e_rabs = 0;
+            ue_context_p->ue_context.nb_of_failed_e_rabs = 0;
+            memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab));
+            for(int i = 0; i < NB_RB_MAX; i++) {
+              ue_context_p->ue_context.modify_e_rab[i].xid = -1;
+            }
+
+          } else if(ue_context_p->ue_context.e_rab_release_command_flag == 1){
+            xid = ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier;
+            ue_context_p->ue_context.e_rab_release_command_flag = 0;
+            //gtp tunnel delete
+            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)));
+            GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
+            for(i = 0; i < NB_RB_MAX; i++){
+               if(xid == ue_context_p->ue_context.e_rab[i].xid){
+                 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[i];
+                 ue_context_p->ue_context.enb_gtp_teid[i] = 0;
+                 memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i]));
+                 ue_context_p->ue_context.enb_gtp_ebi[i]  = 0;
+               }
+            }
+            itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p);
+            //S1AP_E_RAB_RELEASE_RESPONSE
+            rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(ctxt_pP,
+                    ue_context_p,
+                    xid);
+          } else {
+              rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP,
+                             ue_context_p,
+                             ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier);
+          }
 	}else {
-	  rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP,
+          if(ue_context_p->ue_context.reestablishment_cause == ReestablishmentCause_spare1){
+	    rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP,
 						       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;
+              }
+            }
+          }
 	}
       }    
 #else  // establish a dedicated bearer 
@@ -4577,6 +6127,53 @@ rrc_eNB_decode_dcch(
             PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
             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++) {
+          if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) {
+            reestablish_rnti = reestablish_rnti_map[i][1];
+            ue_context_p = rrc_eNB_get_ue_context(
+                              RC.rrc[ctxt_pP->module_id],
+                              reestablish_rnti);
+            // clear currentC-RNTI from map
+            reestablish_rnti_map[i][0] = 0;
+            reestablish_rnti_map[i][1] = 0;
+            break;
+          }
+        }
+        LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n",
+              i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]);
+
+        if (!ue_context_p) {
+          LOG_E(RRC,
+                PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentComplete without UE context, falt\n",
+                PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+          break;
+        }
+
+        if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present ==
+            RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) {
+          rrc_eNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p,
+              ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.rrc_TransactionIdentifier,
+              &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8);
+
+#if defined(FLEXRAN_AGENT_SB_IF)
+          //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future
+          if (mac_agent_registered[ctxt_pP->module_id]) {
+            agent_mac_xface[ctxt_pP->eNB_index]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id,
+                                                                                      ue_context_p->ue_id_rnti,
+                                                                                      PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED);
+          }
+#endif
+        }
+        //ue_context_p->ue_context.ue_release_timer = 0;
+        ue_context_p->ue_context.ue_reestablishment_timer = 1;
+        // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered
+        ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000;
+      }
       break;
 
     case UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete:
@@ -5029,13 +6626,22 @@ rrc_enb_task(
       break;
 
     case S1AP_PAGING_IND:
-      LOG_E(RRC, "[eNB %d] Received not yet implemented message %s\n", instance, msg_name_p);
+      LOG_D(RRC, "[eNB %d] Received Paging message from S1AP: %s\n", instance, msg_name_p);
+      rrc_eNB_process_PAGING_IND(msg_p, msg_name_p, instance);
       break;
   
     case S1AP_E_RAB_SETUP_REQ: 
       rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(msg_p, msg_name_p, instance);
       LOG_D(RRC, "[eNB %d] Received the message %s\n", instance, msg_name_p);
       break;
+
+    case S1AP_E_RAB_MODIFY_REQ:
+      rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(msg_p, msg_name_p, instance);
+      break;
+
+    case S1AP_E_RAB_RELEASE_COMMAND:
+      rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(msg_p, msg_name_p, instance);
+      break;
     
     case S1AP_UE_CONTEXT_RELEASE_REQ:
       rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ(msg_p, msg_name_p, instance);
@@ -5049,6 +6655,11 @@ 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) {
+        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;
+      }
       break;
 
 #   endif
diff --git a/openair2/RRC/LITE/rrc_eNB_GTPV1U.c b/openair2/RRC/LITE/rrc_eNB_GTPV1U.c
index 9aca0491669e8b12899a738c6b8364ed4d853488..e5f2c5aaae1c469c4da1ffbcda1a41a0d7c264d4 100644
--- a/openair2/RRC/LITE/rrc_eNB_GTPV1U.c
+++ b/openair2/RRC/LITE/rrc_eNB_GTPV1U.c
@@ -47,7 +47,8 @@ extern RAN_CONTEXT_t RC;
 int
 rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   const protocol_ctxt_t* const ctxt_pP,
-  const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP
+  const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP,
+  uint8_t                         *inde_list
 )
 {
   rnti_t                         rnti;
@@ -66,15 +67,18 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
 
     for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) {
       
-      ue_context_p->ue_context.enb_gtp_teid[i+ue_context_p->ue_context.setup_e_rabs]  = create_tunnel_resp_pP->enb_S1u_teid[i];
-      ue_context_p->ue_context.enb_gtp_addrs[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_addr;
-      ue_context_p->ue_context.enb_gtp_ebi[i+ue_context_p->ue_context.setup_e_rabs]   = create_tunnel_resp_pP->eps_bearer_id[i];
+//      ue_context_p->ue_context.enb_gtp_teid[i+ue_context_p->ue_context.setup_e_rabs]  = create_tunnel_resp_pP->enb_S1u_teid[i];
+//      ue_context_p->ue_context.enb_gtp_addrs[i+ue_context_p->ue_context.setup_e_rabs] = create_tunnel_resp_pP->enb_addr;
+//      ue_context_p->ue_context.enb_gtp_ebi[i+ue_context_p->ue_context.setup_e_rabs]   = create_tunnel_resp_pP->eps_bearer_id[i];
+      ue_context_p->ue_context.enb_gtp_teid[inde_list[i]]  = create_tunnel_resp_pP->enb_S1u_teid[i];
+      ue_context_p->ue_context.enb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr;
+      ue_context_p->ue_context.enb_gtp_ebi[inde_list[i]]   = create_tunnel_resp_pP->eps_bearer_id[i];
       
       LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n",
             PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
             create_tunnel_resp_pP->enb_S1u_teid[i],
-	    ue_context_p->ue_context.enb_gtp_teid[i+ue_context_p->ue_context.setup_e_rabs],
-            i+ue_context_p->ue_context.setup_e_rabs, 
+            ue_context_p->ue_context.enb_gtp_teid[inde_list[i]],            
+            inde_list[i],
 	    i,
             create_tunnel_resp_pP->eps_bearer_id[i],
 	    create_tunnel_resp_pP->enb_addr.length);
diff --git a/openair2/RRC/LITE/rrc_eNB_GTPV1U.h b/openair2/RRC/LITE/rrc_eNB_GTPV1U.h
index 981c3f8d3ba8b1379c0f997c5a89f09513036226..aedbdeac5e12bdd510ad5d286f3d82bf4cab83f2 100644
--- a/openair2/RRC/LITE/rrc_eNB_GTPV1U.h
+++ b/openair2/RRC/LITE/rrc_eNB_GTPV1U.h
@@ -43,7 +43,8 @@
 int
 rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
   const protocol_ctxt_t* const ctxt_pP,
-  const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP
+  const gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP,
+  uint8_t                         *inde_list
 );
 
 #   endif
diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c
index 24ee3c06dafa7a46b8920697db8969b87a806f55..d2c0d0acbe8f7375370fdc3699af8f6d6be1ca86 100644
--- a/openair2/RRC/LITE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c
@@ -342,6 +342,8 @@ static void process_eNB_security_key (
 
   /* Saves the security key */
   memcpy (ue_context_pP->ue_context.kenb, security_key_pP, SECURITY_KEY_LENGTH);
+  memset (ue_context_pP->ue_context.nh, 0, SECURITY_KEY_LENGTH);
+  ue_context_pP->ue_context.nh_ncc = -1;
 
   for (i = 0; i < 32; i++) {
     sprintf(&ascii_buffer[2 * i], "%02X", ue_context_pP->ue_context.kenb[i]);
@@ -355,7 +357,7 @@ static void process_eNB_security_key (
 
 
 //------------------------------------------------------------------------------
-static void
+void
 rrc_pdcp_config_security(
   const protocol_ctxt_t* const ctxt_pP,
   rrc_eNB_ue_context_t*          const ue_context_pP,
@@ -892,6 +894,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
   //MessageDef                     *message_gtpv1u_p = NULL;
   gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
   gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
+  uint8_t                         inde_list[NB_RB_MAX - 3]={0};
 
   struct rrc_eNB_ue_context_s* ue_context_p = NULL;
   protocol_ctxt_t              ctxt;
@@ -937,10 +940,12 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
         memcpy(&create_tunnel_req.sgw_addr[i],
                &S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].sgw_addr,
                sizeof(transport_layer_addr_t));
+        inde_list[create_tunnel_req.num_tunnels]= i;
+        create_tunnel_req.num_tunnels++;
       }
     
       create_tunnel_req.rnti       = ue_context_p->ue_context.rnti; // warning put zero above
-      create_tunnel_req.num_tunnels    = i;
+//      create_tunnel_req.num_tunnels    = i;
 
       gtpv1u_create_s1u_tunnel(
         instance,
@@ -949,7 +954,8 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
 
       rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
           &ctxt,
-          &create_tunnel_resp); 
+          &create_tunnel_resp,
+          &inde_list[0]); 
       ue_context_p->ue_context.setup_e_rabs=ue_context_p->ue_context.nb_of_e_rabs;
     }
 
@@ -1191,6 +1197,7 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const ch
     }
     return (-1);
   } else {
+    ue_context_p->ue_context.ue_release_timer_s1 = 0;
     PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
     rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context_p);
     /*
@@ -1265,9 +1272,12 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
   uint32_t                        eNB_ue_s1ap_id;
   gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
   gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
+  uint8_t                         inde_list[NB_RB_MAX - 3]={0};
 
   struct rrc_eNB_ue_context_s* ue_context_p = NULL;
   protocol_ctxt_t              ctxt;
+  uint8_t                      e_rab_done;
+
   ue_initial_id  = S1AP_E_RAB_SETUP_REQ (msg_p).ue_initial_id;
   eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (msg_p).eNB_ue_s1ap_id;
   ue_context_p   = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id);
@@ -1298,35 +1308,46 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
 
       memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
       uint8_t nb_e_rabs_tosetup = S1AP_E_RAB_SETUP_REQ  (msg_p).nb_e_rabs_tosetup;
+      e_rab_done = 0;
 
       // keep the previous bearer
       // the index for the rec
       for (i = 0; 
-	   i < nb_e_rabs_tosetup; 
+	  // i < nb_e_rabs_tosetup; 
+           i < NB_RB_MAX - 3;  // loop all e-rabs in e_rab[] 
 	   i++) {
-	if (ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status == E_RAB_STATUS_DONE) 
-	  LOG_W(RRC,"E-RAB already configured, reconfiguring\n");
-        ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status = E_RAB_STATUS_NEW;
-        ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].param = S1AP_E_RAB_SETUP_REQ  (msg_p).e_rab_setup_params[i];
-
+	//if (ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status == E_RAB_STATUS_DONE) 
+	//  LOG_W(RRC,"E-RAB already configured, reconfiguring\n");
+        // check e-rab status, if e rab status is greater than E_RAB_STATUS_DONE, don't not config this one
+        if(ue_context_p->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE)
+            continue;
+        //ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status = E_RAB_STATUS_NEW;
+        //ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].param = S1AP_E_RAB_SETUP_REQ  (msg_p).e_rab_setup_params[i];
+        ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW;
+        ue_context_p->ue_context.e_rab[i].param = S1AP_E_RAB_SETUP_REQ  (msg_p).e_rab_setup_params[e_rab_done];
 
-        create_tunnel_req.eps_bearer_id[i]       = S1AP_E_RAB_SETUP_REQ  (msg_p).e_rab_setup_params[i].e_rab_id;
-        create_tunnel_req.sgw_S1u_teid[i]        = S1AP_E_RAB_SETUP_REQ  (msg_p).e_rab_setup_params[i].gtp_teid;
+        create_tunnel_req.eps_bearer_id[e_rab_done]       = S1AP_E_RAB_SETUP_REQ  (msg_p).e_rab_setup_params[e_rab_done].e_rab_id;
+        create_tunnel_req.sgw_S1u_teid[e_rab_done]        = S1AP_E_RAB_SETUP_REQ  (msg_p).e_rab_setup_params[e_rab_done].gtp_teid;
 
-        memcpy(&create_tunnel_req.sgw_addr[i],
-               & S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i].sgw_addr,
+        memcpy(&create_tunnel_req.sgw_addr[e_rab_done],
+               & S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done].sgw_addr,
                sizeof(transport_layer_addr_t));
 	
 	LOG_I(RRC,"E_RAB setup REQ: local index %d teid %u, eps id %d \n", 
-	      i+ue_context_p->ue_context.setup_e_rabs,
-	      create_tunnel_req.sgw_S1u_teid[i],
+	      i,
+	      create_tunnel_req.sgw_S1u_teid[e_rab_done],
 	       create_tunnel_req.eps_bearer_id[i] );
+        inde_list[e_rab_done] = i;
+        e_rab_done++;        
+        if(e_rab_done >= nb_e_rabs_tosetup){
+            break;
+        }
       }
       ue_context_p->ue_context.nb_of_e_rabs=nb_e_rabs_tosetup;
      
      
       create_tunnel_req.rnti       = ue_context_p->ue_context.rnti; // warning put zero above
-      create_tunnel_req.num_tunnels    = i;
+      create_tunnel_req.num_tunnels    = e_rab_done;
       
       // NN: not sure if we should create a new tunnel: need to check teid, etc.
       gtpv1u_create_s1u_tunnel(
@@ -1336,7 +1357,8 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
 
       rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
           &ctxt,
-          &create_tunnel_resp);
+          &create_tunnel_resp,
+          &inde_list[0]);
 
       ue_context_p->ue_context.setup_e_rabs+=nb_e_rabs_tosetup;
 
@@ -1400,12 +1422,17 @@ int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
 	S1AP_E_RAB_SETUP_RESP  (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
 	e_rabs_failed++;
 	// TODO add cause when it will be integrated
-      }
-      
+      } 
       
       S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
       S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;
       // NN: add conditions for e_rabs_failed 
+    } else {
+      /*debug info for the xid */ 
+      LOG_D(RRC,"xid does not corresponds  (context e_rab index %d, status %d, xid %d/%d) \n ",
+      	     e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, ue_context_pP->ue_context.e_rab[e_rab].xid);
+    } 
+  }
       if ((e_rabs_done > 0) ){  
 
 	LOG_I(RRC,"S1AP_E_RAB_SETUP_RESP: sending the message: nb_of_erabs %d, total e_rabs %d, index %d\n",
@@ -1424,17 +1451,528 @@ int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
 	
 	itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
       }
+  for(int i = 0; i < NB_RB_MAX; i++) {
+      ue_context_pP->ue_context.e_rab[i].xid = -1;
+  }
+  
+  return 0;
+}
+
+int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance)
+{
+  int                             i;
+  uint16_t                        ue_initial_id;
+  uint32_t                        eNB_ue_s1ap_id;
+  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+  protocol_ctxt_t              ctxt;
+
+  ue_initial_id  = S1AP_E_RAB_MODIFY_REQ (msg_p).ue_initial_id;
+  eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id;
+  ue_context_p   = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id);
+  LOG_D(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d, nb_of_e_rabs %d\n",
+        instance, msg_name, ue_initial_id, eNB_ue_s1ap_id, S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify);
+
+  if (ue_context_p == NULL) {
+    /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */
+    LOG_W(RRC, "[eNB %d] In S1AP_E_RAB_MODIFY_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id);
+    int nb_of_e_rabs_failed = 0;
+    MessageDef *msg_fail_p = NULL;
+
+    msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
+
+    S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id;
+    S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0;
+
+    for (nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; nb_of_e_rabs_failed++) {
+      S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id =
+              S1AP_E_RAB_MODIFY_REQ (msg_p).e_rab_modify_params[nb_of_e_rabs_failed].e_rab_id;
+      S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK;
+      S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances;
+    }
+    S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed;
+
+    itti_send_msg_to_task(TASK_S1AP, instance, msg_fail_p);
+    return (-1);
+
+  } else {
+    PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
+    ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id;
+
+    /* Save e RAB information for later */
+    {
+      int j;
+      boolean_t is_treated[S1AP_MAX_E_RAB] = {FALSE};
+      uint8_t nb_of_failed_e_rabs = 0;
+
+      // keep the previous bearer
+      // the index for the rec
+      for (i = 0; i < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; i++) {
+        if (is_treated[i] == TRUE) {
+          // already treated
+          continue;
+        }
+        for (j = i+1; j < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; j++) {
+          if (is_treated[j] == FALSE &&
+            S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) {
+            // handle multiple E-RAB ID
+            ue_context_p->ue_context.modify_e_rab[j].status = E_RAB_STATUS_NEW;
+            ue_context_p->ue_context.modify_e_rab[j].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id;
+            ue_context_p->ue_context.modify_e_rab[j].cause = S1AP_CAUSE_RADIO_NETWORK;
+            ue_context_p->ue_context.modify_e_rab[j].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances;
+            nb_of_failed_e_rabs++;
+            is_treated[i] = TRUE;
+            is_treated[j] = TRUE;
+          }
+        }
+        if (is_treated[i] == TRUE) {
+          // handle multiple E-RAB ID
+          ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
+          ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
+          ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
+          ue_context_p->ue_context.modify_e_rab[i].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances;
+          nb_of_failed_e_rabs++;
+          continue;
+        }
+
+        if (S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.length == 0) {
+          // nas_pdu.length == 0
+          ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
+          ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
+          ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_NAS;
+          ue_context_p->ue_context.modify_e_rab[i].cause_value = 3;//S1ap_CauseNas_unspecified;
+          nb_of_failed_e_rabs++;
+          is_treated[i] = TRUE;
+          continue;
+        }
+
+        for (j = 0; j < NB_RB_MAX-3; j++) {
+          if (ue_context_p->ue_context.e_rab[j].param.e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) {
+            if(ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_TORELEASE || ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_DONE){
+              break;
+            }
+            ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
+            ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_NOTHING;
+            ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
+            ue_context_p->ue_context.modify_e_rab[i].param.qos =  S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].qos;
+            ue_context_p->ue_context.modify_e_rab[i].param.nas_pdu.length = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.length;
+            ue_context_p->ue_context.modify_e_rab[i].param.nas_pdu.buffer = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.buffer;
+            ue_context_p->ue_context.modify_e_rab[i].param.sgw_addr = ue_context_p->ue_context.e_rab[j].param.sgw_addr;
+            ue_context_p->ue_context.modify_e_rab[i].param.gtp_teid = ue_context_p->ue_context.e_rab[j].param.gtp_teid;
+
+            is_treated[i] = TRUE;
+            break;
+          }
+        }
+
+        if (is_treated[i] == FALSE) {
+          // handle Unknown E-RAB ID
+          ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW;
+          ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id;
+          ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK;
+          ue_context_p->ue_context.modify_e_rab[i].cause_value = 30;//S1ap_CauseRadioNetwork_unknown_E_RAB_ID;
+          nb_of_failed_e_rabs++;
+          is_treated[i] = TRUE;
+        }
+      }
+
+      ue_context_p->ue_context.nb_of_modify_e_rabs = S1AP_E_RAB_MODIFY_REQ  (msg_p).nb_e_rabs_tomodify;
+      ue_context_p->ue_context.nb_of_failed_e_rabs = nb_of_failed_e_rabs;
+    }
+
+    /* TODO parameters yet to process ... */
+    {
+      //      S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_ambr;
+    }
+
+    if (ue_context_p->ue_context.nb_of_failed_e_rabs < ue_context_p->ue_context.nb_of_modify_e_rabs) {
+      if (0 == rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(&ctxt, ue_context_p, 0)) {
+        return (0);
+      }
+    }
+
+    {
+      int nb_of_e_rabs_failed = 0;
+      MessageDef *msg_fail_p = NULL;
+
+      msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
+
+      S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id;
+//      S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB];
+      S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0;
+
+      for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < ue_context_p->ue_context.nb_of_failed_e_rabs; nb_of_e_rabs_failed++) {
+        S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id =
+                ue_context_p->ue_context.modify_e_rab[nb_of_e_rabs_failed].param.e_rab_id;
+        S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause = ue_context_p->ue_context.modify_e_rab[nb_of_e_rabs_failed].cause;
+      }
+      S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed;
+
+      itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p);
+
+      ue_context_p->ue_context.nb_of_modify_e_rabs = 0;
+      ue_context_p->ue_context.nb_of_failed_e_rabs = 0;
+      memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab));
+
+      return (0);
+    }
+  }  // end of ue_context_p != NULL
+}
+
+/*NN: careful about the typcast of xid (long -> uint8_t*/
+int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP,
+           rrc_eNB_ue_context_t*          const ue_context_pP,
+           uint8_t xid ) {
+
+  MessageDef      *msg_p         = NULL;
+  int i;
+  int e_rab;
+  int e_rabs_done = 0;
+  int e_rabs_failed = 0;
+  msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
+  S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
+
+  for (e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_modify_e_rabs; e_rab++) {
+
+    /* only respond to the corresponding transaction */
+    if (xid == ue_context_pP->ue_context.modify_e_rab[e_rab].xid) {
+      if (ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_DONE) {
+        for (i = 0; i < ue_context_pP->ue_context.setup_e_rabs; i++) {
+          if (ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id == ue_context_pP->ue_context.e_rab[i].param.e_rab_id) {
+            // Update ue_context_pP->ue_context.e_rab
+            ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_ESTABLISHED;
+            ue_context_pP->ue_context.e_rab[i].param.qos = ue_context_pP->ue_context.modify_e_rab[e_rab].param.qos;
+            ue_context_pP->ue_context.e_rab[i].cause = S1AP_CAUSE_NOTHING;
+            break;
+          }
+        }
+        if (i < ue_context_pP->ue_context.setup_e_rabs) {
+          S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id;
+              // TODO add other information from S1-U when it will be integrated
+
+          LOG_D (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d, xid %d): nb_of_modify_e_rabs %d,  e_rab_id %d \n ",
+              e_rabs_done,  e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid,
+              ue_context_pP->ue_context.nb_of_modify_e_rabs,
+              S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id);
 
+          e_rabs_done++;
+        } else {
+          // unexpected
+          S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id;
+
+          S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK;
+          S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause_value = 30;//S1ap_CauseRadioNetwork_unknown_E_RAB_ID;
+
+          e_rabs_failed++;
+        }
+      } else if ((ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_NEW) ||
+          (ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)){
+        LOG_D (RRC,"E-RAB is NEW or already ESTABLISHED\n");
+      } else {  /* status == E_RAB_STATUS_FAILED; */
+        S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id;
+        // add failure cause when defined
+        S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause = ue_context_pP->ue_context.modify_e_rab[e_rab].cause;
+
+        e_rabs_failed++;
+      }
     } else {
-      /*debug info for the xid */ 
+      /*debug info for the xid */
       LOG_D(RRC,"xid does not corresponds  (context e_rab index %d, status %d, xid %d/%d) \n ",
-      	     e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, ue_context_pP->ue_context.e_rab[e_rab].xid);
+             e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid, ue_context_pP->ue_context.modify_e_rab[e_rab].xid);
     }
-    
   }
-  
+
+
+  S1AP_E_RAB_MODIFY_RESP (msg_p).nb_of_e_rabs = e_rabs_done;
+  S1AP_E_RAB_MODIFY_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed;
+  // NN: add conditions for e_rabs_failed
+  if (e_rabs_done > 0 || e_rabs_failed > 0) {
+    LOG_D(RRC,"S1AP_E_RAB_MODIFY_RESP: sending the message: nb_of_modify_e_rabs %d, total e_rabs %d, index %d\n",
+    ue_context_pP->ue_context.nb_of_modify_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab);
+MSC_LOG_TX_MESSAGE(
+     MSC_RRC_ENB,
+     MSC_S1AP_ENB,
+     (const char *)&S1AP_E_RAB_SETUP_RESP (msg_p),
+     sizeof(s1ap_e_rab_setup_resp_t),
+     MSC_AS_TIME_FMT" E_RAB_MODIFY_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail",
+     MSC_AS_TIME_ARGS(ctxt_pP),
+     ue_context_pP->ue_id_rnti,
+     S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id,
+     e_rabs_done, e_rabs_failed);
+
+    itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
+  }
+
   return 0;
 }
+int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance){
+    uint16_t                        mme_ue_s1ap_id;
+    uint32_t                        eNB_ue_s1ap_id;
+    struct rrc_eNB_ue_context_s*    ue_context_p = NULL;
+    protocol_ctxt_t                 ctxt;
+    e_rab_release_t e_rab_release_params[S1AP_MAX_E_RAB];
+    uint8_t nb_e_rabs_torelease;
+    int erab;
+    int i;
+    uint8_t b_existed,is_existed;
+    uint8_t xid;
+    uint8_t e_rab_release_drb;
+    MessageDef *                    msg_delete_tunnels_p = NULL;
+    e_rab_release_drb = 0;
+    memcpy(&e_rab_release_params[0], &(S1AP_E_RAB_RELEASE_COMMAND (msg_p).e_rab_release_params[0]), sizeof(e_rab_release_t)*S1AP_MAX_E_RAB);
+
+    mme_ue_s1ap_id  = S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id;
+    eNB_ue_s1ap_id = S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id;
+    nb_e_rabs_torelease = S1AP_E_RAB_RELEASE_COMMAND (msg_p).nb_e_rabs_torelease;
+    ue_context_p   = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id);
+    if(ue_context_p != NULL){
+        PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
+
+        xid = rrc_eNB_get_next_transaction_identifier(ctxt.module_id);
+
+        LOG_D(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d  ENB_UE_S1AP_ID %d release_e_rabs %d \n",
+            mme_ue_s1ap_id, eNB_ue_s1ap_id,nb_e_rabs_torelease);
+        for(erab = 0; erab < nb_e_rabs_torelease; erab++){
+            b_existed = 0;
+            is_existed = 0;
+            for ( i = erab-1;  i>= 0; i--){
+                if (e_rab_release_params[erab].e_rab_id == e_rab_release_params[i].e_rab_id){
+                    is_existed = 1;
+                    break;
+                }
+            }
+            if(is_existed == 1){
+                //e_rab_id is existed
+                continue;
+            }
+            for ( i = 0;  i < NB_RB_MAX; i++){
+                if (e_rab_release_params[erab].e_rab_id == ue_context_p->ue_context.e_rab[i].param.e_rab_id){
+                    b_existed = 1;
+                    break;
+                }
+            }
+            if(b_existed == 0) {
+                //no e_rab_id
+                ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id;
+                ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK;
+                ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 30;
+                ue_context_p->ue_context.nb_release_of_e_rabs++;
+            } else {
+                if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_FAILED){
+                    ue_context_p->ue_context.e_rab[i].xid = xid;
+                    continue;
+                } else if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED){
+                    ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE;
+                    ue_context_p->ue_context.e_rab[i].xid = xid;
+                    e_rab_release_drb++;
+                }else{
+                    //e_rab_id status NG
+                    ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id;
+                    ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK;
+                    ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 0;
+                    ue_context_p->ue_context.nb_release_of_e_rabs++;
+                }
+            }
+        }
+        if(e_rab_release_drb > 0) {
+            //RRCConnectionReconfiguration To UE
+            rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(&ctxt, ue_context_p, xid, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.length, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.buffer);
+        } else {
+            //gtp tunnel delete
+            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)));
+            GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti;
+            for(i = 0; i < NB_RB_MAX; i++){
+               if(xid == ue_context_p->ue_context.e_rab[i].xid){
+                 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[i];
+                 ue_context_p->ue_context.enb_gtp_teid[i] = 0;
+                 memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i]));
+                 ue_context_p->ue_context.enb_gtp_ebi[i]  = 0;
+               }
+            }
+
+            itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p);
+
+            //S1AP_E_RAB_RELEASE_RESPONSE
+            rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid);
+        }
+    } else {
+        LOG_E(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d  ENB_UE_S1AP_ID %d  Error ue_context_p NULL \n",
+            S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id, S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id);
+         return -1;
+    }
+
+    return 0;
+}
+
+
+int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid){
+    int e_rabs_released = 0;
+    MessageDef   *msg_p;
+
+    msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_RELEASE_RESPONSE);
+    S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
+    
+    for (int i = 0;  i < NB_RB_MAX; i++){
+        if (xid == ue_context_pP->ue_context.e_rab[i].xid){
+            S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rab_release[e_rabs_released].e_rab_id = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
+            e_rabs_released++;
+            //clear
+            memset(&ue_context_pP->ue_context.e_rab[i],0,sizeof(e_rab_param_t));
+        }
+    }
+    S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_released = e_rabs_released;
+    S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_failed = ue_context_pP->ue_context.nb_release_of_e_rabs;
+    memcpy(&(S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rabs_failed[0]),&ue_context_pP->ue_context.e_rabs_release_failed[0],sizeof(e_rab_failed_t)*ue_context_pP->ue_context.nb_release_of_e_rabs);
+
+    ue_context_pP->ue_context.setup_e_rabs -= e_rabs_released;
+    LOG_I(RRC,"S1AP-E-RAB RELEASE RESPONSE: ENB_UE_S1AP_ID %d release_e_rabs %d setup_e_rabs %d \n",
+              S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id,
+              e_rabs_released, ue_context_pP->ue_context.setup_e_rabs);
+    
+    itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
+    //clear xid
+    for(int i = 0; i < NB_RB_MAX; i++) {
+        ue_context_pP->ue_context.e_rab[i].xid = -1;
+    }
+    //clear release e_rabs
+    ue_context_pP->ue_context.nb_release_of_e_rabs = 0;
+    memset(&ue_context_pP->ue_context.e_rabs_release_failed[0],0,sizeof(e_rab_failed_t)*S1AP_MAX_E_RAB);
+    return 0;
+}
+
+/*------------------------------------------------------------------------------*/
+int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance)
+{
+  const unsigned int Ttab[4] = {32,64,128,256};
+  uint8_t Tc,Tue;  /* DRX cycle of UE */
+  uint32_t pcch_nB;  /* 4T, 2T, T, T/2, T/4, T/8, T/16, T/32 */
+  uint32_t N;  /* N: min(T,nB). total count of PF in one DRX cycle */
+  uint32_t Ns = 0;  /* Ns: max(1,nB/T) */
+  uint8_t i_s;  /* i_s = floor(UE_ID/N) mod Ns */
+  uint32_t T;  /* DRX cycle */
+  for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) {
+       LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc,
+             S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]);
+      if (RC.rrc[instance]->configuration.mcc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc
+          && RC.rrc[instance]->configuration.mnc == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc
+          && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) {
+          for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
+              lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type;
+              /* get nB from configuration */
+              /* get default DRX cycle from configuration */
+              Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id];
+              if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) {
+                  continue;
+              }
+              Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx;
+              /* set T = min(Tc,Tue) */
+              T = Tc < Tue ? Ttab[Tc] : Ttab[Tue];
+              /* set pcch_nB = PCCH-Config->nB */
+              pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id];
+              switch (pcch_nB) {
+                case PCCH_Config__nB_fourT:
+                    Ns = 4;
+                    break;
+                case PCCH_Config__nB_twoT:
+                    Ns = 2;
+                    break;
+                default:
+                    Ns = 1;
+                    break;
+              }
+              /* set N = min(T,nB) */
+              if (pcch_nB > PCCH_Config__nB_oneT) {
+                switch (pcch_nB) {
+                case PCCH_Config__nB_halfT:
+                  N = T/2;
+                  break;
+                case PCCH_Config__nB_quarterT:
+                  N = T/4;
+                  break;
+                case PCCH_Config__nB_oneEighthT:
+                  N = T/8;
+                  break;
+                case PCCH_Config__nB_oneSixteenthT:
+                  N = T/16;
+                  break;
+                case PCCH_Config__nB_oneThirtySecondT:
+                  N = T/32;
+                  break;
+                default:
+                  /* pcch_nB error */
+                  LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND:  pcch_nB error (pcch_nB %d) \n",
+                      instance, pcch_nB);
+                  return (-1);
+                }
+              } else {
+                N = T;
+              }
+
+              /* insert data to UE_PF_PO or update data in UE_PF_PO */
+              pthread_mutex_lock(&ue_pf_po_mutex);
+              uint8_t i = 0;
+              for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
+                if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value))
+                    || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) {
+                    /* set T = min(Tc,Tue) */
+                    UE_PF_PO[CC_id][i].T = T;
+                    /* set UE_ID */
+                    UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value;
+                    /* calculate PF and PO */
+                    /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */
+                    UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N);
+                    /* set PO */
+                    /* i_s = floor(UE_ID/N) mod Ns */
+                    i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns);
+                    if (Ns == 1) {
+                        UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0;
+                    } else if (Ns==2) {
+                        UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s);
+                    } else if (Ns==4) {
+                        UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1)));
+                    }
+                    if (UE_PF_PO[CC_id][i].enable_flag == TRUE) {
+                        //paging exist UE log
+                        LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
+                    } else {
+                        /* set enable_flag */
+                        UE_PF_PO[CC_id][i].enable_flag = TRUE;
+                        //paging new UE log
+                        LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO);
+                    }
+                    break;
+                }
+              }
+              pthread_mutex_unlock(&ue_pf_po_mutex);
+
+              uint32_t length;
+              uint8_t buffer[RRC_BUF_SIZE];
+              uint8_t *message_buffer;
+              /* Transfer data to PDCP */
+              MessageDef *message_p;
+              message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ);
+              /* Create message for PDCP (DLInformationTransfer_t) */
+              length = do_Paging (instance,
+                                  buffer,
+                                  S1AP_PAGING_IND(msg_p).ue_paging_identity,
+                                  S1AP_PAGING_IND(msg_p).cn_domain);
+              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);
+              RRC_PCCH_DATA_REQ (message_p).sdu_size  = length;
+              RRC_PCCH_DATA_REQ (message_p).sdu_p     = message_buffer;
+              RRC_PCCH_DATA_REQ (message_p).mode      = PDCP_TRANSMISSION_MODE_TRANSPARENT;  /* not used */
+              RRC_PCCH_DATA_REQ (message_p).rnti      = P_RNTI;
+              RRC_PCCH_DATA_REQ (message_p).ue_index  = i;
+              RRC_PCCH_DATA_REQ (message_p).CC_id  = CC_id;
+              LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length);
+              itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p);
+          }
+      }
+  }
+
+  return (0);
+}
 
 # endif /* defined(ENABLE_ITTI) */
 #endif /* defined(ENABLE_USE_MME) */
diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.h b/openair2/RRC/LITE/rrc_eNB_S1AP.h
index 6b2de919bd44403e4e3ae99229c41e4d47668fed..a924caf254c664159089e1bcf27579bbbb687b67 100644
--- a/openair2/RRC/LITE/rrc_eNB_S1AP.h
+++ b/openair2/RRC/LITE/rrc_eNB_S1AP.h
@@ -79,6 +79,11 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co
                                                      const uint8_t                ho_state
                                                      );
 
+int
+rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP,
+                                                     rrc_eNB_ue_context_t*          const ue_context_pP,
+                                                     const uint8_t                ho_state
+                                                     );
 
 /*! \fn void rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(uint8_t mod_id, uint8_t ue_index)
  *\brief create a S1AP_INITIAL_CONTEXT_SETUP_RESP for S1AP.
@@ -186,6 +191,24 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name
  */
 int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t*  const ue_context_pP, uint8_t xid );  
 
+/*! \fn rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance);
+ *\brief process a S1AP dedicated E_RAB modify request message received from S1AP.
+ *\param msg_p Message received by RRC.
+ *\param msg_name Message name.
+ *\param instance Message instance.
+ *\return 0 when successful, -1 if the UE index can not be retrieved.
+ */
+int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance);
+
+/*! \fn rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t*  const ue_context_pP, uint8_t xid )
+ *\brief send a S1AP dedicated E_RAB modify response
+ *\param ctxt_pP contxt infirmation
+ *\param e_contxt_pP ue specific context at the eNB
+ *\param xid transaction identifier
+ *\return 0 when successful, -1 if the UE index can not be retrieved.
+ */
+int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t*  const ue_context_pP, uint8_t xid );
+
 /*! \fn rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance)
  *\brief process a S1AP_UE_CTXT_MODIFICATION_REQ message received from S1AP.
  *\param msg_p Message received by RRC.
@@ -213,6 +236,39 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char *
  */
 int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const char *msg_name, instance_t instance);
 
+/*! \fn rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance)
+ *\brief process a S1AP_PAGING_IND message received from S1AP.
+ *\param msg_p Message received by RRC.
+ *\param msg_name Message name.
+ *\param instance Message instance.
+ *\return 0 when successful, -1 if the UE index can not be retrieved.
+ */
+int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance);
+
+void
+rrc_pdcp_config_security(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_t*          const ue_context_pP,
+  const uint8_t send_security_mode_command
+);
+/*! \fn rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance);
+ *\brief process a S1AP dedicated E_RAB release command message received from S1AP.
+ *\param msg_p Message received by RRC.
+ *\param msg_name Message name.
+ *\param instance Message instance.
+ *\return 0 when successful, -1 if the UE index can not be retrieved.
+ */
+int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance);
+
+/*! \fn rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t*  const ue_context_pP, uint8_t xid )
+ *\brief send a S1AP dedicated E_RAB release response
+ *\param ctxt_pP contxt infirmation
+ *\param e_contxt_pP ue specific context at the eNB
+ *\param xid transaction identifier
+ *\return 0 when successful, -1 if the UE index can not be retrieved.
+ */
+int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t*  const ue_context_pP, uint8_t xid );
+
 #   endif
 # endif /* defined(ENABLE_USE_MME) */
 #endif /* RRC_ENB_S1AP_H_ */
diff --git a/openair2/RRC/LITE/rrc_eNB_UE_context.c b/openair2/RRC/LITE/rrc_eNB_UE_context.c
index 78f85a6da2cffeac00853e13964abcf3ae6bff20..0ae3d7ca151fbed5b997f51ac09b5bde03f1e0c6 100644
--- a/openair2/RRC/LITE/rrc_eNB_UE_context.c
+++ b/openair2/RRC/LITE/rrc_eNB_UE_context.c
@@ -136,6 +136,10 @@ rrc_eNB_allocate_new_UE_context(
 
   memset(new_p, 0, sizeof(struct rrc_eNB_ue_context_s));
   new_p->local_uid = uid_linear_allocator_new(rrc_instance_pP);
+  for(int i = 0; i < NB_RB_MAX; i++) {
+      new_p->ue_context.e_rab[i].xid = -1;
+      new_p->ue_context.modify_e_rab[i].xid = -1;
+  }
   return new_p;
 }
 
@@ -151,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;
+  }
 }
 
 
@@ -184,6 +202,7 @@ void rrc_eNB_remove_ue_context(
   rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_pP);
   uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid);
   free(ue_context_pP);
+  rrc_instance_pP->Nb_ue --;
   LOG_I(RRC,
         PROTOCOL_RRC_CTXT_UE_FMT" Removed UE context\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
diff --git a/openair2/RRC/LITE/vars.h b/openair2/RRC/LITE/vars.h
index fbf3ae1dff944696e7e1ef745e23315aaec83971..e3bab5f5eb48aa577400a62d92d1397ab2ed25cf 100644
--- a/openair2/RRC/LITE/vars.h
+++ b/openair2/RRC/LITE/vars.h
@@ -36,6 +36,8 @@
 #include "COMMON/mac_rrc_primitives.h"
 #include "LAYER2/MAC/defs.h"
 
+UE_PF_PO_t UE_PF_PO[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
+pthread_mutex_t ue_pf_po_mutex;
 UE_RRC_INST *UE_rrc_inst;
 #include "LAYER2/MAC/extern.h"
 #define MAX_U32 0xFFFFFFFF
@@ -236,4 +238,10 @@ float RSRQ_meas_mapping[35] = {
   -2
 };
 
+// only used for RRC connection re-establishment procedure TS36.331 5.3.7
+// [0]: current C-RNTI, [1]: prior C-RNTI
+// insert one when eNB received RRCConnectionReestablishmentRequest message
+// delete one when eNB received RRCConnectionReestablishmentComplete message
+uint16_t reestablish_rnti_map[NUMBER_OF_UE_MAX][2] = {{0}};
+
 #endif
diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c
index aacfa561fd62190031d5ea2d0ca9603ea390f109..4234bc373d70a725414c60706b97aa9b5bbe63ea 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB.c
+++ b/openair3/GTPV1-U/gtpv1u_eNB.c
@@ -767,6 +767,7 @@ gtpv1u_create_s1u_tunnel(
       gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB               = s1u_teid;
       gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_eNB_stack_session = stack_req.apiInfo.createTunnelEndPointInfo.hStackSession;
       gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_sgw               = create_tunnel_req_pP->sgw_S1u_teid[i];
+      gtpv1u_ue_data_p->num_bearers++;
       create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_teid;
 
     } else {
@@ -808,7 +809,88 @@ gtpv1u_create_s1u_tunnel(
   return 0;
 }
 
+int gtpv1u_update_s1u_tunnel(
+    const instance_t                              instanceP,
+    const gtpv1u_enb_create_tunnel_req_t * const  create_tunnel_req_pP,
+    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,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);
+  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_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
+  //-----------------------
+  bearers_total =gtpv1u_ue_data_new_p->num_bearers;
+  for(j = 0;j<GTPV1U_MAX_BEARERS_ID;j++){
+
+    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;
+
+}
 
 //-----------------------------------------------------------------------------
 static int gtpv1u_delete_s1u_tunnel(
diff --git a/openair3/GTPV1-U/gtpv1u_eNB_task.h b/openair3/GTPV1-U/gtpv1u_eNB_task.h
index 6f74c73a2926d0074cfca368845f7a797e1d28b3..5a7822fe8c7322e12a6a32d231cec8c6af1d1df6 100644
--- a/openair3/GTPV1-U/gtpv1u_eNB_task.h
+++ b/openair3/GTPV1-U/gtpv1u_eNB_task.h
@@ -49,5 +49,9 @@ gtpv1u_create_s1u_tunnel(
   const gtpv1u_enb_create_tunnel_req_t *  const create_tunnel_req_pP,
         gtpv1u_enb_create_tunnel_resp_t * const create_tunnel_resp_pP);
 
-
+int
+gtpv1u_update_s1u_tunnel(
+    const instance_t                              instanceP,
+    const gtpv1u_enb_create_tunnel_req_t * const  create_tunnel_req_pP,
+    const rnti_t                                  prior_rnti);
 #endif /* GTPV1U_ENB_TASK_H_ */
diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c
index 08a18b629e0f58ccd075247f83c8832885a78230..aba32aa494cf41049669a2a096892fc5470296e1 100644
--- a/openair3/S1AP/s1ap_eNB.c
+++ b/openair3/S1AP/s1ap_eNB.c
@@ -364,6 +364,12 @@ void *s1ap_eNB_task(void *arg)
 				&S1AP_E_RAB_SETUP_RESP(received_msg));
     }
     break;
+
+    case S1AP_E_RAB_MODIFY_RESP: {
+      s1ap_eNB_e_rab_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+        &S1AP_E_RAB_MODIFY_RESP(received_msg));
+    }
+    break;
       
     case S1AP_NAS_NON_DELIVERY_IND: {
       s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
@@ -397,6 +403,12 @@ void *s1ap_eNB_task(void *arg)
     }
     break;
 
+   case S1AP_E_RAB_RELEASE_RESPONSE: {
+        s1ap_eNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+                                    &S1AP_E_RAB_RELEASE_RESPONSE(received_msg));
+    }
+    break;
+
     default:
       S1AP_ERROR("Received unhandled message: %d:%s\n",
                  ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c
index f8daf6c67a7582983e26505a3a63699c5e9ef000..eac52c53ba6fc52cf13340267630a41d1de68c8c 100644
--- a/openair3/S1AP/s1ap_eNB_decoder.c
+++ b/openair3/S1AP/s1ap_eNB_decoder.c
@@ -108,7 +108,15 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
     ret = s1ap_decode_s1ap_pagingies(
             &message->msg.s1ap_PagingIEs, &initiating_p->value);
     s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message);
-    S1AP_ERROR("TODO Paging initiating message\n");
+    message_id = S1AP_PAGING_LOG;
+    message_string_size = strlen(message_string);
+    message_p           = itti_alloc_new_message_sized(TASK_S1AP,
+                          message_id,
+                          message_string_size + sizeof (IttiMsgText));
+    message_p->ittiMsg.s1ap_paging_log.size = message_string_size;
+    memcpy(&message_p->ittiMsg.s1ap_paging_log.text, message_string, message_string_size);
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+    S1AP_INFO("Paging initiating message\n");
     free(message_string);
     break;
 
@@ -128,12 +136,36 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
     free(message_string);
     S1AP_INFO("E_RABSetup initiating message\n");
     break;
+
+  case S1ap_ProcedureCode_id_E_RABModify:
+    ret = s1ap_decode_s1ap_e_rabmodifyrequesties(
+            &message->msg.s1ap_E_RABModifyRequestIEs, &initiating_p->value);
+    message_id = S1AP_E_RAB_MODIFY_REQUEST_LOG;
+    message_string_size = strlen(message_string);
+    message_p           = itti_alloc_new_message_sized(TASK_S1AP,
+                          message_id,
+                          message_string_size + sizeof (IttiMsgText));
+    message_p->ittiMsg.s1ap_e_rab_modify_request_log.size = message_string_size;
+    memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_request_log.text, message_string, message_string_size);
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+    free(message_string);
+    S1AP_INFO("E_RABModify initiating message\n");
+    break;
+
   case S1ap_ProcedureCode_id_E_RABRelease:
-    ret = s1ap_decode_s1ap_e_rabreleasecommandies(&message->msg.s1ap_E_RABReleaseCommandIEs, 
-						 &initiating_p->value);
-    //s1ap_xer_print_s1ap_e_rabsetuprequest(s1ap_xer__print2sp, message_string, message);
-    S1AP_INFO("TODO  E_RABRelease nitiating message\n");
+    ret = s1ap_decode_s1ap_e_rabreleasecommandies(
+            &message->msg.s1ap_E_RABReleaseCommandIEs, &initiating_p->value);
+    s1ap_xer_print_s1ap_e_rabreleasecommand(s1ap_xer__print2sp, message_string, message);
+    message_id = S1AP_E_RAB_RELEASE_REQUEST_LOG;
+    message_string_size = strlen(message_string);
+    message_p           = itti_alloc_new_message_sized(TASK_S1AP,
+                          message_id,
+                          message_string_size + sizeof (IttiMsgText));
+    message_p->ittiMsg.s1ap_e_rab_release_request_log.size = message_string_size;
+    memcpy(&message_p->ittiMsg.s1ap_e_rab_release_request_log.text, message_string, message_string_size);
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
     free(message_string);
+    S1AP_INFO("TODO  E_RABRelease nitiating message\n");    
     break;
 
   default:
diff --git a/openair3/S1AP/s1ap_eNB_encoder.c b/openair3/S1AP/s1ap_eNB_encoder.c
index 4ab2f1f317f2cbee3f55404c53ed705cce10f158..9a5f422158dc592d685935d01bdbff06c17095c0 100644
--- a/openair3/S1AP/s1ap_eNB_encoder.c
+++ b/openair3/S1AP/s1ap_eNB_encoder.c
@@ -100,6 +100,16 @@ int s1ap_eNB_encode_e_rab_setup_response(S1ap_E_RABSetupResponseIEs_t  *E_RABSet
 					 uint8_t                              **buffer,
 					 uint32_t                              *length);
 
+static inline
+int s1ap_eNB_encode_e_rab_modify_response(S1ap_E_RABModifyResponseIEs_t  *E_RABModifyResponseIEs,
+           uint8_t                              **buffer,
+           uint32_t                              *length);
+
+static inline
+int s1ap_eNB_encode_e_rab_release_response(S1ap_E_RABReleaseResponseIEs_t  *s1ap_E_RABReleaseResponseIEs,
+                     uint8_t                              **buffer,
+                     uint32_t                              *length);
+
 int s1ap_eNB_encode_pdu(s1ap_message *message, uint8_t **buffer, uint32_t *len)
 {
   DevAssert(message != NULL);
@@ -264,6 +274,32 @@ int s1ap_eNB_encode_successfull_outcome(s1ap_message *s1ap_message_p,
     free(message_string);
     S1AP_INFO("E_RABSetup successful message\n");
     break;
+
+  case S1ap_ProcedureCode_id_E_RABModify:
+    ret = s1ap_eNB_encode_e_rab_modify_response (
+           &s1ap_message_p->msg.s1ap_E_RABModifyResponseIEs, buffer, len);
+    message_id =  S1AP_E_RAB_MODIFY_RESPONSE_LOG ;
+    message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
+    message_p->ittiMsg.s1ap_e_rab_modify_response_log.size = message_string_size;
+    memcpy(&message_p->ittiMsg.s1ap_e_rab_modify_response_log.text, message_string, message_string_size);
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+    free(message_string);
+    S1AP_INFO("E_RABModify successful message\n");
+    break;
+
+  case S1ap_ProcedureCode_id_E_RABRelease:
+    ret = s1ap_eNB_encode_e_rab_release_response (
+           &s1ap_message_p->msg.s1ap_E_RABReleaseResponseIEs, buffer, len);
+    s1ap_xer_print_s1ap_e_rabreleaseresponse(s1ap_xer__print2sp, message_string, s1ap_message_p);
+    message_id =  S1AP_E_RAB_RELEASE_RESPONSE_LOG ;
+    message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText));
+    message_p->ittiMsg.s1ap_e_rab_release_response_log.size = message_string_size;
+    memcpy(&message_p->ittiMsg.s1ap_e_rab_release_response_log.text, message_string, message_string_size);
+    itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p);
+    free(message_string);
+    S1AP_INFO("E_RAB Release successful message\n");
+    break;
+
   default:
     S1AP_WARN("Unknown procedure ID (%d) for successfull outcome message\n",
                (int)s1ap_message_p->procedureCode);
@@ -563,3 +599,48 @@ int s1ap_eNB_encode_e_rab_setup_response(S1ap_E_RABSetupResponseIEs_t  *s1ap_E_R
          &asn_DEF_S1ap_E_RABSetupResponse,
          e_rab_setup_response_p);
 }
+
+static inline
+int s1ap_eNB_encode_e_rab_modify_response(S1ap_E_RABModifyResponseIEs_t  *s1ap_E_RABModifyResponseIEs,
+           uint8_t                              **buffer,
+           uint32_t                              *length)
+{
+  S1ap_E_RABModifyResponse_t  e_rab_modify_response;
+  S1ap_E_RABModifyResponse_t  *e_rab_modify_response_p = &e_rab_modify_response;
+
+  memset((void *)e_rab_modify_response_p, 0,
+         sizeof(e_rab_modify_response));
+
+  if (s1ap_encode_s1ap_e_rabmodifyresponseies (e_rab_modify_response_p, s1ap_E_RABModifyResponseIEs) < 0) {
+    return -1;
+  }
+
+  return s1ap_generate_successfull_outcome(buffer,
+         length,
+         S1ap_ProcedureCode_id_E_RABModify,
+         S1ap_Criticality_reject,
+         &asn_DEF_S1ap_E_RABModifyResponse,
+         e_rab_modify_response_p);
+}
+static inline
+int s1ap_eNB_encode_e_rab_release_response(S1ap_E_RABReleaseResponseIEs_t  *s1ap_E_RABReleaseResponseIEs,
+                     uint8_t                              **buffer,
+                     uint32_t                              *length)
+{
+    S1ap_E_RABReleaseResponse_t  e_rab_release_response;
+    S1ap_E_RABReleaseResponse_t  *e_rab_release_response_p = &e_rab_release_response;
+
+  memset((void *)e_rab_release_response_p, 0,
+         sizeof(e_rab_release_response));
+
+  if (s1ap_encode_s1ap_e_rabreleaseresponseies (e_rab_release_response_p, s1ap_E_RABReleaseResponseIEs) < 0) {
+    return -1;
+  }
+
+  return s1ap_generate_successfull_outcome(buffer,
+         length,
+         S1ap_ProcedureCode_id_E_RABRelease,
+         S1ap_Criticality_reject,
+         &asn_DEF_S1ap_E_RABReleaseResponse,
+         e_rab_release_response_p);
+}
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index 186f034644eda4802ee90aa58fc124827b444a0e..0b02fc6db9ee4c0580ec108bdeb50bd162372d52 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -81,6 +81,20 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t               assoc_id,
 					uint32_t               stream,
 					struct s1ap_message_s *s1ap_message_p);
 
+static
+int s1ap_eNB_handle_paging(uint32_t               assoc_id,
+    uint32_t               stream,
+    struct s1ap_message_s *message_p);
+
+static
+int s1ap_eNB_handle_e_rab_modify_request(uint32_t               assoc_id,
+    uint32_t               stream,
+    struct s1ap_message_s *s1ap_message_p);
+
+static
+int s1ap_eNB_handle_e_rab_release_command(uint32_t               assoc_id,
+    uint32_t               stream,
+    struct s1ap_message_s *s1ap_message_p);
 
 /* Handlers matrix. Only eNB related procedure present here */
 s1ap_message_decoded_callback messages_callback[][3] = {
@@ -90,11 +104,11 @@ s1ap_message_decoded_callback messages_callback[][3] = {
   { 0, 0, 0 }, /* PathSwitchRequest */
   { 0, 0, 0 }, /* HandoverCancel */
   { s1ap_eNB_handle_e_rab_setup_request, 0, 0 }, /* E_RABSetup */
-  { 0, 0, 0 }, /* E_RABModify */
-  { 0, 0, 0 }, /* E_RABRelease */
+  { s1ap_eNB_handle_e_rab_modify_request, 0, 0 }, /* E_RABModify */
+  { s1ap_eNB_handle_e_rab_release_command, 0, 0 }, /* E_RABRelease */
   { 0, 0, 0 }, /* E_RABReleaseIndication */
   { s1ap_eNB_handle_initial_context_request, 0, 0 }, /* InitialContextSetup */
-  { 0, 0, 0 }, /* Paging */
+  { s1ap_eNB_handle_paging, 0, 0 }, /* Paging */
   { s1ap_eNB_handle_nas_downlink, 0, 0 }, /* downlinkNASTransport */
   { 0, 0, 0 }, /* initialUEMessage */
   { 0, 0, 0 }, /* uplinkNASTransport */
@@ -950,7 +964,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t               assoc_id,
       S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = NULL;
       
       S1AP_WARN("NAS PDU is not provided, generate a E_RAB_SETUP Failure (TBD) back to MME \n");
-      return -1;
+      // return -1;
     }
 
     /* Set the transport layer address */
@@ -983,4 +997,382 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t               assoc_id,
   return 0;
 }
 
+static
+int s1ap_eNB_handle_paging(uint32_t               assoc_id,
+    uint32_t               stream,
+    struct s1ap_message_s *s1ap_message_p)
+{
+  S1ap_PagingIEs_t *paging_p;
+  s1ap_eNB_mme_data_t   *mme_desc_p        = NULL;
+  s1ap_eNB_instance_t   *s1ap_eNB_instance = NULL;
+  MessageDef            *message_p         = NULL;
+
+  DevAssert(s1ap_message_p != NULL);
+  // received Paging Message from MME
+  S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id);
+
+  paging_p = &s1ap_message_p->msg.s1ap_PagingIEs;
+
+  /* Paging procedure -> stream != 0 */
+  if (stream == 0) {
+    S1AP_ERROR("[SCTP %d] Received Paging procedure on stream (%d)\n",
+               assoc_id, stream);
+    return -1;
+  }
+
+  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
+    S1AP_ERROR("[SCTP %d] Received Paging for non "
+               "existing MME context\n", assoc_id);
+    return -1;
+  }
+
+  s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance;
+  if (s1ap_eNB_instance == NULL) {
+    S1AP_ERROR("[SCTP %d] Received Paging for non existing MME context : s1ap_eNB_instance is NULL\n",
+               assoc_id);
+    return -1;
+  }
+
+  message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PAGING_IND);
+
+  /* convert S1ap_PagingIEs_t to s1ap_paging_ind_t */
+  /* convert UE Identity Index value */
+  S1AP_PAGING_IND(message_p).ue_index_value  = BIT_STRING_to_uint32(&paging_p->ueIdentityIndexValue);
+  S1AP_DEBUG("[SCTP %d] Received Paging ue_index_value (%d)\n",
+            assoc_id,(uint32_t)S1AP_PAGING_IND(message_p).ue_index_value);
+
+  S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0;
+  S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0;
+
+  /* convert UE Paging Identity */
+  if (paging_p->uePagingID.present == S1ap_UEPagingID_PR_s_TMSI) {
+      S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_s_tmsi;
+      OCTET_STRING_TO_INT8(&paging_p->uePagingID.choice.s_TMSI.mMEC, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code);
+      OCTET_STRING_TO_INT32(&paging_p->uePagingID.choice.s_TMSI.m_TMSI, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi);
+  } else if (paging_p->uePagingID.present == S1ap_UEPagingID_PR_iMSI) {
+      S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_imsi;
+      S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length = 0;
+      for (int i = 0; i < paging_p->uePagingID.choice.iMSI.size; i++) {
+          S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i] = (uint8_t)(paging_p->uePagingID.choice.iMSI.buf[i] & 0x0F );
+          S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++;
+          S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] = (uint8_t)((paging_p->uePagingID.choice.iMSI.buf[i]>>4) & 0x0F);
+          LOG_D(S1AP,"paging : i %d %d imsi %d %d \n",2*i,2*i+1,S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1]);
+          if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2*i+1] == 0x0F) {
+              if(i != paging_p->uePagingID.choice.iMSI.size - 1){
+                  /* invalid paging_p->uePagingID.choise.iMSI.buffer */
+                  S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI error(i %d 0x0F)\n", assoc_id,i);
+                  return -1;
+              }
+          } else {
+              S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length++;
+          }
+      }
+      if (S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length >= S1AP_IMSI_LENGTH) {
+          /* invalid paging_p->uePagingID.choise.iMSI.size */
+          S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.choise.iMSI.size(%d) is over IMSI length(%d)\n", assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length, S1AP_IMSI_LENGTH);
+          return -1;
+      }  
+} else {
+      /* invalid paging_p->uePagingID.present */
+      S1AP_ERROR("[SCTP %d] Received Paging : uePagingID.present(%d) is unknown\n", assoc_id, paging_p->uePagingID.present);
+      return -1;
+  }
+
+#if 0
+  /* convert Paging DRX(optional) */
+  if (paging_p->presenceMask & S1AP_PAGINGIES_PAGINGDRX_PRESENT) {
+      switch(paging_p->pagingDRX) {
+        case S1ap_PagingDRX_v32:
+          S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_32;
+         break;
+        case S1ap_PagingDRX_v64:
+          S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_64;
+        break;
+        case S1ap_PagingDRX_v128:
+          S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_128;
+        break;
+        case S1ap_PagingDRX_v256:
+          S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
+        break;
+        default:
+          // when UE Paging DRX is no value
+          S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
+        break;
+      }
+  }
+#endif
+  S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256;
+
+  /* convert cnDomain */
+  if (paging_p->cnDomain == S1ap_CNDomain_ps) {
+      S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_PS;
+  } else if (paging_p->cnDomain == S1ap_CNDomain_cs) {
+      S1AP_PAGING_IND(message_p).cn_domain = CN_DOMAIN_CS;
+  } else {
+      /* invalid paging_p->cnDomain */
+      S1AP_ERROR("[SCTP %d] Received Paging : cnDomain(%ld) is unknown\n", assoc_id, paging_p->cnDomain);
+      return -1;
+  }
+
+  memset (&S1AP_PAGING_IND(message_p).plmn_identity[0], 0, sizeof(plmn_identity_t)*256);
+  memset (&S1AP_PAGING_IND(message_p).tac[0], 0, sizeof(int16_t)*256);
+  S1AP_PAGING_IND(message_p).tai_size = 0;
+
+  for (int i = 0; i < paging_p->taiList.s1ap_TAIItem.count; i++) {
+     S1AP_INFO("[SCTP %d] Received Paging taiList: i %d, count %d\n", assoc_id, i, paging_p->taiList.s1ap_TAIItem.count);
+     S1ap_TAIItem_t s1ap_TAIItem;
+     memset (&s1ap_TAIItem, 0, sizeof(S1ap_TAIItem_t));
+
+     memcpy(&s1ap_TAIItem, paging_p->taiList.s1ap_TAIItem.array[i], sizeof(S1ap_TAIItem_t));
+
+     TBCD_TO_MCC_MNC(&s1ap_TAIItem.tAI.pLMNidentity, S1AP_PAGING_IND(message_p).plmn_identity[i].mcc,
+              S1AP_PAGING_IND(message_p).plmn_identity[i].mnc,
+              S1AP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length);
+     OCTET_STRING_TO_INT16(&s1ap_TAIItem.tAI.tAC, S1AP_PAGING_IND(message_p).tac[i]);
+     S1AP_PAGING_IND(message_p).tai_size++;
+     S1AP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id, S1AP_PAGING_IND(message_p).plmn_identity[i].mcc, S1AP_PAGING_IND(message_p).plmn_identity[i].mnc, S1AP_PAGING_IND(message_p).tac[i]);
+  }
+
+#if 0
+ // CSG Id(optional) List is not used
+  if (paging_p->presenceMask & S1AP_PAGINGIES_CSG_IDLIST_PRESENT) {
+      // TODO
+  }
+
+  /* convert pagingPriority (optional) if has value */
+  if (paging_p->presenceMask & S1AP_PAGINGIES_PAGINGPRIORITY_PRESENT) {
+      switch(paging_p->pagingPriority) {
+      case S1ap_PagingPriority_priolevel1:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL1;
+        break;
+      case S1ap_PagingPriority_priolevel2:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL2;
+        break;
+      case S1ap_PagingPriority_priolevel3:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL3;
+        break;
+      case S1ap_PagingPriority_priolevel4:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL4;
+        break;
+      case S1ap_PagingPriority_priolevel5:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL5;
+        break;
+      case S1ap_PagingPriority_priolevel6:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL6;
+        break;
+      case S1ap_PagingPriority_priolevel7:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL7;
+        break;
+      case S1ap_PagingPriority_priolevel8:
+          S1AP_PAGING_IND(message_p).paging_priority = PAGING_PRIO_LEVEL8;
+        break;
+      default:
+        /* invalid paging_p->pagingPriority */
+        S1AP_ERROR("[SCTP %d] Received paging : pagingPriority(%ld) is invalid\n", assoc_id, paging_p->pagingPriority);
+        return -1;
+      }
+  }
+#endif
+  //paging parameter values
+  S1AP_DEBUG("[SCTP %d] Received Paging parameters: ue_index_value %d  cn_domain %d paging_drx %d paging_priority %d\n",assoc_id,
+          S1AP_PAGING_IND(message_p).ue_index_value, S1AP_PAGING_IND(message_p).cn_domain,
+          S1AP_PAGING_IND(message_p).paging_drx, S1AP_PAGING_IND(message_p).paging_priority);
+  S1AP_DEBUG("[SCTP %d] Received Paging parameters(ue): presenceMask %d  s_tmsi.m_tmsi %d s_tmsi.mme_code %d IMSI length %d (0-5) %d%d%d%d%d%d\n",assoc_id,
+          S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi,
+          S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.length,
+          S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[0], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[1],
+          S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[3],
+          S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[4], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[5]);
+
+  /* send message to RRC */
+  itti_send_msg_to_task(TASK_RRC_ENB, s1ap_eNB_instance->instance, message_p);
+  
+   return 0;
+}
+
+static
+int s1ap_eNB_handle_e_rab_modify_request(uint32_t               assoc_id,
+          uint32_t               stream,
+          struct s1ap_message_s *s1ap_message_p) {
+
+  int i;
+
+  s1ap_eNB_mme_data_t   *mme_desc_p       = NULL;
+  s1ap_eNB_ue_context_t *ue_desc_p        = NULL;
+  MessageDef            *message_p        = NULL;
+  int nb_of_e_rabs_failed = 0;
+
+  S1ap_E_RABModifyRequestIEs_t         *s1ap_E_RABModifyRequest;
+  DevAssert(s1ap_message_p != NULL);
+
+  s1ap_E_RABModifyRequest = &s1ap_message_p->msg.s1ap_E_RABModifyRequestIEs;
+
+  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
+    S1AP_ERROR("[SCTP %d] Received E-RAB modify request for non "
+               "existing MME context\n", assoc_id);
+    return -1;
+  }
+
+
+  if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
+                   s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID)) == NULL) {
+    S1AP_ERROR("[SCTP %d] Received E-RAB modify request for non "
+               "existing UE context 0x%06lx\n", assoc_id,
+               s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID);
+    return -1;
+  }
 
+  /* E-RAB modify request = UE-related procedure -> stream != 0 */
+  if (stream == 0) {
+    S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
+               assoc_id, stream);
+    return -1;
+  }
+
+  ue_desc_p->rx_stream = stream;
+
+  if ( ue_desc_p->mme_ue_s1ap_id != s1ap_E_RABModifyRequest->mme_ue_s1ap_id){
+    S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)",
+        ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABModifyRequest->mme_ue_s1ap_id);
+    message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP);
+
+    S1AP_E_RAB_MODIFY_RESP (message_p).eNB_ue_s1ap_id = s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID;
+//        S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB];
+    S1AP_E_RAB_MODIFY_RESP (message_p).nb_of_e_rabs = 0;
+
+    for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count; nb_of_e_rabs_failed++) {
+      S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id =
+            ((S1ap_E_RABToBeModifiedItemBearerModReq_t *)s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.array[nb_of_e_rabs_failed])->e_RAB_ID;
+      S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK;
+      S1AP_E_RAB_MODIFY_RESP (message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = 13;//S1ap_CauseRadioNetwork_unknown_mme_ue_s1ap_id;
+    }
+    S1AP_E_RAB_MODIFY_RESP (message_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed;
+
+    s1ap_eNB_e_rab_modify_resp(mme_desc_p->s1ap_eNB_instance->instance,
+                               &S1AP_E_RAB_MODIFY_RESP(message_p));
+
+    message_p = NULL;
+    return -1;
+  }
+
+  message_p        = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_MODIFY_REQ);
+
+  S1AP_E_RAB_MODIFY_REQ(message_p).ue_initial_id  = ue_desc_p->ue_initial_id;
+
+  S1AP_E_RAB_MODIFY_REQ(message_p).mme_ue_s1ap_id  = s1ap_E_RABModifyRequest->mme_ue_s1ap_id;
+  S1AP_E_RAB_MODIFY_REQ(message_p).eNB_ue_s1ap_id  = s1ap_E_RABModifyRequest->eNB_UE_S1AP_ID;
+
+  S1AP_E_RAB_MODIFY_REQ(message_p).nb_e_rabs_tomodify =
+    s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count;
+
+  for (i = 0; i < s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.count; i++) {
+    S1ap_E_RABToBeModifiedItemBearerModReq_t *item_p;
+
+    item_p = (S1ap_E_RABToBeModifiedItemBearerModReq_t *)s1ap_E_RABModifyRequest->e_RABToBeModifiedListBearerModReq.s1ap_E_RABToBeModifiedItemBearerModReq.array[i];
+
+    S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].e_rab_id = item_p->e_RAB_ID;
+
+    // check for the NAS PDU
+    if (item_p->nAS_PDU.size > 0 ) {
+      S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = item_p->nAS_PDU.size;
+
+      S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size);
+
+      memcpy(S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer,
+             item_p->nAS_PDU.buf, item_p->nAS_PDU.size);
+    } else {
+      S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = 0;
+      S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = NULL;
+      continue;
+    }
+
+    /* Set the QOS informations */
+    S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.qci = item_p->e_RABLevelQoSParameters.qCI;
+
+    S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.priority_level =
+      item_p->e_RABLevelQoSParameters.allocationRetentionPriority.priorityLevel;
+    S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_capability =
+      item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionCapability;
+    S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_vulnerability =
+      item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability;
+
+  }
+
+  itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
+
+  return 0;
+}
+// handle e-rab release command and send it to rrc_end
+static
+int s1ap_eNB_handle_e_rab_release_command(uint32_t               assoc_id,
+                                          uint32_t               stream,
+                                          struct s1ap_message_s *s1ap_message_p) {
+
+  int i;
+
+  s1ap_eNB_mme_data_t   *mme_desc_p       = NULL;
+  s1ap_eNB_ue_context_t *ue_desc_p        = NULL;
+  MessageDef            *message_p        = NULL;
+
+  S1ap_E_RABReleaseCommandIEs_t         *s1ap_E_RABReleaseCommand;
+  DevAssert(s1ap_message_p != NULL);
+  s1ap_E_RABReleaseCommand = &s1ap_message_p->msg.s1ap_E_RABReleaseCommandIEs;
+  
+  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
+    S1AP_ERROR("[SCTP %d] Received E-RAB release command for non existing MME context\n", assoc_id);
+    return -1;
+  }
+  if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance,
+          s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID)) == NULL) {
+    S1AP_ERROR("[SCTP %d] Received E-RAB release command for non existing UE context 0x%06lx\n", assoc_id,
+               s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID);
+    return -1;
+  }
+
+  /* Initial context request = UE-related procedure -> stream != 0 */
+  if (stream == 0) {
+    S1AP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
+               assoc_id, stream);
+    return -1;
+  }
+
+  ue_desc_p->rx_stream = stream;
+
+  if ( ue_desc_p->mme_ue_s1ap_id != s1ap_E_RABReleaseCommand->mme_ue_s1ap_id){
+    S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)",
+          ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABReleaseCommand->mme_ue_s1ap_id);
+  }
+
+  S1AP_DEBUG("[SCTP %d] Received E-RAB release command for eNB_UE_S1AP_ID %ld mme_ue_s1ap_id %ld\n",
+          assoc_id, s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID, s1ap_E_RABReleaseCommand->mme_ue_s1ap_id);
+
+  message_p        = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_RELEASE_COMMAND);
+
+  S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = s1ap_E_RABReleaseCommand->eNB_UE_S1AP_ID;
+  S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = s1ap_E_RABReleaseCommand->mme_ue_s1ap_id;
+  if(s1ap_E_RABReleaseCommand->nas_pdu.size > 0 ){
+    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = s1ap_E_RABReleaseCommand->nas_pdu.size;
+
+    S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer =
+      malloc(sizeof(uint8_t) * s1ap_E_RABReleaseCommand->nas_pdu.size);
+
+    memcpy(S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer,
+    		s1ap_E_RABReleaseCommand->nas_pdu.buf,
+    		s1ap_E_RABReleaseCommand->nas_pdu.size);
+  } else {
+	  S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = 0;
+	  S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL;
+  }
+
+  S1AP_E_RAB_RELEASE_COMMAND(message_p).nb_e_rabs_torelease = s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.count;
+  for(i=0; i < s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.count; i++){
+	  S1ap_E_RABItem_t *item_p;
+	  item_p = (S1ap_E_RABItem_t*)s1ap_E_RABReleaseCommand->e_RABToBeReleasedList.s1ap_E_RABItem.array[i];
+	  S1AP_E_RAB_RELEASE_COMMAND(message_p).e_rab_release_params[i].e_rab_id = item_p->e_RAB_ID;
+	  S1AP_DEBUG("[SCTP] Received E-RAB release command for e-rab id %ld\n", item_p->e_RAB_ID);
+  }
+
+  itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
+
+  return 0;
+}
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index ea0dbcb70af653217564fec618977d56de8fb686..d6d9b52c07a2cd6719b9bc63fbcda72bf4d11c4a 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -837,3 +837,282 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance,
 
   return ret;
 }
+
+//------------------------------------------------------------------------------
+int s1ap_eNB_e_rab_modify_resp(instance_t instance,
+            s1ap_e_rab_modify_resp_t *e_rab_modify_resp_p)
+//------------------------------------------------------------------------------
+{
+  s1ap_eNB_instance_t          *s1ap_eNB_instance_p = NULL;
+  struct s1ap_eNB_ue_context_s *ue_context_p        = NULL;
+
+  S1ap_E_RABModifyResponseIEs_t  *initial_ies_p  = NULL;
+
+  s1ap_message  message;
+
+  uint8_t  *buffer  = NULL;
+  uint32_t length;
+  int      ret = -1;
+  int      i;
+
+  /* Retrieve the S1AP eNB instance associated with Mod_id */
+  s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
+
+  DevAssert(e_rab_modify_resp_p != NULL);
+  DevAssert(s1ap_eNB_instance_p != NULL);
+
+  if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
+                e_rab_modify_resp_p->eNB_ue_s1ap_id)) == NULL) {
+    /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
+    S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n",
+              e_rab_modify_resp_p->eNB_ue_s1ap_id);
+    return -1;
+  }
+
+  /* Uplink NAS transport can occur either during an s1ap connected state
+   * or during initial attach (for example: NAS authentication).
+   */
+  if (!(ue_context_p->ue_state == S1AP_UE_CONNECTED ||
+        ue_context_p->ue_state == S1AP_UE_WAITING_CSR)) {
+    S1AP_WARN("You are attempting to send NAS data over non-connected "
+              "eNB ue s1ap id: %06x, current state: %d\n",
+              e_rab_modify_resp_p->eNB_ue_s1ap_id, ue_context_p->ue_state);
+    return -1;
+  }
+
+  /* Prepare the S1AP message to encode */
+  memset(&message, 0, sizeof(s1ap_message));
+
+  message.direction     = S1AP_PDU_PR_successfulOutcome;
+  message.procedureCode = S1ap_ProcedureCode_id_E_RABModify;
+  message.criticality   = S1ap_Criticality_reject;
+
+  initial_ies_p = &message.msg.s1ap_E_RABModifyResponseIEs;
+
+  initial_ies_p->eNB_UE_S1AP_ID = e_rab_modify_resp_p->eNB_ue_s1ap_id;
+  initial_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
+
+  if ( e_rab_modify_resp_p->nb_of_e_rabs >= 1 )
+    initial_ies_p->presenceMask |= S1AP_E_RABMODIFYRESPONSEIES_E_RABMODIFYLISTBEARERMODRES_PRESENT;
+
+  for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs; i++) {
+    S1ap_E_RABModifyItemBearerModRes_t *modify_item;
+
+    modify_item = calloc(1, sizeof(S1ap_E_RABModifyItemBearerModRes_t));
+
+    modify_item->e_RAB_ID = e_rab_modify_resp_p->e_rabs[i].e_rab_id;
+
+    S1AP_DEBUG("e_rab_modify_resp: modified e_rab ID %ld\n",
+        modify_item->e_RAB_ID);
+
+    S1ap_IE_t *ie = s1ap_new_ie(S1ap_ProtocolIE_ID_id_E_RABModifyItemBearerModRes,
+        S1ap_Criticality_ignore,
+        &asn_DEF_S1ap_E_RABModifyItemBearerModRes,
+        modify_item);
+
+    ASN_SEQUENCE_ADD(&initial_ies_p->e_RABModifyListBearerModRes.s1ap_E_RABModifyItemBearerModRes,
+                     ie);
+  }
+
+  if ( e_rab_modify_resp_p->nb_of_e_rabs_failed >= 1 )
+    initial_ies_p->presenceMask |= S1AP_E_RABMODIFYRESPONSEIES_E_RABFAILEDTOMODIFYLIST_PRESENT;
+
+  for (i = 0; i < e_rab_modify_resp_p->nb_of_e_rabs_failed; i++) {
+    S1ap_E_RABItem_t *failed_item;
+
+    failed_item = calloc(1, sizeof(S1ap_E_RABItem_t));
+
+    failed_item->e_RAB_ID = e_rab_modify_resp_p->e_rabs_failed[i].e_rab_id;
+    switch(e_rab_modify_resp_p->e_rabs_failed[i].cause)
+    {
+    case S1AP_CAUSE_RADIO_NETWORK:
+        failed_item->cause.present = S1ap_Cause_PR_radioNetwork;
+        failed_item->cause.choice.radioNetwork = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
+        break;
+    case S1AP_CAUSE_TRANSPORT:
+        failed_item->cause.present = S1ap_Cause_PR_transport;
+        failed_item->cause.choice.transport = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
+        break;
+    case S1AP_CAUSE_NAS:
+        failed_item->cause.present = S1ap_Cause_PR_nas;
+        failed_item->cause.choice.nas = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
+        break;
+    case S1AP_CAUSE_PROTOCOL:
+        failed_item->cause.present = S1ap_Cause_PR_protocol;
+        failed_item->cause.choice.protocol = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
+        break;
+    case S1AP_CAUSE_MISC:
+        failed_item->cause.present = S1ap_Cause_PR_misc;
+        failed_item->cause.choice.misc = e_rab_modify_resp_p->e_rabs_failed[i].cause_value;
+        break;
+    default:
+        break;
+    }
+    S1AP_DEBUG("e_rab_modify_resp: failed e_rab ID %ld\n",
+        failed_item->e_RAB_ID);
+
+    S1ap_IE_t *ie = s1ap_new_ie(S1ap_ProtocolIE_ID_id_E_RABItem,
+        S1ap_Criticality_ignore,
+        &asn_DEF_S1ap_E_RABItem,
+        failed_item);
+
+    ASN_SEQUENCE_ADD(&initial_ies_p->e_RABFailedToModifyList.s1ap_E_RABItem,
+                     ie);
+  }
+
+  fprintf(stderr, "start encode\n");
+  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
+    S1AP_ERROR("Failed to encode uplink transport\n");
+    /* Encode procedure has failed... */
+    return -1;
+  }
+
+  MSC_LOG_TX_MESSAGE(
+    MSC_S1AP_ENB,
+    MSC_S1AP_MME,
+    (const char *)buffer,
+    length,
+    MSC_AS_TIME_FMT" E_RAN Modify successful Outcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
+    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+    initial_ies_p->eNB_UE_S1AP_ID,
+    initial_ies_p->mme_ue_s1ap_id);
+
+  /* UE associated signalling -> use the allocated stream */
+  s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
+                                   ue_context_p->mme_ref->assoc_id, buffer,
+                                   length, ue_context_p->tx_stream);
+
+  return ret;
+}
+//------------------------------------------------------------------------------
+int s1ap_eNB_e_rab_release_resp(instance_t instance,
+			      s1ap_e_rab_release_resp_t *e_rab_release_resp_p)
+//------------------------------------------------------------------------------
+{
+  s1ap_eNB_instance_t          *s1ap_eNB_instance_p = NULL;
+  struct s1ap_eNB_ue_context_s *ue_context_p        = NULL;
+
+  S1ap_E_RABReleaseResponseIEs_t  *release_response_ies_p  = NULL;
+
+  s1ap_message  message;
+
+  uint8_t  *buffer  = NULL;
+  uint32_t length;
+  int      ret = -1;
+  int      i;
+  /* Retrieve the S1AP eNB instance associated with Mod_id */
+  s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance);
+  DevAssert(e_rab_release_resp_p != NULL);
+  DevAssert(s1ap_eNB_instance_p != NULL);
+
+  /* Prepare the S1AP message to encode */
+  memset(&message, 0, sizeof(s1ap_message));
+
+  message.direction     = S1AP_PDU_PR_successfulOutcome;
+  message.procedureCode = S1ap_ProcedureCode_id_E_RABRelease;
+  message.criticality = S1ap_Criticality_ignore;
+
+  if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
+          e_rab_release_resp_p->eNB_ue_s1ap_id)) == NULL) {
+    /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */
+    S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n",
+            e_rab_release_resp_p->eNB_ue_s1ap_id);
+    return -1;
+  }
+
+  release_response_ies_p = &message.msg.s1ap_E_RABReleaseResponseIEs;
+  release_response_ies_p->eNB_UE_S1AP_ID = e_rab_release_resp_p->eNB_ue_s1ap_id;
+  release_response_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
+
+  if ( e_rab_release_resp_p->nb_of_e_rabs_released > 0 )
+      release_response_ies_p->presenceMask |= S1AP_E_RABRELEASERESPONSEIES_E_RABRELEASELISTBEARERRELCOMP_PRESENT;
+
+  //release
+  for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_released; i++) {
+
+    S1ap_E_RABReleaseItemBearerRelComp_t *new_item;
+
+    new_item = calloc(1, sizeof(S1ap_E_RABReleaseItemBearerRelComp_t));
+
+    new_item->e_RAB_ID = e_rab_release_resp_p->e_rab_release[i].e_rab_id;
+
+    S1AP_DEBUG("e_rab_release_resp: e_rab ID %ld\n",new_item->e_RAB_ID);
+
+    ASN_SEQUENCE_ADD(&release_response_ies_p->e_RABReleaseListBearerRelComp.s1ap_E_RABReleaseItemBearerRelComp,
+                     new_item);
+
+  }
+
+  if ( e_rab_release_resp_p->nb_of_e_rabs_failed > 0 )
+      release_response_ies_p->presenceMask |= S1AP_E_RABRELEASERESPONSEIES_E_RABFAILEDTORELEASELIST_PRESENT;
+
+  //release failed
+  for (i = 0; i < e_rab_release_resp_p->nb_of_e_rabs_failed; i++) {
+      S1ap_E_RABItem_t     *new_rabitem;
+      new_rabitem = calloc(1, sizeof(S1ap_E_RABItem_t));
+      //e_rab_id
+      new_rabitem->e_RAB_ID = e_rab_release_resp_p->e_rabs_failed[i].e_rab_id;
+      //cause
+      switch(e_rab_release_resp_p->e_rabs_failed[i].cause)
+      {
+        case S1AP_CAUSE_NOTHING:
+          new_rabitem->cause.present = S1ap_Cause_PR_NOTHING;
+        break;
+
+        case S1AP_CAUSE_RADIO_NETWORK:
+          new_rabitem->cause.present = S1ap_Cause_PR_radioNetwork;
+          new_rabitem->cause.choice.radioNetwork = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
+        break;
+
+        case S1AP_CAUSE_TRANSPORT:
+          new_rabitem->cause.present = S1ap_Cause_PR_transport;
+          new_rabitem->cause.choice.transport = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
+        break;
+
+        case S1AP_CAUSE_NAS:
+          new_rabitem->cause.present = S1ap_Cause_PR_nas;
+          new_rabitem->cause.choice.nas = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
+        break;
+
+        case S1AP_CAUSE_PROTOCOL:
+          new_rabitem->cause.present = S1ap_Cause_PR_protocol;
+          new_rabitem->cause.choice.protocol = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
+        break;
+
+        case S1AP_CAUSE_MISC:
+        default:
+          new_rabitem->cause.present = S1ap_Cause_PR_misc;
+          new_rabitem->cause.choice.misc = e_rab_release_resp_p->e_rabs_failed[i].cause_value;
+        break;
+      }
+      S1AP_DEBUG("e_rab_release_resp: failed e_rab ID %ld\n",new_rabitem->e_RAB_ID);
+      ASN_SEQUENCE_ADD(&release_response_ies_p->e_RABFailedToReleaseList.s1ap_E_RABItem, new_rabitem);
+  }
+
+  fprintf(stderr, "start encode\n");
+  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
+    S1AP_ERROR("Failed to encode release response\n");
+    /* Encode procedure has failed... */
+    return -1;
+  }
+
+  MSC_LOG_TX_MESSAGE(
+    MSC_S1AP_ENB,
+    MSC_S1AP_MME,
+    (const char *)buffer,
+    length,
+    MSC_AS_TIME_FMT" E_RAN Release successfulOutcome eNB_ue_s1ap_id %u mme_ue_s1ap_id %u",
+    0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
+    e_rab_release_resp_p->eNB_ue_s1ap_id,
+    ue_context_p->mme_ue_s1ap_id);
+
+  /* UE associated signalling -> use the allocated stream */
+  s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance,
+                                   ue_context_p->mme_ref->assoc_id, buffer,
+                                   length, ue_context_p->tx_stream);
+
+  S1AP_INFO("e_rab_release_response sended eNB_UE_S1AP_ID %d  mme_ue_s1ap_id %d nb_of_e_rabs_released %d nb_of_e_rabs_failed %d\n",
+          e_rab_release_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,e_rab_release_resp_p->nb_of_e_rabs_released,e_rab_release_resp_p->nb_of_e_rabs_failed);
+
+  return ret;
+}
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.h b/openair3/S1AP/s1ap_eNB_nas_procedures.h
index 269387257653e30efef12d630f58fd9b48bcde44..bb2a0488bfd898fb5ec87a62e0d205767c19d467 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.h
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.h
@@ -44,4 +44,9 @@ int s1ap_eNB_ue_capabilities(instance_t instance,
 int s1ap_eNB_e_rab_setup_resp(instance_t instance,
                               s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p);
 
+int s1ap_eNB_e_rab_modify_resp(instance_t instance,
+               s1ap_e_rab_modify_resp_t *e_rab_modify_resp_p);
+
+int s1ap_eNB_e_rab_release_resp(instance_t instance,
+                  s1ap_e_rab_release_resp_t *e_rab_release_resp_p);
 #endif /* S1AP_ENB_NAS_PROCEDURES_H_ */
diff --git a/openair3/SECU/kdf.c b/openair3/SECU/kdf.c
index 0717d17c59dbcac17a4e553eaa1c50902998bbc1..1073df8ebedf7f0e6a647b183122e394ce141982 100644
--- a/openair3/SECU/kdf.c
+++ b/openair3/SECU/kdf.c
@@ -63,3 +63,43 @@ int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB
 }
 #endif
 
+int derive_keNB_star(
+  const uint8_t *kenb_32,
+  const uint16_t pci,
+  const uint32_t earfcn_dl,
+  const bool     is_rel8_only,
+  uint8_t       *kenb_star)
+{
+  // see 33.401 section A.5 KeNB* derivation function
+  uint8_t                                 s[10] = {0};
+
+  // FC = 0x13
+  s[0] = FC_KENB_STAR;
+  // P0 = PCI (target physical cell id)
+  s[1] = (pci & 0x0000ff00) >> 8;
+  s[2] = (pci & 0x000000ff);
+  // L0 = length of PCI (i.e. 0x00 0x02)
+  s[3] = 0x00;
+  s[4] = 0x02;
+  // P1 = EARFCN-DL (target physical cell downlink frequency)
+  if (is_rel8_only) {
+    s[5] = (earfcn_dl & 0x0000ff00) >> 8;
+    s[6] = (earfcn_dl & 0x000000ff);
+	s[7] = 0x00;
+	s[8] = 0x02;
+	kdf (kenb_32, 32, s, 9, kenb_star, 32);
+  } else {
+	s[5] = (earfcn_dl & 0x00ff0000) >> 16;
+	s[6] = (earfcn_dl & 0x0000ff00) >> 8;
+	s[7] = (earfcn_dl & 0x000000ff);
+	s[8] = 0x00;
+	s[9] = 0x03;
+	kdf (kenb_32, 32, s, 10, kenb_star, 32);
+  }
+  // L1 length of EARFCN-DL (i.e. L1 = 0x00 0x02 if EARFCN-DL is between 0 and 65535, and L1 = 0x00 0x03 if EARFCN-DL is between 65536 and 262143)
+  // NOTE: The length of EARFCN-DL cannot be generally set to 3 bytes for backward compatibility reasons: A Rel-8
+  // entity (UE or eNB) would always assume an input parameter length of 2 bytes for the EARFCN-DL. This
+  // would lead to different derived keys if another entity assumed an input parameter length of 3 bytes for the
+  // EARFCN-DL.
+  return 0;
+}
diff --git a/openair3/SECU/secu_defs.h b/openair3/SECU/secu_defs.h
index 4130098c991199bc2ef916bb4680ac9c54f62a11..8ec05f3dafe58afeb6ddb5cd9c542c3818487e6c 100644
--- a/openair3/SECU/secu_defs.h
+++ b/openair3/SECU/secu_defs.h
@@ -23,6 +23,7 @@
 #define SECU_DEFS_H_
 
 #include "security_types.h"
+#include <stdbool.h>
 
 #define EIA0_ALG_ID     0x00
 #define EIA1_128_ALG_ID 0x01
@@ -44,6 +45,9 @@ void kdf(const uint8_t *key,
 
 int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t *keNB);
 
+int derive_keNB_star(const uint8_t *kenb_32, const uint16_t pci, const uint32_t earfcn_dl,
+                      const bool is_rel8_only, uint8_t * kenb_star);
+
 int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id,
                    const uint8_t kasme[32], uint8_t *knas);
 
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 792f16e92a1bcdf6aeb9f843170befeb4bb48962..04a8f72505aaab5cda5fbe4c33ddbc11b0235dcc 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -1188,6 +1188,10 @@ int main( int argc, char **argv )
     RCconfig_L1();
   }
 #endif
+
+    // init UE_PF_PO and mutex lock
+    pthread_mutex_init(&ue_pf_po_mutex, NULL);
+    memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
   
   
   mlockall(MCL_CURRENT | MCL_FUTURE);
@@ -1457,7 +1461,7 @@ int main( int argc, char **argv )
   pthread_cond_destroy(&nfapi_sync_cond);
   pthread_mutex_destroy(&nfapi_sync_mutex);
 
-
+  pthread_mutex_destroy(&ue_pf_po_mutex);
 
   // *** Handle per CC_id openair0
   if (UE_flag==1) {