diff --git a/common/utils/itti/intertask_interface.c b/common/utils/itti/intertask_interface.c
index 554f50a2a103bf35044030974e8347d5bf22491e..85b5fef5096a4ddabf4f0463ebb07d6675c2d3d0 100644
--- a/common/utils/itti/intertask_interface.c
+++ b/common/utils/itti/intertask_interface.c
@@ -391,6 +391,103 @@ int itti_send_msg_to_task(task_id_t destination_task_id, instance_t instance, Me
   return 0;
 }
 
+/* same as itti_send_msg_to_task but returns -1 in case of failure instead of crashing */
+/* TODO: this is a hack - the whole logic needs a proper rework. */
+/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
+int itti_try_send_msg_to_task(task_id_t destination_task_id, instance_t instance, MessageDef *message)
+{
+  thread_id_t destination_thread_id;
+  task_id_t origin_task_id;
+  message_list_t *new;
+  uint32_t priority;
+  message_number_t message_number;
+  uint32_t message_id;
+
+  AssertFatal (message != NULL, "Message is NULL!\n");
+  AssertFatal (destination_task_id < itti_desc.task_max, "Destination task id (%d) is out of range (%d)\n", destination_task_id, itti_desc.task_max);
+
+  destination_thread_id = TASK_GET_THREAD_ID(destination_task_id);
+  message->ittiMsgHeader.destinationTaskId = destination_task_id;
+  message->ittiMsgHeader.instance = instance;
+  message->ittiMsgHeader.lte_time.frame = itti_desc.lte_time.frame;
+  message->ittiMsgHeader.lte_time.slot = itti_desc.lte_time.slot;
+  message_id = message->ittiMsgHeader.messageId;
+  AssertFatal (message_id < itti_desc.messages_id_max, "Message id (%d) is out of range (%d)!\n", message_id, itti_desc.messages_id_max);
+
+  origin_task_id = ITTI_MSG_ORIGIN_ID(message);
+
+  priority = itti_get_message_priority (message_id);
+
+  /* Increment the global message number */
+  message_number = itti_increment_message_number ();
+
+  itti_dump_queue_message (origin_task_id, message_number, message, itti_desc.messages_info[message_id].name,
+                           sizeof(MessageHeader) + message->ittiMsgHeader.ittiMsgSize);
+
+  if (destination_task_id != TASK_UNKNOWN) {
+
+    if (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_ENDED) {
+      ITTI_DEBUG(ITTI_DEBUG_ISSUES, " Message %s, number %lu with priority %d can not be sent from %s to queue (%u:%s), ended destination task!\n",
+                 itti_desc.messages_info[message_id].name,
+                 message_number,
+                 priority,
+                 itti_get_task_name(origin_task_id),
+                 destination_task_id,
+                 itti_get_task_name(destination_task_id));
+    } else {
+      /* We cannot send a message if the task is not running */
+      AssertFatal (itti_desc.threads[destination_thread_id].task_state == TASK_STATE_READY,
+                   "Task %s Cannot send message %s (%d) to thread %d, it is not in ready state (%d)!\n",
+                   itti_get_task_name(origin_task_id),
+                   itti_desc.messages_info[message_id].name,
+                   message_id,
+                   destination_thread_id,
+                   itti_desc.threads[destination_thread_id].task_state);
+
+      /* Allocate new list element */
+      new = (message_list_t *) itti_malloc (origin_task_id, destination_task_id, sizeof(struct message_list_s));
+
+      /* Fill in members */
+      new->msg = message;
+      new->message_number = message_number;
+      new->message_priority = priority;
+
+      /* Enqueue message in destination task queue */
+      if (lfds611_queue_enqueue(itti_desc.tasks[destination_task_id].message_queue, new) == 0) {
+        itti_free(origin_task_id, new);
+        return -1;
+      }
+
+      {
+        /* Only use event fd for tasks, subtasks will pool the queue */
+        if (TASK_GET_PARENT_TASK_ID(destination_task_id) == TASK_UNKNOWN) {
+          ssize_t write_ret;
+          eventfd_t sem_counter = 1;
+
+          /* Call to write for an event fd must be of 8 bytes */
+          write_ret = write (itti_desc.threads[destination_thread_id].task_event_fd, &sem_counter, sizeof(sem_counter));
+          AssertFatal (write_ret == sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n",
+                       destination_thread_id, (int) write_ret, (int) sizeof(sem_counter));
+        }
+      }
+
+      ITTI_DEBUG(ITTI_DEBUG_SEND, " Message %s, number %lu with priority %d successfully sent from %s to queue (%u:%s)\n",
+                 itti_desc.messages_info[message_id].name,
+                 message_number,
+                 priority,
+                 itti_get_task_name(origin_task_id),
+                 destination_task_id,
+                 itti_get_task_name(destination_task_id));
+    }
+  } else {
+    /* This is a debug message to TASK_UNKNOWN, we can release safely release it */
+    int result = itti_free(origin_task_id, message);
+    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+  }
+
+  return 0;
+}
+
 void itti_subscribe_event_fd(task_id_t task_id, int fd)
 {
   thread_id_t thread_id;
diff --git a/common/utils/itti/intertask_interface.h b/common/utils/itti/intertask_interface.h
index 606c851d1de02dd6647f68321499a83da3e6fcc3..ada34ce1b722a09722373cc5a650870364891b4e 100644
--- a/common/utils/itti/intertask_interface.h
+++ b/common/utils/itti/intertask_interface.h
@@ -108,6 +108,18 @@ int itti_send_broadcast_message(MessageDef *message_p);
  **/
 int itti_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message);
 
