diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h
index ce51ac78cad021f60a16bd746fdafc20e561e39f..b9f7a0d02f9ee60c39d971c2ba51170d90d4fdcf 100644
--- a/openair2/COMMON/s1ap_messages_def.h
+++ b/openair2/COMMON/s1ap_messages_def.h
@@ -58,12 +58,15 @@ MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_RESP   , MESSAGE_PRIORITY_MED, s1ap_ue_relea
 MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, s1ap_ue_release_complete_t      , s1ap_ue_release_complete)
 MESSAGE_DEF(S1AP_UE_CTXT_MODIFICATION_RESP , MESSAGE_PRIORITY_MED, s1ap_ue_ctxt_modification_resp_t , s1ap_ue_ctxt_modification_resp)
 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)
 
 /* S1AP -> RRC messages */
 MESSAGE_DEF(S1AP_DOWNLINK_NAS              , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t              , s1ap_downlink_nas )
 MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, s1ap_initial_context_setup_req_t , s1ap_initial_context_setup_req )
 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_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 c39725b737f1bb6c0750e1317046366b50679207..83c9ca64ca6e91b95a8af5e0be523974389f93c8 100644
--- a/openair2/COMMON/s1ap_messages_types.h
+++ b/openair2/COMMON/s1ap_messages_types.h
@@ -47,12 +47,15 @@
 #define S1AP_NAS_NON_DELIVERY_IND(mSGpTR)       (mSGpTR)->ittiMsg.s1ap_nas_non_delivery_ind
 #define S1AP_UE_CTXT_MODIFICATION_RESP(mSGpTR)  (mSGpTR)->ittiMsg.s1ap_ue_ctxt_modification_resp
 #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_DOWNLINK_NAS(mSGpTR)               (mSGpTR)->ittiMsg.s1ap_downlink_nas
 #define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR)  (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req
 #define S1AP_UE_CTXT_MODIFICATION_REQ(mSGpTR)   (mSGpTR)->ittiMsg.s1ap_ue_ctxt_modification_req
 #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_UE_CONTEXT_RELEASE_REQ(mSGpTR)     (mSGpTR)->ittiMsg.s1ap_ue_release_req
@@ -390,7 +393,7 @@ typedef struct s1ap_initial_context_setup_fail_s {
   unsigned  eNB_ue_s1ap_id:24;
 
   /* TODO add cause */
-} s1ap_initial_context_setup_fail_t, s1ap_ue_ctxt_modification_fail_t;
+} s1ap_initial_context_setup_fail_t, s1ap_ue_ctxt_modification_fail_t, s1ap_e_rab_setup_req_fail_t;
 
 typedef struct s1ap_nas_non_delivery_ind_s {
   unsigned  eNB_ue_s1ap_id:24;
@@ -439,6 +442,7 @@ typedef struct s1ap_downlink_nas_s {
   nas_pdu_t nas_pdu;
 } s1ap_downlink_nas_t;
 
+
 typedef struct s1ap_initial_context_setup_req_s {
   /* UE id for initial connection to S1AP */
   uint16_t ue_initial_id;
@@ -479,6 +483,39 @@ typedef struct s1ap_paging_ind_s {
   paging_priority_t paging_priority;
 } s1ap_paging_ind_t;
 
+typedef struct s1ap_e_rab_setup_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 setup in the list */
+  uint8_t nb_e_rabs_tosetup;
+
+  /* E RAB setup request */
+  e_rab_t e_rab_setup_params[S1AP_MAX_E_RAB];
+
+} s1ap_e_rab_setup_req_t;
+
+typedef struct s1ap_e_rab_setup_resp_s {
+  unsigned  eNB_ue_s1ap_id:24;
+
+  /* Number of e_rab setup-ed in the list */
+  uint8_t       nb_of_e_rabs;
+  /* list of e_rab setup-ed by RRC layers */
+  e_rab_setup_t e_rabs[S1AP_MAX_E_RAB];
+
+  /* Number of e_rab failed to be setup in list */
+  uint8_t        nb_of_e_rabs_failed;
+  /* list of e_rabs that failed to be setup */
+  e_rab_failed_t e_rabs_failed[S1AP_MAX_E_RAB];
+} s1ap_e_rab_setup_resp_t;
+
+
 // S1AP --> RRC messages
 typedef struct s1ap_ue_release_command_s {
 
diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c
index e3f6d8e78c13fc86f900a86a14ef2dfff7b8d1e0..e719d6729fa2b97cff038192994f1e5442d55626 100644
--- a/openair2/LAYER2/MAC/config.c
+++ b/openair2/LAYER2/MAC/config.c
@@ -189,6 +189,10 @@ rrc_mac_config_req(
         mac_xface->macphy_exit("NULL ul_SpecificParameters");
       }
     }
+    else {
+      eNB_mac_inst[Mod_id].lcid_active[logicalChannelIdentity]=1;
+      LOG_I(MAC,"[CONFIG][eNB %d] lcid %d is active for UE rnti %x on cc_id % \n",Mod_id,rntiP,CC_id);
+    }
   }
 
   if (mac_MainConfig != NULL) {
diff --git a/openair2/LAYER2/MAC/defs.h b/openair2/LAYER2/MAC/defs.h
index a0a43b6d7951ea3f4eb9fa1cebb9aa2dad5e34d7..3c9568d41ff14305e442eabde8c3405db84544d7 100644
--- a/openair2/LAYER2/MAC/defs.h
+++ b/openair2/LAYER2/MAC/defs.h
@@ -887,7 +887,7 @@ typedef struct {
   SBMAP_CONF sbmap_conf;
 
   ///  active flag for Other lcid
-  //  uint8_t lcid_active[NB_RB_MAX];
+  uint8_t lcid_active[NB_RB_MAX];
   /// eNB stats
   eNB_STATS eNB_stats[MAX_NUM_CCs];
   // MAC function execution peformance profiler
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index 52e0f60d65bdd7a7ede16b57c908cd5159b9a125..ca08f076952d3766f7104abc90a3156986a0ba66 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -435,10 +435,12 @@ schedule_ue_spec(
   int                   N_RBG[MAX_NUM_CCs];
   unsigned char         aggregation;
   mac_rlc_status_resp_t rlc_status;
-  unsigned char         header_len_dcch=0, header_len_dcch_tmp=0,header_len_dtch=0,header_len_dtch_tmp=0, ta_len=0;
-  unsigned char         sdu_lcids[11],offset,num_sdus=0;
+  unsigned char         header_len_dcch=0, header_len_dcch_tmp=0, header_len_dcch_last=0; 
+  unsigned char         header_len_dtch=0, header_len_dtch_tmp=0, header_len_dtch_last=0; 
+  unsigned char         ta_len=0;
+  unsigned char         sdu_lcids[NB_RB_MAX],lcid,offset,num_sdus=0;
   uint16_t              nb_rb,nb_rb_temp,total_nb_available_rb[MAX_NUM_CCs],nb_available_rb;
-  uint16_t              TBS,j,sdu_lengths[11],rnti,padding=0,post_padding=0;
+  uint16_t              TBS,j,sdu_lengths[NB_RB_MAX],rnti,padding=0,post_padding=0;
   unsigned char         dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
   unsigned char         round            = 0;
   unsigned char         harq_pid         = 0;
@@ -903,84 +905,92 @@ schedule_ue_spec(
                                        ENB_FLAG_YES,
                                        MBMS_FLAG_NO,
                                        DCCH+1,
-                                       (char *)&dlsch_buffer[sdu_lengths[0]]);
+                                       (char *)&dlsch_buffer[sdu_lengths[num_sdus]]);
 
             sdu_lcids[num_sdus] = DCCH1;
             sdu_length_total += sdu_lengths[num_sdus];
             header_len_dcch += 2;
             UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1]+=1;
             UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus];
