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");