+/* TODO: this is a hack. Almost no caller of itti_send_msg_to_task checks
+ * the return value so it has been changed to crash the program in case
+ * of failure instead of returning -1 as the documentation above says.
+ * The RLC UM code may receive too much data when doing UDP at a higher
+ * throughput than the link allows and so for this specific case we need
+ * a version that actually returns -1 on failure.
+ *
+ * This needs to be cleaned at some point.
+ */
+/* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
+int itti_try_send_msg_to_task(task_id_t task_id, instance_t instance, MessageDef *message);
+
 /** \brief Add a new fd to monitor.
  * NOTE: it is up to the user to read data associated with the fd
  *  \param task_id Task ID of the receiving task
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index a12a0fd21078ade08e5e513710769e26a1c61525..9ca33c9404d610cc29d4c1eac6f9210147db6790 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -738,6 +738,8 @@ typedef struct RU_t_s{
   void                 (*fh_south_asynch_in)(struct RU_t_s *ru,int *frame, int *subframe);
   /// function pointer to initialization function for radio interface
   int                  (*start_rf)(struct RU_t_s *ru);
+  /// function pointer to release function for radio interface
+  int                  (*stop_rf)(struct RU_t_s *ru);
   /// function pointer to initialization function for radio interface
   int                  (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB);
   /// function pointer to RX front-end processing routine (DFTs/prefix removal or NULL)
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
index aeaa55a79acd6312288102ea1ebf60132c0a8507..0729073eba3cc5e6ca1351603329d83c095497bc 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c
@@ -154,7 +154,7 @@ schedule_next_dlue(module_id_t module_idP, int CC_id,
 }
 
 //------------------------------------------------------------------------------
-unsigned char
+int
 generate_dlsch_header(unsigned char *mac_header,
 		      unsigned char num_sdus,
 		      unsigned short *sdu_lengths,
@@ -344,7 +344,6 @@ generate_dlsch_header(unsigned char *mac_header,
   //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header);
 
   return ((unsigned char *) mac_header_ptr - mac_header);
-
 }
 
 //------------------------------------------------------------------------------
@@ -563,33 +562,28 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 		 frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag)
 //------------------------------------------------------------------------------
 {
-
-
-  uint8_t CC_id;
+  int CC_id;
   int UE_id;
-  unsigned char aggregation;
+  int aggregation;
   mac_rlc_status_resp_t rlc_status;
-  unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0;
-  unsigned char header_len_dtch = 0, header_len_dtch_tmp =
-    0, header_len_dtch_last = 0;
-  unsigned char ta_len = 0;
-  unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0;
-  uint16_t nb_rb, nb_rb_temp, nb_available_rb;
-  uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding =
-    0, post_padding = 0;
+  int ta_len = 0;
+  unsigned char sdu_lcids[NB_RB_MAX];
+  int lcid, offset, num_sdus = 0;
+  int nb_rb, nb_rb_temp, nb_available_rb;
+  uint16_t sdu_lengths[NB_RB_MAX];
+  int TBS, j, rnti, padding = 0, post_padding = 0;
   unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
-  unsigned char round = 0;
-  unsigned char harq_pid = 0;
+  int round = 0;
+  int harq_pid = 0;
   eNB_UE_STATS *eNB_UE_stats = NULL;
-  uint16_t sdu_length_total = 0;
+  int sdu_length_total = 0;
 
   eNB_MAC_INST *eNB = RC.mac[module_idP];
   COMMON_channels_t *cc = eNB->common_channels;
   UE_list_t *UE_list = &eNB->UE_list;
   int continue_flag = 0;
   int32_t normalized_rx_power, target_rx_power;
-  int32_t tpc = 1;
-  static int32_t tpc_accumulated = 0;
+  int tpc = 1;
   UE_sched_ctrl *ue_sched_ctl;
   int mcs;
   int i;
@@ -601,6 +595,8 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
   nfapi_dl_config_request_pdu_t *dl_config_pdu;
   int tdd_sfa;
   int ta_update;
+  int header_length_last;
+  int header_length_total;
 
 #if 0
   if (UE_list->head == -1) {
@@ -792,6 +788,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
       if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue;
 
+      header_length_total = 0;
       sdu_length_total = 0;
       num_sdus = 0;
 
@@ -838,8 +835,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	  if (cc[CC_id].tdd_Config != NULL) {
 	    UE_list->UE_template[CC_id][UE_id].DAI++;
 	    update_ul_dci(module_idP, CC_id, rnti,
-			  UE_list->UE_template[CC_id][UE_id].
-			  DAI);
+			  UE_list->UE_template[CC_id][UE_id].DAI);
 	    LOG_D(MAC,
 		  "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
 		  CC_id, subframeP, UE_id,
@@ -988,13 +984,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 		module_idP, frameP, CC_id, UE_id);
 	}
       } else {		/* This is a potentially new SDU opportunity */