-            num_sdus++;
-            LOG_D(MAC,"[eNB %d] CC_id %d Got %d bytes for DCCH from RLC\n",module_idP,CC_id,sdu_lengths[0]);
-          }
-        }
-
-        // check for DTCH and update header information
-        // here we should loop over all possible DTCH
-
-        header_len_dtch = 3; // 3 bytes DTCH SDU subheader
-
-        LOG_D(MAC,"[eNB %d], Frame %d, DTCH->DLSCH, CC_id %d, Checking RLC status (rab %d, tbs %d, len %d)\n",
-              module_idP,frameP,CC_id,DTCH,TBS,
-              TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);
-
-        if (TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) {
-          rlc_status = mac_rlc_status_ind(
-                         module_idP,
-                         rnti,
-			 module_idP,
-                         frameP,
-                         ENB_FLAG_YES,
-                         MBMS_FLAG_NO,
-                         DTCH,
-                         TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);
-
-          if (rlc_status.bytes_in_buffer > 0) {
-
-            LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB], Frame %d, DTCH->DLSCH, CC_id %d, Requesting %d bytes from RLC (hdr len dtch %d)\n",
-                  module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total-header_len_dtch,header_len_dtch);
-            sdu_lengths[num_sdus] = mac_rlc_data_req(
-                                      module_idP,
-                                      rnti,
-				      module_idP,
-                                      frameP,
-                                      ENB_FLAG_YES,
-                                      MBMS_FLAG_NO,
-                                      DTCH,
-                                      (char*)&dlsch_buffer[sdu_length_total]);
-
-            LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] CC_id %d Got %d bytes for DTCH %d \n",
-                  module_idP,CC_id,sdu_lengths[num_sdus],DTCH);
-            sdu_lcids[num_sdus] = DTCH;
-            sdu_length_total += sdu_lengths[num_sdus];
-            UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DTCH]+=1;
-            UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DTCH]+=sdu_lengths[num_sdus];
-
-            if (sdu_lengths[num_sdus] < 128) {
-              header_len_dtch=2;
-            }
-
-            num_sdus++;
-          } else {
-            header_len_dtch = 0;
-          }
+	    LOG_D(MAC,"[eNB %d] CC_id %d Got %d bytes for DCCH from RLC\n",module_idP,CC_id,sdu_lengths[num_sdus]);
+	    num_sdus++;
+	  }
         }
 
-        // there is a payload
-        if (((sdu_length_total + header_len_dcch + header_len_dtch )> 0)) {
-
-          // Now compute number of required RBs for total sdu length
-          // Assume RAH format 2
-          // adjust  header lengths
-          header_len_dcch_tmp = header_len_dcch;
-          header_len_dtch_tmp = header_len_dtch;
-
-          if (header_len_dtch==0) {
-            header_len_dcch = (header_len_dcch >0) ? 1 : header_len_dcch;  // remove length field
-          } else {
-            header_len_dtch = (header_len_dtch > 0) ? 1 :header_len_dtch;     // remove length field for the last SDU
-          }
-
+	// assume the max dtch header size, and adjust it later
+	header_len_dtch=0;
+	header_len_dtch_last=0; // the header length of the last mac sdu
+	// lcid has to be sorted before the actual allocation (similar struct as ue_list).
+	for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){
+	  // TBD: check if the lcid is active
+	  
+	  header_len_dtch+=3; 
+	  header_len_dtch_last=3;
+	  LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
+		module_idP,frameP,lcid,TBS,
+		TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);
+	  
+	  if (TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) { // NN: > 2 ? 
+	    rlc_status = mac_rlc_status_ind(module_idP,
+					    rnti,
+					    module_idP,
+					    frameP,
+					    ENB_FLAG_YES,
+					    MBMS_FLAG_NO,
+					    lcid,
+					    TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);
+	   
+
+	    if (rlc_status.bytes_in_buffer > 0) {
+	      
+	      LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH%d->DLSCH, Requesting %d bytes from RLC (total hdr len dtch %d)\n",
+		    module_idP,frameP,lcid,TBS-header_len_dcch-sdu_length_total-header_len_dtch,header_len_dtch);
+	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+						       rnti,
+						       module_idP,
+						       frameP,
+						       ENB_FLAG_YES,
+						       MBMS_FLAG_NO,
+						       lcid,
+						       (char*)&dlsch_buffer[sdu_length_total]);
+	      
+	      LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],lcid);
+	      sdu_lcids[num_sdus] = lcid;
+	      sdu_length_total += sdu_lengths[num_sdus];
+	      UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]+=1;
+	      UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid]+=sdu_lengths[num_sdus];
+	      if (sdu_lengths[num_sdus] < 128) {
+		header_len_dtch--;
+		header_len_dtch_last--;
+	      }
+	      num_sdus++;
+	    } // no data for this LCID
+	    else {
+	      header_len_dtch-=3;
+	    }
+	  } // no TBS left
+	  else {
+	    header_len_dtch-=3;
+	    break; 
+	  }
+	}
+	if (header_len_dtch == 0 )
+	  header_len_dtch_last= 0;
+	// there is at least one SDU 
+	// if (num_sdus > 0 ){
+	if ((sdu_length_total + header_len_dcch + header_len_dtch )> 0) {
+	  
+	  // Now compute number of required RBs for total sdu length
+	  // Assume RAH format 2
+	  // adjust  header lengths
+	  header_len_dcch_tmp = header_len_dcch;
+	  header_len_dtch_tmp = header_len_dtch;
+	  if (header_len_dtch==0) {
+	    header_len_dcch = (header_len_dcch >0) ? 1 : 0;//header_len_dcch;  // remove length field
+	  } else {
+	    header_len_dtch_last-=1; // now use it to find how many bytes has to be removed for the last MAC SDU 
+	    header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last  :header_len_dtch;     // remove length field for the last SDU
+	  }
 
           mcs = eNB_UE_stats->dlsch_mcs1;
 
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
index 1018c6e7d8483ff60121c33eb9007f337573ef0d..6bfb598db595d44721ca6573f9ed62dc790daffd 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c
@@ -69,16 +69,15 @@
 // This table holds the allowable PRB sizes for ULSCH transmissions
 uint8_t rb_table[33] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,72,75,80,81,90,96,100};
 