-
 	rlc_status.bytes_in_buffer = 0;
+
 	// Now check RLC information to compute number of required RBs
 	// get maximum TBS size for RLC request
-	TBS =
-	  get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb);
-	// check first for RLC data on DCCH
+	TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb);
+
 	// add the length for  all the control elements (timing adv, drx, etc) : header + payload
 
 	if (ue_sched_ctl->ta_timer == 0) {
@@ -1009,38 +1004,42 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
 	ta_len = (ta_update != 31) ? 2 : 0;
 
-	header_len_dcch = 2;	// 2 bytes DCCH SDU subheader
-
-	if (TBS - ta_len - header_len_dcch > 0) {
-	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch));	// transport block set size
+	// RLC data on DCCH
+	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
+	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
+                                          TBS - ta_len - header_length_total - sdu_length_total - 3);
 
 	  sdu_lengths[0] = 0;
 
-	  if (rlc_status.bytes_in_buffer > 0) {	// There is DCCH to transmit
-	    LOG_D(MAC,
-		  "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
+	  if (rlc_status.bytes_in_buffer > 0) {
+	    LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
 		  module_idP, frameP, subframeP, CC_id,
-		  TBS - header_len_dcch);
-	    sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS,	//not used
-					      (char *)
-					      &dlsch_buffer
-					      [0]);
+		  TBS - ta_len - header_length_total - sdu_length_total - 3);
+
+	    sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
+                                              TBS, //not used
+					      (char *)&dlsch_buffer[0]);
 
 	    T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
 	      T_INT(CC_id), T_INT(rnti), T_INT(frameP),
 	      T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH),
 	      T_INT(sdu_lengths[0]));
 
-	    LOG_D(MAC,
-		  "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
+	    LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
 		  module_idP, CC_id, sdu_lengths[0]);
+
 	    sdu_length_total = sdu_lengths[0];
 	    sdu_lcids[0] = DCCH;
             UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH;
             UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0];
 	    UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1;
 	    UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0];
+
+            header_length_last = 1 + 1 + (sdu_lengths[0] >= 128);
+            header_length_total += header_length_last;
+
 	    num_sdus = 1;
+
 #ifdef DEBUG_eNB_SCHEDULER
 	    LOG_T(MAC,
 		  "[eNB %d][DCCH] CC_id %d Got %d bytes :",
@@ -1052,26 +1051,25 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
 	    LOG_T(MAC, "\n");
 #endif
-	  } else {
-	    header_len_dcch = 0;
-	    sdu_length_total = 0;
 	  }
 	}
-	// check for DCCH1 and update header information (assume 2 byte sub-header)
-	if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) {
-	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total));	// transport block set size less allocations for timing advance and
+
+	// RLC data on DCCH1
+	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
+	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
+                                          TBS - ta_len - header_length_total - sdu_length_total - 3);
+
 	  // DCCH SDU
 	  sdu_lengths[num_sdus] = 0;
 
 	  if (rlc_status.bytes_in_buffer > 0) {
-	    LOG_D(MAC,
-		  "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
+	    LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
 		  module_idP, frameP, CC_id,
-		  TBS - header_len_dcch - sdu_length_total);
-	    sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS,	//not used
-						      (char *)
-						      &dlsch_buffer
-						      [sdu_length_total]);
+		  TBS - ta_len - header_length_total - sdu_length_total - 3);
+
+	    sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
+                                                      TBS, //not used
+						      (char *)&dlsch_buffer[sdu_length_total]);
 
 	    T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
 	      T_INT(CC_id), T_INT(rnti), T_INT(frameP),
@@ -1080,13 +1078,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
 	    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].lcid_sdu[num_sdus] = DCCH1;
             UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus];
-	    UE_list->eNB_UE_stats[CC_id][UE_id].
-	      num_pdu_tx[DCCH1] += 1;
+	    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];
+
+            header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
+            header_length_total += header_length_last;
+
 	    num_sdus++;
+
 #ifdef DEBUG_eNB_SCHEDULER
 	    LOG_T(MAC,
 		  "[eNB %d][DCCH1] CC_id %d Got %d bytes :",
@@ -1098,25 +1099,18 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
 	    LOG_T(MAC, "\n");
 #endif
-
 	  }
 	}
-	// assume the max dtch header size, and adjust it later
-	header_len_dtch = 0;
-	header_len_dtch_last = 0;	// the header length of the last mac sdu
-	// lcid has to be sorted before the actual allocation (similar struct as ue_list).
+
+	// TODO: 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
+	  // TODO: 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",
+	  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);
+                TBS - ta_len - header_length_total - sdu_length_total - 3);
 