-void rx_sdu(
-  const module_id_t enb_mod_idP,
-  const int         CC_idP,
-  const frame_t     frameP,
-  const sub_frame_t subframeP,
-  const rnti_t      rntiP,
-  uint8_t          *sduP,
-  const uint16_t    sdu_lenP,
-  const int         harq_pidP,
-  uint8_t          *msg3_flagP)
+void rx_sdu(const module_id_t enb_mod_idP,
+	    const int         CC_idP,
+	    const frame_t     frameP,
+	    const sub_frame_t subframeP,
+	    const rnti_t      rntiP,
+	    uint8_t          *sduP,
+	    const uint16_t    sdu_lenP,
+	    const int         harq_pidP,
+	    uint8_t          *msg3_flagP)
 {
 
   unsigned char  rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
@@ -216,8 +215,8 @@ void rx_sdu(
   for (i=0; i<num_sdu; i++) {
     LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
 
-    switch (rx_lcids[i]) {
-    case CCCH :
+    if (rx_lcids[i] == CCCH) {
+
       LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
             enb_mod_idP,CC_idP,frameP,
             payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
@@ -274,94 +273,80 @@ void rx_sdu(
         } // if process is active
       } // loop on RA processes
 
-      break;
 
-    case  DCCH :
-    case DCCH1 :
+    } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
       //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
 
 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
       LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
-
       for (j=0; j<32; j++) {
         LOG_T(MAC,"%x ",payload_ptr[j]);
       }
-
       LOG_T(MAC,"\n");
 #endif
 
       if (UE_id != -1) {
         //  This check is just to make sure we didn't get a bogus SDU length, to be removed ...
         if (rx_lengths[i]<CCCH_PAYLOAD_SIZE_MAX) {
-          LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n",
-                enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]);
-
+          LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH%d, received %d bytes form UE %d \n",
+                enb_mod_idP,CC_idP,frameP, rx_lcids[i], rx_lengths[i], UE_id);
+	  
           mac_rlc_data_ind(
-            enb_mod_idP,
-            rntiP,
-	      enb_mod_idP,
-            frameP,
-            ENB_FLAG_YES,
-            MBMS_FLAG_NO,
-            rx_lcids[i],
-            (char *)payload_ptr,
-            rx_lengths[i],
-            1,
-            NULL);//(unsigned int*)crc_status);
+			   enb_mod_idP,
+			   rntiP,
+			   enb_mod_idP,
+			   frameP,
+			   ENB_FLAG_YES,
+			   MBMS_FLAG_NO,
+			   rx_lcids[i],
+			   (char *)payload_ptr,
+			   rx_lengths[i],
+			   1,
+			   NULL);//(unsigned int*)crc_status);
           UE_list->eNB_UE_stats[CC_idP][UE_id].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];
         }
       } /* UE_id != -1 */
-
-      //      }
-      break;
-
-    case DTCH: // default DRB
-      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
+      
+    } else if ((rx_lcids[i]  < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) {
+      LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH%d, received %d bytes form UE %d \n",
+	    enb_mod_idP,CC_idP,frameP, rx_lcids[i], rx_lengths[i], UE_id);
 
 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
       LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
-
       for (j=0; j<32; j++) {
         LOG_T(MAC,"%x ",payload_ptr[j]);
       }
-
       LOG_T(MAC,"\n");
 #endif
 
-      LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
-            enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i]);
-
       if (UE_id != -1) {
         if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
           mac_rlc_data_ind(
-            enb_mod_idP,
-            rntiP,
-            enb_mod_idP,
-            frameP,
-            ENB_FLAG_YES,
-            MBMS_FLAG_NO,
-            DTCH,
-            (char *)payload_ptr,
-            rx_lengths[i],
-            1,
-            NULL);//(unsigned int*)crc_status);
+			   enb_mod_idP,
+			   rntiP,
+			   enb_mod_idP,
+			   frameP,
+			   ENB_FLAG_YES,
+			   MBMS_FLAG_NO,
+			   rx_lcids[i],
+			   (char *)payload_ptr,
+			   rx_lengths[i],
+			   1,
+			   NULL);//(unsigned int*)crc_status);
+
           UE_list->eNB_UE_stats[CC_idP][UE_id].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];
         }
-      } /* UE_id != -1 */
-
-      //      }
-      break;
-
-    default :  //if (rx_lcids[i] >= DTCH) {
-      if (UE_id != -1)
-        UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
+      } else { /* UE_id != -1 */
+	UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
+      }    
+    } else {
+      UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
       LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
             enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
-      break;
     }
-
+    
     payload_ptr+=rx_lengths[i];
   }
 
diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
index ee6340cb43a4b7dfb6483725b3e57cffeba8d328..90d227eb35a500f27d913845239727c05d565605 100644
--- a/openair2/LAYER2/MAC/ue_procedures.c
+++ b/openair2/LAYER2/MAC/ue_procedures.c
@@ -302,16 +302,12 @@ uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_i
 
 //------------------------------------------------------------------------------
 void