-	  if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) {	// NN: > 2 ?
+	  if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
 	    rlc_status = mac_rlc_status_ind(module_idP,
 					    rnti,
 					    module_idP,
@@ -1125,25 +1119,22 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 					    ENB_FLAG_YES,
 					    MBMS_FLAG_NO,
 					    lcid,
-					    TBS - ta_len -
-					    header_len_dcch -
-					    sdu_length_total -
-					    header_len_dtch);
+					    TBS - ta_len - header_length_total - sdu_length_total - 3);
 
 
-	    if (rlc_status.bytes_in_buffer > 0) {
 
+	    if (rlc_status.bytes_in_buffer > 0) {
 	      LOG_D(MAC,
 		    "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
 		    module_idP, frameP,
-		    TBS - header_len_dcch -
-		    sdu_length_total - header_len_dtch, lcid,
-		    header_len_dtch);
-	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS,	//not used
-						       (char
-							*)
-						       &dlsch_buffer
-						       [sdu_length_total]);
+                    TBS - ta_len - header_length_total - sdu_length_total - 3,
+		    lcid,
+		    header_length_total);
+
+	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid,
+                                                       TBS, //not used
+						       (char *)&dlsch_buffer[sdu_length_total]);
+
 	      T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
 		T_INT(CC_id), T_INT(rnti), T_INT(frameP),
 		T_INT(subframeP), T_INT(harq_pid),
@@ -1152,50 +1143,39 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	      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_pdu_tx[lcid]++;
               UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid;
               UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus];
-	      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--;
-	      }
+	      UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus];
+
+              header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
+              header_length_total += header_length_last;
+
 	      num_sdus++;
+
 	      UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
-	    }	// no data for this LCID
-	    else {
-	      header_len_dtch -= 3;
 	    }
-	  }		// no TBS left
-	  else {
-	    header_len_dtch -= 3;
+	  } else {
+            // no TBS left
 	    break;
 	  }
 	}
-	if (header_len_dtch == 0)
-	  header_len_dtch_last = 0;
-	// there is at least one SDU
+
+        /* last header does not have length field */
+        if (header_length_total) {
+          header_length_total -= header_length_last;
+          header_length_total++;
+        }
+
+	// there is at least one SDU or TA command
 	// if (num_sdus > 0 ){
-	if ((sdu_length_total + header_len_dcch +
-	     header_len_dtch) > 0) {
+	if (ta_len + sdu_length_total + header_length_total > 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;
 
@@ -1207,16 +1187,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
 	  TBS = get_TBS_DL(mcs, nb_rb);
 
-	  while (TBS <
-		 (sdu_length_total + header_len_dcch +
-		  header_len_dtch + ta_len)) {
+	  while (TBS < sdu_length_total + header_length_total + ta_len) {
 	    nb_rb += min_rb_unit[CC_id];	//
 
 	    if (nb_rb > nb_available_rb) {	// if we've gone beyond the maximum number of RBs
 	      // (can happen if N_RB_DL is odd)
-	      TBS =
-		get_TBS_DL(eNB_UE_stats->dlsch_mcs1,
-			   nb_available_rb);
+	      TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb);
 	      nb_rb = nb_available_rb;
 	      break;
 	    }
@@ -1250,13 +1226,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	  }
 
 	  // decrease mcs until TBS falls below required length
-	  while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs > 0)) {
+	  while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) {
 	    mcs--;
 	    TBS = get_TBS_DL(mcs, nb_rb);
 	  }
 
 	  // if we have decreased too much or we don't have enough RBs, increase MCS
-	  while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len))
+	  while ((TBS < sdu_length_total + header_length_total + ta_len)
 		 && (((ue_sched_ctl->dl_pow_off[CC_id] > 0)
 		      && (mcs < 28))
 		     || ((ue_sched_ctl->dl_pow_off[CC_id] == 0)
@@ -1277,23 +1253,14 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	  //  TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
 #endif
 
-	  if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) {
-	    padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len);
+	  if (TBS - header_length_total - sdu_length_total - ta_len <= 2) {
+	    padding = TBS - header_length_total - sdu_length_total - ta_len;
 	    post_padding = 0;
 	  } else {
 	    padding = 0;
-
-	    // adjust the header len
-	    if (header_len_dtch == 0) {
-	      header_len_dcch = header_len_dcch_tmp;
-	    } else {	//if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
-	      header_len_dtch = header_len_dtch_tmp;
-	    }
-
-	    post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len;	// 1 is for the postpadding header
+	    post_padding = 1;
 	  }
 
-
 	  offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus,	//num_sdus
 					 sdu_lengths,	//
 					 sdu_lcids, 255,	// no drx
@@ -1304,12 +1271,12 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	  //#ifdef DEBUG_eNB_SCHEDULER
 	  if (ta_update != 31) {
 	    LOG_D(MAC,
-		  "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n",
+		  "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n",
 		  module_idP, frameP, UE_id, CC_id,
 		  sdu_length_total, num_sdus, sdu_lengths[0],
 		  sdu_lcids[0], offset, ta_update, padding,
 		  post_padding, mcs, TBS, nb_rb,
-		  header_len_dcch, header_len_dtch);
+		  header_length_total);
 	  }
 	  //#endif
 #ifdef DEBUG_eNB_SCHEDULER
@@ -1327,11 +1294,16 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 		 dlsch_buffer, sdu_length_total);
 	  // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);
 
+#if 0
 	  // fill remainder of DLSCH with random data
 	  for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
 	    UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = (char) (taus() & 0xff);
 	  }
-
+#endif
+	  // fill remainder of DLSCH with 0
+	  for (j = 0; j < (TBS - sdu_length_total - offset); j++) {
+	    UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0;
+	  }
 
 	  if (opt_enabled == 1) {
 	    trace_pdu(1, (uint8_t *)
@@ -1348,8 +1320,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	  T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP),
 	    T_INT(CC_id), T_INT(rnti), T_INT(frameP),
 	    T_INT(subframeP), T_INT(harq_pid),
-	    T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].
-		     payload[0], TBS));
+	    T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS));
 
 	  UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb;
 
@@ -1378,6 +1349,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 			  UE_list->UE_template[CC_id][UE_id].
 			  DAI);
 	  }
+
 	  // do PUCCH power control
 	  // this is the normalized RX power
 	  eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
@@ -1399,18 +1371,15 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
 	      if (normalized_rx_power > (target_rx_power + 4)) {
 		tpc = 0;	//-1
-		tpc_accumulated--;
 	      } else if (normalized_rx_power < (target_rx_power - 4)) {
 		tpc = 2;	//+1
-		tpc_accumulated++;
 	      } else {
 		tpc = 1;	//0
 	      }
 
 	      LOG_D(MAC,
-		    "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
-		    module_idP, frameP, subframeP, harq_pid,
-		    tpc, tpc_accumulated,
+		    "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n",
+		    module_idP, frameP, subframeP, harq_pid, tpc,
 		    normalized_rx_power, target_rx_power);
 
 	    }	// Po_PUCCH has been updated
@@ -1456,13 +1425,13 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 		  module_idP, CC_id, harq_pid, mcs);
 
 	  }
+
 	  LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n",
 		dl_req->number_pdu);
+
 	  if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP,
 					 dl_config_pdu->dci_dl_pdu.
 					 dci_dl_pdu_rel8.aggregation_level, rnti)) {
-
-
 	    ue_sched_ctl->round[CC_id][harq_pid] = 0;
 	    dl_req->number_dci++;
 	    dl_req->number_pdu++;
@@ -1482,8 +1451,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	    UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
 	    UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs;
 	    UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0;
-	    AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated !=
-			NULL,
+	    AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL,
 			"physicalConfigDedicated is NULL\n");
 	    AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL,
 			"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n");
@@ -1506,15 +1474,10 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 				    0,	//number of PRBs treated as one subband, not used here
 				    0	// number of beamforming vectors, not used here
 				    );
-	    eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->
-							  TX_req
-							  [CC_id].tx_request_body,
+	    eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body,
 							  (frameP * 10) + subframeP,
 							  TBS, eNB->pdu_index[CC_id],