-ue_send_sdu(
-  module_id_t module_idP,
-  uint8_t CC_id,
-  frame_t frameP,
-  uint8_t* sdu,
-  uint16_t sdu_len,
-  uint8_t eNB_index
-)
-//------------------------------------------------------------------------------
-{
+ue_send_sdu(module_id_t module_idP,
+	    uint8_t CC_id,
+	    frame_t frameP,
+	    uint8_t* sdu,
+	    uint16_t sdu_len,
+	    uint8_t eNB_index) {
 
   unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
   unsigned char rx_lcids[NB_RB_MAX];
@@ -401,7 +397,7 @@ ue_send_sdu(
 #ifdef DEBUG_HEADER_PARSING
     LOG_D(MAC,"[UE] SDU %d : LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
 #endif
-
+    
     if (rx_lcids[i] == CCCH) {
 
       LOG_D(MAC,"[UE %d] rnti %x Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n",
@@ -431,7 +427,7 @@ ue_send_sdu(
                        eNB_index,
                        0);
 
-    } else if (rx_lcids[i] == DCCH) {
+    } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
       LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", module_idP, frameP, rx_lcids[i],eNB_index,rx_lengths[i]);
       mac_rlc_data_ind(module_idP,
                        UE_mac_inst[module_idP].crnti,
@@ -439,53 +435,39 @@ ue_send_sdu(
                        frameP,
                        ENB_FLAG_NO,
                        MBMS_FLAG_NO,
-                       DCCH,
-                       (char *)payload_ptr,
-                       rx_lengths[i],
-                       1,
-                       NULL);
-    } else if (rx_lcids[i] == DCCH1) {
-      LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", module_idP, frameP, rx_lcids[i], eNB_index,rx_lengths[i]);
-      mac_rlc_data_ind(module_idP,
-                       UE_mac_inst[module_idP].crnti,
-		       eNB_index,
-		       frameP,
-                       ENB_FLAG_NO,
-                       MBMS_FLAG_NO,
-                       DCCH1,
+                       rx_lcids[i],
                        (char *)payload_ptr,
                        rx_lengths[i],
                        1,
                        NULL);
-    } else if (rx_lcids[i] == DTCH) {
+ 
+    } else if ((rx_lcids[i]  < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) {
+      
       LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", module_idP, frameP,rx_lcids[i], eNB_index,rx_lengths[i]);
 
 #if defined(ENABLE_MAC_PAYLOAD_DEBUG)
       int j;
-
-      for (j=0; j<rx_lengths[i]; j++) {
-        LOG_T(MAC,"%x.",(unsigned char)payload_ptr[j]);
-      }
-
+      for (j=0;j<rx_lengths[i];j++)
+	LOG_T(MAC,"%x.",(unsigned char)payload_ptr[j]);
       LOG_T(MAC,"\n");
 #endif
-
       mac_rlc_data_ind(module_idP,
-                       UE_mac_inst[module_idP].crnti,
+		       UE_mac_inst[module_idP].crnti,
 		       eNB_index,
 		       frameP,
-                       ENB_FLAG_NO,
-                       MBMS_FLAG_NO,
-                       DTCH,
-                       (char *)payload_ptr,
-                       rx_lengths[i],
-                       1,
-                       NULL);
+		       ENB_FLAG_NO,
+		       MBMS_FLAG_NO,
+		       rx_lcids[i],
+		       (char *)payload_ptr,
+		       rx_lengths[i],
+		       1,
+		       NULL);
+    } else {
+      LOG_E(MAC,"[UE %d] Frame %d : unknown LCID %d (eNB %d)\n", module_idP, frameP,rx_lcids[i], eNB_index);
     }
-
     payload_ptr+= rx_lengths[i];
   }
-
+  
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
   stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
 }
@@ -1196,10 +1178,11 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
 {
 
   mac_rlc_status_resp_t rlc_status;
-  uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0;
+  uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0,dtch_header_len_last=0;
   uint8_t dcch_header_len_tmp=0, dtch_header_len_tmp=0;
   uint8_t bsr_header_len=0, bsr_ce_len=0, bsr_len=0;
   uint8_t phr_header_len=0, phr_ce_len=0,phr_len=0;
+  uint8_t lcid=0;
   uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
   uint8_t sdu_lcids[8]    = { 0, 0, 0, 0, 0, 0, 0, 0 };
   uint8_t payload_offset=0,num_sdus=0;
@@ -1277,18 +1260,27 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
   // check for UL bandwidth requests and add SR control element
 
   // Check for DCCH first
-  sdu_lengths[0]=0;
 
   if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH] == LCID_NOT_EMPTY) {
 
-    rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index, frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index
+    rlc_status = mac_rlc_status_ind(module_idP, 
+				    UE_mac_inst[module_idP].crnti, 
+				    eNB_index, 
+				    frameP,
+				    ENB_FLAG_NO,
+				    MBMS_FLAG_NO, // eNB_index
                                     DCCH,
                                     (buflen-dcch_header_len-bsr_len-phr_len));
     LOG_D(MAC, "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to "
           "send (Transport Block size %d, mac header len %d)\n",
           module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch_header_len);
 
-    sdu_lengths[0] += mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,ENB_FLAG_NO, MBMS_FLAG_NO,
+    sdu_lengths[0] += mac_rlc_data_req(module_idP, 
+				       UE_mac_inst[module_idP].crnti,
+				       eNB_index,
+				       frameP,
+				       ENB_FLAG_NO, 
+				       MBMS_FLAG_NO,
                                        DCCH,
                                        (char *)&ulsch_buff[sdu_lengths[0]]);
 
@@ -1306,11 +1298,15 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
   // if the RLC AM is used, then RLC will only provide 2 bytes for ACK
   // in this case, we sould add bsr
 
-
   // DCCH1
   if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH1] == LCID_NOT_EMPTY) {
 
-    rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index
+    rlc_status = mac_rlc_status_ind(module_idP, 
+				    UE_mac_inst[module_idP].crnti, 
+				    eNB_index,
+				    frameP,
+				    ENB_FLAG_NO,
+				    MBMS_FLAG_NO, // eNB_index
                                     DCCH1,
                                     (buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-sdu_length_total));
 
@@ -1318,9 +1314,14 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
           " send (Transport Block size %d, mac header len %d)\n",
           module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch1_header_len);
 
-    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
-                            DCCH1,
-                            (char *)&ulsch_buff[sdu_lengths[0]]);
+    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 
+					     UE_mac_inst[module_idP].crnti,
+					     eNB_index,
+					     frameP,
+					     ENB_FLAG_NO,
+					     MBMS_FLAG_NO,
+					     DCCH1,
+					     (char *)&ulsch_buff[sdu_lengths[num_sdus]]);
     sdu_length_total += sdu_lengths[num_sdus];
     sdu_lcids[num_sdus] = DCCH1;
     LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH1\n",module_idP,sdu_lengths[num_sdus]);
@@ -1331,8 +1332,14 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
     dcch1_header_len =0;
   }
 
-  if ((UE_mac_inst[module_idP].scheduling_info.LCID_status[DTCH] == LCID_NOT_EMPTY) &&
-      ((bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len+sdu_length_total) <= buflen)) {
+  dtch_header_len=0;
+  dtch_header_len_last=0;
+  for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){
+    dtch_header_len+=3; 
+    dtch_header_len_last=3;
+    
+    if ((UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) &&
+	((bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len+sdu_length_total) <= buflen)) {
 
     // optimize the dtch header lenght
     //if ((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH] > 128) &&
@@ -1343,29 +1350,47 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
     else
     dtch_header_len = 2;//sizeof(SCH_SUBHEADER_SHORT);
      */
-    rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti, eNB_index,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index
-                                    DTCH,
-                                    buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total);
-
-    LOG_D(MAC,"[UE %d] Frame %d : UL-DTCH -> ULSCH, %d bytes to send (Transport Block size %d, mac header len %d, BSR byte[DTCH] %d)\n",
-          module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dtch_header_len,
-          UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH]);
-
-    sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,UE_mac_inst[module_idP].crnti,eNB_index,frameP, ENB_FLAG_NO, MBMS_FLAG_NO, // eNB_index
-                            DTCH,
-                            (char *)&ulsch_buff[sdu_length_total]);
-
-    //adjust dtch header
-    dtch_header_len = (sdu_lengths[num_sdus] >= 128) ? 3 : 2;
-    LOG_D(MAC,"[UE %d] TX Got %d bytes for DTCH\n",module_idP,sdu_lengths[num_sdus]);
-    sdu_lcids[num_sdus] = DTCH;
-    sdu_length_total += sdu_lengths[num_sdus];
-    num_sdus++;
-    UE_mac_inst[module_idP].ul_active = update_bsr(module_idP, frameP, eNB_index,DTCH, UE_mac_inst[module_idP].scheduling_info.LCGID[DTCH]);
-  } else { // no rlc pdu : generate the dummy header
-    dtch_header_len = 0;
+      rlc_status = mac_rlc_status_ind(module_idP, 
+				      UE_mac_inst[module_idP].crnti, 
+				      eNB_index,
+				      frameP,
+				      ENB_FLAG_NO,
+				      MBMS_FLAG_NO, // eNB_index
+				      lcid,
+				      buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total);
+
+      LOG_D(MAC,"[UE %d] Frame %d : UL-DTCH -> ULSCH%d, %d bytes to send (Transport Block size %d, mac header len %d, BSR byte[%d] %d)\n",
+	    module_idP,frameP, lcid, rlc_status.bytes_in_buffer,buflen,dtch_header_len,
+	    lcid, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcid]);
+      
+       if (rlc_status.bytes_in_buffer > 0) {
+	 sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
+						  UE_mac_inst[module_idP].crnti,
+						  eNB_index,
+						  frameP, 
+						  ENB_FLAG_NO, 
+						  MBMS_FLAG_NO, // eNB_index
+						  lcid,
+						  (char *)&ulsch_buff[sdu_length_total]);
+	 
+	 //adjust dtch header
+	 LOG_D(MAC,"[UE %d] TX Got %d bytes for DTCH\n",module_idP,sdu_lengths[num_sdus]);
+	 sdu_lcids[num_sdus] = lcid;
+	 sdu_length_total += sdu_lengths[num_sdus];
+	 if (sdu_lengths[num_sdus] < 128) {
+	   dtch_header_len --;
+	   dtch_header_len_last --;
+	 }
+	 num_sdus++;
+	 UE_mac_inst[module_idP].ul_active = update_bsr(module_idP, frameP, eNB_index,lcid, UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]);
+       } else {
+	 dtch_header_len -= 3;
+       }
+    } else { // no rlc pdu : generate the dummy header
+      dtch_header_len -= 3;
+    }
   }