-							  eNB->
-							  UE_list.DLSCH_pdu[CC_id][0][(unsigned char)
-										      UE_id].payload
-							  [0]);
+							  eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]);
 
 	    LOG_D(MAC,
 		  "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",
@@ -1523,10 +1486,7 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 	    eNB->pdu_index[CC_id]++;
 	    program_dlsch_acknak(module_idP, CC_id, UE_id,
 				 frameP, subframeP,
-				 dl_config_pdu->
-				 dci_dl_pdu.dci_dl_pdu_rel8.
-				 cce_idx);
-
+				 dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx);
 	  } else {
 	    LOG_W(MAC,
 		  "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n",
@@ -1550,7 +1510,6 @@ schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
 
   stop_meas(&eNB->schedule_dlsch);
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT);
-
 }
 
 //------------------------------------------------------------------------------
diff --git a/openair2/LAYER2/MAC/proto.h b/openair2/LAYER2/MAC/proto.h
index 07159f9c2432484b99576b6116da7d66860d9a61..2586c94f432887276f6359e5039b55770dae3bd9 100644
--- a/openair2/LAYER2/MAC/proto.h
+++ b/openair2/LAYER2/MAC/proto.h
@@ -855,15 +855,15 @@ in the DLSCH buffer.
 @param post_padding number of bytes for padding at the end of MAC PDU
 @returns Number of bytes used for header
 */
-unsigned char generate_dlsch_header(unsigned char *mac_header,
-				    unsigned char num_sdus,
-				    unsigned short *sdu_lengths,
-				    unsigned char *sdu_lcids,
-				    unsigned char drx_cmd,
-				    unsigned short timing_advance_cmd,
-				    unsigned char *ue_cont_res_id,
-				    unsigned char short_padding,
-				    unsigned short post_padding);
+int generate_dlsch_header(unsigned char *mac_header,
+                          unsigned char num_sdus,
+                          unsigned short *sdu_lengths,
+                          unsigned char *sdu_lcids,
+                          unsigned char drx_cmd,
+                          unsigned short timing_advance_cmd,
+                          unsigned char *ue_cont_res_id,
+                          unsigned char short_padding,
+                          unsigned short post_padding);
 
 /** \brief RRC eNB Configuration primitive for PHY/MAC.  Allows configuration of PHY/MAC resources based on System Information (SI), RRCConnectionSetup and RRCConnectionReconfiguration messages.
 @param Mod_id Instance ID of eNB
diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
index d27d46ff4282b4ca3488a85ffb649f6f5d7d80ee..783441bd586928fb2dfe9dfc61dc1e926ca31ada 100644
--- a/openair2/LAYER2/RLC/rlc.c
+++ b/openair2/LAYER2/RLC/rlc.c
@@ -437,6 +437,15 @@ rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
       break;
 
     case RLC_MODE_UM:
+      /* TODO: this is a hack, needs better solution. Let's not use too
+       * much memory and store at maximum 5 millions bytes.
+       */
+      /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
+      if (rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um) > 5000000) {
+        free_mem_block(sdu_pP, __func__);
+        return RLC_OP_STATUS_OUT_OF_RESSOURCES;
+      }
+
       new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
 
       if (new_sdu_p != NULL) {
diff --git a/openair3/UDP/udp_eNB_task.c b/openair3/UDP/udp_eNB_task.c
index 527715eb7a2470c3577bb1a3b5a4fa40303af74b..4d6bd6e033a45417a2044e2cfb39ffff3ac8d1c8 100644
--- a/openair3/UDP/udp_eNB_task.c
+++ b/openair3/UDP/udp_eNB_task.c
@@ -270,10 +270,21 @@ void udp_eNB_receiver(struct udp_socket_desc_s *udp_sock_pP)
             n, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
 #endif
 
-      if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) {
+      /* TODO: this is a hack. Let's accept failures and do nothing when
+       * it happens. Since itti_send_msg_to_task crashes when the message
+       * queue is full we wrote itti_try_send_msg_to_task that returns -1
+       * if the queue is full.
+       */
+      /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
+      //if (itti_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) {
+      if (itti_try_send_msg_to_task(udp_sock_pP->task_id, INSTANCE_DEFAULT, message_p) < 0) {
+#if 0
         LOG_I(UDP_, "Failed to send message %d to task %d\n",
               UDP_DATA_IND,
               udp_sock_pP->task_id);
+#endif
+        itti_free(TASK_UDP, message_p);
+        itti_free(TASK_UDP, forwarded_buffer);
         return;
       }
     }
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 01a2c68bf3b5147e45945fff430a1dad2acdf2fb..e1c5d10de561435bae4171bbf1714f6730b63470 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -163,13 +163,6 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
 
 
 static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) {
-
-  static double cpu_freq_GHz = 0.0;
-
-  if (cpu_freq_GHz == 0.0)
-    cpu_freq_GHz = get_cpu_freq_GHz();
-
-
   start_meas(&softmodem_stats_rxtx_sf);
 
   // *******************************************************************
diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
index d909da627fa81ec88e1dfd950af7e9cba0d90c61..d9bda6a037993a4771c58eb4d9791f1ed9df40ee 100644
--- a/targets/RT/USER/lte-ru.c
+++ b/targets/RT/USER/lte-ru.c
@@ -1523,7 +1523,13 @@ static void* ru_thread( void* param ) {
   
 
   printf( "Exiting ru_thread \n");
- 
+
+  if (ru->stop_rf != NULL) {
+    if (ru->stop_rf(ru) != 0)
+      LOG_E(HW,"Could not stop the RF device\n");
+    else LOG_I(PHY,"RU %d rf device stopped\n",ru->idx);
+  }
+
   ru_thread_status = 0;
   return &ru_thread_status;
 
@@ -1617,6 +1623,12 @@ int start_rf(RU_t *ru) {
   return(ru->rfdevice.trx_start_func(&ru->rfdevice));
 }
 
+int stop_rf(RU_t *ru)
+{
+  ru->rfdevice.trx_end_func(&ru->rfdevice);
+  return 0;
+}
+
 extern void fep_full(RU_t *ru);
 extern void ru_fep_full_2thread(RU_t *ru);
 extern void feptx_ofdm(RU_t *ru);
@@ -2082,6 +2094,7 @@ void set_function_spec_param(RU_t *ru)
     ru->fh_south_in            = rx_rf;                               // local synchronous RF RX
     ru->fh_south_out           = tx_rf;                               // local synchronous RF TX
     ru->start_rf               = start_rf;                            // need to start the local RF interface
+    ru->stop_rf                = stop_rf;
     printf("configuring ru_id %d (start_rf %p)\n", ru->idx, start_rf);
 /*
     if (ru->function == eNodeB_3GPP) { // configure RF parameters only for 3GPP eNodeB, we need to get them from RAU otherwise
@@ -2113,6 +2126,7 @@ void set_function_spec_param(RU_t *ru)
       ru->fh_south_asynch_in   = NULL;                // no asynchronous UL
     }
     ru->start_rf               = NULL;                 // no local RF
+    ru->stop_rf                = NULL;
     ru->start_if               = start_if;             // need to start if interface for IF5
     ru->ifdevice.host_type     = RAU_HOST;
     ru->ifdevice.eth_params    = &ru->eth_params;
@@ -2137,6 +2151,7 @@ void set_function_spec_param(RU_t *ru)
     ru->fh_north_out           = NULL;
     ru->fh_north_asynch_in     = NULL;
     ru->start_rf               = NULL;                // no local RF
+    ru->stop_rf                = NULL;
     ru->start_if               = start_if;            // need to start if interface for IF4p5
     ru->ifdevice.host_type     = RAU_HOST;
     ru->ifdevice.eth_params    = &ru->eth_params;
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 6b52bab64cbb14505aba552f88d66d8863c12e9a..03313146df30ab2dc486fc10ab494f48e7650226 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -1005,10 +1005,8 @@ int main( int argc, char **argv )
 
   printf("Runtime table\n");
   fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
-  cpuf=get_cpu_freq_GHz();
-  
-  
-  
+
+
 #ifndef DEADLINE_SCHEDULER
   
   printf("NO deadline scheduler\n");