-
+  
   lcgid= get_bsr_lcgid(module_idP);
 
   if (lcgid < 0 ) {
@@ -1406,6 +1431,9 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
 
   LOG_T(MAC,"[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n",  module_idP,frameP,bsr_s, bsr_l, phr_p);
 
+  if (dtch_header_len == 0 )
+    dtch_header_len_last =0;
+
   // adjust the header length
   dcch_header_len_tmp = dcch_header_len;
   dtch_header_len_tmp = dtch_header_len;
@@ -1413,7 +1441,8 @@ void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subf
   if (dtch_header_len==0) {
     dcch_header_len = (dcch_header_len>0)? 1: dcch_header_len;
   } else {
-    dtch_header_len= (dtch_header_len >0)? 1: dtch_header_len;   // for short and long, cut the length+F fields
+    dtch_header_len_last-=1; 
+    dtch_header_len= (dtch_header_len >0)? dtch_header_len - dtch_header_len_last : dtch_header_len;   
   }
 
   if ((buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total) <= 2) {
diff --git a/openair2/RRC/LITE/defs.h b/openair2/RRC/LITE/defs.h
index bae3dc887a7adfe1cfc5163d420a7b00d0f9dc48..1a4d6e0fe1aec4461f2b3e4a3d454fc282f0fae4 100644
--- a/openair2/RRC/LITE/defs.h
+++ b/openair2/RRC/LITE/defs.h
@@ -220,7 +220,8 @@ typedef struct UE_S_TMSI_s {
 #if defined(ENABLE_ITTI)
 typedef enum e_rab_satus_e {
   E_RAB_STATUS_NEW,
-  E_RAB_STATUS_DONE,
+  E_RAB_STATUS_DONE, // from the eNB perspective
+  E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE
   E_RAB_STATUS_FAILED,
 } e_rab_status_t;
 
@@ -232,7 +233,6 @@ typedef struct e_rab_param_s {
 
 
 
-
 /* Intermediate structure for Handover management. Associated per-UE in eNB_RRC_INST */
 typedef struct HANDOVER_INFO_s {
   uint8_t ho_prepare;
@@ -347,10 +347,12 @@ typedef struct eNB_RRC_UE_s {
 
   security_capabilities_t            security_capabilities;
 
+  /* Total number of e_rab already setup in the list */
+  uint8_t                           setup_e_rabs;
   /* Number of e_rab to be setup in the list */
   uint8_t                            nb_of_e_rabs;
   /* list of e_rab to be setup by RRC layers */
-  e_rab_param_t                      e_rab[S1AP_MAX_E_RAB];
+  e_rab_param_t                      e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB];
 
   // LG: For GTPV1 TUNNELS
   uint32_t                           enb_gtp_teid[S1AP_MAX_E_RAB];
diff --git a/openair2/RRC/LITE/proto.h b/openair2/RRC/LITE/proto.h
index 5d77698c8e4a5b3a5465f50c2c91d7b0c3780687..5d5875b03297ee275958e73b56ab5fe863752d1d 100644
--- a/openair2/RRC/LITE/proto.h
+++ b/openair2/RRC/LITE/proto.h
@@ -257,6 +257,17 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
   const uint8_t                ho_state
 );
 
+void
+rrc_eNB_generate_dedeicatedRRCConnectionReconfiguration(
+  const protocol_ctxt_t* const ctxt_pP,
+  rrc_eNB_ue_context_t*          const ue_context_pP,
+  const uint8_t                ho_state
+);
+
+void 
+rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP,
+			  rrc_eNB_ue_context_t*  ue_context_pP);
+
 #if defined(ENABLE_ITTI)
 /**\brief RRC eNB task.
    \param void *args_p Pointer on arguments to start the task. */
diff --git a/openair2/RRC/LITE/rrc_eNB.c b/openair2/RRC/LITE/rrc_eNB.c
index f19c3bced4b9d9d7796b520a8de0a8fed4b87d74..db70e4daf5039aa5c31a96c70998fda69d930d5c 100644
--- a/openair2/RRC/LITE/rrc_eNB.c
+++ b/openair2/RRC/LITE/rrc_eNB.c
@@ -1055,13 +1055,232 @@ rrc_eNB_generate_RRCConnectionRelease(
     PDCP_TRANSMISSION_MODE_CONTROL);
 }
 
+// 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_defaultRRCConnectionReconfiguration(
-  const protocol_ctxt_t* const ctxt_pP,
-  rrc_eNB_ue_context_t*          const ue_context_pP,
-  const uint8_t                ho_state
-)
+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; 
+  //DRB_ToAddModList_t**                RRC_DRB_configList=&ue_context_pP->ue_context.DRB_configList;
+
+  struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL;
+  DedicatedInfoNAS_t                 *dedicatedInfoNas                 = NULL;
+
+  long                               *logicalchannelgroup, *logicalchannelgroup_drb;
+  int drb_Identity_index;
+
+// Configure DRB
+  //*DRB_configList = CALLOC(1, sizeof(*DRB_configList));
+  *DRB_configList = CALLOC(1, sizeof(**DRB_configList));
+  
+  for ( i = 0  ;
+	i < ue_context_pP->ue_context.nb_of_e_rabs;
+	i++){
+    // bypass the already configured erabs
+    if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) {
+      //drb_identiy_index++;
+      continue;
+    }
+    DRB_config = CALLOC(1, sizeof(*DRB_config));
+
+    DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long));
+    *(DRB_config->eps_BearerIdentity) = 5L; 
+
+    DRB_config->drb_Identity = (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id;
+    // 1 + drb_identiy_index;  
+
+    DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
+    *(DRB_config->logicalChannelIdentity) = (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){
+    case 1: // RLC _UM 
+    case 2:
+    case 3:
+    case 4: 
+    case 5:
+      // 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;
+      // 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;
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    default: 
+      // 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
+       PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM));
+       DRB_pdcp_config->rlc_AM = PDCP_rlc_AM;
+       PDCP_rlc_AM->statusReportRequired = FALSE;
+       
+      //LOG_I(RRC,"not supported qci %d\n", ue_context_pP->ue_context.e_rab[i].param.qos.qci);
+      break;
+    }
+
+    DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed;
+    
+    DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config));
+    DRB_config->logicalChannelConfig = DRB_lchan_config;
+    DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters));
+    DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters;
+
+    DRB_ul_SpecificParameters->priority = ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level;
+    // TO DO
+    DRB_ul_SpecificParameters->prioritisedBitRate =
+      LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
+    DRB_ul_SpecificParameters->bucketSizeDuration =
+      LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50;
+    
+    // LCG for DTCH can take the value from 1 to 3 as defined in 36331: normally controlled by upper layers (like RRM)
+    logicalchannelgroup_drb = CALLOC(1, sizeof(long));
+    *logicalchannelgroup_drb = 1;
+    DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb;
+    
+    ASN_SEQUENCE_ADD(&(*DRB_configList)->list, DRB_config);
+  
+#if defined(ENABLE_ITTI)   
+
+    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);
+    }
+    /* 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->list.count == 0) {
+      free(dedicatedInfoNASList);
+      dedicatedInfoNASList = NULL;
+    }
+#endif
+    
+    ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; 
+    
+  }
+  
+  memset(buffer, 0, RRC_BUF_SIZE);
+
+   size = do_RRCConnectionReconfiguration(ctxt_pP,
+					  buffer,
+					  rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),   //Transaction_id,
+					  (SRB_ToAddModList_t*)NULL, 
+					  (DRB_ToAddModList_t*)*DRB_configList,
+					  (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
+#ifdef Rel10
+                                         , (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" dedicated rrcConnectionReconfiguration UE %x MUI %d size %u",
+    MSC_AS_TIME_ARGS(ctxt_pP),
+    ue_context_pP->ue_context.rnti,
+    rrc_eNB_mui,
+    size);
+
+  pdcp_rrc_data_req(
+    ctxt_pP,
+    DCCH,
+    rrc_eNB_mui++,
+    SDU_CONFIRM_NO,
+    size,
+    buffer,
+    PDCP_TRANSMISSION_MODE_CONTROL);
+
+
+}
+#endif 
+//-----------------------------------------------------------------------------
+void
+rrc_eNB_generate_defaultRRCConnectionReconfiguration(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];
@@ -1193,7 +1412,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
   *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4
   // DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32
   // NN: this is the 1st DRB for this ue, so set it to 1
-  // NN: this is the 1st DRB for this ue, so set it to 1
   DRB_config->drb_Identity = (DRB_Identity_t) 1;  // (ue_mod_idP+1); //allowed values 1..32, value: x
   DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long));
   *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2
@@ -1625,11 +1843,9 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(
 
 #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
@@ -3818,7 +4034,8 @@ rrc_eNB_decode_dcch(
   UE_EUTRA_Capability_t              *UE_EUTRA_Capability = NULL;
   int i;
   struct rrc_eNB_ue_context_s*        ue_context_p = NULL;
-
+  int dedicated_DRB=0; 
+  
   if ((Srb_id != 1) && (Srb_id != 2)) {
     LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received message on SRB%d, should not have ...\n",
           PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
@@ -3946,23 +4163,36 @@ rrc_eNB_decode_dcch(
           rrcConnectionReconfigurationComplete.
           criticalExtensions.choice.
           rrcConnectionReconfigurationComplete_r8);
-        ue_context_p->ue_context.Status = RRC_RECONFIGURED;
-        LOG_I(RRC,
-              PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED \n",
-              PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+        if (ue_context_p->ue_context.Status == RRC_RECONFIGURED){
+	  dedicated_DRB = 1;
+	  LOG_I(RRC,
+		PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB)\n",
+		PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+	}else {
+	  ue_context_p->ue_context.Status = RRC_RECONFIGURED;
+	  LOG_I(RRC,
+		PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB)\n",
+		PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP));
+	}
       }
-
-#if defined(ENABLE_USE_MME)
-#   if defined(ENABLE_ITTI)
-
+#if defined(ENABLE_ITTI)
+#   if defined(ENABLE_USE_MME)
       if (EPC_MODE_ENABLED == 1) {
-        rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(
-          ctxt_pP,
-          ue_context_p);
+	if (dedicated_DRB == 1){
+	  rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP,
+					     ue_context_p);
+	}else {
+	  rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP,
+						       ue_context_p);
+	}
+      }    
+#else  // establish a dedicated bearer 
+      if (dedicated_DRB == 0 ) {
+	rrc_eNB_reconfigure_DRBs(ctxt_pP,ue_context_p);
       }
-
-#   endif
+      
 #endif
+#endif 
       break;
 
     case UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete:
@@ -4255,6 +4485,41 @@ rrc_eNB_decode_dcch(
 }
 
 #if defined(ENABLE_ITTI)
+void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP,
+			       rrc_eNB_ue_context_t*  ue_context_pP){
+
+  int i;
+
+  for (i = 0; 
+       i < NB_RB_MAX;  // S1AP_MAX_E_RAB
+       i++) {
+    
+    if ( (ue_context_pP->ue_context.e_rab[i].status != E_RAB_STATUS_ESTABLISHED) || 
+	 (ue_context_pP->ue_context.e_rab[i].status != E_RAB_STATUS_DONE)  ){ 
+	LOG_I(RRC,"setting up the dedicated DRBs %d \n", i);
+	ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_NEW;
+        ue_context_pP->ue_context.e_rab[i].param.e_rab_id = i;
+	ue_context_pP->ue_context.e_rab[i].param.qos.qci = i % 9;
+	ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level= i % PRIORITY_LEVEL_LOWEST;
+	ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_capability= PRE_EMPTION_CAPABILITY_DISABLED;
+	ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_vulnerability= PRE_EMPTION_VULNERABILITY_DISABLED;
+	ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL;
+	ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length = 0;
+	//	memset (ue_context_pP->ue_context.e_rab[i].param.sgw_addr.buffer,0,20);
+	ue_context_pP->ue_context.e_rab[i].param.sgw_addr.length = 0;
+	ue_context_pP->ue_context.e_rab[i].param.gtp_teid=0;
+	
+       	ue_context_pP->ue_context.nb_of_e_rabs++;
+	}
+    
+    ue_context_pP->ue_context.setup_e_rabs+=ue_context_pP->ue_context.nb_of_e_rabs;
+
+  }
+  
+  rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0);
+}
+
+
 //-----------------------------------------------------------------------------
 void*
 rrc_enb_task(
@@ -4350,7 +4615,12 @@ rrc_enb_task(
     case S1AP_PAGING_IND:
       LOG_E(RRC, "[eNB %d] Received not yet implemented message %s\n", instance, msg_name_p);
       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_UE_CONTEXT_RELEASE_REQ:
       rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ(msg_p, msg_name_p, instance);
       break;
diff --git a/openair2/RRC/LITE/rrc_eNB_S1AP.c b/openair2/RRC/LITE/rrc_eNB_S1AP.c
index 5c41658862149af84f0fd0a5ab48ed3a4070264d..da5c749b119e04fe8ea810fc0b89cfe4c6b8bd81 100644
--- a/openair2/RRC/LITE/rrc_eNB_S1AP.c
+++ b/openair2/RRC/LITE/rrc_eNB_S1AP.c
@@ -474,8 +474,10 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(
       S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].gtp_teid = ue_context_pP->ue_context.enb_gtp_teid[e_rab];
       S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr = ue_context_pP->ue_context.enb_gtp_addrs[e_rab];
       S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr.length = 4;
+      ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
     } else {
       e_rabs_failed++;
+      ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
       S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).e_rabs_failed[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
       // TODO add cause when it will be integrated
     }
@@ -842,6 +844,93 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS(
     return (0);
   }
 }
+int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance)
+{
+  uint16_t                        ue_initial_id;
+  uint32_t                        eNB_ue_s1ap_id;
+  MessageDef                     *message_gtpv1u_p = NULL;
+  gtpv1u_enb_create_tunnel_req_t  create_tunnel_req;
+  gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp;
+
+  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
+  protocol_ctxt_t              ctxt;
+  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);
+  LOG_I(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_SETUP_REQ (msg_p).nb_e_rabs_tosetup);
+
+  if (ue_context_p == NULL) {
+    /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */
+    MessageDef *msg_fail_p = NULL;
+
+    LOG_W(RRC, "[eNB %d] In S1AP_E_RAB_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id);
+
+    msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_SETUP_REQUEST_FAIL);
+    S1AP_E_RAB_SETUP_REQ  (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id;
+
+    // TODO add failure cause when defined!
+
+    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 = S1AP_E_RAB_SETUP_REQ  (msg_p).eNB_ue_s1ap_id;
+
+    /* Save e RAB information for later */
+    {
+      int i;
+
+      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;
+
+      // keep the previous bearer
+      for (i = ue_context_p->ue_context.setup_e_rabs; 
+	   i < ue_context_p->ue_context.setup_e_rabs + nb_e_rabs_tosetup; 
+	   i++) {
+	if (ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) 
+	  LOG_W(RRC,"E-RAB already configured, reconfiguring\n");
+        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[i];
+
+
+        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;
+
+        memcpy(&create_tunnel_req.sgw_addr[i],
+               & S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i].sgw_addr,
+               sizeof(transport_layer_addr_t));
+	
+      }
+      ue_context_p->ue_context.nb_of_e_rabs=nb_e_rabs_tosetup;
+      ue_context_p->ue_context.setup_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;
+      
+      // NN: not sure if we should create a new tunnel: need to check teid, etc.
+      gtpv1u_create_s1u_tunnel(
+        instance,
+        &create_tunnel_req,
+        &create_tunnel_resp);
+
+      rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP(
+          &ctxt,
+          &create_tunnel_resp);
+      
+    }
+
+    /* TODO parameters yet to process ... */
+    {
+      //      S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_ambr;
+    }
+
+    rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(&ctxt, ue_context_p, 0);
+							 
+    return (0);
+  }
+}
 
 /*------------------------------------------------------------------------------*/
 int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance)
@@ -884,7 +973,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
 
       memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req));
       ue_context_p->ue_context.nb_of_e_rabs = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs;
-
+     
       for (i = 0; i < ue_context_p->ue_context.nb_of_e_rabs; i++) {
         ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW;
         ue_context_p->ue_context.e_rab[i].param = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i];
@@ -897,6 +986,8 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char
                &S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].sgw_addr,
                sizeof(transport_layer_addr_t));
       }
+      
+      ue_context_p->ue_context.setup_e_rabs =ue_context_p->ue_context.nb_of_e_rabs;
 
       create_tunnel_req.rnti       = ue_context_p->ue_context.rnti; // warning put zero above
       create_tunnel_req.num_tunnels    = i;
@@ -1217,6 +1308,52 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const ch
   }
 }
 
+rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP,
+				   rrc_eNB_ue_context_t*          const ue_context_pP){
+
+  MessageDef      *msg_p         = NULL;
+  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_SETUP_RESP);
+  S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id;
+
+  for (e_rab = ue_context_pP->ue_context.setup_e_rabs - ue_context_pP->ue_context.nb_of_e_rabs; 
+       e_rab < ue_context_pP->ue_context.setup_e_rabs; e_rab++) {
+    if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) {
+      e_rabs_done++;
+      S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
+      // TODO add other information from S1-U when it will be integrated
+      S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].gtp_teid = ue_context_pP->ue_context.enb_gtp_teid[e_rab];
+      S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr = ue_context_pP->ue_context.enb_gtp_addrs[e_rab];
+      S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr.length = 4;
+      ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED;
+    } else {
+      e_rabs_failed++;
+      ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED;
+      S1AP_E_RAB_SETUP_RESP  (msg_p).e_rabs_failed[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id;
+      // TODO add cause when it will be integrated
+    }
+  }
+
+  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_SETUP_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_SETUP_RESP (msg_p).eNB_ue_s1ap_id,
+    e_rabs_done, e_rabs_failed);
+
+
+  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;
+
+  itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p);
+}
 
 # endif /* defined(ENABLE_ITTI) */
 #endif /* defined(ENABLE_USE_MME) */
diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c
index c880c3f3b4bd14ec45b217df4a1ffb6be346a5d9..0b1eee094d743dfc2dd484fc672db5c15066f780 100644
--- a/openair3/S1AP/s1ap_eNB.c
+++ b/openair3/S1AP/s1ap_eNB.c
@@ -328,6 +328,12 @@ void *s1ap_eNB_task(void *arg)
     }
     break;
 
+    case S1AP_E_RAB_SETUP_RESP: {
+      s1ap_eNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
+				&S1AP_E_RAB_SETUP_RESP(received_msg));
+    }
+    break;
+      
     case S1AP_NAS_NON_DELIVERY_IND: {
       s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
                                     &S1AP_NAS_NON_DELIVERY_IND(received_msg));
diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c
index f8230520ce25acda109361a94d467f1d4cfc3002..0c4a70a204b627310174c10b1208e0385f6e2494 100644
--- a/openair3/S1AP/s1ap_eNB_decoder.c
+++ b/openair3/S1AP/s1ap_eNB_decoder.c
@@ -120,6 +120,14 @@ static int s1ap_eNB_decode_initiating_message(s1ap_message *message,
     break;
 
 
+  case S1ap_ProcedureCode_id_E_RABSetup:
+    ret = s1ap_decode_s1ap_e_rabsetuprequesties(
+						&message->msg.s1ap_E_RABSetupRequestIEs, &initiating_p->value);
+    s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, message);
+    //message_id = S1AP_E_RABSETUP_REQ_LOG;
+    S1AP_ERROR("TODO E_RABSetup initiating message\n");
+    free(message_string);
+    break;
   default:
     S1AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
                (int)initiating_p->procedureCode);
diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c
index 6f0d4128c7174d1b96a819b240038a3e7f2a99e4..45cf8f4cea9a27fc0b86417566bb6becb922b247 100644
--- a/openair3/S1AP/s1ap_eNB_handlers.c
+++ b/openair3/S1AP/s1ap_eNB_handlers.c
@@ -82,6 +82,13 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t               assoc_id,
     uint32_t               stream,
     struct s1ap_message_s *s1ap_message_p);
 
+
+static
+int s1ap_eNB_handle_e_rab_setup_request(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] = {
   { 0, 0, 0 }, /* HandoverPreparation */
@@ -89,7 +96,7 @@ s1ap_message_decoded_callback messages_callback[][3] = {
   { 0, 0, 0 }, /* HandoverNotification */
   { 0, 0, 0 }, /* PathSwitchRequest */
   { 0, 0, 0 }, /* HandoverCancel */
-  { 0, 0, 0 }, /* E_RABSetup */
+  { s1ap_eNB_handle_e_rab_setup_request, 0, 0 }, /* E_RABSetup */
   { 0, 0, 0 }, /* E_RABModify */
   { 0, 0, 0 }, /* E_RABRelease */
   { 0, 0, 0 }, /* E_RABReleaseIndication */
@@ -872,3 +879,107 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t               assoc_id,
   }
 }
 
+static
+int s1ap_eNB_handle_e_rab_setup_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;
+
+  S1ap_E_RABSetupRequestIEs_t         *s1ap_E_RABSetupRequest;
+  DevAssert(s1ap_message_p != NULL);
+
+  s1ap_E_RABSetupRequest = &s1ap_message_p->msg.s1ap_E_RABSetupRequestIEs;
+
+  if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) {
+    S1AP_ERROR("[SCTP %d] Received initial context setup 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_RABSetupRequest->eNB_UE_S1AP_ID)) == NULL) {
+    S1AP_ERROR("[SCTP %d] Received initial context setup request for non "
+               "existing UE context 0x%06x\n", assoc_id,
+               s1ap_E_RABSetupRequest->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_RABSetupRequest->mme_ue_s1ap_id){
+    S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %d)", 
+	      ue_desc_p->mme_ue_s1ap_id, s1ap_E_RABSetupRequest->mme_ue_s1ap_id);
+
+  }
+  message_p        = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_SETUP_REQ);
+ 
+  S1AP_E_RAB_SETUP_REQ(message_p).ue_initial_id  = ue_desc_p->ue_initial_id;
+  
+  S1AP_E_RAB_SETUP_REQ(message_p).mme_ue_s1ap_id  = s1ap_E_RABSetupRequest->mme_ue_s1ap_id;
+  S1AP_E_RAB_SETUP_REQ(message_p).eNB_ue_s1ap_id  = s1ap_E_RABSetupRequest->eNB_UE_S1AP_ID;
+   
+   S1AP_E_RAB_SETUP_REQ(message_p).nb_e_rabs_tosetup =
+    s1ap_E_RABSetupRequest->e_RABToBeSetupListBearerSUReq.s1ap_E_RABToBeSetupItemBearerSUReq.count;
+ 
+  for (i = 0; i < s1ap_E_RABSetupRequest->e_RABToBeSetupListBearerSUReq.s1ap_E_RABToBeSetupItemBearerSUReq.count; i++) {
+    S1ap_E_RABToBeSetupItemBearerSUReq_t *item_p;
+   
+    item_p = (S1ap_E_RABToBeSetupItemBearerSUReq_t *)s1ap_E_RABSetupRequest->e_RABToBeSetupListBearerSUReq.s1ap_E_RABToBeSetupItemBearerSUReq.array[i];
+
+    S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_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_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = item_p->nAS_PDU.size;
+
+      S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size);
+
+      memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer,
+             item_p->nAS_PDU.buf, item_p->nAS_PDU.size);
+    } else {
+      S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = 0;
+      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;
+    }
+
+    /* Set the transport layer address */
+    memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.buffer,
+           item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size);
+    S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length =
+      item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused;
+
+    /* GTP tunnel endpoint ID */
+    OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].gtp_teid);
+
+    /* Set the QOS informations */
+    S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI;
+
+    S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.priority_level =
+      item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel;
+    S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.pre_emp_capability =
+      item_p->e_RABlevelQoSParameters.allocationRetentionPriority.pre_emptionCapability;
+    S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_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;
+}
+
+
diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c
index 0cd4c08cb1244d2ab1a53bf3a2a3ccbbe7fecac0..e54a04f00991e77409b0b7d8943dd4a363f7c67a 100644
--- a/openair3/S1AP/s1ap_eNB_nas_procedures.c
+++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c
@@ -686,3 +686,94 @@ int s1ap_eNB_ue_capabilities(instance_t instance,
   return ret;
 }
 
+//------------------------------------------------------------------------------
+int s1ap_eNB_e_rab_setup_resp(instance_t instance, 
+			      s1ap_e_rab_setup_resp_t *e_rab_setup_resp_p)
+//------------------------------------------------------------------------------
+{
+  s1ap_eNB_instance_t          *s1ap_eNB_instance_p = NULL;
+  struct s1ap_eNB_ue_context_s *ue_context_p        = NULL;
+
+  S1ap_E_RABSetupResponseIEs_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_setup_resp_p != NULL);
+  DevAssert(s1ap_eNB_instance_p != NULL);
+
+  if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p,
+					      e_rab_setup_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_setup_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_setup_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_RABSetup;
+
+  initial_ies_p = &message.msg.s1ap_E_RABSetupResponseIEs;
+
+  initial_ies_p->eNB_UE_S1AP_ID = e_rab_setup_resp_p->eNB_ue_s1ap_id;
+  initial_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id;
+
+  for (i = 0; i < e_rab_setup_resp_p->nb_of_e_rabs; i++) {
+    S1ap_E_RABSetupItemBearerSURes_t *new_item;
+
+    new_item = calloc(1, sizeof(S1ap_E_RABSetupItemBearerSURes_t));
+
+    new_item->e_RAB_ID = e_rab_setup_resp_p->e_rabs[i].e_rab_id;
+    GTP_TEID_TO_ASN1(e_rab_setup_resp_p->e_rabs[i].gtp_teid, &new_item->gTP_TEID);
+    new_item->transportLayerAddress.buf = e_rab_setup_resp_p->e_rabs[i].eNB_addr.buffer;
+    new_item->transportLayerAddress.size = e_rab_setup_resp_p->e_rabs[i].eNB_addr.length;
+    new_item->transportLayerAddress.bits_unused = 0;
+
+    ASN_SEQUENCE_ADD(&initial_ies_p->e_RABSetupListBearerSURes.s1ap_E_RABSetupItemBearerSURes,
+                     new_item);
+  }
+
+  if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) {
+    S1AP_ERROR("Failed to encode uplink NAS 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 Setup successfulOutcome 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;
+}